PyObjC framework SensitiveContentAnalysis
PyObjC-framework-SensitiveContentAnalysis provides Python wrappers for Apple's macOS SensitiveContentAnalysis framework (macOS 14.0+). This framework enables apps to check images and videos for nudity, supporting features like Sensitive Content Warning and Communication Safety parental controls. The library is part of the larger PyObjC project, which acts as a bridge between Python and Objective-C, allowing Python applications to leverage macOS's native Cocoa APIs. Version 12.1 is the latest release, with regular updates aligning with macOS SDK changes and Python versions.
Warnings
- gotcha The SensitiveContentAnalysis framework requires a specific code-signing entitlement (`com.apple.developer.sensitivecontentanalysis.client`) for your macOS application bundle to return meaningful results. Without this entitlement, the framework may not detect sensitive content or may return errors indicating 'User Safety not enabled'. This entitlement must be added via Xcode capabilities, not programmatically in Python.
- breaking PyObjC 12.0 dropped support for Python 3.9. Projects targeting older Python versions should use PyObjC 11.x or earlier. PyObjC 11.0 dropped support for Python 3.8.
- breaking PyObjC 11.1 introduced changes to how `init` family methods (constructors) handle object references, aligning with `clang`'s Automatic Reference Counting (ARC) documentation. This means `[NSObject alloc]` proxies now correctly model that `init` methods steal a reference to `self` and return a new one. Incorrect usage in previous versions, which might have accidentally worked, could now lead to crashes.
- gotcha There was a change in PyObjC 10.3 regarding `__init__` not being called when a user implements `__new__`. While PyObjC 10.3.1 partially reintroduced the ability to use `__init__` in such cases, code relying on the PyObjC-provided `__new__` still cannot use `__init__`.
- deprecated The `isAlloc` attribute of `objc.selector` is deprecated and will be removed in PyObjC 12. This attribute was related to internal reference counting mechanisms that are no longer used by the bridge.
- breaking PyObjC 12.1 automatically disables Key-Value Observing (KVO) usage for subclasses of `NSProxy` defined in Python. If your application relies on KVO with such custom proxy classes, this change will prevent it from working as before.
Install
-
pip install pyobjc-framework-sensitivecontentanalysis
Imports
- SCSensitivityAnalyzer
from SensitiveContentAnalysis import SCSensitivityAnalyzer
- SCSensitivityAnalysis
from SensitiveContentAnalysis import SCSensitivityAnalysis
Quickstart
import SensitiveContentAnalysis
import objc
from PyObjCTools import AppHelper
# NOTE: For SensitiveContentAnalysis to return positive results,
# your macOS application MUST be signed with the
# 'com.apple.developer.sensitivecontentanalysis.client' entitlement.
# This is typically added via Xcode capabilities, not Python code.
# Without it, analysis might always return 'None' or errors like 'User Safety not enabled'.
# Placeholder for a CGImage. In a real app, you'd load this
# from a file (e.g., using Quartz.CGImageSourceCreateWithURL).
# For a runnable example, we define a dummy function.
def create_dummy_cgimage():
# In a real application, you would load a CGImage from a file or buffer.
# This is a conceptual placeholder.
print("\n--- Placeholder: Create a dummy CGImage ---")
print("In a real app, load an image using e.g., Quartz.CGImageSourceCreateWithURL.")
# A real CGImage object from a framework like Quartz would be passed here.
# For demonstration, we'll return None and assume external setup.
return None # Replace with an actual CGImage object
def analysis_completion_handler(result, error):
if error:
print(f"Analysis Error: {error}")
if 'User Safety either not entitled' in str(error):
print("HINT: Ensure your app has the 'com.apple.developer.sensitivecontentanalysis.client' entitlement.")
elif result:
print(f"Sensitive Content Analysis Result: {result.isSensitive()}")
if result.isSensitive():
print("Intervention guidance:", result.interventionPolicy())
else:
print("No result or error provided.")
AppHelper.stopEventLoop()
def perform_analysis():
image = create_dummy_cgimage()
if image is None:
print("Cannot proceed without a real CGImage object. Please set up image loading.")
return
analyzer = SensitiveContentAnalysis.SCSensitivityAnalyzer.alloc().init()
analyzer.analyzeCGImage_completionHandler_(image, analysis_completion_handler)
if __name__ == '__main__':
print("Starting SensitiveContentAnalysis example...")
# To run this in a context where the framework actually works,
# you'd typically embed it in a py2app created application bundle
# that has the necessary entitlements.
AppHelper.callAfter(perform_analysis)
AppHelper.runEventLoop()
print("SensitiveContentAnalysis example finished.")