Skip to content

Storage & Schema

Schema-driven per-device configuration rendered as UI forms by the host. DeviceStorage plus the JsonSchema* shapes.

camera_ui_sdk.storage

PluginConfig module-attribute

PluginConfig = dict[str, Any]

Plugin configuration type.

OnSetCallback module-attribute

OnSetCallback = Callable[[Any, Any], None | Any] | Callable[[Any, Any], Awaitable[None | Any]] | Callable[[Any, Any], Coroutine[Any, Any, None | Any]]

Callback type for onSet handlers.

OnGetCallback module-attribute

OnGetCallback = Callable[[], None | Any] | Callable[[], Awaitable[None | Any]] | Callable[[], Coroutine[Any, Any, None | Any]]

Callback type for onGet handlers.

JsonSchemaType module-attribute

JsonSchemaType = Literal['string', 'number', 'boolean', 'array', 'object', 'button', 'submit']

Available schema field types for configuration UI.

StringFormat module-attribute

StringFormat = Literal['date-time', 'date', 'time', 'email', 'uuid', 'ipv4', 'ipv6', 'password', 'textarea', 'qrCode', 'image']

String format types for validation/display.

Used on string-typed schemas to render a specialized UI control:

  • date-time: ISO 8601 date+time picker.
  • date: date-only picker.
  • time: time-only picker.
  • email: email input with format validation.
  • uuid: UUID input with format validation.
  • ipv4: IPv4 address input.
  • ipv6: IPv6 address input.
  • password: masked input that hides characters.
  • textarea: multi-line text area for longer free text.
  • qrCode: value is rendered as a QR code (read-only display).
  • image: value is a data URL or path; rendered as a thumbnail.

ButtonColor module-attribute

ButtonColor = Literal['success', 'info', 'warn', 'danger']

Button color variants.

SchemaConditionOperator module-attribute

SchemaConditionOperator = Literal['eq', 'neq', 'gt', 'lt', 'in', 'nin']

Comparison operators for conditional field visibility.

T module-attribute

T = TypeVar('T', str, int, float, bool, list[str], list[int], list[float], list[bool], str | list[str])

Generic type variable for schema default values.

V1 module-attribute

V1 = ExtTypeVar('V1', default=str)

TypeVar for generic getValue return type.

V2 module-attribute

V2 = ExtTypeVar('V2', bound=Mapping[str, Any], default=dict[str, Any])

TypeVar for generic storage values type. Compatible with TypedDict.

JsonSchema module-attribute

JsonSchema = JsonSchemaString | JsonSchemaNumber | JsonSchemaBoolean | JsonSchemaEnum | JsonSchemaArray | JsonSchemaObject | JsonSchemaButton | JsonSchemaSubmit

Union of every top-level schema type (with callbacks).

Use this when defining the schemas you pass to defineSchemas, addSchema, or changeSchema. Each entry describes one configurable field rendered in the UI; the discriminator is the type property.

JsonSchemaWithoutKey module-attribute

JsonSchemaWithoutKey = JsonSchemaString | JsonSchemaNumber | JsonSchemaBoolean | JsonSchemaEnum | JsonSchemaArray | JsonSchemaObject | JsonSchemaButton | JsonSchemaSubmit

Schema accepted where the key is supplied externally, e.g. as a dict property.

JsonSchemaWithoutCallbacks module-attribute

JsonSchemaWithoutCallbacks = JsonSchemaStringWithoutCallbacks | JsonSchemaNumberWithoutCallbacks | JsonSchemaBooleanWithoutCallbacks | JsonSchemaEnumWithoutCallbacks | JsonSchemaArrayWithoutCallbacks | JsonSchemaObjectWithoutCallbacks

Union type of schemas without callbacks. Use this for nested schemas (e.g., array items).

SchemaCondition

Bases: TypedDict

Condition that controls when a field is visible. The field is shown only when the condition evaluates to true against the current form values.

Combine multiple conditions on a field via a list: all must pass (logical AND).

Example

Show apiKey only when authMode equals token::

{
    "key": "apiKey",
    "type": "string",
    "title": "API Key",
    "description": "",
    "condition": {"key": "authMode", "value": "token"},
}

Show port only when protocol is one of the listed values::

{"key": "protocol", "operator": "in", "value": ["http", "https"]}

key instance-attribute

key: Required[str]

Key of another field whose value drives visibility.

value instance-attribute

value: Required[Any]

Expected value: a single value, or a list for in / nin.

operator instance-attribute

operator: SchemaConditionOperator

Comparison operator (default: eq).

JsonFactorySchema

Bases: TypedDict

Base schema interface for all schema types. Contains common fields like type, key, title, description.

type instance-attribute

type: JsonSchemaType

Field type.

key instance-attribute

key: str

Unique field identifier.

title instance-attribute

title: str

Display title.

description instance-attribute

description: str

Field description/help text.

JsonBaseSchemaWithoutCallbacks

Bases: JsonFactorySchema, Generic[T]

Base schema without callbacks, used for nested schemas. Extends factory schema with common display options.

group instance-attribute

group: str

Optional group name for organizing fields.

hidden instance-attribute

hidden: bool

Hide field from UI.

required instance-attribute

required: bool

Mark field as required.

readonly instance-attribute

readonly: bool

Make field read-only.

placeholder instance-attribute

placeholder: str

Placeholder text for empty fields.

defaultValue instance-attribute

defaultValue: T

Default value when not set.

condition instance-attribute

condition: SchemaCondition | list[SchemaCondition]

Condition for conditional field visibility. List = all must be true (AND).

JsonBaseSchema

Bases: JsonBaseSchemaWithoutCallbacks[T], Generic[T]

Base schema with callbacks, the full schema interface. Adds storage and callback options for dynamic behavior.

store instance-attribute

store: bool

Whether to persist this field to storage.

onSet instance-attribute

onSet: OnSetCallback

Called after setValue writes the key, changed or not. setConfig calls it only for keys that changed. Receives (new_value, old_value).

onGet instance-attribute

onGet: OnGetCallback

Callback to get computed value.

JsonStringSchema

Bases: TypedDict

String-specific schema options.

type instance-attribute

type: Literal['string']

Schema type discriminator.

format instance-attribute

format: StringFormat

String format for validation/display. See StringFormat for behavior per format.

minLength instance-attribute

minLength: int

Minimum string length (inclusive).

maxLength instance-attribute

maxLength: int

Maximum string length (inclusive).

JsonNumberSchema

Bases: TypedDict

Number-specific schema options.

type instance-attribute

type: Literal['number']

Schema type discriminator.

minimum instance-attribute

minimum: int | float

Minimum value.

maximum instance-attribute

maximum: int | float

Maximum value.

step instance-attribute

step: int | float

Step increment for number input.

JsonBooleanSchema

Bases: TypedDict

Boolean-specific schema options.

type instance-attribute

type: Literal['boolean']

Schema type discriminator.

JsonEnumSchema

Bases: TypedDict

Enum/select schema options.

type instance-attribute

type: Literal['string']

Schema type discriminator.

enum instance-attribute

enum: list[str]

Available options.

enumLabels instance-attribute

enumLabels: dict[str, str]

Display labels per enum value; values without a label show the raw value.

multiple instance-attribute

multiple: bool

Allow multiple selection.

minItems instance-attribute

minItems: int

Minimum number of selected values (multiple only).

JsonArraySchema

Bases: TypedDict

Array schema options.

type instance-attribute

type: Literal['array']

Schema type discriminator.

opened instance-attribute

opened: bool

Whether array items are expanded by default.

minItems instance-attribute

minItems: int

Minimum number of entries.

items instance-attribute

items: JsonSchemaWithoutCallbacks

Schema for array items.

JsonObjectSchema

Bases: TypedDict

Object schema options.

The value is a plain dict; each property is its own keyed sub-field. As array items this yields structured lists, e.g. [{"name", "cameras"}].

type instance-attribute

type: Literal['object']

Schema type discriminator.

properties instance-attribute

properties: list[JsonSchemaWithoutCallbacks]

Sub-fields of the object value.

JsonSchemaString

Bases: JsonBaseSchema[str]

Complete string schema with callbacks.

format instance-attribute

format: StringFormat

String format for validation/display. See StringFormat for behavior per format.

minLength instance-attribute

minLength: int

Minimum string length (inclusive).

maxLength instance-attribute

maxLength: int

Maximum string length (inclusive).

JsonSchemaStringWithoutCallbacks

Bases: JsonBaseSchemaWithoutCallbacks[str]

String schema without callbacks (for nested use).

JsonSchemaNumber

Bases: JsonBaseSchema[int | float]

Complete number schema with callbacks.

JsonSchemaNumberWithoutCallbacks

Bases: JsonBaseSchemaWithoutCallbacks[int | float]

Number schema without callbacks (for nested use).

JsonSchemaBoolean

Bases: JsonBaseSchema[bool]

Complete boolean schema with callbacks.

JsonSchemaBooleanWithoutCallbacks

Bases: JsonBaseSchemaWithoutCallbacks[bool]

Boolean schema without callbacks (for nested use).

JsonSchemaEnum

Bases: JsonBaseSchema[str | list[str]]

Complete enum schema with callbacks.

JsonSchemaEnumWithoutCallbacks

Bases: JsonBaseSchemaWithoutCallbacks[str | list[str]]

Enum schema without callbacks (for nested use).

JsonSchemaArray

Bases: JsonBaseSchema[list[str] | list[int] | list[float] | list[bool]]

Complete array schema with callbacks.

JsonSchemaArrayWithoutCallbacks

Bases: JsonBaseSchemaWithoutCallbacks[list[str] | list[int] | list[float] | list[bool]]

Array schema without callbacks (for nested use).

JsonSchemaObject

Bases: JsonBaseSchema[dict[str, Any]]

Complete object schema with callbacks.

JsonSchemaObjectWithoutCallbacks

Bases: JsonBaseSchemaWithoutCallbacks[dict[str, Any]]

Object schema without callbacks (for nested use).

JsonSchemaButton

Bases: TypedDict

Button schema: triggers an action without storing a value.

type instance-attribute

type: Required[Literal['button']]

Schema type discriminator.

key instance-attribute

key: Required[str]

Unique field identifier.

title instance-attribute

title: Required[str]

Display title.

description instance-attribute

description: Required[str]

Field description/help text.

onSet instance-attribute

onSet: Callable[[], Awaitable[None]] | Callable[[], None]

Click handler.

group instance-attribute

group: str

Optional group name for organizing fields.

color instance-attribute

color: ButtonColor

Button color variant.

JsonSchemaSubmit

Bases: TypedDict

Submit button schema: submits form data and can return an updated schema.

type instance-attribute

type: Required[Literal['submit']]

Schema type discriminator.

key instance-attribute

key: Required[str]

Unique field identifier.

title instance-attribute

title: Required[str]

Display title.

description instance-attribute

description: Required[str]

Field description/help text.

onClick instance-attribute

onClick: Required[Callable[[Any], Awaitable[FormSubmitResponse | None]]]

Submit handler; receives form values, can return toast/schema updates.

group instance-attribute

group: str

Optional group name for organizing fields.

color instance-attribute

color: ButtonColor

Button color variant.

ToastMessage

Bases: TypedDict

Toast notification message.

Returned from a submit handler (JsonSchemaSubmit.onClick) inside a FormSubmitResponse to surface a transient banner in the UI, for example to confirm that a credential check succeeded or failed.

type instance-attribute

type: Literal['info', 'success', 'warning', 'error']

Severity, controls the icon and color of the banner.

message instance-attribute

message: str

Human-readable message text.

FormSubmitSchema

Bases: TypedDict

Form submit input data.

config instance-attribute

config: dict[str, Any]

Form configuration values.

FormSubmitResponse

Bases: TypedDict

Form submit response, returned by JsonSchemaSubmit.onClick.

Used to react to a user-triggered submit (e.g. "Test connection", "Pair device") with optional UI feedback. Either field may be set:

  • toast shows a transient banner.
  • schema replaces the current form schema, useful for multi-step flows where the next step depends on the submitted values.

toast instance-attribute

toast: ToastMessage

Optional toast banner to display after the submit completes.

schema instance-attribute

schema: list[JsonSchemaWithoutCallbacks]

Optional updated schema definitions (full replacement of fields).

SchemaConfig

Bases: TypedDict

Schema configuration bundle. Contains both schema definitions and current values.

schema instance-attribute

schema: list[JsonSchema]

Schema definitions.

config instance-attribute

config: dict[str, Any]

Current configuration values.

DeviceStorage

Bases: Protocol, Generic[V2]

Device storage interface for plugin/camera configuration.

Provides methods to read/write configuration values and manage schemas. Each plugin and camera can have its own storage instance.

Example
# Get a value with default
threshold = await storage.getValue("motionThreshold", 50)

# Set a value
await storage.setValue("motionThreshold", 75)

# Add a new schema field
await storage.addSchema(
    {
        "type": "number",
        "key": "sensitivity",
        "title": "Sensitivity",
        "description": "Detection sensitivity (0-100)",
        "minimum": 0,
        "maximum": 100,
        "defaultValue": 50,
    }
)

schemas instance-attribute

schemas: list[JsonSchema]

Current schema definitions.

values instance-attribute

values: V2

Current configuration values.

getValue async

getValue(key: str) -> V1 | None
getValue(key: str, default_value: V1) -> V1
getValue(key: str, default_value: V1 | None = None) -> V1 | None

Get a configuration value.

If the schema declares an onGet callback, its result is returned as-is, with no fallback. Otherwise resolves in order: the stored value, then the schema default, then the provided default.

Parameters:

Name Type Description Default
key str

Configuration key

required
default_value V1 | None

Default value if key doesn't exist

None

Returns:

Type Description
V1 | None

The configuration value or default

setValue async

setValue(key: str, new_value: Any) -> None

Set a configuration value.

Takes effect only if a schema exists for the key. Passing None deletes the key: it reads as never-set again and the schema default applies. For a field whose schema opts into storage (store: True) the value is durably persisted before the coroutine completes; the schema's onSet fires afterwards.

Parameters:

Name Type Description Default
key str

Configuration key

required
new_value Any

New value to set, or None to delete the key

required

submitValue async

submitValue(key: str, new_value: Any) -> FormSubmitResponse | None

Submit a value (for submit-type schemas).

Parameters:

Name Type Description Default
key str

Schema key

required
new_value Any

Submitted value

required

Returns:

Type Description
FormSubmitResponse | None

Optional response with toast/schema updates

hasValue

hasValue(key: str) -> bool

Check if a configuration value exists.

Parameters:

Name Type Description Default
key str

Configuration key

required

getConfig async

getConfig() -> SchemaConfig

Get the schema definitions and the values they own.

Internal values written with setInternalValue are left out, read them with getValue.

Returns:

Type Description
SchemaConfig

Schema definitions and their current values

setConfig async

setConfig(new_config: V2) -> None

Merge configuration values into the current config.

Only keys present in new_config are updated (not a full replace); arrays are replaced, not merged. Keys without a schema are ignored. Values are durably persisted before the coroutine completes; onSet fires for each key whose value changed.

Parameters:

Name Type Description Default
new_config V2

Configuration values to merge in

required

defineSchemas

defineSchemas(schemas: list[JsonSchema]) -> None

Define all schemas for this storage.

Parameters:

Name Type Description Default
schemas list[JsonSchema]

Array of schema definitions

required

addSchema async

addSchema(schema: JsonSchema) -> None

Add a new schema field.

Parameters:

Name Type Description Default
schema JsonSchema

Schema definition to add

required

removeSchema async

removeSchema(key: str) -> None

Remove a schema field.

The field's stored value is deleted along with the schema; the removal is durably persisted when the coroutine completes.

Parameters:

Name Type Description Default
key str

Schema key to remove

required

changeSchema async

changeSchema(key: str, new_schema: dict[str, Any]) -> None

Replace an existing schema field with a full schema.

The whole schema is replaced, individual fields are not merged. It is a no-op when no schema with that key is registered (use addSchema to add a new field). The passed key always wins.

Parameters:

Name Type Description Default
key str

Schema key to replace

required
new_schema dict[str, Any]

Full schema definition that replaces the current one

required

getSchema

getSchema(key: str) -> JsonSchema | None

Get a schema definition by key.

Parameters:

Name Type Description Default
key str

Schema key

required

Returns:

Type Description
JsonSchema | None

Schema or None

hasSchema

hasSchema(key: str) -> bool

Check if a schema exists.

Parameters:

Name Type Description Default
key str

Schema key

required

setInternalValue async

setInternalValue(key: str, value: Any) -> None

Set an internal value without a schema and persist it.

Internal values stay out of getConfig and can only be written by the plugin itself. When the coroutine completes, the value is durably persisted. Passing None deletes the key; it reads as never-set again.

Parameters:

Name Type Description Default
key str

Internal key (typically prefixed with '_')

required
value Any

Value to set, or None to delete the key

required

setInternalValueSync

setInternalValueSync(key: str, value: Any) -> None

Set an internal value and write it to disk before returning.

For callbacks that must not return before the value is safe, such as the synchronous storage hook of a library. The write blocks the event loop, so use setInternalValue everywhere else. Once the call returns, the value survives a crash of the plugin. Passing None deletes the key.

Parameters:

Name Type Description Default
key str

Internal key (typically prefixed with '_')

required
value Any

Value to set, or None to delete the key

required

save async

save() -> None

Persist all changes to storage.

When the coroutine completes, all values are durably persisted.