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. Coroutine functions are awaited.
PROTOCOL_LEVEL
module-attribute
¶
Compatibility level of the plugin surface: the plugin-facing API and the
plugin wire protocol. Bumped only on breaking changes, never for additive
features. The CLI stamps the level a plugin was built against into its
bundle (cameraui.protocolLevel in the bundle package.json); the server
compares that stamp with its own level and refuses to start plugins outside
its supported range.
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.
PluginInterfaces
module-attribute
¶
PluginInterfaces = MotionDetectionInterface | ObjectDetectionInterface | AudioDetectionInterface | FaceDetectionInterface | LicensePlateDetectionInterface | ClassifierDetectionInterface | ClipDetectionInterface | DiscoveryProvider
Union of all optional plugin interfaces.
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 once after every assigned camera is wired up and configureCameras() returned. Start timers and warm-ups here.
SHUTDOWN
class-attribute
instance-attribute
¶
Emitted when the host tears the plugin down. Release files, sockets, timers and child processes now.
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).
Example
coreManager
property
¶
System-level operations: 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.
sensorManager
property
¶
Registers standalone sensors: entities of their own, persisted across restarts, assignable to cameras by the user.
downloadManager
property
¶
Mints token-protected download URLs for files the plugin exposes to the UI (clip exports, snapshots).
notificationManager
property
¶
Publishes notifications to every installed notifier and the in-app UI. Requires :attr:PluginCapability.PublishNotifications.
storagePath
property
¶
Absolute path to the plugin's writable storage directory, created and cleaned up by the host.
on ¶
Subscribe to a lifecycle event. Returns self for chaining.
once ¶
Subscribe to a lifecycle event for one delivery only. Returns self for chaining.
off ¶
Remove a previously registered listener (alias of :meth:removeListener).
removeListener ¶
Remove a previously registered listener.
removeAllListeners ¶
Remove every listener for event, or every listener when no event is given.
PluginCapability ¶
Bases: StrEnum
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
¶
Allows api.notificationManager.publish. Without it the host 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 before the plugin is started.
name
instance-attribute
¶
Stable, unique identifier: registry key, log prefix and 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 consuming 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).
pythonVersion
instance-attribute
¶
Required Python interpreter version for Python plugins. Ignored by Node and Go plugins.
dependencies
instance-attribute
¶
Extra dependencies installed into the plugin's runtime (Go module paths, PyPI or npm names).
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: StrEnum
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). Matching against enrolled faces happens in the NVR.
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 (network scan + adoption). Only valid for camera-controlling roles.
NVR
class-attribute
instance-attribute
¶
Implements NVRInterface (events and recordings). Exactly one plugin per host fills this role at runtime.
Notifier
class-attribute
instance-attribute
¶
Implements NotifierInterface, so the NotificationManager can dispatch notifications to this plugin.
OAuthCapable
class-attribute
instance-attribute
¶
Implements the OAuthCapable base interface plus at least one of the flow sub-interfaces below.
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: StrEnum
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
¶
Cross-camera aggregator (smart-home bridge, recorder). Owns no cameras and provides no sensors.
SensorProvider
class-attribute
instance-attribute
¶
Adds sensors to cameras owned by other plugins, for example a detector running on foreign video frames.
CameraController
class-attribute
instance-attribute
¶
Manages cameras and their media streams: stream URLs, PTZ, snapshots. Provides no sensors for foreign cameras.
CameraAndSensorProvider
class-attribute
instance-attribute
¶
Manages cameras and exposes sensors, on its own cameras and, with consumes set, on foreign ones.
AudioDetectionInterface ¶
Bases: Protocol
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.
detectAudio
async
¶
detectAudio(audio: AudioFrameData, config: dict[str, Any] | None = None) -> AudioDetectionPluginResponse | None
Run detection on a pre-decoded audio frame. Called from automation / benchmark pipelines.
audioDetectionSettings
async
¶
Return the JSON schema used to render the audio-detection settings form in the UI, or None for no schema.
AudioDetectionPluginResponse ¶
Bases: TypedDict
Result of an audio detection run.
AudioMetadata ¶
Bases: TypedDict
Audio metadata passed to audio detector test methods.
mimeType
instance-attribute
¶
Container format of the audio buffer.
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.
The host calls :meth:configureCameras once at startup with every camera
already assigned to this plugin, then :meth:onCameraAdded /
:meth:onCameraReleased as the user adds or removes cameras at runtime.
StorageT types storage.values so plugin code gets autocompletion
for its own settings shape.
Example
class MyPlugin(BasePlugin[MyStorageValues]):
async def configureCameras(self, cameras: list[CameraDevice]) -> None:
self.model_path = self.storage.values.get("model_path")
for camera in cameras:
await self.onCameraAdded(camera)
async def onCameraAdded(self, camera: CameraDevice) -> None:
self.state[camera.id] = await self.attach(camera)
async def onCameraReleased(self, camera_id: str) -> None:
self.state.pop(camera_id, None)
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. Attach handlers, open vendor sessions, warm up models here. 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. 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. Release per-camera resources (sessions, timers, decoders) before returning.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cameraId
|
str
|
ID of the camera that was released. |
required |
configureSensors
async
¶
Called once on startup with every sensor this plugin may consume:
sensors whose type is listed in contract.consumes and that are
exposed. Each sensor carries type, assignedCameraIds and
connected, so consumers decide rendering purely from that data.
Optional, only bridge plugins override it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sensors
|
list[SensorLike]
|
Consumable sensors known at startup. |
required |
onSensorAdded
async
¶
Called when a sensor enters this plugin's consumable view at runtime: it was created, became exposed, or its type became consumable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sensor
|
SensorLike
|
The sensor that appeared. |
required |
onSensorReleased
async
¶
Called when a sensor permanently leaves the consumable view: it
was deleted or unexposed. Plugin connectivity does NOT fire this,
watch sensor.onConnectedChanged for that.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sensorId
|
str
|
Persistent id of the sensor that left. |
required |
ClassifierDetectionInterface ¶
Bases: Protocol
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, or None for no schema.
ClassifierDetectionPluginResponse ¶
ClipDetectionInterface ¶
Bases: Protocol
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.
embedImages
async
¶
embedImages(images: list[bytes], config: dict[str, Any] | None = None) -> list[ClipDetectionPluginResponse | None]
Run the CLIP image branch over a batch of encoded images (JPEG/PNG).
One result per input in the same order, None where decoding or embedding failed. Meant for re-indexing stored images after an embedding-model change.
getTextEmbedding
async
¶
Run the CLIP text branch and return a vector usable for semantic-search queries against stored image embeddings.
getTextEmbeddings
async
¶
Run the CLIP text branch once per embedding space the plugin can currently serve.
The configured search model comes first. Lets semantic search also cover embeddings produced by an older model during a transition.
clipSettings
async
¶
Return the JSON schema for the CLIP settings form in the UI, or None for no schema.
ClipDetectionPluginResponse ¶
Bases: TypedDict
Result of a CLIP image embedding run.
embeddings
instance-attribute
¶
Embedding vectors generated for the input.
embeddingModel
instance-attribute
¶
Model that produced the embeddings; consumers must not mix models.
scoreBand
instance-attribute
¶
[floor, ceiling] of raw text-image cosine scores for this model; consumers map scores to a 0..1 relevance scale and treat a missing band as score 0.
ClipTextEmbeddingResult ¶
Bases: TypedDict
Result of a CLIP text embedding request.
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 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
Implemented by plugins that locate faces and emit per-face embeddings. The NVR owns matching against enrolled faces, the plugin only emits raw detections and 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, or None for no schema.
FaceDetectionPluginResponse ¶
ImageMetadata ¶
LicensePlateDetectionInterface ¶
Bases: Protocol
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, or None for no schema.
LicensePlateDetectionPluginResponse ¶
MotionDetectionInterface ¶
Bases: Protocol
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 frames, supplied by automation / benchmark pipelines to avoid re-encoding.
motionDetectionSettings
async
¶
Return the JSON schema used to render the motion-detection settings form in the UI, or None for no schema.
MotionDetectionPluginResponse ¶
Bases: TypedDict
Result of a motion detection run.
videoData
instance-attribute
¶
Annotated re-encoded clip for the UI test panel, when the plugin renders one.
ObjectDetectionInterface ¶
Bases: Protocol
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, or None for no schema.
ObjectDetectionPluginResponse ¶
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.
subtitle
instance-attribute
¶
Optional second bold line, honoured natively on iOS; other notifiers may fold it into the body.
severity
instance-attribute
¶
Drives DND / Critical-Alerts behaviour and Quiet-Hours bypass. Defaults to :attr:Severity.Info.
tag
instance-attribute
¶
Collapse-key (e.g. motion:cam-1). The host replaces an older entry
with the same tag in the in-app list. Delivery is not throttled: every
publish is sent. Notifiers may map it to a platform collapse-id.
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).
Preferred over inline thumbnail bytes when a URL is available; empty
renders text-only.
videoUrl
instance-attribute
¶
Publicly-fetchable URL to a short MP4 clip. Notifiers that can render
video (iOS attachments) prefer it over imageUrl; everything else
ignores it, so always send the image alongside. Keep clips small: the
receiving phone downloads inside a tight OS budget.
deepLink
instance-attribute
¶
Router-relative path for mobile / web tap-handlers (e.g. /cameras/cam-1). No host, no scheme.
data
instance-attribute
¶
Plugin-specific context (cameraId, eventId, plugin-defined keys), string values only.
adminOnly
instance-attribute
¶
Restricts delivery to users with the master or admin role. Use it for
operational alerts (camera offline, disk full, plugin failures) so they
don't reach guests the instance is merely shared with. Defaults to
False.
silent
instance-attribute
¶
Delivers without sound, vibration or badge increment: meant for publishes
that replace an earlier notification with the same tag (e.g. a richer
description superseding the initial alert). The banner still updates.
Ignored when severity is :attr:Severity.Critical. Defaults to
False.
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 the devices this notifier knows for the given users, each
carrying its ownerUserId. Return [] when the notifier is
unavailable (e.g. invalid license). Called often, keep it 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, a failing notifier never aborts the fan-out.
register_device
async
¶
Create a new device. input is plugin-specific JSON the manager forwards opaquely.
revoke_device
async
¶
Permanently remove a device. Called when the user revokes it through their notifier-specific UI.
update_device
async
¶
Mutate name / active on an existing device. Return 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, or None for no schema.
Severity ¶
Bases: StrEnum
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 or colour.
Critical
class-attribute
instance-attribute
¶
Highest-priority delivery on supporting notifiers; bypasses Quiet Hours.
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. Returns one human-readable error per problem found, empty 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. |