Plugin API¶
Core plugin lifecycle: BasePlugin, the manifest contract, optional interfaces (discovery, notifier, detection).
camera_ui_sdk.plugin ¶
APIListener
module-attribute
¶
Listener for plugin lifecycle events. May be a plain callable or a coroutine function — the runtime awaits the latter.
PythonVersion
module-attribute
¶
Python interpreter major.minor version a Python plugin requires. The host ensures a matching interpreter exists in its venv pool before launching the plugin; Node and Go plugins ignore this field.
OAuthStatus
module-attribute
¶
Lifecycle phase of an OAuth provider connection, carried in OAuthState.status.
API_EVENT ¶
Bases: Enum
Lifecycle events emitted on the PluginAPI EventEmitter.
Plugins subscribe with api.on(API_EVENT.X, handler) to react to
host-driven phase changes.
FINISH_LAUNCHING
class-attribute
instance-attribute
¶
Emitted exactly once after the plugin has been constructed, all
assigned cameras have been wired up, and configureCameras() has
returned. Use this to start background work that must wait until the
camera set is stable (timers, model warm-up, outbound connections).
SHUTDOWN
class-attribute
instance-attribute
¶
Emitted when the host is tearing the plugin down (graceful stop, reload or process exit). Listeners must release resources synchronously enough to finish before the host kills the process — open files, sockets, timers, child processes.
PluginAPI ¶
Bases: Protocol
The PluginAPI is injected into the plugin at runtime and exposes the
system services the plugin is allowed to talk to. It also acts as an
EventEmitter for plugin lifecycle events (see :class:API_EVENT).
The API is passed to the plugin constructor and should be stored for later use.
Example
coreManager
property
¶
System-level operations such as the FFmpeg path and the server addresses used for media URLs (HTTP/RTSP).
deviceManager
property
¶
Owns the camera devices assigned to this plugin and publishes camera-state changes.
downloadManager
property
¶
Mints token-protected download URLs for files the plugin wants to expose to the UI (e.g. clip exports, snapshots).
notificationManager
property
¶
Publishes notifications into the host so they fan out to every
installed Notifier-plugin and the in-app UI. Requires
:attr:PluginCapability.PublishNotifications in the plugin contract.
storagePath
property
¶
Absolute path to the plugin's writable storage directory. Created and cleaned up by the host. Use it for caches, models, sqlite/bolt files.
on ¶
Subscribe to a lifecycle event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
API_EVENT
|
Lifecycle event to subscribe to. |
required |
f
|
APIListener
|
Event listener (sync callable or coroutine function). |
required |
Returns:
| Type | Description |
|---|---|
Any
|
Self for chaining. |
once ¶
Subscribe to a lifecycle event for one delivery only.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
API_EVENT
|
Lifecycle event to subscribe to. |
required |
f
|
APIListener
|
Event listener (sync callable or coroutine function). |
required |
Returns:
| Type | Description |
|---|---|
Any
|
Self for chaining. |
off ¶
Remove a previously registered listener (alias of
:meth:removeListener).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
API_EVENT
|
Lifecycle event the listener was registered for. |
required |
f
|
APIListener
|
Listener to remove. |
required |
removeListener ¶
Remove a previously registered listener.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
API_EVENT
|
Lifecycle event the listener was registered for. |
required |
f
|
APIListener
|
Listener to remove. |
required |
PluginCapability ¶
Bases: str, Enum
Permission a plugin requests so it can call a host-provided system feature. Each capability gates one outgoing SDK call — calls without the matching capability are rejected by the host.
PublishNotifications
class-attribute
instance-attribute
¶
Grants the plugin permission to call
api.notificationManager.publish. Without this capability the host
silently drops published notifications and logs an error.
PluginContract ¶
Bases: TypedDict
Manifest contract a plugin declares so the host knows what it does
and what it needs at load time. Validated by helper.py before the
plugin is started.
name
instance-attribute
¶
Stable, unique identifier for the plugin instance — used as the registry key, log prefix and the storage namespace.
provides
instance-attribute
¶
Sensor types the plugin produces. Empty for hubs and pure camera-controllers; required for sensor providers.
consumes
instance-attribute
¶
Sensor types the plugin reads from other plugins (e.g. a face plugin consumes camera video frames).
interfaces
instance-attribute
¶
Capability flags the plugin implements (see :class:PluginInterface).
capabilities
instance-attribute
¶
Permissions the plugin requests to call host system features (see
:class:PluginCapability). The host enforces these — calls without a
matching capability are rejected.
pythonVersion
instance-attribute
¶
Required Python interpreter version for Python plugins. Ignored by Node / Go plugins.
dependencies
instance-attribute
¶
Extra package dependencies installed into the plugin's runtime (Go module paths for Go plugins; PyPI / npm names for Python and Node plugins).
PluginInfo ¶
Bases: TypedDict
Lightweight handle identifying an installed plugin — used in RPC payloads and managers to refer to the plugin without shipping its full state.
PluginInterface ¶
Bases: str, Enum
Capability flags a plugin advertises in its contract.
The host uses these to decide which RPC handlers to wire up and which UI affordances to show.
MotionDetection
class-attribute
instance-attribute
¶
Implements MotionDetectionInterface (video-based motion detection).
ObjectDetection
class-attribute
instance-attribute
¶
Implements ObjectDetectionInterface (e.g. person, vehicle, animal).
AudioDetection
class-attribute
instance-attribute
¶
Implements AudioDetectionInterface (event/keyword audio detection).
FaceDetection
class-attribute
instance-attribute
¶
Implements FaceDetectionInterface (face localisation + embeddings). The NVR owns matching against enrolled faces; the plugin only emits detections + embeddings.
LicensePlateDetection
class-attribute
instance-attribute
¶
Implements LicensePlateDetectionInterface (plate localisation + OCR).
ClassifierDetection
class-attribute
instance-attribute
¶
Implements ClassifierDetectionInterface (generic image classification emitting attribute/label pairs).
ClipDetection
class-attribute
instance-attribute
¶
Implements ClipDetectionInterface (CLIP image and text embeddings used for semantic search).
DiscoveryProvider
class-attribute
instance-attribute
¶
Implements DiscoveryProvider — plugin can scan the network for new cameras and adopt them. Only valid for camera-controlling roles.
NVR
class-attribute
instance-attribute
¶
Implements NVRInterface — persists events and recordings, and serves them back to the UI / mobile clients. Exactly one plugin per host fills this role at runtime.
Notifier
class-attribute
instance-attribute
¶
Implements NotifierInterface (get_devices, send_notification, ...). Lets the central NotificationManager dispatch notifications to this plugin regardless of role — see camera_ui_sdk/plugin/notifier.py.
OAuthCapable
class-attribute
instance-attribute
¶
Implements the OAuthCapable base interface (getOAuthMetadata, getOAuthState, disconnect) plus at least one flow sub-interface — see camera_ui_sdk/plugin/oauth.py.
OAuthDeviceFlow
class-attribute
instance-attribute
¶
Implements OAuthDeviceFlowCapable (RFC 8628 Device Authorization Grant).
OAuthAuthCodeFlow
class-attribute
instance-attribute
¶
Implements OAuthAuthCodeFlowCapable (Authorization Code Flow + PKCE).
OAuthClientCredentials
class-attribute
instance-attribute
¶
Implements OAuthClientCredentialsCapable (user-supplied client_id + client_secret).
PluginRole ¶
Bases: str, Enum
Role a plugin plays in the system. The role decides which lifecycle hooks the host invokes and which contract validations apply.
Hub
class-attribute
instance-attribute
¶
System-wide aggregator that attaches to cameras owned by other plugins
to provide a cross-camera service (e.g. bridging cameras and sensors into a
smart-home platform, or recording and notifications). A hub creates no
cameras of its own and provides no sensors (provides must be empty); it
attaches to cameras via the hub assignment and typically reads camera and
sensor state through consumes.
SensorProvider
class-attribute
instance-attribute
¶
Adds sensors to existing cameras without owning the camera itself. Typical use: a detection plugin that consumes another plugin's video frames and emits motion / object / face detections back into the system.
CameraController
class-attribute
instance-attribute
¶
Manages cameras and their media streams (ONVIF, RTSP, generic IP, ...). The plugin is responsible for stream URLs, PTZ, snapshots, and the lifecycle hooks in BasePlugin. It does not produce sensors for foreign cameras.
CameraAndSensorProvider
class-attribute
instance-attribute
¶
Combined role: plugin both manages cameras and exposes sensors (its
own cameras and, when consumes is set, also foreign cameras). Used
by integrations that ship a complete camera + detection stack.
AudioDetectionInterface ¶
Bases: Protocol
Interface implemented by plugins that perform audio event or keyword detection.
testAudioDetection
async
¶
testAudioDetection(audio_data: bytes, metadata: AudioMetadata, config: dict[str, Any]) -> AudioDetectionPluginResponse | None
Run detection on an audio buffer captured by the UI test panel;
metadata carries the input MIME type (mpeg/wav/ogg).
audioDetectionSettings
async
¶
Return the JSON schema used to render the audio-detection settings form in the UI. Return None for no schema.
AudioDetectionPluginResponse ¶
Bases: TypedDict
Response from an audio detection test.
AudioMetadata ¶
Bases: TypedDict
Audio metadata for detection test requests.
BasePlugin ¶
Bases: ABC, Generic[StorageT]
Base class every plugin extends.
It wires up the three dependencies the host injects (logger, PluginAPI, DeviceStorage) and declares the lifecycle methods the host calls on the plugin.
Lifecycle order: the host calls :meth:configureCameras once at startup
with every camera already assigned to this plugin, then calls
:meth:onCameraAdded / :meth:onCameraReleased as the user adds or
removes cameras at runtime.
The generic type parameter StorageT types storage.values so plugin
code gets autocompletion for its own settings shape.
Example
class MyStorageValues(TypedDict):
model_path: str
threshold: float
class MyPlugin(BasePlugin[MyStorageValues]):
async def configureCameras(self, cameras: list[CameraDevice]) -> None:
# storage.values is typed as MyStorageValues
model_path = self.storage.values.get("model_path") # str
for camera in cameras:
await self.onCameraAdded(camera)
async def onCameraAdded(self, camera: CameraDevice) -> None:
# Initialize camera controller
pass
async def onCameraReleased(self, camera_id: str) -> None:
# Cleanup camera controller
pass
storage_schema
property
¶
Override to register a JSON schema for the plugin-level settings form rendered in the UI. Default: no schema.
configureCameras
abstractmethod
async
¶
Called once on startup with every camera already assigned to this plugin. The plugin should attach handlers, open vendor sessions, and warm up models. Raising aborts plugin startup.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cameras
|
list[CameraDevice]
|
Cameras already assigned to this plugin. |
required |
onCameraAdded
abstractmethod
async
¶
Called whenever a camera is assigned to this plugin at runtime —
after a discovery adoption (:meth:DiscoveryProvider.onAdoptCamera)
or after the user re-assigns an existing camera in the UI. The
plugin should set up the same per-camera state as in
:meth:configureCameras.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
camera
|
CameraDevice
|
The camera device that was added. |
required |
onCameraReleased
abstractmethod
async
¶
Called when a camera is unassigned from this plugin or deleted from the system. The plugin must release per-camera resources (sessions, timers, decoders) before returning.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cameraId
|
str
|
ID of the camera that was released. |
required |
ClassifierDetectionInterface ¶
Bases: Protocol
Interface implemented by plugins that run a generic image classifier and emit attribute/label pairs (e.g. weather, scene, activity).
testClassifierDetection
async
¶
testClassifierDetection(image_data: bytes, metadata: ImageMetadata, config: dict[str, Any]) -> ClassifierDetectionPluginResponse | None
Run classification on a single image captured by the UI test panel and return the result for preview rendering.
detectClassifications
async
¶
detectClassifications(frame: VideoFrameData, config: dict[str, Any] | None = None) -> ClassifierDetectionPluginResponse | None
Run classification on a pre-decoded video frame.
classifierDetectionSettings
async
¶
Return the JSON schema for the classifier-detection settings form in the UI. Return None for no schema.
ClassifierDetectionPluginResponse ¶
Bases: TypedDict
Response from a classifier detection test.
ClipDetectionInterface ¶
Bases: Protocol
Interface implemented by plugins that generate CLIP image and text embeddings used for semantic search over recorded events.
testClipEmbedding
async
¶
testClipEmbedding(image_data: bytes, metadata: ImageMetadata, config: dict[str, Any]) -> ClipDetectionPluginResponse | None
Run the CLIP image branch on a single image captured by the UI test panel.
detectClipEmbedding
async
¶
detectClipEmbedding(frame: VideoFrameData, config: dict[str, Any] | None = None) -> ClipDetectionPluginResponse | None
Run the CLIP image branch on a pre-decoded video frame.
getTextEmbedding
async
¶
Run the CLIP text branch and return a single embedding vector usable for semantic-search queries against previously stored image embeddings.
clipSettings
async
¶
Return the JSON schema for the CLIP settings form in the UI. Return None for no schema.
ClipDetectionPluginResponse ¶
Bases: TypedDict
Response from a CLIP embedding test.
ClipTextEmbeddingResult ¶
Bases: TypedDict
Result of text-to-embedding conversion — a single embedding vector plus the model name used to produce it, so downstream code can refuse to mix embeddings from different models.
DiscoveryProvider ¶
Bases: Protocol
Implemented by plugins that can scan the network for new cameras and adopt them. Only plugins with a camera-controlling role (CameraController or CameraAndSensorProvider) are queried for discovery.
onDiscoverCameras
async
¶
Scan the network and return the cameras the plugin can offer for adoption. Called by the host on demand (UI rescan button) or on a polling schedule.
Returns:
| Type | Description |
|---|---|
list[DiscoveredCamera]
|
Cameras currently discoverable by this plugin. |
onGetCameraSettings
async
¶
Return a JSON schema describing the form fields (credentials, transport options, ...) the user must fill in to adopt this specific discovered camera.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
camera
|
DiscoveredCamera
|
The discovered camera the user is about to adopt. |
required |
Returns:
| Type | Description |
|---|---|
list[JsonSchemaWithoutCallbacks]
|
Schema for the adoption form. |
onAdoptCamera
async
¶
Probe the device with the user-provided settings and return the
camera configuration the host should persist. The host then creates
the camera and invokes :meth:BasePlugin.onCameraAdded on the
plugin.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
camera
|
DiscoveredCamera
|
The discovered camera being adopted. |
required |
cameraSettings
|
dict[str, object]
|
Values entered into the adoption form. |
required |
Returns:
| Type | Description |
|---|---|
CameraConfig
|
Final camera configuration for the host to persist. |
FaceDetectionInterface ¶
Bases: Protocol
Interface implemented by plugins that locate faces and emit per-face embeddings. The NVR owns matching against enrolled faces; the plugin only emits raw detections + embeddings.
testFaceDetection
async
¶
testFaceDetection(image_data: bytes, metadata: ImageMetadata, config: dict[str, Any]) -> FaceDetectionPluginResponse | None
Run face detection on a single image captured by the UI test panel and return the result for preview rendering.
detectFaces
async
¶
detectFaces(frame: VideoFrameData, config: dict[str, Any] | None = None) -> FaceDetectionPluginResponse | None
Run face detection on a pre-decoded video frame.
faceDetectionSettings
async
¶
Return the JSON schema for the face-detection settings form in the UI. Return None for no schema.
FaceDetectionPluginResponse ¶
Bases: TypedDict
Response from a face detection test.
ImageMetadata ¶
Bases: TypedDict
Image metadata for detection test requests.
LicensePlateDetectionInterface ¶
Bases: Protocol
Interface implemented by plugins that locate license plates and run OCR on them.
testLicensePlateDetection
async
¶
testLicensePlateDetection(image_data: bytes, metadata: ImageMetadata, config: dict[str, Any]) -> LicensePlateDetectionPluginResponse | None
Run detection on a single image captured by the UI test panel and return the result for preview rendering.
detectLicensePlates
async
¶
detectLicensePlates(frame: VideoFrameData, config: dict[str, Any] | None = None) -> LicensePlateDetectionPluginResponse | None
Run detection on a pre-decoded video frame.
licensePlateDetectionSettings
async
¶
Return the JSON schema for the license-plate-detection settings form in the UI. Return None for no schema.
LicensePlateDetectionPluginResponse ¶
Bases: TypedDict
Response from a license plate detection test.
MotionDetectionInterface ¶
Bases: Protocol
Interface implemented by plugins that perform video-based motion
detection. The host invokes :meth:testMotionDetection from the UI test
panel and :meth:detectMotion from automation / benchmark pipelines.
testMotionDetection
async
¶
testMotionDetection(video_data: bytes, config: dict[str, Any]) -> MotionDetectionPluginResponse | None
Run detection on a raw video buffer captured by the UI test panel and return the result for preview rendering.
detectMotion
async
¶
detectMotion(frames: list[VideoFrameData], config: dict[str, Any] | None = None) -> MotionDetectionPluginResponse | None
Run detection on already-decoded :class:VideoFrameData. Called
from automation / benchmark pipelines that supply pre-decoded frames
directly to avoid re-encoding.
motionDetectionSettings
async
¶
Return the JSON schema used to render the motion-detection settings form in the UI. Return None for no schema.
MotionDetectionPluginResponse ¶
Bases: TypedDict
Response from a motion detection test.
ObjectDetectionInterface ¶
Bases: Protocol
Interface implemented by plugins that perform object detection (person, vehicle, animal, ...).
testObjectDetection
async
¶
testObjectDetection(image_data: bytes, metadata: ImageMetadata, config: dict[str, Any]) -> ObjectDetectionPluginResponse | None
Run detection on a single image captured by the UI test panel;
metadata carries the image dimensions.
detectObjects
async
¶
detectObjects(frame: VideoFrameData, config: dict[str, Any] | None = None) -> ObjectDetectionPluginResponse | None
Run detection on a pre-decoded video frame. Called from automation / benchmark pipelines.
objectDetectionSettings
async
¶
Return the JSON schema used to render the object-detection settings form in the UI. Return None for no schema.
ObjectDetectionPluginResponse ¶
Bases: TypedDict
Response from an object detection test.
Notification ¶
Bases: TypedDict
Payload published via api.notificationManager.publish or routed by
the host. Plugins fill the user-visible fields; the host stamps the
message id, timestamp and source identifier on receive — plugins do not
set those.
subtitle
instance-attribute
¶
Optional second bold line between title and body. Honoured natively
on iOS (APNs alert.subtitle); other notifiers may fold it into the
body or ignore it.
severity
instance-attribute
¶
Drives DND / Critical-Alerts behaviour and Quiet-Hours bypass.
Defaults to :attr:Severity.Info if omitted.
tag
instance-attribute
¶
Collapse-key for dedup at both manager and notifier level (e.g.
motion:cam-1 — multiple events with the same tag inside the throttle
window collapse into one notification on the device).
thumbnail
instance-attribute
¶
Optional inline JPEG attached to the notification.
imageUrl
instance-attribute
¶
Publicly-fetchable URL to a rich image (e.g. a detection snapshot).
Notifier-agnostic: FCM/APNs and other notifiers fetch it to render the
image. Preferred over inline thumbnail bytes when a URL is available;
empty renders text-only.
deepLink
instance-attribute
¶
Router-relative path consumed by mobile / web tap-handlers (e.g.
/cameras/cam-1?startTs=...). No host, no scheme.
data
instance-attribute
¶
Plugin-specific context (cameraId, eventId, plugin-defined keys). String values keep the wire format predictable across notifier implementations.
adminOnly
instance-attribute
¶
Restricts delivery to users with the master or admin role. Use it for
operational alerts that concern whoever runs the instance — camera
offline, disk full, plugin failures — so they don't reach guests the
instance is merely shared with. Defaults to False (every user of the
instance receives it, subject to their own notification settings).
NotifierDevice ¶
Bases: TypedDict
A push-target managed by a notifier plugin (one phone, one chat, ...).
Devices are owned by the plugin that registered them; the manager queries plugins for their device list rather than maintaining a shared registry.
NotifierInterface ¶
Bases: Protocol
Implemented by plugins that deliver notifications.
The NotificationManager invokes these methods over RPC. Plugins own their device storage — the manager never persists devices itself.
get_devices
async
¶
Return every device this notifier knows about for the given users.
Each device carries its ownerUserId so the caller can map results
back. May return [] when the notifier is unavailable (e.g. license
invalid). Called frequently — keep cheap.
get_device
async
¶
Return a single device by id, or None if not found.
send_notification
async
¶
Deliver a notification to the given devices in one call. Errors are logged; the manager never aborts a fan-out because one notifier failed.
register_device
async
¶
Create a new device on this notifier. input is plugin-specific
JSON whose schema the notifier defines; the NotificationManager
forwards it opaquely.
revoke_device
async
¶
Permanently remove a device. Called when the user revokes the device through their notifier-specific UI.
update_device
async
¶
Mutate a subset of fields on an existing device. patch is
plugin-agnostic (name, active); plugins ignore unknown keys.
Returns the updated device, or None if the id isn't ours so the
manager can probe the next plugin.
notificationSettings
async
¶
Return the JSON schema used to render the notifier's settings form in the UI. Return None for no schema.
Severity ¶
Bases: str, Enum
Classifies how urgent a Notification is.
Notifiers map this to platform-specific delivery characteristics; the
host bypasses user-configured Quiet Hours for Critical.
Info
class-attribute
instance-attribute
¶
Standard notification — default delivery (sound + banner).
Warn
class-attribute
instance-attribute
¶
Heightened attention; notifiers may use a different sound/colour.
Critical
class-attribute
instance-attribute
¶
Highest-priority delivery on supporting notifiers; bypasses user-configured Quiet Hours on the host.
OAuthAuthCodeFlowCapable ¶
Bases: OAuthCapable, Protocol
Implemented by plugins that use the Authorization Code Flow with PKCE.
The host opens the auth URL and forwards the IdP redirect's code+state to
completeAuthCodeFlow.
OAuthCapable ¶
Bases: Protocol
Base interface every OAuth-capable plugin implements, alongside at least one flow sub-interface. IdP-agnostic — the plugin brings its own endpoint config and knows nothing about the host's internals.
getOAuthMetadata
async
¶
Return IdP display info, scope descriptions and the implemented flow sub-interfaces.
getOAuthState
async
¶
Return a snapshot of the current lifecycle state; the host polls this to mirror progress.
disconnect
async
¶
Revoke the current grant at the IdP and clear stored tokens.
OAuthClientCredentialsCapable ¶
Bases: OAuthCapable, Protocol
Implemented by plugins that authenticate with a user-supplied client_id + client_secret (no user redirect). The plugin validates by fetching a token immediately.
configureClientCredentials
async
¶
Store the supplied credentials and fetch an initial token to validate them.
OAuthDeviceFlowCapable ¶
Bases: OAuthCapable, Protocol
Implemented by plugins whose IdP supports the RFC 8628 Device
Authorization Grant. The plugin polls the IdP internally; the host only
polls getOAuthState to mirror progress.
OAuthMetadata ¶
Bases: TypedDict
Informational data the host renders in the connect dialog.
idpDisplayName
instance-attribute
¶
Human name of the identity provider, e.g. cameraui.com, Spotify.
scopeDescriptions
instance-attribute
¶
Maps each scope to a human-readable description.
supportedFlows
instance-attribute
¶
Flow sub-interfaces the plugin implements, so the host knows which affordance to render.
OAuthProviderConfig ¶
Bases: TypedDict
Points the plugin's OAuth manager at an identity provider.
preset
instance-attribute
¶
Built-in IdP endpoint set, e.g. cameraui.com. When unset, the explicit endpoints are used.
deviceAuthUrl
instance-attribute
¶
Device-authorization endpoint (used when preset is unset).
authUrl
instance-attribute
¶
Authorization endpoint (used when preset is unset).
tokenUrl
instance-attribute
¶
Token endpoint (used when preset is unset).
revokeUrl
instance-attribute
¶
Revocation endpoint (used when preset is unset).
OAuthProviderDeclaration ¶
Bases: TypedDict
One provider a plugin integrates with. A single-provider plugin declares exactly one.
OAuthState ¶
Bases: TypedDict
Snapshot of a provider connection's lifecycle. Lives in the plugin and
is the source of truth for both the host UI and downstream plugin code
that needs a token. The host polls it via getOAuthState while a flow
runs.
userCode
instance-attribute
¶
Device-flow user code shown to the user (set while awaiting_user).
verificationUri
instance-attribute
¶
Device-flow verification URI the user opens (set while awaiting_user).
verificationUriComplete
instance-attribute
¶
Verification URI with the user code embedded — rendered as a QR code.
authUrl
instance-attribute
¶
Authorization-code-flow URL the browser must open (set while awaiting_user).
userEmail
instance-attribute
¶
Connected account email (set while connected).
connectedAt
instance-attribute
¶
Unix timestamp the grant was established (set while connected).
scopesGranted
instance-attribute
¶
Scopes granted by the IdP (set while connected).
errorCode
instance-attribute
¶
OAuth error code (set while error): access_denied | expired_token | server_error.
errorMessage
instance-attribute
¶
Human-readable error detail (set while error).
can_create_cameras ¶
Report whether the plugin can create cameras (role is CameraController or CameraAndSensorProvider). Used to gate camera-creating operations such as DiscoveryProvider adoption.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract
|
PluginContract
|
Plugin contract to inspect. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the plugin may create cameras. |
can_provide_sensors_to_any_cameras ¶
Report whether the plugin is allowed to add sensors to cameras owned by other plugins (true for SensorProvider and CameraAndSensorProvider). Hub and pure CameraController plugins only see their own cameras.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract
|
PluginContract
|
Plugin contract to inspect. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the plugin may attach sensors to any camera. |
get_contract_validation_errors ¶
Check the structural validity of an unknown contract object — required fields present, enum values inside the accepted sets — and return one human-readable error per problem found. Returns an empty list when the contract is valid.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract
|
object
|
Untrusted candidate contract (e.g. parsed manifest JSON). |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
Error messages, empty if the contract is valid. |
has_capability ¶
Report whether the plugin requested the given capability.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract
|
PluginContract
|
Plugin contract to inspect. |
required |
cap
|
PluginCapability
|
Capability to check (e.g. :attr: |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if |
has_interface ¶
Report whether the plugin implements the given capability.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract
|
PluginContract
|
Plugin contract to inspect. |
required |
iface
|
PluginInterface
|
Interface to check (e.g. :attr: |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if |
is_hub ¶
Report whether the plugin's role is Hub (a cross-camera aggregator such as a smart-home bridge or recorder, which owns no cameras of its own).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract
|
PluginContract
|
Plugin contract to inspect. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the role is :attr: |
validate_contract_consistency ¶
Enforce role-specific consistency rules on top of the structural check (e.g. SensorProvider plugins must declare at least one provided sensor; Hub plugins cannot expose sensors). Raises on the first violation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contract
|
PluginContract
|
Already-structurally-valid contract. |
required |
plugin_name
|
str | None
|
Optional plugin name; used to prefix error messages. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
When the contract violates a role-specific rule. |