diff --git a/codegen/layouts/models.hbs b/codegen/layouts/models.hbs deleted file mode 100644 index f23be870..00000000 --- a/codegen/layouts/models.hbs +++ /dev/null @@ -1,17 +0,0 @@ -from typing import Any, Dict, List, Optional, Union -from typing_extensions import Self -import abc -from dataclasses import dataclass -from ..utils.deep_attr_dict import DeepAttrDict - -{{#each resources}} - -{{> model-dataclass}} -{{/each}} -{{#each abstractClasses}} - -{{> abstract-route-class}} -{{/each}} - - -{{> abstract-routes}} diff --git a/codegen/layouts/partials/model-dataclass.hbs b/codegen/layouts/partials/resource-dataclass.hbs similarity index 100% rename from codegen/layouts/partials/model-dataclass.hbs rename to codegen/layouts/partials/resource-dataclass.hbs diff --git a/codegen/layouts/resource.hbs b/codegen/layouts/resource.hbs new file mode 100644 index 00000000..6d8a10fb --- /dev/null +++ b/codegen/layouts/resource.hbs @@ -0,0 +1,6 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +{{> resource-dataclass}} diff --git a/codegen/layouts/resources-index.hbs b/codegen/layouts/resources-index.hbs new file mode 100644 index 00000000..4e79ef1a --- /dev/null +++ b/codegen/layouts/resources-index.hbs @@ -0,0 +1,3 @@ +{{#each resources}} +from .{{moduleName}} import {{className}} +{{/each}} diff --git a/codegen/layouts/route.hbs b/codegen/layouts/route.hbs index cdaf11fe..8ab8b8d3 100644 --- a/codegen/layouts/route.hbs +++ b/codegen/layouts/route.hbs @@ -1,16 +1,20 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import ({{modelImportList}}) +{{#if resourceImportList}} +from ..resources import ({{resourceImportList}}) +{{/if}} {{#each childClasses}} -from .{{module}} import {{className}} -{{else}} - +from .{{module}} import {{abstractClassName}}, {{className}} {{/each}} {{#if importResolveActionAttempt}} from ..modules.action_attempts import resolve_action_attempt {{/if}} +{{> abstract-route-class abstractClass}} + + class {{className}}({{abstractClassName}}): def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): self.client = client diff --git a/codegen/layouts/routes-index.hbs b/codegen/layouts/routes-index.hbs index 147933cc..e4c951fd 100644 --- a/codegen/layouts/routes-index.hbs +++ b/codegen/layouts/routes-index.hbs @@ -1,11 +1,15 @@ from typing import Any, Dict +import abc +from dataclasses import dataclass from ..client import SeamHttpClient -from .models import AbstractRoutes {{#each namespaces}} -from .{{namespace}} import {{className}} +from .{{namespace}} import {{abstractClassName}}, {{className}} {{/each}} +{{> abstract-routes}} + + class Routes(AbstractRoutes): def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): {{#each namespaces}} diff --git a/codegen/lib/layouts/models.ts b/codegen/lib/layouts/models.ts deleted file mode 100644 index 7e946cc3..00000000 --- a/codegen/lib/layouts/models.ts +++ /dev/null @@ -1,163 +0,0 @@ -// Builds the template context for seam/routes/models.py. -// Dataclasses come from the blueprint resources, events, action attempts, and -// pagination; the abstract route classes mirror the generated route classes. - -import type { Blueprint, Property, Resource } from '@seamapi/blueprint' -import { pascalCase } from 'change-case' - -import type { ClassModel } from '../class-model.js' -import { convertCustomResourceName } from '../custom-resource-name-conversions.js' -import { mapPropertyToPythonType } from '../python-type.js' -import { getMethodLayoutContext } from './route.js' - -// Python hard keywords cannot be used as identifiers. When a property name -// collides with one (e.g. "from"), the dataclass field and keyword argument -// are suffixed with an underscore while the original name is preserved as the -// dict key. -const PYTHON_KEYWORDS = new Set([ - 'False', - 'None', - 'True', - 'and', - 'as', - 'assert', - 'async', - 'await', - 'break', - 'class', - 'continue', - 'def', - 'del', - 'elif', - 'else', - 'except', - 'finally', - 'for', - 'from', - 'global', - 'if', - 'import', - 'in', - 'is', - 'lambda', - 'nonlocal', - 'not', - 'or', - 'pass', - 'raise', - 'return', - 'try', - 'while', - 'with', - 'yield', -]) - -const toSafeIdentifier = (name: string): string => - PYTHON_KEYWORDS.has(name) ? `${name}_` : name - -export interface ModelsLayoutContext { - resources: Array<{ - className: string - properties: Array<{ - name: string - safeName: string - type: string - isDictParam: boolean - }> - }> - abstractClasses: Array<{ - className: string - showPass: boolean - childProperties: Array<{ namespace: string; abstractClassName: string }> - methods: Array<{ - name: string - hasParams: boolean - signatureParams: string - returnType: string - }> - }> - routesNamespaces: Array<{ namespace: string; abstractClassName: string }> -} - -// The action attempt and event variants each generate a single dataclass with -// the union of the variant properties. The first occurrence of a property -// name wins. -const mergeResourceProperties = (resources: Resource[]): Property[] => { - const merged = new Map() - for (const { properties } of resources) { - for (const property of properties) { - if (!merged.has(property.name)) merged.set(property.name, property) - } - } - return [...merged.values()] -} - -export const setModelsLayoutContext = ( - blueprint: Blueprint, - classMap: Map, - topLevelNamespaces: string[], -): ModelsLayoutContext => { - const models = new Map() - - for (const resource of blueprint.resources) { - models.set(resource.resourceType, resource.properties) - } - - // The event and action attempt variants merge into a single dataclass with - // the union of the variant properties, overriding the base resource schema. - models.set( - 'action_attempt', - mergeResourceProperties(blueprint.actionAttempts), - ) - models.set('event', mergeResourceProperties(blueprint.events)) - - if (blueprint.pagination != null) { - models.set('pagination', blueprint.pagination.properties) - } - - const resources = [...models.entries()] - .sort(([a], [b]) => (a < b ? -1 : 1)) - .map(([name, properties]) => ({ - className: pascalCase(convertCustomResourceName(name)), - properties: properties.map((property) => { - const type = mapPropertyToPythonType(property) - return { - name: property.name, - safeName: toSafeIdentifier(property.name), - type, - isDictParam: - type.startsWith('Dict') || property.name === 'properties', - } - }), - })) - - const abstractClasses = [...classMap.values()] - // Define classes without children first for parent-child referencing. - // Array#sort is stable, so ties keep class-map insertion order. - .sort( - (a, b) => a.childClassIdentifiers.length - b.childClassIdentifiers.length, - ) - .map((cls) => ({ - className: `Abstract${cls.name}`, - showPass: - cls.methods.length === 0 && cls.childClassIdentifiers.length === 0, - childProperties: cls.childClassIdentifiers.map((i) => ({ - namespace: i.namespace, - abstractClassName: `Abstract${i.className}`, - })), - methods: cls.methods.map((method) => { - const { name, hasParams, signatureParams, returnType } = - getMethodLayoutContext(method) - return { name, hasParams, signatureParams, returnType } - }), - })) - - return { - resources, - abstractClasses, - routesNamespaces: topLevelNamespaces.map((ns) => ({ - namespace: ns, - abstractClassName: `Abstract${pascalCase(ns)}`, - })), - } -} diff --git a/codegen/lib/layouts/resources.ts b/codegen/lib/layouts/resources.ts new file mode 100644 index 00000000..0a07b6b7 --- /dev/null +++ b/codegen/lib/layouts/resources.ts @@ -0,0 +1,136 @@ +// Builds the template context for the seam/resources modules. +// Each blueprint resource, along with events, action attempts, and pagination, +// becomes a dataclass in its own module, re-exported from seam/resources/__init__.py. + +import type { Blueprint, Property, Resource } from '@seamapi/blueprint' +import { pascalCase, snakeCase } from 'change-case' + +import { convertCustomResourceName } from '../custom-resource-name-conversions.js' +import { mapPropertyToPythonType } from '../python-type.js' + +// Python hard keywords cannot be used as identifiers. When a property name +// collides with one (e.g. "from"), the dataclass field and keyword argument +// are suffixed with an underscore while the original name is preserved as the +// dict key. +const PYTHON_KEYWORDS = new Set([ + 'False', + 'None', + 'True', + 'and', + 'as', + 'assert', + 'async', + 'await', + 'break', + 'class', + 'continue', + 'def', + 'del', + 'elif', + 'else', + 'except', + 'finally', + 'for', + 'from', + 'global', + 'if', + 'import', + 'in', + 'is', + 'lambda', + 'nonlocal', + 'not', + 'or', + 'pass', + 'raise', + 'return', + 'try', + 'while', + 'with', + 'yield', +]) + +const toSafeIdentifier = (name: string): string => + PYTHON_KEYWORDS.has(name) ? `${name}_` : name + +export interface ResourceLayoutContext { + className: string + moduleName: string + properties: Array<{ + name: string + safeName: string + type: string + isDictParam: boolean + }> +} + +export interface ResourcesIndexLayoutContext { + resources: Array<{ className: string; moduleName: string }> +} + +// The action attempt and event variants each generate a single dataclass with +// the union of the variant properties. The first occurrence of a property +// name wins. +const mergeResourceProperties = (resources: Resource[]): Property[] => { + const merged = new Map() + for (const { properties } of resources) { + for (const property of properties) { + if (!merged.has(property.name)) merged.set(property.name, property) + } + } + return [...merged.values()] +} + +export const getResourceLayoutContexts = ( + blueprint: Blueprint, +): ResourceLayoutContext[] => { + const models = new Map() + + for (const resource of blueprint.resources) { + models.set(resource.resourceType, resource.properties) + } + + // The event and action attempt variants merge into a single dataclass with + // the union of the variant properties, overriding the base resource schema. + models.set( + 'action_attempt', + mergeResourceProperties(blueprint.actionAttempts), + ) + models.set('event', mergeResourceProperties(blueprint.events)) + + if (blueprint.pagination != null) { + models.set('pagination', blueprint.pagination.properties) + } + + return [...models.entries()] + .map(([name, properties]) => { + const className = pascalCase(convertCustomResourceName(name)) + return { + className, + // Derived from the class name rather than the resource type so the + // module always matches the dataclass it exports (e.g. the "event" + // resource becomes SeamEvent in seam_event.py). + moduleName: snakeCase(className), + properties: properties.map((property) => { + const type = mapPropertyToPythonType(property) + return { + name: property.name, + safeName: toSafeIdentifier(property.name), + type, + isDictParam: + type.startsWith('Dict') || property.name === 'properties', + } + }), + } + }) + .sort((a, b) => (a.moduleName < b.moduleName ? -1 : 1)) +} + +export const setResourcesIndexLayoutContext = ( + resources: ResourceLayoutContext[], +): ResourcesIndexLayoutContext => ({ + resources: resources.map(({ className, moduleName }) => ({ + className, + moduleName, + })), +}) diff --git a/codegen/lib/layouts/route.ts b/codegen/lib/layouts/route.ts index ba7a6c6a..34c971f3 100644 --- a/codegen/lib/layouts/route.ts +++ b/codegen/lib/layouts/route.ts @@ -1,5 +1,7 @@ // Builds the template context for route class files (seam/routes/{namespace}.py). -// The context mirrors the output of the nextlove ClassFile#serializeToClass. +// Each module holds the abstract route class alongside its concrete +// implementation. The context mirrors the output of the nextlove +// ClassFile#serializeToClass. import { type ClassMethod, @@ -21,11 +23,29 @@ export interface MethodLayoutContext { resAccessor: string } +export interface AbstractClassLayoutContext { + className: string + showPass: boolean + childProperties: Array<{ namespace: string; abstractClassName: string }> + methods: Array<{ + name: string + hasParams: boolean + signatureParams: string + returnType: string + }> +} + export interface RouteLayoutContext { className: string abstractClassName: string - modelImportList: string - childClasses: Array<{ namespace: string; className: string; module: string }> + abstractClass: AbstractClassLayoutContext + resourceImportList: string + childClasses: Array<{ + namespace: string + className: string + abstractClassName: string + module: string + }> importResolveActionAttempt: boolean methods: MethodLayoutContext[] } @@ -77,28 +97,42 @@ export const getMethodLayoutContext = ( } export const setRouteLayoutContext = (cls: ClassModel): RouteLayoutContext => { - const validClasses = [ - `Abstract${cls.name}`, - ...Array.from( - new Set( - cls.methods.map((m) => - m.returnResource.replace(/^List\[/, '').replace(/\]$/, ''), - ), + const resourceClasses = Array.from( + new Set( + cls.methods.map((m) => + m.returnResource.replace(/^List\[/, '').replace(/\]$/, ''), ), ), - ].filter((classInstance) => classInstance !== '') + ).filter((className) => className !== '' && className !== 'None') const importResolveActionAttempt = cls.methods.some( ({ returnResource }) => returnResource === 'ActionAttempt', ) + const abstractClassName = `Abstract${cls.name}` + return { className: cls.name, - abstractClassName: `Abstract${cls.name}`, - modelImportList: validClasses.filter((c) => c !== 'None').join(','), + abstractClassName, + abstractClass: { + className: abstractClassName, + showPass: + cls.methods.length === 0 && cls.childClassIdentifiers.length === 0, + childProperties: cls.childClassIdentifiers.map((i) => ({ + namespace: i.namespace, + abstractClassName: `Abstract${i.className}`, + })), + methods: cls.methods.map((method) => { + const { name, hasParams, signatureParams, returnType } = + getMethodLayoutContext(method) + return { name, hasParams, signatureParams, returnType } + }), + }, + resourceImportList: resourceClasses.join(','), childClasses: cls.childClassIdentifiers.map((i) => ({ namespace: i.namespace, className: i.className, + abstractClassName: `Abstract${i.className}`, module: `${cls.namespace}_${i.namespace}`, })), importResolveActionAttempt, diff --git a/codegen/lib/layouts/routes-index.ts b/codegen/lib/layouts/routes-index.ts index 3654e6df..c7aaf0a0 100644 --- a/codegen/lib/layouts/routes-index.ts +++ b/codegen/lib/layouts/routes-index.ts @@ -1,10 +1,17 @@ // Builds the template context for seam/routes/__init__.py. +// Holds AbstractRoutes alongside the concrete Routes class, mirroring how each +// route module pairs its abstract class with its implementation. // Mirrors the nextlove routes.py.template.ts. import { pascalCase } from 'change-case' export interface RoutesIndexLayoutContext { - namespaces: Array<{ namespace: string; className: string }> + namespaces: Array<{ + namespace: string + className: string + abstractClassName: string + }> + routesNamespaces: Array<{ namespace: string; abstractClassName: string }> } export const setRoutesIndexLayoutContext = ( @@ -13,5 +20,10 @@ export const setRoutesIndexLayoutContext = ( namespaces: topLevelNamespaces.map((ns) => ({ namespace: ns, className: pascalCase(ns), + abstractClassName: `Abstract${pascalCase(ns)}`, + })), + routesNamespaces: topLevelNamespaces.map((ns) => ({ + namespace: ns, + abstractClassName: `Abstract${pascalCase(ns)}`, })), }) diff --git a/codegen/lib/routes.ts b/codegen/lib/routes.ts index 6675e271..4b82eff5 100644 --- a/codegen/lib/routes.ts +++ b/codegen/lib/routes.ts @@ -4,7 +4,7 @@ // blueprint plugin places in the Metalsmith metadata; no OpenAPI parsing // happens here. Documented blueprint routes and namespaces map to route // classes, endpoints to methods, and the blueprint resources, events, action -// attempts, and pagination to the dataclasses in the models module. +// attempts, and pagination to one dataclass module each under seam/resources. import type { Blueprint, Response } from '@seamapi/blueprint' import { pascalCase } from 'change-case' @@ -12,7 +12,10 @@ import type Metalsmith from 'metalsmith' import type { ClassModel } from './class-model.js' import { convertCustomResourceName } from './custom-resource-name-conversions.js' -import { setModelsLayoutContext } from './layouts/models.js' +import { + getResourceLayoutContexts, + setResourcesIndexLayoutContext, +} from './layouts/resources.js' import { setRouteLayoutContext } from './layouts/route.js' import { setRoutesIndexLayoutContext } from './layouts/routes-index.js' import { mapParameterToPythonType } from './python-type.js' @@ -21,7 +24,8 @@ interface Metadata { blueprint: Blueprint } -const rootPath = 'seam/routes' +const routesPath = 'seam/routes' +const resourcesPath = 'seam/resources' const toNamespace = (path: string): string => path.slice(1).replaceAll('/', '_') @@ -96,7 +100,7 @@ export const routes = ( .map((entry) => toNamespace(entry.path)) for (const cls of classMap.values()) { - const k = `${rootPath}/${cls.namespace}.py` + const k = `${routesPath}/${cls.namespace}.py` files[k] = { contents: Buffer.from('\n'), layout: 'route.hbs', @@ -104,16 +108,26 @@ export const routes = ( } } - files[`${rootPath}/models.py`] = { + files[`${routesPath}/__init__.py`] = { contents: Buffer.from('\n'), - layout: 'models.hbs', - ...setModelsLayoutContext(blueprint, classMap, topLevelNamespaces), + layout: 'routes-index.hbs', + ...setRoutesIndexLayoutContext(topLevelNamespaces), } - files[`${rootPath}/__init__.py`] = { + const resourceContexts = getResourceLayoutContexts(blueprint) + + for (const resource of resourceContexts) { + files[`${resourcesPath}/${resource.moduleName}.py`] = { + contents: Buffer.from('\n'), + layout: 'resource.hbs', + ...resource, + } + } + + files[`${resourcesPath}/__init__.py`] = { contents: Buffer.from('\n'), - layout: 'routes-index.hbs', - ...setRoutesIndexLayoutContext(topLevelNamespaces), + layout: 'resources-index.hbs', + ...setResourcesIndexLayoutContext(resourceContexts), } } diff --git a/codegen/smith.ts b/codegen/smith.ts index c3a8bc7f..8c266f98 100644 --- a/codegen/smith.ts +++ b/codegen/smith.ts @@ -11,7 +11,10 @@ import { helpers, routes } from './lib/index.js' const rootDir = dirname(fileURLToPath(import.meta.url)) -await Promise.all([deleteAsync('./seam/routes')]) +await Promise.all([ + deleteAsync('./seam/routes'), + deleteAsync('./seam/resources'), +]) const partials = await getHandlebarsPartials(`${rootDir}/layouts/partials`) diff --git a/seam/client.py b/seam/client.py index b4c00c30..2ac9f3ae 100644 --- a/seam/client.py +++ b/seam/client.py @@ -3,6 +3,7 @@ import niquests as requests from importlib.metadata import version from urllib3.util import Retry +import abc from .constants import LTS_VERSION from .exceptions import ( @@ -10,7 +11,6 @@ SeamHttpInvalidInputError, SeamHttpUnauthorizedError, ) -from .models import AbstractSeamHttpClient SDK_HEADERS = { "seam-sdk-name": "seamapi/python", @@ -21,6 +21,24 @@ DEFAULT_RETRIES = Retry() +class AbstractSeamHttpClient(abc.ABC): + @abc.abstractmethod + def __init__(self, base_url: str, auth_headers: Dict[str, str], **kwargs): + raise NotImplementedError + + @abc.abstractmethod + def request(self, method: str, url: str, *args, **kwargs): + raise NotImplementedError + + @abc.abstractmethod + def _handle_response(self, response: requests.Response): + raise NotImplementedError + + @abc.abstractmethod + def _handle_error_response(self, response: requests.Response): + raise NotImplementedError + + class SeamHttpClient(requests.Session, AbstractSeamHttpClient): def __init__( self, diff --git a/seam/exceptions.py b/seam/exceptions.py index f915e3f5..73fc3210 100644 --- a/seam/exceptions.py +++ b/seam/exceptions.py @@ -1,5 +1,5 @@ from typing import Any, Dict -from .routes.models import ActionAttempt +from .resources import ActionAttempt # HTTP diff --git a/seam/models.py b/seam/models.py index da8511f6..2ef8b440 100644 --- a/seam/models.py +++ b/seam/models.py @@ -1,27 +1,9 @@ from typing import Dict, List, Optional, Union -import niquests as requests from typing_extensions import Self import abc -from .routes.models import AbstractRoutes, Workspace - - -class AbstractSeamHttpClient(abc.ABC): - @abc.abstractmethod - def __init__(self, base_url: str, auth_headers: Dict[str, str], **kwargs): - raise NotImplementedError - - @abc.abstractmethod - def request(self, method: str, url: str, *args, **kwargs): - raise NotImplementedError - - @abc.abstractmethod - def _handle_response(self, response: requests.Response): - raise NotImplementedError - - @abc.abstractmethod - def _handle_error_response(self, response: requests.Response): - raise NotImplementedError +from .routes import AbstractRoutes +from .resources import Workspace class AbstractSeam(AbstractRoutes): diff --git a/seam/modules/action_attempts.py b/seam/modules/action_attempts.py index d178baa9..0f4da8b3 100644 --- a/seam/modules/action_attempts.py +++ b/seam/modules/action_attempts.py @@ -3,7 +3,7 @@ from ..client import SeamHttpClient from ..exceptions import SeamActionAttemptFailedError, SeamActionAttemptTimeoutError -from ..routes.models import ActionAttempt +from ..resources import ActionAttempt TIMEOUT = 5.0 POLLING_INTERVAL = 0.5 diff --git a/seam/resources/__init__.py b/seam/resources/__init__.py new file mode 100644 index 00000000..ce1d8c5d --- /dev/null +++ b/seam/resources/__init__.py @@ -0,0 +1,30 @@ +from .access_code import AccessCode +from .access_grant import AccessGrant +from .access_method import AccessMethod +from .acs_access_group import AcsAccessGroup +from .acs_credential import AcsCredential +from .acs_encoder import AcsEncoder +from .acs_entrance import AcsEntrance +from .acs_system import AcsSystem +from .acs_user import AcsUser +from .action_attempt import ActionAttempt +from .batch import Batch +from .client_session import ClientSession +from .connect_webview import ConnectWebview +from .connected_account import ConnectedAccount +from .customer_portal import CustomerPortal +from .device import Device +from .device_provider import DeviceProvider +from .instant_key import InstantKey +from .noise_threshold import NoiseThreshold +from .pagination import Pagination +from .phone import Phone +from .seam_event import SeamEvent +from .space import Space +from .thermostat_daily_program import ThermostatDailyProgram +from .thermostat_schedule import ThermostatSchedule +from .unmanaged_access_code import UnmanagedAccessCode +from .unmanaged_device import UnmanagedDevice +from .user_identity import UserIdentity +from .webhook import Webhook +from .workspace import Workspace diff --git a/seam/resources/access_code.py b/seam/resources/access_code.py new file mode 100644 index 00000000..549d246a --- /dev/null +++ b/seam/resources/access_code.py @@ -0,0 +1,68 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class AccessCode: + access_code_id: str + code: str + common_code_key: str + created_at: str + device_id: str + dormakaba_oracode_metadata: Dict[str, Any] + ends_at: str + errors: List[Dict[str, Any]] + is_backup: bool + is_backup_access_code_available: bool + is_external_modification_allowed: bool + is_managed: bool + is_offline_access_code: bool + is_one_time_use: bool + is_scheduled_on_device: bool + is_waiting_for_code_assignment: bool + name: str + pending_mutations: List[Dict[str, Any]] + pulled_backup_access_code_id: str + starts_at: str + status: str + type: str + warnings: List[Dict[str, Any]] + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return AccessCode( + access_code_id=d.get("access_code_id", None), + code=d.get("code", None), + common_code_key=d.get("common_code_key", None), + created_at=d.get("created_at", None), + device_id=d.get("device_id", None), + dormakaba_oracode_metadata=DeepAttrDict( + d.get("dormakaba_oracode_metadata", None) + ), + ends_at=d.get("ends_at", None), + errors=d.get("errors", None), + is_backup=d.get("is_backup", None), + is_backup_access_code_available=d.get( + "is_backup_access_code_available", None + ), + is_external_modification_allowed=d.get( + "is_external_modification_allowed", None + ), + is_managed=d.get("is_managed", None), + is_offline_access_code=d.get("is_offline_access_code", None), + is_one_time_use=d.get("is_one_time_use", None), + is_scheduled_on_device=d.get("is_scheduled_on_device", None), + is_waiting_for_code_assignment=d.get( + "is_waiting_for_code_assignment", None + ), + name=d.get("name", None), + pending_mutations=d.get("pending_mutations", None), + pulled_backup_access_code_id=d.get("pulled_backup_access_code_id", None), + starts_at=d.get("starts_at", None), + status=d.get("status", None), + type=d.get("type", None), + warnings=d.get("warnings", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/access_grant.py b/seam/resources/access_grant.py new file mode 100644 index 00000000..5b0977f2 --- /dev/null +++ b/seam/resources/access_grant.py @@ -0,0 +1,52 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class AccessGrant: + access_grant_id: str + access_grant_key: str + access_method_ids: List[str] + client_session_token: str + created_at: str + customization_profile_id: str + display_name: str + ends_at: str + errors: List[Dict[str, Any]] + instant_key_url: str + location_ids: List[str] + name: str + pending_mutations: List[Dict[str, Any]] + requested_access_methods: List[Dict[str, Any]] + reservation_key: str + space_ids: List[str] + starts_at: str + user_identity_id: str + warnings: List[Dict[str, Any]] + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return AccessGrant( + access_grant_id=d.get("access_grant_id", None), + access_grant_key=d.get("access_grant_key", None), + access_method_ids=d.get("access_method_ids", None), + client_session_token=d.get("client_session_token", None), + created_at=d.get("created_at", None), + customization_profile_id=d.get("customization_profile_id", None), + display_name=d.get("display_name", None), + ends_at=d.get("ends_at", None), + errors=d.get("errors", None), + instant_key_url=d.get("instant_key_url", None), + location_ids=d.get("location_ids", None), + name=d.get("name", None), + pending_mutations=d.get("pending_mutations", None), + requested_access_methods=d.get("requested_access_methods", None), + reservation_key=d.get("reservation_key", None), + space_ids=d.get("space_ids", None), + starts_at=d.get("starts_at", None), + user_identity_id=d.get("user_identity_id", None), + warnings=d.get("warnings", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/access_method.py b/seam/resources/access_method.py new file mode 100644 index 00000000..8347e77f --- /dev/null +++ b/seam/resources/access_method.py @@ -0,0 +1,48 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class AccessMethod: + access_method_id: str + client_session_token: str + code: str + created_at: str + customization_profile_id: str + display_name: str + errors: List[Dict[str, Any]] + instant_key_url: str + is_assignment_required: bool + is_encoding_required: bool + is_issued: bool + is_ready_for_assignment: bool + is_ready_for_encoding: bool + issued_at: str + mode: str + pending_mutations: List[Dict[str, Any]] + warnings: List[Dict[str, Any]] + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return AccessMethod( + access_method_id=d.get("access_method_id", None), + client_session_token=d.get("client_session_token", None), + code=d.get("code", None), + created_at=d.get("created_at", None), + customization_profile_id=d.get("customization_profile_id", None), + display_name=d.get("display_name", None), + errors=d.get("errors", None), + instant_key_url=d.get("instant_key_url", None), + is_assignment_required=d.get("is_assignment_required", None), + is_encoding_required=d.get("is_encoding_required", None), + is_issued=d.get("is_issued", None), + is_ready_for_assignment=d.get("is_ready_for_assignment", None), + is_ready_for_encoding=d.get("is_ready_for_encoding", None), + issued_at=d.get("issued_at", None), + mode=d.get("mode", None), + pending_mutations=d.get("pending_mutations", None), + warnings=d.get("warnings", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/acs_access_group.py b/seam/resources/acs_access_group.py new file mode 100644 index 00000000..099a8fd2 --- /dev/null +++ b/seam/resources/acs_access_group.py @@ -0,0 +1,46 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class AcsAccessGroup: + access_group_type: str + access_group_type_display_name: str + access_schedule: Dict[str, Any] + acs_access_group_id: str + acs_system_id: str + connected_account_id: str + created_at: str + display_name: str + errors: List[Dict[str, Any]] + external_type: str + external_type_display_name: str + is_managed: bool + name: str + pending_mutations: List[Dict[str, Any]] + warnings: List[Dict[str, Any]] + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return AcsAccessGroup( + access_group_type=d.get("access_group_type", None), + access_group_type_display_name=d.get( + "access_group_type_display_name", None + ), + access_schedule=DeepAttrDict(d.get("access_schedule", None)), + acs_access_group_id=d.get("acs_access_group_id", None), + acs_system_id=d.get("acs_system_id", None), + connected_account_id=d.get("connected_account_id", None), + created_at=d.get("created_at", None), + display_name=d.get("display_name", None), + errors=d.get("errors", None), + external_type=d.get("external_type", None), + external_type_display_name=d.get("external_type_display_name", None), + is_managed=d.get("is_managed", None), + name=d.get("name", None), + pending_mutations=d.get("pending_mutations", None), + warnings=d.get("warnings", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/acs_credential.py b/seam/resources/acs_credential.py new file mode 100644 index 00000000..0e9e463b --- /dev/null +++ b/seam/resources/acs_credential.py @@ -0,0 +1,76 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class AcsCredential: + access_method: str + acs_credential_id: str + acs_credential_pool_id: str + acs_system_id: str + acs_user_id: str + assa_abloy_vostio_metadata: Dict[str, Any] + card_number: str + code: str + connected_account_id: str + created_at: str + display_name: str + ends_at: str + errors: List[Dict[str, Any]] + external_type: str + external_type_display_name: str + is_issued: bool + is_latest_desired_state_synced_with_provider: bool + is_managed: bool + is_multi_phone_sync_credential: bool + is_one_time_use: bool + issued_at: str + latest_desired_state_synced_with_provider_at: str + parent_acs_credential_id: str + starts_at: str + user_identity_id: str + visionline_metadata: Dict[str, Any] + warnings: List[Dict[str, Any]] + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return AcsCredential( + access_method=d.get("access_method", None), + acs_credential_id=d.get("acs_credential_id", None), + acs_credential_pool_id=d.get("acs_credential_pool_id", None), + acs_system_id=d.get("acs_system_id", None), + acs_user_id=d.get("acs_user_id", None), + assa_abloy_vostio_metadata=DeepAttrDict( + d.get("assa_abloy_vostio_metadata", None) + ), + card_number=d.get("card_number", None), + code=d.get("code", None), + connected_account_id=d.get("connected_account_id", None), + created_at=d.get("created_at", None), + display_name=d.get("display_name", None), + ends_at=d.get("ends_at", None), + errors=d.get("errors", None), + external_type=d.get("external_type", None), + external_type_display_name=d.get("external_type_display_name", None), + is_issued=d.get("is_issued", None), + is_latest_desired_state_synced_with_provider=d.get( + "is_latest_desired_state_synced_with_provider", None + ), + is_managed=d.get("is_managed", None), + is_multi_phone_sync_credential=d.get( + "is_multi_phone_sync_credential", None + ), + is_one_time_use=d.get("is_one_time_use", None), + issued_at=d.get("issued_at", None), + latest_desired_state_synced_with_provider_at=d.get( + "latest_desired_state_synced_with_provider_at", None + ), + parent_acs_credential_id=d.get("parent_acs_credential_id", None), + starts_at=d.get("starts_at", None), + user_identity_id=d.get("user_identity_id", None), + visionline_metadata=DeepAttrDict(d.get("visionline_metadata", None)), + warnings=d.get("warnings", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/acs_encoder.py b/seam/resources/acs_encoder.py new file mode 100644 index 00000000..a5d3df05 --- /dev/null +++ b/seam/resources/acs_encoder.py @@ -0,0 +1,26 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class AcsEncoder: + acs_encoder_id: str + acs_system_id: str + connected_account_id: str + created_at: str + display_name: str + errors: List[Dict[str, Any]] + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return AcsEncoder( + acs_encoder_id=d.get("acs_encoder_id", None), + acs_system_id=d.get("acs_system_id", None), + connected_account_id=d.get("connected_account_id", None), + created_at=d.get("created_at", None), + display_name=d.get("display_name", None), + errors=d.get("errors", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/acs_entrance.py b/seam/resources/acs_entrance.py new file mode 100644 index 00000000..99c712b9 --- /dev/null +++ b/seam/resources/acs_entrance.py @@ -0,0 +1,68 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class AcsEntrance: + acs_entrance_id: str + acs_system_id: str + akiles_metadata: Dict[str, Any] + assa_abloy_vostio_metadata: Dict[str, Any] + avigilon_alta_metadata: Dict[str, Any] + brivo_metadata: Dict[str, Any] + can_belong_to_reservation: bool + can_unlock_with_card: bool + can_unlock_with_cloud_key: bool + can_unlock_with_code: bool + can_unlock_with_mobile_key: bool + connected_account_id: str + created_at: str + display_name: str + dormakaba_ambiance_metadata: Dict[str, Any] + dormakaba_community_metadata: Dict[str, Any] + errors: List[Dict[str, Any]] + hotek_metadata: Dict[str, Any] + is_locked: bool + latch_metadata: Dict[str, Any] + salto_ks_metadata: Dict[str, Any] + salto_space_metadata: Dict[str, Any] + space_ids: List[str] + visionline_metadata: Dict[str, Any] + warnings: List[Dict[str, Any]] + + @staticmethod + def from_dict(d: Dict[str, Any]): + return AcsEntrance( + acs_entrance_id=d.get("acs_entrance_id", None), + acs_system_id=d.get("acs_system_id", None), + akiles_metadata=DeepAttrDict(d.get("akiles_metadata", None)), + assa_abloy_vostio_metadata=DeepAttrDict( + d.get("assa_abloy_vostio_metadata", None) + ), + avigilon_alta_metadata=DeepAttrDict(d.get("avigilon_alta_metadata", None)), + brivo_metadata=DeepAttrDict(d.get("brivo_metadata", None)), + can_belong_to_reservation=d.get("can_belong_to_reservation", None), + can_unlock_with_card=d.get("can_unlock_with_card", None), + can_unlock_with_cloud_key=d.get("can_unlock_with_cloud_key", None), + can_unlock_with_code=d.get("can_unlock_with_code", None), + can_unlock_with_mobile_key=d.get("can_unlock_with_mobile_key", None), + connected_account_id=d.get("connected_account_id", None), + created_at=d.get("created_at", None), + display_name=d.get("display_name", None), + dormakaba_ambiance_metadata=DeepAttrDict( + d.get("dormakaba_ambiance_metadata", None) + ), + dormakaba_community_metadata=DeepAttrDict( + d.get("dormakaba_community_metadata", None) + ), + errors=d.get("errors", None), + hotek_metadata=DeepAttrDict(d.get("hotek_metadata", None)), + is_locked=d.get("is_locked", None), + latch_metadata=DeepAttrDict(d.get("latch_metadata", None)), + salto_ks_metadata=DeepAttrDict(d.get("salto_ks_metadata", None)), + salto_space_metadata=DeepAttrDict(d.get("salto_space_metadata", None)), + space_ids=d.get("space_ids", None), + visionline_metadata=DeepAttrDict(d.get("visionline_metadata", None)), + warnings=d.get("warnings", None), + ) diff --git a/seam/resources/acs_system.py b/seam/resources/acs_system.py new file mode 100644 index 00000000..4051ff27 --- /dev/null +++ b/seam/resources/acs_system.py @@ -0,0 +1,54 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class AcsSystem: + acs_access_group_count: float + acs_system_id: str + acs_user_count: float + connected_account_id: str + connected_account_ids: List[str] + created_at: str + default_credential_manager_acs_system_id: str + errors: List[Dict[str, Any]] + external_type: str + external_type_display_name: str + image_alt_text: str + image_url: str + is_credential_manager: bool + location: Dict[str, Any] + name: str + system_type: str + system_type_display_name: str + visionline_metadata: Dict[str, Any] + warnings: List[Dict[str, Any]] + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return AcsSystem( + acs_access_group_count=d.get("acs_access_group_count", None), + acs_system_id=d.get("acs_system_id", None), + acs_user_count=d.get("acs_user_count", None), + connected_account_id=d.get("connected_account_id", None), + connected_account_ids=d.get("connected_account_ids", None), + created_at=d.get("created_at", None), + default_credential_manager_acs_system_id=d.get( + "default_credential_manager_acs_system_id", None + ), + errors=d.get("errors", None), + external_type=d.get("external_type", None), + external_type_display_name=d.get("external_type_display_name", None), + image_alt_text=d.get("image_alt_text", None), + image_url=d.get("image_url", None), + is_credential_manager=d.get("is_credential_manager", None), + location=DeepAttrDict(d.get("location", None)), + name=d.get("name", None), + system_type=d.get("system_type", None), + system_type_display_name=d.get("system_type_display_name", None), + visionline_metadata=DeepAttrDict(d.get("visionline_metadata", None)), + warnings=d.get("warnings", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/acs_user.py b/seam/resources/acs_user.py new file mode 100644 index 00000000..c0b43b09 --- /dev/null +++ b/seam/resources/acs_user.py @@ -0,0 +1,62 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class AcsUser: + access_schedule: Dict[str, Any] + acs_system_id: str + acs_user_id: str + connected_account_id: str + created_at: str + display_name: str + email: str + email_address: str + errors: List[Dict[str, Any]] + external_type: str + external_type_display_name: str + full_name: str + hid_acs_system_id: str + is_managed: bool + is_suspended: bool + pending_mutations: List[Dict[str, Any]] + phone_number: str + salto_ks_metadata: Dict[str, Any] + salto_space_metadata: Dict[str, Any] + user_identity_email_address: str + user_identity_full_name: str + user_identity_id: str + user_identity_phone_number: str + warnings: List[Dict[str, Any]] + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return AcsUser( + access_schedule=DeepAttrDict(d.get("access_schedule", None)), + acs_system_id=d.get("acs_system_id", None), + acs_user_id=d.get("acs_user_id", None), + connected_account_id=d.get("connected_account_id", None), + created_at=d.get("created_at", None), + display_name=d.get("display_name", None), + email=d.get("email", None), + email_address=d.get("email_address", None), + errors=d.get("errors", None), + external_type=d.get("external_type", None), + external_type_display_name=d.get("external_type_display_name", None), + full_name=d.get("full_name", None), + hid_acs_system_id=d.get("hid_acs_system_id", None), + is_managed=d.get("is_managed", None), + is_suspended=d.get("is_suspended", None), + pending_mutations=d.get("pending_mutations", None), + phone_number=d.get("phone_number", None), + salto_ks_metadata=DeepAttrDict(d.get("salto_ks_metadata", None)), + salto_space_metadata=DeepAttrDict(d.get("salto_space_metadata", None)), + user_identity_email_address=d.get("user_identity_email_address", None), + user_identity_full_name=d.get("user_identity_full_name", None), + user_identity_id=d.get("user_identity_id", None), + user_identity_phone_number=d.get("user_identity_phone_number", None), + warnings=d.get("warnings", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/action_attempt.py b/seam/resources/action_attempt.py new file mode 100644 index 00000000..59025c6e --- /dev/null +++ b/seam/resources/action_attempt.py @@ -0,0 +1,22 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class ActionAttempt: + action_attempt_id: str + action_type: str + error: Dict[str, Any] + result: Dict[str, Any] + status: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return ActionAttempt( + action_attempt_id=d.get("action_attempt_id", None), + action_type=d.get("action_type", None), + error=DeepAttrDict(d.get("error", None)), + result=DeepAttrDict(d.get("result", None)), + status=d.get("status", None), + ) diff --git a/seam/resources/batch.py b/seam/resources/batch.py new file mode 100644 index 00000000..03186721 --- /dev/null +++ b/seam/resources/batch.py @@ -0,0 +1,60 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class Batch: + access_codes: List[Dict[str, Any]] + access_grants: List[Dict[str, Any]] + access_methods: List[Dict[str, Any]] + acs_access_groups: List[Dict[str, Any]] + acs_credentials: List[Dict[str, Any]] + acs_encoders: List[Dict[str, Any]] + acs_entrances: List[Dict[str, Any]] + acs_systems: List[Dict[str, Any]] + acs_users: List[Dict[str, Any]] + action_attempts: List[Dict[str, Any]] + client_sessions: List[Dict[str, Any]] + connect_webviews: List[Dict[str, Any]] + connected_accounts: List[Dict[str, Any]] + devices: List[Dict[str, Any]] + events: List[Dict[str, Any]] + instant_keys: List[Dict[str, Any]] + noise_thresholds: List[Dict[str, Any]] + spaces: List[Dict[str, Any]] + thermostat_daily_programs: List[Dict[str, Any]] + thermostat_schedules: List[Dict[str, Any]] + unmanaged_access_codes: List[Dict[str, Any]] + unmanaged_devices: List[Dict[str, Any]] + user_identities: List[Dict[str, Any]] + workspaces: List[Dict[str, Any]] + + @staticmethod + def from_dict(d: Dict[str, Any]): + return Batch( + access_codes=d.get("access_codes", None), + access_grants=d.get("access_grants", None), + access_methods=d.get("access_methods", None), + acs_access_groups=d.get("acs_access_groups", None), + acs_credentials=d.get("acs_credentials", None), + acs_encoders=d.get("acs_encoders", None), + acs_entrances=d.get("acs_entrances", None), + acs_systems=d.get("acs_systems", None), + acs_users=d.get("acs_users", None), + action_attempts=d.get("action_attempts", None), + client_sessions=d.get("client_sessions", None), + connect_webviews=d.get("connect_webviews", None), + connected_accounts=d.get("connected_accounts", None), + devices=d.get("devices", None), + events=d.get("events", None), + instant_keys=d.get("instant_keys", None), + noise_thresholds=d.get("noise_thresholds", None), + spaces=d.get("spaces", None), + thermostat_daily_programs=d.get("thermostat_daily_programs", None), + thermostat_schedules=d.get("thermostat_schedules", None), + unmanaged_access_codes=d.get("unmanaged_access_codes", None), + unmanaged_devices=d.get("unmanaged_devices", None), + user_identities=d.get("user_identities", None), + workspaces=d.get("workspaces", None), + ) diff --git a/seam/resources/client_session.py b/seam/resources/client_session.py new file mode 100644 index 00000000..77569368 --- /dev/null +++ b/seam/resources/client_session.py @@ -0,0 +1,36 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class ClientSession: + client_session_id: str + connect_webview_ids: List[str] + connected_account_ids: List[str] + created_at: str + customer_key: str + device_count: float + expires_at: str + token: str + user_identifier_key: str + user_identity_id: str + user_identity_ids: List[str] + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return ClientSession( + client_session_id=d.get("client_session_id", None), + connect_webview_ids=d.get("connect_webview_ids", None), + connected_account_ids=d.get("connected_account_ids", None), + created_at=d.get("created_at", None), + customer_key=d.get("customer_key", None), + device_count=d.get("device_count", None), + expires_at=d.get("expires_at", None), + token=d.get("token", None), + user_identifier_key=d.get("user_identifier_key", None), + user_identity_id=d.get("user_identity_id", None), + user_identity_ids=d.get("user_identity_ids", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/connect_webview.py b/seam/resources/connect_webview.py new file mode 100644 index 00000000..7de83e04 --- /dev/null +++ b/seam/resources/connect_webview.py @@ -0,0 +1,52 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class ConnectWebview: + accepted_capabilities: List[str] + accepted_providers: List[str] + any_provider_allowed: bool + authorized_at: str + automatically_manage_new_devices: bool + connect_webview_id: str + connected_account_id: str + created_at: str + custom_metadata: Dict[str, Any] + custom_redirect_failure_url: str + custom_redirect_url: str + customer_key: str + device_selection_mode: str + login_successful: bool + selected_provider: str + status: str + url: str + wait_for_device_creation: bool + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return ConnectWebview( + accepted_capabilities=d.get("accepted_capabilities", None), + accepted_providers=d.get("accepted_providers", None), + any_provider_allowed=d.get("any_provider_allowed", None), + authorized_at=d.get("authorized_at", None), + automatically_manage_new_devices=d.get( + "automatically_manage_new_devices", None + ), + connect_webview_id=d.get("connect_webview_id", None), + connected_account_id=d.get("connected_account_id", None), + created_at=d.get("created_at", None), + custom_metadata=DeepAttrDict(d.get("custom_metadata", None)), + custom_redirect_failure_url=d.get("custom_redirect_failure_url", None), + custom_redirect_url=d.get("custom_redirect_url", None), + customer_key=d.get("customer_key", None), + device_selection_mode=d.get("device_selection_mode", None), + login_successful=d.get("login_successful", None), + selected_provider=d.get("selected_provider", None), + status=d.get("status", None), + url=d.get("url", None), + wait_for_device_creation=d.get("wait_for_device_creation", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/connected_account.py b/seam/resources/connected_account.py new file mode 100644 index 00000000..b6904caa --- /dev/null +++ b/seam/resources/connected_account.py @@ -0,0 +1,50 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class ConnectedAccount: + accepted_capabilities: List[str] + account_type: str + account_type_display_name: str + automatically_manage_new_devices: bool + connected_account_id: str + created_at: str + custom_metadata: Dict[str, Any] + customer_key: str + default_checkin_time: str + default_checkout_time: str + display_name: str + errors: List[Dict[str, Any]] + ical_feed_origin: str + ical_url: str + image_url: str + time_zone: str + user_identifier: Dict[str, Any] + warnings: List[Dict[str, Any]] + + @staticmethod + def from_dict(d: Dict[str, Any]): + return ConnectedAccount( + accepted_capabilities=d.get("accepted_capabilities", None), + account_type=d.get("account_type", None), + account_type_display_name=d.get("account_type_display_name", None), + automatically_manage_new_devices=d.get( + "automatically_manage_new_devices", None + ), + connected_account_id=d.get("connected_account_id", None), + created_at=d.get("created_at", None), + custom_metadata=DeepAttrDict(d.get("custom_metadata", None)), + customer_key=d.get("customer_key", None), + default_checkin_time=d.get("default_checkin_time", None), + default_checkout_time=d.get("default_checkout_time", None), + display_name=d.get("display_name", None), + errors=d.get("errors", None), + ical_feed_origin=d.get("ical_feed_origin", None), + ical_url=d.get("ical_url", None), + image_url=d.get("image_url", None), + time_zone=d.get("time_zone", None), + user_identifier=DeepAttrDict(d.get("user_identifier", None)), + warnings=d.get("warnings", None), + ) diff --git a/seam/resources/customer_portal.py b/seam/resources/customer_portal.py new file mode 100644 index 00000000..eafd6ac5 --- /dev/null +++ b/seam/resources/customer_portal.py @@ -0,0 +1,22 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class CustomerPortal: + created_at: str + customer_key: str + expires_at: str + url: str + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return CustomerPortal( + created_at=d.get("created_at", None), + customer_key=d.get("customer_key", None), + expires_at=d.get("expires_at", None), + url=d.get("url", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/device.py b/seam/resources/device.py new file mode 100644 index 00000000..e55bd6c2 --- /dev/null +++ b/seam/resources/device.py @@ -0,0 +1,100 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class Device: + can_configure_auto_lock: bool + can_hvac_cool: bool + can_hvac_heat: bool + can_hvac_heat_cool: bool + can_program_offline_access_codes: bool + can_program_online_access_codes: bool + can_program_thermostat_programs_as_different_each_day: bool + can_program_thermostat_programs_as_same_each_day: bool + can_program_thermostat_programs_as_weekday_weekend: bool + can_remotely_lock: bool + can_remotely_unlock: bool + can_run_thermostat_programs: bool + can_simulate_connection: bool + can_simulate_disconnection: bool + can_simulate_hub_connection: bool + can_simulate_hub_disconnection: bool + can_simulate_paid_subscription: bool + can_simulate_removal: bool + can_turn_off_hvac: bool + can_unlock_with_code: bool + capabilities_supported: List[str] + connected_account_id: str + created_at: str + custom_metadata: Dict[str, Any] + device_id: str + device_manufacturer: Dict[str, Any] + device_provider: Dict[str, Any] + device_type: str + display_name: str + errors: List[Dict[str, Any]] + is_managed: bool + location: Dict[str, Any] + nickname: str + properties: Dict[str, Any] + space_ids: List[str] + warnings: List[Dict[str, Any]] + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return Device( + can_configure_auto_lock=d.get("can_configure_auto_lock", None), + can_hvac_cool=d.get("can_hvac_cool", None), + can_hvac_heat=d.get("can_hvac_heat", None), + can_hvac_heat_cool=d.get("can_hvac_heat_cool", None), + can_program_offline_access_codes=d.get( + "can_program_offline_access_codes", None + ), + can_program_online_access_codes=d.get( + "can_program_online_access_codes", None + ), + can_program_thermostat_programs_as_different_each_day=d.get( + "can_program_thermostat_programs_as_different_each_day", None + ), + can_program_thermostat_programs_as_same_each_day=d.get( + "can_program_thermostat_programs_as_same_each_day", None + ), + can_program_thermostat_programs_as_weekday_weekend=d.get( + "can_program_thermostat_programs_as_weekday_weekend", None + ), + can_remotely_lock=d.get("can_remotely_lock", None), + can_remotely_unlock=d.get("can_remotely_unlock", None), + can_run_thermostat_programs=d.get("can_run_thermostat_programs", None), + can_simulate_connection=d.get("can_simulate_connection", None), + can_simulate_disconnection=d.get("can_simulate_disconnection", None), + can_simulate_hub_connection=d.get("can_simulate_hub_connection", None), + can_simulate_hub_disconnection=d.get( + "can_simulate_hub_disconnection", None + ), + can_simulate_paid_subscription=d.get( + "can_simulate_paid_subscription", None + ), + can_simulate_removal=d.get("can_simulate_removal", None), + can_turn_off_hvac=d.get("can_turn_off_hvac", None), + can_unlock_with_code=d.get("can_unlock_with_code", None), + capabilities_supported=d.get("capabilities_supported", None), + connected_account_id=d.get("connected_account_id", None), + created_at=d.get("created_at", None), + custom_metadata=DeepAttrDict(d.get("custom_metadata", None)), + device_id=d.get("device_id", None), + device_manufacturer=DeepAttrDict(d.get("device_manufacturer", None)), + device_provider=DeepAttrDict(d.get("device_provider", None)), + device_type=d.get("device_type", None), + display_name=d.get("display_name", None), + errors=d.get("errors", None), + is_managed=d.get("is_managed", None), + location=DeepAttrDict(d.get("location", None)), + nickname=d.get("nickname", None), + properties=DeepAttrDict(d.get("properties", None)), + space_ids=d.get("space_ids", None), + warnings=d.get("warnings", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/device_provider.py b/seam/resources/device_provider.py new file mode 100644 index 00000000..29ea7c96 --- /dev/null +++ b/seam/resources/device_provider.py @@ -0,0 +1,74 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class DeviceProvider: + can_configure_auto_lock: bool + can_hvac_cool: bool + can_hvac_heat: bool + can_hvac_heat_cool: bool + can_program_offline_access_codes: bool + can_program_online_access_codes: bool + can_program_thermostat_programs_as_different_each_day: bool + can_program_thermostat_programs_as_same_each_day: bool + can_program_thermostat_programs_as_weekday_weekend: bool + can_remotely_lock: bool + can_remotely_unlock: bool + can_run_thermostat_programs: bool + can_simulate_connection: bool + can_simulate_disconnection: bool + can_simulate_hub_connection: bool + can_simulate_hub_disconnection: bool + can_simulate_paid_subscription: bool + can_simulate_removal: bool + can_turn_off_hvac: bool + can_unlock_with_code: bool + device_provider_name: str + display_name: str + image_url: str + provider_categories: List[str] + + @staticmethod + def from_dict(d: Dict[str, Any]): + return DeviceProvider( + can_configure_auto_lock=d.get("can_configure_auto_lock", None), + can_hvac_cool=d.get("can_hvac_cool", None), + can_hvac_heat=d.get("can_hvac_heat", None), + can_hvac_heat_cool=d.get("can_hvac_heat_cool", None), + can_program_offline_access_codes=d.get( + "can_program_offline_access_codes", None + ), + can_program_online_access_codes=d.get( + "can_program_online_access_codes", None + ), + can_program_thermostat_programs_as_different_each_day=d.get( + "can_program_thermostat_programs_as_different_each_day", None + ), + can_program_thermostat_programs_as_same_each_day=d.get( + "can_program_thermostat_programs_as_same_each_day", None + ), + can_program_thermostat_programs_as_weekday_weekend=d.get( + "can_program_thermostat_programs_as_weekday_weekend", None + ), + can_remotely_lock=d.get("can_remotely_lock", None), + can_remotely_unlock=d.get("can_remotely_unlock", None), + can_run_thermostat_programs=d.get("can_run_thermostat_programs", None), + can_simulate_connection=d.get("can_simulate_connection", None), + can_simulate_disconnection=d.get("can_simulate_disconnection", None), + can_simulate_hub_connection=d.get("can_simulate_hub_connection", None), + can_simulate_hub_disconnection=d.get( + "can_simulate_hub_disconnection", None + ), + can_simulate_paid_subscription=d.get( + "can_simulate_paid_subscription", None + ), + can_simulate_removal=d.get("can_simulate_removal", None), + can_turn_off_hvac=d.get("can_turn_off_hvac", None), + can_unlock_with_code=d.get("can_unlock_with_code", None), + device_provider_name=d.get("device_provider_name", None), + display_name=d.get("display_name", None), + image_url=d.get("image_url", None), + provider_categories=d.get("provider_categories", None), + ) diff --git a/seam/resources/instant_key.py b/seam/resources/instant_key.py new file mode 100644 index 00000000..8ee16b20 --- /dev/null +++ b/seam/resources/instant_key.py @@ -0,0 +1,30 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class InstantKey: + client_session_id: str + created_at: str + customization: Dict[str, Any] + customization_profile_id: str + expires_at: str + instant_key_id: str + instant_key_url: str + user_identity_id: str + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return InstantKey( + client_session_id=d.get("client_session_id", None), + created_at=d.get("created_at", None), + customization=DeepAttrDict(d.get("customization", None)), + customization_profile_id=d.get("customization_profile_id", None), + expires_at=d.get("expires_at", None), + instant_key_id=d.get("instant_key_id", None), + instant_key_url=d.get("instant_key_url", None), + user_identity_id=d.get("user_identity_id", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/noise_threshold.py b/seam/resources/noise_threshold.py new file mode 100644 index 00000000..19f4a47c --- /dev/null +++ b/seam/resources/noise_threshold.py @@ -0,0 +1,26 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class NoiseThreshold: + device_id: str + ends_daily_at: str + name: str + noise_threshold_decibels: float + noise_threshold_id: str + noise_threshold_nrs: float + starts_daily_at: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return NoiseThreshold( + device_id=d.get("device_id", None), + ends_daily_at=d.get("ends_daily_at", None), + name=d.get("name", None), + noise_threshold_decibels=d.get("noise_threshold_decibels", None), + noise_threshold_id=d.get("noise_threshold_id", None), + noise_threshold_nrs=d.get("noise_threshold_nrs", None), + starts_daily_at=d.get("starts_daily_at", None), + ) diff --git a/seam/resources/pagination.py b/seam/resources/pagination.py new file mode 100644 index 00000000..4e5fda03 --- /dev/null +++ b/seam/resources/pagination.py @@ -0,0 +1,18 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class Pagination: + has_next_page: bool + next_page_cursor: str + next_page_url: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return Pagination( + has_next_page=d.get("has_next_page", None), + next_page_cursor=d.get("next_page_cursor", None), + next_page_url=d.get("next_page_url", None), + ) diff --git a/seam/resources/phone.py b/seam/resources/phone.py new file mode 100644 index 00000000..d80239b2 --- /dev/null +++ b/seam/resources/phone.py @@ -0,0 +1,32 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class Phone: + created_at: str + custom_metadata: Dict[str, Any] + device_id: str + device_type: str + display_name: str + errors: List[Dict[str, Any]] + nickname: str + properties: Dict[str, Any] + warnings: List[Dict[str, Any]] + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return Phone( + created_at=d.get("created_at", None), + custom_metadata=DeepAttrDict(d.get("custom_metadata", None)), + device_id=d.get("device_id", None), + device_type=d.get("device_type", None), + display_name=d.get("display_name", None), + errors=d.get("errors", None), + nickname=d.get("nickname", None), + properties=DeepAttrDict(d.get("properties", None)), + warnings=d.get("warnings", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/seam_event.py b/seam/resources/seam_event.py new file mode 100644 index 00000000..614fdbf9 --- /dev/null +++ b/seam/resources/seam_event.py @@ -0,0 +1,198 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class SeamEvent: + access_code_id: str + connected_account_custom_metadata: Dict[str, Any] + connected_account_id: str + created_at: str + device_custom_metadata: Dict[str, Any] + device_id: str + event_description: str + event_id: str + event_type: str + occurred_at: str + workspace_id: str + change_reason: str + changed_properties: List[Dict[str, Any]] + description: str + from_: Dict[str, Any] + to: Dict[str, Any] + requested_mutations: List[Dict[str, Any]] + code: str + access_code_errors: List[Dict[str, Any]] + access_code_warnings: List[Dict[str, Any]] + connected_account_errors: List[Dict[str, Any]] + connected_account_warnings: List[Dict[str, Any]] + device_errors: List[Dict[str, Any]] + device_warnings: List[Dict[str, Any]] + backup_access_code_id: str + access_grant_id: str + acs_entrance_id: str + access_grant_key: str + ends_at: str + starts_at: str + error_message: str + missing_device_ids: List[str] + access_grant_ids: List[str] + access_grant_keys: List[str] + access_method_id: str + is_backup_code: bool + acs_system_id: str + acs_system_errors: List[Dict[str, Any]] + acs_system_warnings: List[Dict[str, Any]] + acs_credential_id: str + acs_user_id: str + acs_encoder_id: str + acs_access_group_id: str + client_session_id: str + connect_webview_id: str + customer_key: str + connected_account_type: str + action_attempt_id: str + action_type: str + status: str + error_code: str + battery_level: float + battery_status: str + device_name: str + minut_metadata: Dict[str, Any] + noise_level_decibels: float + noise_level_nrs: float + noise_threshold_id: str + noise_threshold_name: str + noiseaware_metadata: Dict[str, Any] + access_code_is_managed: bool + is_via_bluetooth: bool + is_via_nfc: bool + method: str + user_identity_id: str + reason: Dict[str, Any] + climate_preset_key: str + is_fallback_climate_preset: bool + thermostat_schedule_id: str + cooling_set_point_celsius: float + cooling_set_point_fahrenheit: float + fan_mode_setting: str + heating_set_point_celsius: float + heating_set_point_fahrenheit: float + hvac_mode_setting: str + lower_limit_celsius: float + lower_limit_fahrenheit: float + temperature_celsius: float + temperature_fahrenheit: float + upper_limit_celsius: float + upper_limit_fahrenheit: float + desired_temperature_celsius: float + desired_temperature_fahrenheit: float + activation_reason: str + image_url: str + motion_sub_type: str + video_url: str + acs_entrance_ids: List[str] + device_ids: List[str] + space_id: str + space_key: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return SeamEvent( + access_code_id=d.get("access_code_id", None), + connected_account_custom_metadata=DeepAttrDict( + d.get("connected_account_custom_metadata", None) + ), + connected_account_id=d.get("connected_account_id", None), + created_at=d.get("created_at", None), + device_custom_metadata=DeepAttrDict(d.get("device_custom_metadata", None)), + device_id=d.get("device_id", None), + event_description=d.get("event_description", None), + event_id=d.get("event_id", None), + event_type=d.get("event_type", None), + occurred_at=d.get("occurred_at", None), + workspace_id=d.get("workspace_id", None), + change_reason=d.get("change_reason", None), + changed_properties=d.get("changed_properties", None), + description=d.get("description", None), + from_=DeepAttrDict(d.get("from", None)), + to=DeepAttrDict(d.get("to", None)), + requested_mutations=d.get("requested_mutations", None), + code=d.get("code", None), + access_code_errors=d.get("access_code_errors", None), + access_code_warnings=d.get("access_code_warnings", None), + connected_account_errors=d.get("connected_account_errors", None), + connected_account_warnings=d.get("connected_account_warnings", None), + device_errors=d.get("device_errors", None), + device_warnings=d.get("device_warnings", None), + backup_access_code_id=d.get("backup_access_code_id", None), + access_grant_id=d.get("access_grant_id", None), + acs_entrance_id=d.get("acs_entrance_id", None), + access_grant_key=d.get("access_grant_key", None), + ends_at=d.get("ends_at", None), + starts_at=d.get("starts_at", None), + error_message=d.get("error_message", None), + missing_device_ids=d.get("missing_device_ids", None), + access_grant_ids=d.get("access_grant_ids", None), + access_grant_keys=d.get("access_grant_keys", None), + access_method_id=d.get("access_method_id", None), + is_backup_code=d.get("is_backup_code", None), + acs_system_id=d.get("acs_system_id", None), + acs_system_errors=d.get("acs_system_errors", None), + acs_system_warnings=d.get("acs_system_warnings", None), + acs_credential_id=d.get("acs_credential_id", None), + acs_user_id=d.get("acs_user_id", None), + acs_encoder_id=d.get("acs_encoder_id", None), + acs_access_group_id=d.get("acs_access_group_id", None), + client_session_id=d.get("client_session_id", None), + connect_webview_id=d.get("connect_webview_id", None), + customer_key=d.get("customer_key", None), + connected_account_type=d.get("connected_account_type", None), + action_attempt_id=d.get("action_attempt_id", None), + action_type=d.get("action_type", None), + status=d.get("status", None), + error_code=d.get("error_code", None), + battery_level=d.get("battery_level", None), + battery_status=d.get("battery_status", None), + device_name=d.get("device_name", None), + minut_metadata=DeepAttrDict(d.get("minut_metadata", None)), + noise_level_decibels=d.get("noise_level_decibels", None), + noise_level_nrs=d.get("noise_level_nrs", None), + noise_threshold_id=d.get("noise_threshold_id", None), + noise_threshold_name=d.get("noise_threshold_name", None), + noiseaware_metadata=DeepAttrDict(d.get("noiseaware_metadata", None)), + access_code_is_managed=d.get("access_code_is_managed", None), + is_via_bluetooth=d.get("is_via_bluetooth", None), + is_via_nfc=d.get("is_via_nfc", None), + method=d.get("method", None), + user_identity_id=d.get("user_identity_id", None), + reason=DeepAttrDict(d.get("reason", None)), + climate_preset_key=d.get("climate_preset_key", None), + is_fallback_climate_preset=d.get("is_fallback_climate_preset", None), + thermostat_schedule_id=d.get("thermostat_schedule_id", None), + cooling_set_point_celsius=d.get("cooling_set_point_celsius", None), + cooling_set_point_fahrenheit=d.get("cooling_set_point_fahrenheit", None), + fan_mode_setting=d.get("fan_mode_setting", None), + heating_set_point_celsius=d.get("heating_set_point_celsius", None), + heating_set_point_fahrenheit=d.get("heating_set_point_fahrenheit", None), + hvac_mode_setting=d.get("hvac_mode_setting", None), + lower_limit_celsius=d.get("lower_limit_celsius", None), + lower_limit_fahrenheit=d.get("lower_limit_fahrenheit", None), + temperature_celsius=d.get("temperature_celsius", None), + temperature_fahrenheit=d.get("temperature_fahrenheit", None), + upper_limit_celsius=d.get("upper_limit_celsius", None), + upper_limit_fahrenheit=d.get("upper_limit_fahrenheit", None), + desired_temperature_celsius=d.get("desired_temperature_celsius", None), + desired_temperature_fahrenheit=d.get( + "desired_temperature_fahrenheit", None + ), + activation_reason=d.get("activation_reason", None), + image_url=d.get("image_url", None), + motion_sub_type=d.get("motion_sub_type", None), + video_url=d.get("video_url", None), + acs_entrance_ids=d.get("acs_entrance_ids", None), + device_ids=d.get("device_ids", None), + space_id=d.get("space_id", None), + space_key=d.get("space_key", None), + ) diff --git a/seam/resources/space.py b/seam/resources/space.py new file mode 100644 index 00000000..16222eee --- /dev/null +++ b/seam/resources/space.py @@ -0,0 +1,34 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class Space: + acs_entrance_count: float + created_at: str + customer_data: Dict[str, Any] + customer_key: str + device_count: float + display_name: str + geolocation: Dict[str, Any] + name: str + space_id: str + space_key: str + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return Space( + acs_entrance_count=d.get("acs_entrance_count", None), + created_at=d.get("created_at", None), + customer_data=DeepAttrDict(d.get("customer_data", None)), + customer_key=d.get("customer_key", None), + device_count=d.get("device_count", None), + display_name=d.get("display_name", None), + geolocation=DeepAttrDict(d.get("geolocation", None)), + name=d.get("name", None), + space_id=d.get("space_id", None), + space_key=d.get("space_key", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/thermostat_daily_program.py b/seam/resources/thermostat_daily_program.py new file mode 100644 index 00000000..2476fecc --- /dev/null +++ b/seam/resources/thermostat_daily_program.py @@ -0,0 +1,24 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class ThermostatDailyProgram: + created_at: str + device_id: str + name: str + periods: List[Dict[str, Any]] + thermostat_daily_program_id: str + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return ThermostatDailyProgram( + created_at=d.get("created_at", None), + device_id=d.get("device_id", None), + name=d.get("name", None), + periods=d.get("periods", None), + thermostat_daily_program_id=d.get("thermostat_daily_program_id", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/thermostat_schedule.py b/seam/resources/thermostat_schedule.py new file mode 100644 index 00000000..8c48bfa7 --- /dev/null +++ b/seam/resources/thermostat_schedule.py @@ -0,0 +1,34 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class ThermostatSchedule: + climate_preset_key: str + created_at: str + device_id: str + ends_at: str + errors: List[Dict[str, Any]] + is_override_allowed: bool + max_override_period_minutes: int + name: str + starts_at: str + thermostat_schedule_id: str + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return ThermostatSchedule( + climate_preset_key=d.get("climate_preset_key", None), + created_at=d.get("created_at", None), + device_id=d.get("device_id", None), + ends_at=d.get("ends_at", None), + errors=d.get("errors", None), + is_override_allowed=d.get("is_override_allowed", None), + max_override_period_minutes=d.get("max_override_period_minutes", None), + name=d.get("name", None), + starts_at=d.get("starts_at", None), + thermostat_schedule_id=d.get("thermostat_schedule_id", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/unmanaged_access_code.py b/seam/resources/unmanaged_access_code.py new file mode 100644 index 00000000..60dce019 --- /dev/null +++ b/seam/resources/unmanaged_access_code.py @@ -0,0 +1,48 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class UnmanagedAccessCode: + access_code_id: str + cannot_be_managed: bool + cannot_delete_unmanaged_access_code: bool + code: str + created_at: str + device_id: str + dormakaba_oracode_metadata: Dict[str, Any] + ends_at: str + errors: List[Dict[str, Any]] + is_managed: bool + name: str + starts_at: str + status: str + type: str + warnings: List[Dict[str, Any]] + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return UnmanagedAccessCode( + access_code_id=d.get("access_code_id", None), + cannot_be_managed=d.get("cannot_be_managed", None), + cannot_delete_unmanaged_access_code=d.get( + "cannot_delete_unmanaged_access_code", None + ), + code=d.get("code", None), + created_at=d.get("created_at", None), + device_id=d.get("device_id", None), + dormakaba_oracode_metadata=DeepAttrDict( + d.get("dormakaba_oracode_metadata", None) + ), + ends_at=d.get("ends_at", None), + errors=d.get("errors", None), + is_managed=d.get("is_managed", None), + name=d.get("name", None), + starts_at=d.get("starts_at", None), + status=d.get("status", None), + type=d.get("type", None), + warnings=d.get("warnings", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/unmanaged_device.py b/seam/resources/unmanaged_device.py new file mode 100644 index 00000000..85ca4b68 --- /dev/null +++ b/seam/resources/unmanaged_device.py @@ -0,0 +1,90 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class UnmanagedDevice: + can_configure_auto_lock: bool + can_hvac_cool: bool + can_hvac_heat: bool + can_hvac_heat_cool: bool + can_program_offline_access_codes: bool + can_program_online_access_codes: bool + can_program_thermostat_programs_as_different_each_day: bool + can_program_thermostat_programs_as_same_each_day: bool + can_program_thermostat_programs_as_weekday_weekend: bool + can_remotely_lock: bool + can_remotely_unlock: bool + can_run_thermostat_programs: bool + can_simulate_connection: bool + can_simulate_disconnection: bool + can_simulate_hub_connection: bool + can_simulate_hub_disconnection: bool + can_simulate_paid_subscription: bool + can_simulate_removal: bool + can_turn_off_hvac: bool + can_unlock_with_code: bool + capabilities_supported: List[str] + connected_account_id: str + created_at: str + custom_metadata: Dict[str, Any] + device_id: str + device_type: str + errors: List[Dict[str, Any]] + is_managed: bool + location: Dict[str, Any] + properties: Dict[str, Any] + warnings: List[Dict[str, Any]] + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return UnmanagedDevice( + can_configure_auto_lock=d.get("can_configure_auto_lock", None), + can_hvac_cool=d.get("can_hvac_cool", None), + can_hvac_heat=d.get("can_hvac_heat", None), + can_hvac_heat_cool=d.get("can_hvac_heat_cool", None), + can_program_offline_access_codes=d.get( + "can_program_offline_access_codes", None + ), + can_program_online_access_codes=d.get( + "can_program_online_access_codes", None + ), + can_program_thermostat_programs_as_different_each_day=d.get( + "can_program_thermostat_programs_as_different_each_day", None + ), + can_program_thermostat_programs_as_same_each_day=d.get( + "can_program_thermostat_programs_as_same_each_day", None + ), + can_program_thermostat_programs_as_weekday_weekend=d.get( + "can_program_thermostat_programs_as_weekday_weekend", None + ), + can_remotely_lock=d.get("can_remotely_lock", None), + can_remotely_unlock=d.get("can_remotely_unlock", None), + can_run_thermostat_programs=d.get("can_run_thermostat_programs", None), + can_simulate_connection=d.get("can_simulate_connection", None), + can_simulate_disconnection=d.get("can_simulate_disconnection", None), + can_simulate_hub_connection=d.get("can_simulate_hub_connection", None), + can_simulate_hub_disconnection=d.get( + "can_simulate_hub_disconnection", None + ), + can_simulate_paid_subscription=d.get( + "can_simulate_paid_subscription", None + ), + can_simulate_removal=d.get("can_simulate_removal", None), + can_turn_off_hvac=d.get("can_turn_off_hvac", None), + can_unlock_with_code=d.get("can_unlock_with_code", None), + capabilities_supported=d.get("capabilities_supported", None), + connected_account_id=d.get("connected_account_id", None), + created_at=d.get("created_at", None), + custom_metadata=DeepAttrDict(d.get("custom_metadata", None)), + device_id=d.get("device_id", None), + device_type=d.get("device_type", None), + errors=d.get("errors", None), + is_managed=d.get("is_managed", None), + location=DeepAttrDict(d.get("location", None)), + properties=DeepAttrDict(d.get("properties", None)), + warnings=d.get("warnings", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/user_identity.py b/seam/resources/user_identity.py new file mode 100644 index 00000000..36c3da79 --- /dev/null +++ b/seam/resources/user_identity.py @@ -0,0 +1,34 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class UserIdentity: + acs_user_ids: List[str] + created_at: str + display_name: str + email_address: str + errors: List[Dict[str, Any]] + full_name: str + phone_number: str + user_identity_id: str + user_identity_key: str + warnings: List[Dict[str, Any]] + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return UserIdentity( + acs_user_ids=d.get("acs_user_ids", None), + created_at=d.get("created_at", None), + display_name=d.get("display_name", None), + email_address=d.get("email_address", None), + errors=d.get("errors", None), + full_name=d.get("full_name", None), + phone_number=d.get("phone_number", None), + user_identity_id=d.get("user_identity_id", None), + user_identity_key=d.get("user_identity_key", None), + warnings=d.get("warnings", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/resources/webhook.py b/seam/resources/webhook.py new file mode 100644 index 00000000..13adf821 --- /dev/null +++ b/seam/resources/webhook.py @@ -0,0 +1,20 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class Webhook: + event_types: List[str] + secret: str + url: str + webhook_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return Webhook( + event_types=d.get("event_types", None), + secret=d.get("secret", None), + url=d.get("url", None), + webhook_id=d.get("webhook_id", None), + ) diff --git a/seam/resources/workspace.py b/seam/resources/workspace.py new file mode 100644 index 00000000..497e0956 --- /dev/null +++ b/seam/resources/workspace.py @@ -0,0 +1,36 @@ +from typing import Any, Dict, List, Optional, Union +from dataclasses import dataclass +from ..utils.deep_attr_dict import DeepAttrDict + + +@dataclass +class Workspace: + company_name: str + connect_partner_name: str + connect_webview_customization: Dict[str, Any] + is_publishable_key_auth_enabled: bool + is_sandbox: bool + is_suspended: bool + name: str + organization_id: str + publishable_key: str + workspace_id: str + + @staticmethod + def from_dict(d: Dict[str, Any]): + return Workspace( + company_name=d.get("company_name", None), + connect_partner_name=d.get("connect_partner_name", None), + connect_webview_customization=DeepAttrDict( + d.get("connect_webview_customization", None) + ), + is_publishable_key_auth_enabled=d.get( + "is_publishable_key_auth_enabled", None + ), + is_sandbox=d.get("is_sandbox", None), + is_suspended=d.get("is_suspended", None), + name=d.get("name", None), + organization_id=d.get("organization_id", None), + publishable_key=d.get("publishable_key", None), + workspace_id=d.get("workspace_id", None), + ) diff --git a/seam/routes/__init__.py b/seam/routes/__init__.py index 2c14d168..49e7deff 100644 --- a/seam/routes/__init__.py +++ b/seam/routes/__init__.py @@ -1,26 +1,51 @@ from typing import Any, Dict +import abc +from dataclasses import dataclass from ..client import SeamHttpClient -from .models import AbstractRoutes -from .access_codes import AccessCodes -from .access_grants import AccessGrants -from .access_methods import AccessMethods -from .acs import Acs -from .action_attempts import ActionAttempts -from .client_sessions import ClientSessions -from .connect_webviews import ConnectWebviews -from .connected_accounts import ConnectedAccounts -from .customers import Customers -from .devices import Devices -from .events import Events -from .instant_keys import InstantKeys -from .locks import Locks -from .noise_sensors import NoiseSensors -from .phones import Phones -from .spaces import Spaces -from .thermostats import Thermostats -from .user_identities import UserIdentities -from .webhooks import Webhooks -from .workspaces import Workspaces +from .access_codes import AbstractAccessCodes, AccessCodes +from .access_grants import AbstractAccessGrants, AccessGrants +from .access_methods import AbstractAccessMethods, AccessMethods +from .acs import AbstractAcs, Acs +from .action_attempts import AbstractActionAttempts, ActionAttempts +from .client_sessions import AbstractClientSessions, ClientSessions +from .connect_webviews import AbstractConnectWebviews, ConnectWebviews +from .connected_accounts import AbstractConnectedAccounts, ConnectedAccounts +from .customers import AbstractCustomers, Customers +from .devices import AbstractDevices, Devices +from .events import AbstractEvents, Events +from .instant_keys import AbstractInstantKeys, InstantKeys +from .locks import AbstractLocks, Locks +from .noise_sensors import AbstractNoiseSensors, NoiseSensors +from .phones import AbstractPhones, Phones +from .spaces import AbstractSpaces, Spaces +from .thermostats import AbstractThermostats, Thermostats +from .user_identities import AbstractUserIdentities, UserIdentities +from .webhooks import AbstractWebhooks, Webhooks +from .workspaces import AbstractWorkspaces, Workspaces + + +@dataclass +class AbstractRoutes(abc.ABC): + access_codes: AbstractAccessCodes + access_grants: AbstractAccessGrants + access_methods: AbstractAccessMethods + acs: AbstractAcs + action_attempts: AbstractActionAttempts + client_sessions: AbstractClientSessions + connect_webviews: AbstractConnectWebviews + connected_accounts: AbstractConnectedAccounts + customers: AbstractCustomers + devices: AbstractDevices + events: AbstractEvents + instant_keys: AbstractInstantKeys + locks: AbstractLocks + noise_sensors: AbstractNoiseSensors + phones: AbstractPhones + spaces: AbstractSpaces + thermostats: AbstractThermostats + user_identities: AbstractUserIdentities + webhooks: AbstractWebhooks + workspaces: AbstractWorkspaces class Routes(AbstractRoutes): diff --git a/seam/routes/access_codes.py b/seam/routes/access_codes.py index cd684b8f..cdfb8d17 100644 --- a/seam/routes/access_codes.py +++ b/seam/routes/access_codes.py @@ -1,8 +1,150 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractAccessCodes, AccessCode -from .access_codes_simulate import AccessCodesSimulate -from .access_codes_unmanaged import AccessCodesUnmanaged +from ..resources import AccessCode +from .access_codes_simulate import AbstractAccessCodesSimulate, AccessCodesSimulate +from .access_codes_unmanaged import AbstractAccessCodesUnmanaged, AccessCodesUnmanaged + + +class AbstractAccessCodes(abc.ABC): + + @property + @abc.abstractmethod + def simulate(self) -> AbstractAccessCodesSimulate: + raise NotImplementedError() + + @property + @abc.abstractmethod + def unmanaged(self) -> AbstractAccessCodesUnmanaged: + raise NotImplementedError() + + @abc.abstractmethod + def create( + self, + *, + device_id: str, + allow_external_modification: Optional[bool] = None, + attempt_for_offline_device: Optional[bool] = None, + code: Optional[str] = None, + common_code_key: Optional[str] = None, + ends_at: Optional[str] = None, + is_external_modification_allowed: Optional[bool] = None, + is_offline_access_code: Optional[bool] = None, + is_one_time_use: Optional[bool] = None, + max_time_rounding: Optional[str] = None, + name: Optional[str] = None, + prefer_native_scheduling: Optional[bool] = None, + preferred_code_length: Optional[float] = None, + starts_at: Optional[str] = None, + use_backup_access_code_pool: Optional[bool] = None, + use_offline_access_code: Optional[bool] = None + ) -> AccessCode: + raise NotImplementedError() + + @abc.abstractmethod + def create_multiple( + self, + *, + device_ids: List[str], + allow_external_modification: Optional[bool] = None, + attempt_for_offline_device: Optional[bool] = None, + behavior_when_code_cannot_be_shared: Optional[str] = None, + code: Optional[str] = None, + ends_at: Optional[str] = None, + is_external_modification_allowed: Optional[bool] = None, + name: Optional[str] = None, + prefer_native_scheduling: Optional[bool] = None, + preferred_code_length: Optional[float] = None, + starts_at: Optional[str] = None, + use_backup_access_code_pool: Optional[bool] = None + ) -> List[AccessCode]: + raise NotImplementedError() + + @abc.abstractmethod + def delete(self, *, access_code_id: str, device_id: Optional[str] = None) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def generate_code(self, *, device_id: str) -> AccessCode: + raise NotImplementedError() + + @abc.abstractmethod + def get( + self, + *, + access_code_id: Optional[str] = None, + code: Optional[str] = None, + device_id: Optional[str] = None + ) -> AccessCode: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + access_code_ids: Optional[List[str]] = None, + access_grant_id: Optional[str] = None, + access_grant_key: Optional[str] = None, + access_method_id: Optional[str] = None, + customer_key: Optional[str] = None, + device_id: Optional[str] = None, + limit: Optional[float] = None, + page_cursor: Optional[str] = None, + search: Optional[str] = None, + user_identifier_key: Optional[str] = None + ) -> List[AccessCode]: + raise NotImplementedError() + + @abc.abstractmethod + def pull_backup_access_code(self, *, access_code_id: str) -> AccessCode: + raise NotImplementedError() + + @abc.abstractmethod + def report_device_constraints( + self, + *, + device_id: str, + max_code_length: Optional[int] = None, + min_code_length: Optional[int] = None, + supported_code_lengths: Optional[List[float]] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + access_code_id: str, + allow_external_modification: Optional[bool] = None, + attempt_for_offline_device: Optional[bool] = None, + code: Optional[str] = None, + device_id: Optional[str] = None, + ends_at: Optional[str] = None, + is_external_modification_allowed: Optional[bool] = None, + is_managed: Optional[bool] = None, + is_offline_access_code: Optional[bool] = None, + is_one_time_use: Optional[bool] = None, + max_time_rounding: Optional[str] = None, + name: Optional[str] = None, + prefer_native_scheduling: Optional[bool] = None, + preferred_code_length: Optional[float] = None, + starts_at: Optional[str] = None, + type: Optional[str] = None, + use_backup_access_code_pool: Optional[bool] = None, + use_offline_access_code: Optional[bool] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def update_multiple( + self, + *, + common_code_key: str, + ends_at: Optional[str] = None, + name: Optional[str] = None, + starts_at: Optional[str] = None + ) -> None: + raise NotImplementedError() class AccessCodes(AbstractAccessCodes): diff --git a/seam/routes/access_codes_simulate.py b/seam/routes/access_codes_simulate.py index 16bd8b1f..303c347c 100644 --- a/seam/routes/access_codes_simulate.py +++ b/seam/routes/access_codes_simulate.py @@ -1,6 +1,16 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractAccessCodesSimulate, UnmanagedAccessCode +from ..resources import UnmanagedAccessCode + + +class AbstractAccessCodesSimulate(abc.ABC): + + @abc.abstractmethod + def create_unmanaged_access_code( + self, *, code: str, device_id: str, name: str + ) -> UnmanagedAccessCode: + raise NotImplementedError() class AccessCodesSimulate(AbstractAccessCodesSimulate): diff --git a/seam/routes/access_codes_unmanaged.py b/seam/routes/access_codes_unmanaged.py index 56b08b25..35286666 100644 --- a/seam/routes/access_codes_unmanaged.py +++ b/seam/routes/access_codes_unmanaged.py @@ -1,6 +1,59 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractAccessCodesUnmanaged, UnmanagedAccessCode +from ..resources import UnmanagedAccessCode + + +class AbstractAccessCodesUnmanaged(abc.ABC): + + @abc.abstractmethod + def convert_to_managed( + self, + *, + access_code_id: str, + allow_external_modification: Optional[bool] = None, + force: Optional[bool] = None, + is_external_modification_allowed: Optional[bool] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def delete(self, *, access_code_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def get( + self, + *, + access_code_id: Optional[str] = None, + code: Optional[str] = None, + device_id: Optional[str] = None + ) -> UnmanagedAccessCode: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + device_id: str, + limit: Optional[float] = None, + page_cursor: Optional[str] = None, + search: Optional[str] = None, + user_identifier_key: Optional[str] = None + ) -> List[UnmanagedAccessCode]: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + access_code_id: str, + is_managed: bool, + allow_external_modification: Optional[bool] = None, + force: Optional[bool] = None, + is_external_modification_allowed: Optional[bool] = None + ) -> None: + raise NotImplementedError() class AccessCodesUnmanaged(AbstractAccessCodesUnmanaged): diff --git a/seam/routes/access_grants.py b/seam/routes/access_grants.py index 76bd9684..722f733b 100644 --- a/seam/routes/access_grants.py +++ b/seam/routes/access_grants.py @@ -1,7 +1,103 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractAccessGrants, AccessGrant, Batch -from .access_grants_unmanaged import AccessGrantsUnmanaged +from ..resources import AccessGrant, Batch +from .access_grants_unmanaged import ( + AbstractAccessGrantsUnmanaged, + AccessGrantsUnmanaged, +) + + +class AbstractAccessGrants(abc.ABC): + + @property + @abc.abstractmethod + def unmanaged(self) -> AbstractAccessGrantsUnmanaged: + raise NotImplementedError() + + @abc.abstractmethod + def create( + self, + *, + requested_access_methods: List[Dict[str, Any]], + user_identity_id: Optional[str] = None, + user_identity: Optional[Dict[str, Any]] = None, + access_grant_key: Optional[str] = None, + acs_entrance_ids: Optional[List[str]] = None, + customization_profile_id: Optional[str] = None, + device_ids: Optional[List[str]] = None, + ends_at: Optional[str] = None, + location: Optional[Dict[str, Any]] = None, + location_ids: Optional[List[str]] = None, + name: Optional[str] = None, + reservation_key: Optional[str] = None, + space_ids: Optional[List[str]] = None, + space_keys: Optional[List[str]] = None, + starts_at: Optional[str] = None + ) -> AccessGrant: + raise NotImplementedError() + + @abc.abstractmethod + def delete(self, *, access_grant_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def get( + self, + *, + access_grant_id: Optional[str] = None, + access_grant_key: Optional[str] = None + ) -> AccessGrant: + raise NotImplementedError() + + @abc.abstractmethod + def get_related( + self, + *, + access_grant_ids: Optional[List[str]] = None, + access_grant_keys: Optional[List[str]] = None, + exclude: Optional[List[str]] = None, + include: Optional[List[str]] = None + ) -> Batch: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + access_code_id: Optional[str] = None, + access_grant_ids: Optional[List[str]] = None, + access_grant_key: Optional[str] = None, + acs_entrance_id: Optional[str] = None, + acs_system_id: Optional[str] = None, + customer_key: Optional[str] = None, + device_id: Optional[str] = None, + limit: Optional[float] = None, + location_id: Optional[str] = None, + page_cursor: Optional[str] = None, + reservation_key: Optional[str] = None, + space_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> List[AccessGrant]: + raise NotImplementedError() + + @abc.abstractmethod + def request_access_methods( + self, *, access_grant_id: str, requested_access_methods: List[Dict[str, Any]] + ) -> AccessGrant: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + access_grant_id: Optional[str] = None, + access_grant_key: Optional[str] = None, + ends_at: Optional[str] = None, + name: Optional[str] = None, + starts_at: Optional[str] = None + ) -> None: + raise NotImplementedError() class AccessGrants(AbstractAccessGrants): diff --git a/seam/routes/access_grants_unmanaged.py b/seam/routes/access_grants_unmanaged.py index 5601dfed..c80ca667 100644 --- a/seam/routes/access_grants_unmanaged.py +++ b/seam/routes/access_grants_unmanaged.py @@ -1,6 +1,36 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractAccessGrantsUnmanaged + + +class AbstractAccessGrantsUnmanaged(abc.ABC): + + @abc.abstractmethod + def get(self, *, access_grant_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + acs_entrance_id: Optional[str] = None, + acs_system_id: Optional[str] = None, + limit: Optional[float] = None, + page_cursor: Optional[str] = None, + reservation_key: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + access_grant_id: str, + is_managed: bool, + access_grant_key: Optional[str] = None + ) -> None: + raise NotImplementedError() class AccessGrantsUnmanaged(AbstractAccessGrantsUnmanaged): diff --git a/seam/routes/access_methods.py b/seam/routes/access_methods.py index f5172aea..83a03a72 100644 --- a/seam/routes/access_methods.py +++ b/seam/routes/access_methods.py @@ -1,10 +1,89 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractAccessMethods, ActionAttempt, AccessMethod, Batch -from .access_methods_unmanaged import AccessMethodsUnmanaged +from ..resources import ActionAttempt, AccessMethod, Batch +from .access_methods_unmanaged import ( + AbstractAccessMethodsUnmanaged, + AccessMethodsUnmanaged, +) from ..modules.action_attempts import resolve_action_attempt +class AbstractAccessMethods(abc.ABC): + + @property + @abc.abstractmethod + def unmanaged(self) -> AbstractAccessMethodsUnmanaged: + raise NotImplementedError() + + @abc.abstractmethod + def assign_card( + self, + *, + access_method_id: str, + card_number: str, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + @abc.abstractmethod + def delete( + self, + *, + access_method_id: Optional[str] = None, + access_grant_id: Optional[str] = None, + reservation_key: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def encode( + self, + *, + access_method_id: str, + acs_encoder_id: str, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + @abc.abstractmethod + def get(self, *, access_method_id: str) -> AccessMethod: + raise NotImplementedError() + + @abc.abstractmethod + def get_related( + self, + *, + access_method_ids: List[str], + exclude: Optional[List[str]] = None, + include: Optional[List[str]] = None + ) -> Batch: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + access_code_id: Optional[str] = None, + access_grant_id: Optional[str] = None, + access_grant_key: Optional[str] = None, + acs_entrance_id: Optional[str] = None, + device_id: Optional[str] = None, + space_id: Optional[str] = None + ) -> List[AccessMethod]: + raise NotImplementedError() + + @abc.abstractmethod + def unlock_door( + self, + *, + access_method_id: str, + acs_entrance_id: str, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + class AccessMethods(AbstractAccessMethods): def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): self.client = client diff --git a/seam/routes/access_methods_unmanaged.py b/seam/routes/access_methods_unmanaged.py index 36aaa6fc..60dbe0d3 100644 --- a/seam/routes/access_methods_unmanaged.py +++ b/seam/routes/access_methods_unmanaged.py @@ -1,6 +1,24 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractAccessMethodsUnmanaged + + +class AbstractAccessMethodsUnmanaged(abc.ABC): + + @abc.abstractmethod + def get(self, *, access_method_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + access_grant_id: str, + acs_entrance_id: Optional[str] = None, + device_id: Optional[str] = None, + space_id: Optional[str] = None + ) -> None: + raise NotImplementedError() class AccessMethodsUnmanaged(AbstractAccessMethodsUnmanaged): diff --git a/seam/routes/acs.py b/seam/routes/acs.py index 54343a14..8207cf12 100644 --- a/seam/routes/acs.py +++ b/seam/routes/acs.py @@ -1,12 +1,45 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractAcs -from .acs_access_groups import AcsAccessGroups -from .acs_credentials import AcsCredentials -from .acs_encoders import AcsEncoders -from .acs_entrances import AcsEntrances -from .acs_systems import AcsSystems -from .acs_users import AcsUsers +from .acs_access_groups import AbstractAcsAccessGroups, AcsAccessGroups +from .acs_credentials import AbstractAcsCredentials, AcsCredentials +from .acs_encoders import AbstractAcsEncoders, AcsEncoders +from .acs_entrances import AbstractAcsEntrances, AcsEntrances +from .acs_systems import AbstractAcsSystems, AcsSystems +from .acs_users import AbstractAcsUsers, AcsUsers + + +class AbstractAcs(abc.ABC): + + @property + @abc.abstractmethod + def access_groups(self) -> AbstractAcsAccessGroups: + raise NotImplementedError() + + @property + @abc.abstractmethod + def credentials(self) -> AbstractAcsCredentials: + raise NotImplementedError() + + @property + @abc.abstractmethod + def encoders(self) -> AbstractAcsEncoders: + raise NotImplementedError() + + @property + @abc.abstractmethod + def entrances(self) -> AbstractAcsEntrances: + raise NotImplementedError() + + @property + @abc.abstractmethod + def systems(self) -> AbstractAcsSystems: + raise NotImplementedError() + + @property + @abc.abstractmethod + def users(self) -> AbstractAcsUsers: + raise NotImplementedError() class Acs(AbstractAcs): diff --git a/seam/routes/acs_access_groups.py b/seam/routes/acs_access_groups.py index a5cd6b5a..35c0cbd5 100644 --- a/seam/routes/acs_access_groups.py +++ b/seam/routes/acs_access_groups.py @@ -1,6 +1,59 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractAcsAccessGroups, AcsAccessGroup, AcsEntrance, AcsUser +from ..resources import AcsAccessGroup, AcsEntrance, AcsUser + + +class AbstractAcsAccessGroups(abc.ABC): + + @abc.abstractmethod + def add_user( + self, + *, + acs_access_group_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def delete(self, *, acs_access_group_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def get(self, *, acs_access_group_id: str) -> AcsAccessGroup: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + search: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> List[AcsAccessGroup]: + raise NotImplementedError() + + @abc.abstractmethod + def list_accessible_entrances( + self, *, acs_access_group_id: str + ) -> List[AcsEntrance]: + raise NotImplementedError() + + @abc.abstractmethod + def list_users(self, *, acs_access_group_id: str) -> List[AcsUser]: + raise NotImplementedError() + + @abc.abstractmethod + def remove_user( + self, + *, + acs_access_group_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: + raise NotImplementedError() class AcsAccessGroups(AbstractAcsAccessGroups): diff --git a/seam/routes/acs_credentials.py b/seam/routes/acs_credentials.py index 9e037036..7946fed3 100644 --- a/seam/routes/acs_credentials.py +++ b/seam/routes/acs_credentials.py @@ -1,6 +1,87 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractAcsCredentials, AcsCredential, AcsEntrance +from ..resources import AcsCredential, AcsEntrance + + +class AbstractAcsCredentials(abc.ABC): + + @abc.abstractmethod + def assign( + self, + *, + acs_credential_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def create( + self, + *, + access_method: str, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + allowed_acs_entrance_ids: Optional[List[str]] = None, + assa_abloy_vostio_metadata: Optional[Dict[str, Any]] = None, + code: Optional[str] = None, + credential_manager_acs_system_id: Optional[str] = None, + ends_at: Optional[str] = None, + is_multi_phone_sync_credential: Optional[bool] = None, + salto_space_metadata: Optional[Dict[str, Any]] = None, + starts_at: Optional[str] = None, + user_identity_id: Optional[str] = None, + visionline_metadata: Optional[Dict[str, Any]] = None + ) -> AcsCredential: + raise NotImplementedError() + + @abc.abstractmethod + def delete(self, *, acs_credential_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def get(self, *, acs_credential_id: str) -> AcsCredential: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + acs_user_id: Optional[str] = None, + acs_system_id: Optional[str] = None, + user_identity_id: Optional[str] = None, + created_before: Optional[str] = None, + is_multi_phone_sync_credential: Optional[bool] = None, + limit: Optional[float] = None, + page_cursor: Optional[str] = None, + search: Optional[str] = None + ) -> List[AcsCredential]: + raise NotImplementedError() + + @abc.abstractmethod + def list_accessible_entrances(self, *, acs_credential_id: str) -> List[AcsEntrance]: + raise NotImplementedError() + + @abc.abstractmethod + def unassign( + self, + *, + acs_credential_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + acs_credential_id: str, + code: Optional[str] = None, + ends_at: Optional[str] = None + ) -> None: + raise NotImplementedError() class AcsCredentials(AbstractAcsCredentials): diff --git a/seam/routes/acs_encoders.py b/seam/routes/acs_encoders.py index f6892c18..f14315c3 100644 --- a/seam/routes/acs_encoders.py +++ b/seam/routes/acs_encoders.py @@ -1,10 +1,68 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractAcsEncoders, ActionAttempt, AcsEncoder -from .acs_encoders_simulate import AcsEncodersSimulate +from ..resources import ActionAttempt, AcsEncoder +from .acs_encoders_simulate import AbstractAcsEncodersSimulate, AcsEncodersSimulate from ..modules.action_attempts import resolve_action_attempt +class AbstractAcsEncoders(abc.ABC): + + @property + @abc.abstractmethod + def simulate(self) -> AbstractAcsEncodersSimulate: + raise NotImplementedError() + + @abc.abstractmethod + def encode_credential( + self, + *, + acs_encoder_id: str, + access_method_id: Optional[str] = None, + acs_credential_id: Optional[str] = None, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + @abc.abstractmethod + def get(self, *, acs_encoder_id: str) -> AcsEncoder: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + acs_system_id: Optional[str] = None, + acs_system_ids: Optional[List[str]] = None, + acs_encoder_ids: Optional[List[str]] = None, + limit: Optional[float] = None, + page_cursor: Optional[str] = None + ) -> List[AcsEncoder]: + raise NotImplementedError() + + @abc.abstractmethod + def scan_credential( + self, + *, + acs_encoder_id: str, + salto_ks_metadata: Optional[Dict[str, Any]] = None, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + @abc.abstractmethod + def scan_to_assign_credential( + self, + *, + acs_encoder_id: str, + acs_user_id: Optional[str] = None, + salto_ks_metadata: Optional[Dict[str, Any]] = None, + user_identity_id: Optional[str] = None, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + class AcsEncoders(AbstractAcsEncoders): def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): self.client = client diff --git a/seam/routes/acs_encoders_simulate.py b/seam/routes/acs_encoders_simulate.py index d63857c6..ea00fab5 100644 --- a/seam/routes/acs_encoders_simulate.py +++ b/seam/routes/acs_encoders_simulate.py @@ -1,6 +1,45 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractAcsEncodersSimulate + + +class AbstractAcsEncodersSimulate(abc.ABC): + + @abc.abstractmethod + def next_credential_encode_will_fail( + self, + *, + acs_encoder_id: str, + error_code: Optional[str] = None, + acs_credential_id: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def next_credential_encode_will_succeed( + self, *, acs_encoder_id: str, scenario: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def next_credential_scan_will_fail( + self, + *, + acs_encoder_id: str, + error_code: Optional[str] = None, + acs_credential_id_on_seam: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def next_credential_scan_will_succeed( + self, + *, + acs_encoder_id: str, + acs_credential_id_on_seam: Optional[str] = None, + scenario: Optional[str] = None + ) -> None: + raise NotImplementedError() class AcsEncodersSimulate(AbstractAcsEncodersSimulate): diff --git a/seam/routes/acs_entrances.py b/seam/routes/acs_entrances.py index 4e96150b..a2de3399 100644 --- a/seam/routes/acs_entrances.py +++ b/seam/routes/acs_entrances.py @@ -1,10 +1,60 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractAcsEntrances, AcsEntrance, AcsCredential, ActionAttempt - +from ..resources import AcsEntrance, AcsCredential, ActionAttempt from ..modules.action_attempts import resolve_action_attempt +class AbstractAcsEntrances(abc.ABC): + + @abc.abstractmethod + def get(self, *, acs_entrance_id: str) -> AcsEntrance: + raise NotImplementedError() + + @abc.abstractmethod + def grant_access( + self, + *, + acs_entrance_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + acs_credential_id: Optional[str] = None, + acs_entrance_ids: Optional[List[str]] = None, + acs_system_id: Optional[str] = None, + connected_account_id: Optional[str] = None, + customer_key: Optional[str] = None, + limit: Optional[int] = None, + location_id: Optional[str] = None, + page_cursor: Optional[str] = None, + search: Optional[str] = None, + space_id: Optional[str] = None + ) -> List[AcsEntrance]: + raise NotImplementedError() + + @abc.abstractmethod + def list_credentials_with_access( + self, *, acs_entrance_id: str, include_if: Optional[List[str]] = None + ) -> List[AcsCredential]: + raise NotImplementedError() + + @abc.abstractmethod + def unlock( + self, + *, + acs_credential_id: str, + acs_entrance_id: str, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + class AcsEntrances(AbstractAcsEntrances): def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): self.client = client diff --git a/seam/routes/acs_systems.py b/seam/routes/acs_systems.py index f5bf1b41..6e33bdd4 100644 --- a/seam/routes/acs_systems.py +++ b/seam/routes/acs_systems.py @@ -1,6 +1,40 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractAcsSystems, AcsSystem +from ..resources import AcsSystem + + +class AbstractAcsSystems(abc.ABC): + + @abc.abstractmethod + def get(self, *, acs_system_id: str) -> AcsSystem: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + connected_account_id: Optional[str] = None, + customer_key: Optional[str] = None, + search: Optional[str] = None + ) -> List[AcsSystem]: + raise NotImplementedError() + + @abc.abstractmethod + def list_compatible_credential_manager_acs_systems( + self, *, acs_system_id: str + ) -> List[AcsSystem]: + raise NotImplementedError() + + @abc.abstractmethod + def report_devices( + self, + *, + acs_system_id: str, + acs_encoders: Optional[List[Dict[str, Any]]] = None, + acs_entrances: Optional[List[Dict[str, Any]]] = None + ) -> None: + raise NotImplementedError() class AcsSystems(AbstractAcsSystems): diff --git a/seam/routes/acs_users.py b/seam/routes/acs_users.py index 5e13889e..082c08ef 100644 --- a/seam/routes/acs_users.py +++ b/seam/routes/acs_users.py @@ -1,6 +1,132 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractAcsUsers, AcsUser, AcsEntrance +from ..resources import AcsUser, AcsEntrance + + +class AbstractAcsUsers(abc.ABC): + + @abc.abstractmethod + def add_to_access_group( + self, *, acs_access_group_id: str, acs_user_id: str + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def create( + self, + *, + acs_system_id: str, + full_name: str, + access_schedule: Optional[Dict[str, Any]] = None, + acs_access_group_ids: Optional[List[str]] = None, + email: Optional[str] = None, + email_address: Optional[str] = None, + phone_number: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> AcsUser: + raise NotImplementedError() + + @abc.abstractmethod + def delete( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def get( + self, + *, + acs_user_id: Optional[str] = None, + acs_system_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> AcsUser: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + acs_system_id: Optional[str] = None, + created_before: Optional[str] = None, + limit: Optional[int] = None, + page_cursor: Optional[str] = None, + search: Optional[str] = None, + user_identity_email_address: Optional[str] = None, + user_identity_id: Optional[str] = None, + user_identity_phone_number: Optional[str] = None + ) -> List[AcsUser]: + raise NotImplementedError() + + @abc.abstractmethod + def list_accessible_entrances( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> List[AcsEntrance]: + raise NotImplementedError() + + @abc.abstractmethod + def remove_from_access_group( + self, + *, + acs_access_group_id: str, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def revoke_access_to_all_entrances( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def suspend( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def unsuspend( + self, + *, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + access_schedule: Optional[Dict[str, Any]] = None, + acs_system_id: Optional[str] = None, + acs_user_id: Optional[str] = None, + email: Optional[str] = None, + email_address: Optional[str] = None, + full_name: Optional[str] = None, + hid_acs_system_id: Optional[str] = None, + phone_number: Optional[str] = None, + user_identity_id: Optional[str] = None + ) -> None: + raise NotImplementedError() class AcsUsers(AbstractAcsUsers): diff --git a/seam/routes/action_attempts.py b/seam/routes/action_attempts.py index 9be0575a..4b09607b 100644 --- a/seam/routes/action_attempts.py +++ b/seam/routes/action_attempts.py @@ -1,10 +1,33 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractActionAttempts, ActionAttempt - +from ..resources import ActionAttempt from ..modules.action_attempts import resolve_action_attempt +class AbstractActionAttempts(abc.ABC): + + @abc.abstractmethod + def get( + self, + *, + action_attempt_id: str, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + action_attempt_ids: Optional[List[str]] = None, + device_id: Optional[str] = None, + limit: Optional[int] = None, + page_cursor: Optional[str] = None + ) -> List[ActionAttempt]: + raise NotImplementedError() + + class ActionAttempts(AbstractActionAttempts): def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): self.client = client diff --git a/seam/routes/client_sessions.py b/seam/routes/client_sessions.py index 72f7a464..d3ff2094 100644 --- a/seam/routes/client_sessions.py +++ b/seam/routes/client_sessions.py @@ -1,6 +1,80 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractClientSessions, ClientSession +from ..resources import ClientSession + + +class AbstractClientSessions(abc.ABC): + + @abc.abstractmethod + def create( + self, + *, + connect_webview_ids: Optional[List[str]] = None, + connected_account_ids: Optional[List[str]] = None, + customer_id: Optional[str] = None, + customer_key: Optional[str] = None, + expires_at: Optional[str] = None, + user_identifier_key: Optional[str] = None, + user_identity_id: Optional[str] = None, + user_identity_ids: Optional[List[str]] = None + ) -> ClientSession: + raise NotImplementedError() + + @abc.abstractmethod + def delete(self, *, client_session_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def get( + self, + *, + client_session_id: Optional[str] = None, + user_identifier_key: Optional[str] = None + ) -> ClientSession: + raise NotImplementedError() + + @abc.abstractmethod + def get_or_create( + self, + *, + connect_webview_ids: Optional[List[str]] = None, + connected_account_ids: Optional[List[str]] = None, + expires_at: Optional[str] = None, + user_identifier_key: Optional[str] = None, + user_identity_id: Optional[str] = None, + user_identity_ids: Optional[List[str]] = None + ) -> ClientSession: + raise NotImplementedError() + + @abc.abstractmethod + def grant_access( + self, + *, + client_session_id: Optional[str] = None, + connect_webview_ids: Optional[List[str]] = None, + connected_account_ids: Optional[List[str]] = None, + user_identifier_key: Optional[str] = None, + user_identity_id: Optional[str] = None, + user_identity_ids: Optional[List[str]] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + client_session_id: Optional[str] = None, + connect_webview_id: Optional[str] = None, + user_identifier_key: Optional[str] = None, + user_identity_id: Optional[str] = None, + without_user_identifier_key: Optional[bool] = None + ) -> List[ClientSession]: + raise NotImplementedError() + + @abc.abstractmethod + def revoke(self, *, client_session_id: str) -> None: + raise NotImplementedError() class ClientSessions(AbstractClientSessions): diff --git a/seam/routes/connect_webviews.py b/seam/routes/connect_webviews.py index 98bee1cc..ff0db128 100644 --- a/seam/routes/connect_webviews.py +++ b/seam/routes/connect_webviews.py @@ -1,6 +1,48 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractConnectWebviews, ConnectWebview +from ..resources import ConnectWebview + + +class AbstractConnectWebviews(abc.ABC): + + @abc.abstractmethod + def create( + self, + *, + accepted_capabilities: Optional[List[str]] = None, + accepted_providers: Optional[List[str]] = None, + automatically_manage_new_devices: Optional[bool] = None, + custom_metadata: Optional[Dict[str, Any]] = None, + custom_redirect_failure_url: Optional[str] = None, + custom_redirect_url: Optional[str] = None, + customer_key: Optional[str] = None, + excluded_providers: Optional[List[str]] = None, + provider_category: Optional[str] = None, + wait_for_device_creation: Optional[bool] = None + ) -> ConnectWebview: + raise NotImplementedError() + + @abc.abstractmethod + def delete(self, *, connect_webview_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def get(self, *, connect_webview_id: str) -> ConnectWebview: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_key: Optional[str] = None, + limit: Optional[float] = None, + page_cursor: Optional[str] = None, + search: Optional[str] = None, + user_identifier_key: Optional[str] = None + ) -> List[ConnectWebview]: + raise NotImplementedError() class ConnectWebviews(AbstractConnectWebviews): diff --git a/seam/routes/connected_accounts.py b/seam/routes/connected_accounts.py index 05a55b8f..902cdfb7 100644 --- a/seam/routes/connected_accounts.py +++ b/seam/routes/connected_accounts.py @@ -1,7 +1,60 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractConnectedAccounts, ConnectedAccount -from .connected_accounts_simulate import ConnectedAccountsSimulate +from ..resources import ConnectedAccount +from .connected_accounts_simulate import ( + AbstractConnectedAccountsSimulate, + ConnectedAccountsSimulate, +) + + +class AbstractConnectedAccounts(abc.ABC): + + @property + @abc.abstractmethod + def simulate(self) -> AbstractConnectedAccountsSimulate: + raise NotImplementedError() + + @abc.abstractmethod + def delete(self, *, connected_account_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def get( + self, *, connected_account_id: Optional[str] = None, email: Optional[str] = None + ) -> ConnectedAccount: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_key: Optional[str] = None, + limit: Optional[int] = None, + page_cursor: Optional[str] = None, + search: Optional[str] = None, + space_id: Optional[str] = None, + user_identifier_key: Optional[str] = None + ) -> List[ConnectedAccount]: + raise NotImplementedError() + + @abc.abstractmethod + def sync(self, *, connected_account_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + connected_account_id: str, + accepted_capabilities: Optional[List[str]] = None, + automatically_manage_new_devices: Optional[bool] = None, + custom_metadata: Optional[Dict[str, Any]] = None, + customer_key: Optional[str] = None, + display_name: Optional[str] = None + ) -> None: + raise NotImplementedError() class ConnectedAccounts(AbstractConnectedAccounts): diff --git a/seam/routes/connected_accounts_simulate.py b/seam/routes/connected_accounts_simulate.py index 4d7ace4b..9b797da8 100644 --- a/seam/routes/connected_accounts_simulate.py +++ b/seam/routes/connected_accounts_simulate.py @@ -1,6 +1,13 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractConnectedAccountsSimulate + + +class AbstractConnectedAccountsSimulate(abc.ABC): + + @abc.abstractmethod + def disconnect(self, *, connected_account_id: str) -> None: + raise NotImplementedError() class ConnectedAccountsSimulate(AbstractConnectedAccountsSimulate): diff --git a/seam/routes/customers.py b/seam/routes/customers.py index 5de89966..2b9d0c03 100644 --- a/seam/routes/customers.py +++ b/seam/routes/customers.py @@ -1,6 +1,81 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractCustomers, CustomerPortal +from ..resources import CustomerPortal + + +class AbstractCustomers(abc.ABC): + + @abc.abstractmethod + def create_portal( + self, + *, + customer_resources_filters: Optional[List[Dict[str, Any]]] = None, + customization_profile_id: Optional[str] = None, + deep_link: Optional[Dict[str, Any]] = None, + exclude_locale_picker: Optional[bool] = None, + features: Optional[Dict[str, Any]] = None, + is_embedded: Optional[bool] = None, + landing_page: Optional[Dict[str, Any]] = None, + locale: Optional[str] = None, + navigation_mode: Optional[str] = None, + read_only: Optional[bool] = None, + customer_data: Optional[Dict[str, Any]] = None + ) -> CustomerPortal: + raise NotImplementedError() + + @abc.abstractmethod + def delete_data( + self, + *, + access_grant_keys: Optional[List[str]] = None, + booking_keys: Optional[List[str]] = None, + building_keys: Optional[List[str]] = None, + common_area_keys: Optional[List[str]] = None, + customer_keys: Optional[List[str]] = None, + facility_keys: Optional[List[str]] = None, + guest_keys: Optional[List[str]] = None, + listing_keys: Optional[List[str]] = None, + property_keys: Optional[List[str]] = None, + property_listing_keys: Optional[List[str]] = None, + reservation_keys: Optional[List[str]] = None, + resident_keys: Optional[List[str]] = None, + room_keys: Optional[List[str]] = None, + space_keys: Optional[List[str]] = None, + staff_member_keys: Optional[List[str]] = None, + tenant_keys: Optional[List[str]] = None, + unit_keys: Optional[List[str]] = None, + user_identity_keys: Optional[List[str]] = None, + user_keys: Optional[List[str]] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def push_data( + self, + *, + customer_key: str, + access_grants: Optional[List[Dict[str, Any]]] = None, + bookings: Optional[List[Dict[str, Any]]] = None, + buildings: Optional[List[Dict[str, Any]]] = None, + common_areas: Optional[List[Dict[str, Any]]] = None, + facilities: Optional[List[Dict[str, Any]]] = None, + guests: Optional[List[Dict[str, Any]]] = None, + listings: Optional[List[Dict[str, Any]]] = None, + properties: Optional[List[Dict[str, Any]]] = None, + property_listings: Optional[List[Dict[str, Any]]] = None, + reservations: Optional[List[Dict[str, Any]]] = None, + residents: Optional[List[Dict[str, Any]]] = None, + rooms: Optional[List[Dict[str, Any]]] = None, + sites: Optional[List[Dict[str, Any]]] = None, + spaces: Optional[List[Dict[str, Any]]] = None, + staff_members: Optional[List[Dict[str, Any]]] = None, + tenants: Optional[List[Dict[str, Any]]] = None, + units: Optional[List[Dict[str, Any]]] = None, + user_identities: Optional[List[Dict[str, Any]]] = None, + users: Optional[List[Dict[str, Any]]] = None + ) -> None: + raise NotImplementedError() class Customers(AbstractCustomers): diff --git a/seam/routes/devices.py b/seam/routes/devices.py index 026d2549..4d93a114 100644 --- a/seam/routes/devices.py +++ b/seam/routes/devices.py @@ -1,8 +1,74 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractDevices, Device, DeviceProvider -from .devices_simulate import DevicesSimulate -from .devices_unmanaged import DevicesUnmanaged +from ..resources import Device, DeviceProvider +from .devices_simulate import AbstractDevicesSimulate, DevicesSimulate +from .devices_unmanaged import AbstractDevicesUnmanaged, DevicesUnmanaged + + +class AbstractDevices(abc.ABC): + + @property + @abc.abstractmethod + def simulate(self) -> AbstractDevicesSimulate: + raise NotImplementedError() + + @property + @abc.abstractmethod + def unmanaged(self) -> AbstractDevicesUnmanaged: + raise NotImplementedError() + + @abc.abstractmethod + def get( + self, *, device_id: Optional[str] = None, name: Optional[str] = None + ) -> Device: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + connect_webview_id: Optional[str] = None, + connected_account_id: Optional[str] = None, + connected_account_ids: Optional[List[str]] = None, + created_before: Optional[str] = None, + custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_key: Optional[str] = None, + device_ids: Optional[List[str]] = None, + device_type: Optional[str] = None, + device_types: Optional[List[str]] = None, + limit: Optional[float] = None, + manufacturer: Optional[str] = None, + page_cursor: Optional[str] = None, + search: Optional[str] = None, + space_id: Optional[str] = None, + unstable_location_id: Optional[str] = None, + user_identifier_key: Optional[str] = None + ) -> List[Device]: + raise NotImplementedError() + + @abc.abstractmethod + def list_device_providers( + self, *, provider_category: Optional[str] = None + ) -> List[DeviceProvider]: + raise NotImplementedError() + + @abc.abstractmethod + def report_provider_metadata(self, *, devices: List[Dict[str, Any]]) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + device_id: str, + backup_access_code_pool_enabled: Optional[bool] = None, + custom_metadata: Optional[Dict[str, Any]] = None, + is_managed: Optional[bool] = None, + name: Optional[str] = None, + properties: Optional[Dict[str, Any]] = None + ) -> None: + raise NotImplementedError() class Devices(AbstractDevices): diff --git a/seam/routes/devices_simulate.py b/seam/routes/devices_simulate.py index 746c1c65..ca959946 100644 --- a/seam/routes/devices_simulate.py +++ b/seam/routes/devices_simulate.py @@ -1,6 +1,33 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractDevicesSimulate + + +class AbstractDevicesSimulate(abc.ABC): + + @abc.abstractmethod + def connect(self, *, device_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def connect_to_hub(self, *, device_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def disconnect(self, *, device_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def disconnect_from_hub(self, *, device_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def paid_subscription(self, *, device_id: str, is_expired: bool) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def remove(self, *, device_id: str) -> None: + raise NotImplementedError() class DevicesSimulate(AbstractDevicesSimulate): diff --git a/seam/routes/devices_unmanaged.py b/seam/routes/devices_unmanaged.py index 34161e2d..efee5589 100644 --- a/seam/routes/devices_unmanaged.py +++ b/seam/routes/devices_unmanaged.py @@ -1,6 +1,49 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractDevicesUnmanaged, UnmanagedDevice +from ..resources import UnmanagedDevice + + +class AbstractDevicesUnmanaged(abc.ABC): + + @abc.abstractmethod + def get( + self, *, device_id: Optional[str] = None, name: Optional[str] = None + ) -> UnmanagedDevice: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + connect_webview_id: Optional[str] = None, + connected_account_id: Optional[str] = None, + connected_account_ids: Optional[List[str]] = None, + created_before: Optional[str] = None, + custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_key: Optional[str] = None, + device_ids: Optional[List[str]] = None, + device_type: Optional[str] = None, + device_types: Optional[List[str]] = None, + limit: Optional[float] = None, + manufacturer: Optional[str] = None, + page_cursor: Optional[str] = None, + search: Optional[str] = None, + space_id: Optional[str] = None, + unstable_location_id: Optional[str] = None, + user_identifier_key: Optional[str] = None + ) -> List[UnmanagedDevice]: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + device_id: str, + custom_metadata: Optional[Dict[str, Any]] = None, + is_managed: Optional[bool] = None + ) -> None: + raise NotImplementedError() class DevicesUnmanaged(AbstractDevicesUnmanaged): diff --git a/seam/routes/events.py b/seam/routes/events.py index b806dc59..cb352574 100644 --- a/seam/routes/events.py +++ b/seam/routes/events.py @@ -1,6 +1,55 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractEvents, SeamEvent +from ..resources import SeamEvent + + +class AbstractEvents(abc.ABC): + + @abc.abstractmethod + def get( + self, + *, + event_id: Optional[str] = None, + device_id: Optional[str] = None, + event_type: Optional[str] = None + ) -> SeamEvent: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + access_code_id: Optional[str] = None, + access_code_ids: Optional[List[str]] = None, + access_grant_id: Optional[str] = None, + access_grant_ids: Optional[List[str]] = None, + access_method_id: Optional[str] = None, + access_method_ids: Optional[List[str]] = None, + acs_access_group_id: Optional[str] = None, + acs_credential_id: Optional[str] = None, + acs_encoder_id: Optional[str] = None, + acs_entrance_id: Optional[str] = None, + acs_system_id: Optional[str] = None, + acs_system_ids: Optional[List[str]] = None, + acs_user_id: Optional[str] = None, + between: Optional[List[Dict[str, Any]]] = None, + connect_webview_id: Optional[str] = None, + connected_account_id: Optional[str] = None, + customer_key: Optional[str] = None, + device_id: Optional[str] = None, + device_ids: Optional[List[str]] = None, + event_ids: Optional[List[str]] = None, + event_type: Optional[str] = None, + event_types: Optional[List[str]] = None, + limit: Optional[float] = None, + since: Optional[str] = None, + space_id: Optional[str] = None, + space_ids: Optional[List[str]] = None, + unstable_offset: Optional[float] = None, + user_identity_id: Optional[str] = None + ) -> List[SeamEvent]: + raise NotImplementedError() class Events(AbstractEvents): diff --git a/seam/routes/instant_keys.py b/seam/routes/instant_keys.py index 79db12cf..e5ecaa88 100644 --- a/seam/routes/instant_keys.py +++ b/seam/routes/instant_keys.py @@ -1,6 +1,27 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractInstantKeys, InstantKey +from ..resources import InstantKey + + +class AbstractInstantKeys(abc.ABC): + + @abc.abstractmethod + def delete(self, *, instant_key_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def get( + self, + *, + instant_key_id: Optional[str] = None, + instant_key_url: Optional[str] = None + ) -> InstantKey: + raise NotImplementedError() + + @abc.abstractmethod + def list(self, *, user_identity_id: Optional[str] = None) -> List[InstantKey]: + raise NotImplementedError() class InstantKeys(AbstractInstantKeys): diff --git a/seam/routes/locks.py b/seam/routes/locks.py index d1d9d716..c8ba40c3 100644 --- a/seam/routes/locks.py +++ b/seam/routes/locks.py @@ -1,10 +1,77 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractLocks, ActionAttempt, Device -from .locks_simulate import LocksSimulate +from ..resources import ActionAttempt, Device +from .locks_simulate import AbstractLocksSimulate, LocksSimulate from ..modules.action_attempts import resolve_action_attempt +class AbstractLocks(abc.ABC): + + @property + @abc.abstractmethod + def simulate(self) -> AbstractLocksSimulate: + raise NotImplementedError() + + @abc.abstractmethod + def configure_auto_lock( + self, + *, + auto_lock_enabled: bool, + device_id: str, + auto_lock_delay_seconds: Optional[float] = None, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + @abc.abstractmethod + def get( + self, *, device_id: Optional[str] = None, name: Optional[str] = None + ) -> Device: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + connect_webview_id: Optional[str] = None, + connected_account_id: Optional[str] = None, + connected_account_ids: Optional[List[str]] = None, + created_before: Optional[str] = None, + custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_key: Optional[str] = None, + device_ids: Optional[List[str]] = None, + device_type: Optional[str] = None, + device_types: Optional[List[str]] = None, + limit: Optional[float] = None, + manufacturer: Optional[str] = None, + page_cursor: Optional[str] = None, + search: Optional[str] = None, + space_id: Optional[str] = None, + unstable_location_id: Optional[str] = None, + user_identifier_key: Optional[str] = None + ) -> List[Device]: + raise NotImplementedError() + + @abc.abstractmethod + def lock_door( + self, + *, + device_id: str, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + @abc.abstractmethod + def unlock_door( + self, + *, + device_id: str, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + class Locks(AbstractLocks): def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): self.client = client diff --git a/seam/routes/locks_simulate.py b/seam/routes/locks_simulate.py index 9e357ed5..6eeb24b6 100644 --- a/seam/routes/locks_simulate.py +++ b/seam/routes/locks_simulate.py @@ -1,10 +1,32 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractLocksSimulate, ActionAttempt - +from ..resources import ActionAttempt from ..modules.action_attempts import resolve_action_attempt +class AbstractLocksSimulate(abc.ABC): + + @abc.abstractmethod + def keypad_code_entry( + self, + *, + code: str, + device_id: str, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + @abc.abstractmethod + def manual_lock_via_keypad( + self, + *, + device_id: str, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + class LocksSimulate(AbstractLocksSimulate): def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): self.client = client diff --git a/seam/routes/models.py b/seam/routes/models.py deleted file mode 100644 index e2cb3383..00000000 --- a/seam/routes/models.py +++ /dev/null @@ -1,3640 +0,0 @@ -from typing import Any, Dict, List, Optional, Union -from typing_extensions import Self -import abc -from dataclasses import dataclass -from ..utils.deep_attr_dict import DeepAttrDict - - -@dataclass -class AccessCode: - access_code_id: str - code: str - common_code_key: str - created_at: str - device_id: str - dormakaba_oracode_metadata: Dict[str, Any] - ends_at: str - errors: List[Dict[str, Any]] - is_backup: bool - is_backup_access_code_available: bool - is_external_modification_allowed: bool - is_managed: bool - is_offline_access_code: bool - is_one_time_use: bool - is_scheduled_on_device: bool - is_waiting_for_code_assignment: bool - name: str - pending_mutations: List[Dict[str, Any]] - pulled_backup_access_code_id: str - starts_at: str - status: str - type: str - warnings: List[Dict[str, Any]] - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return AccessCode( - access_code_id=d.get("access_code_id", None), - code=d.get("code", None), - common_code_key=d.get("common_code_key", None), - created_at=d.get("created_at", None), - device_id=d.get("device_id", None), - dormakaba_oracode_metadata=DeepAttrDict( - d.get("dormakaba_oracode_metadata", None) - ), - ends_at=d.get("ends_at", None), - errors=d.get("errors", None), - is_backup=d.get("is_backup", None), - is_backup_access_code_available=d.get( - "is_backup_access_code_available", None - ), - is_external_modification_allowed=d.get( - "is_external_modification_allowed", None - ), - is_managed=d.get("is_managed", None), - is_offline_access_code=d.get("is_offline_access_code", None), - is_one_time_use=d.get("is_one_time_use", None), - is_scheduled_on_device=d.get("is_scheduled_on_device", None), - is_waiting_for_code_assignment=d.get( - "is_waiting_for_code_assignment", None - ), - name=d.get("name", None), - pending_mutations=d.get("pending_mutations", None), - pulled_backup_access_code_id=d.get("pulled_backup_access_code_id", None), - starts_at=d.get("starts_at", None), - status=d.get("status", None), - type=d.get("type", None), - warnings=d.get("warnings", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class AccessGrant: - access_grant_id: str - access_grant_key: str - access_method_ids: List[str] - client_session_token: str - created_at: str - customization_profile_id: str - display_name: str - ends_at: str - errors: List[Dict[str, Any]] - instant_key_url: str - location_ids: List[str] - name: str - pending_mutations: List[Dict[str, Any]] - requested_access_methods: List[Dict[str, Any]] - reservation_key: str - space_ids: List[str] - starts_at: str - user_identity_id: str - warnings: List[Dict[str, Any]] - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return AccessGrant( - access_grant_id=d.get("access_grant_id", None), - access_grant_key=d.get("access_grant_key", None), - access_method_ids=d.get("access_method_ids", None), - client_session_token=d.get("client_session_token", None), - created_at=d.get("created_at", None), - customization_profile_id=d.get("customization_profile_id", None), - display_name=d.get("display_name", None), - ends_at=d.get("ends_at", None), - errors=d.get("errors", None), - instant_key_url=d.get("instant_key_url", None), - location_ids=d.get("location_ids", None), - name=d.get("name", None), - pending_mutations=d.get("pending_mutations", None), - requested_access_methods=d.get("requested_access_methods", None), - reservation_key=d.get("reservation_key", None), - space_ids=d.get("space_ids", None), - starts_at=d.get("starts_at", None), - user_identity_id=d.get("user_identity_id", None), - warnings=d.get("warnings", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class AccessMethod: - access_method_id: str - client_session_token: str - code: str - created_at: str - customization_profile_id: str - display_name: str - errors: List[Dict[str, Any]] - instant_key_url: str - is_assignment_required: bool - is_encoding_required: bool - is_issued: bool - is_ready_for_assignment: bool - is_ready_for_encoding: bool - issued_at: str - mode: str - pending_mutations: List[Dict[str, Any]] - warnings: List[Dict[str, Any]] - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return AccessMethod( - access_method_id=d.get("access_method_id", None), - client_session_token=d.get("client_session_token", None), - code=d.get("code", None), - created_at=d.get("created_at", None), - customization_profile_id=d.get("customization_profile_id", None), - display_name=d.get("display_name", None), - errors=d.get("errors", None), - instant_key_url=d.get("instant_key_url", None), - is_assignment_required=d.get("is_assignment_required", None), - is_encoding_required=d.get("is_encoding_required", None), - is_issued=d.get("is_issued", None), - is_ready_for_assignment=d.get("is_ready_for_assignment", None), - is_ready_for_encoding=d.get("is_ready_for_encoding", None), - issued_at=d.get("issued_at", None), - mode=d.get("mode", None), - pending_mutations=d.get("pending_mutations", None), - warnings=d.get("warnings", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class AcsAccessGroup: - access_group_type: str - access_group_type_display_name: str - access_schedule: Dict[str, Any] - acs_access_group_id: str - acs_system_id: str - connected_account_id: str - created_at: str - display_name: str - errors: List[Dict[str, Any]] - external_type: str - external_type_display_name: str - is_managed: bool - name: str - pending_mutations: List[Dict[str, Any]] - warnings: List[Dict[str, Any]] - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return AcsAccessGroup( - access_group_type=d.get("access_group_type", None), - access_group_type_display_name=d.get( - "access_group_type_display_name", None - ), - access_schedule=DeepAttrDict(d.get("access_schedule", None)), - acs_access_group_id=d.get("acs_access_group_id", None), - acs_system_id=d.get("acs_system_id", None), - connected_account_id=d.get("connected_account_id", None), - created_at=d.get("created_at", None), - display_name=d.get("display_name", None), - errors=d.get("errors", None), - external_type=d.get("external_type", None), - external_type_display_name=d.get("external_type_display_name", None), - is_managed=d.get("is_managed", None), - name=d.get("name", None), - pending_mutations=d.get("pending_mutations", None), - warnings=d.get("warnings", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class AcsCredential: - access_method: str - acs_credential_id: str - acs_credential_pool_id: str - acs_system_id: str - acs_user_id: str - assa_abloy_vostio_metadata: Dict[str, Any] - card_number: str - code: str - connected_account_id: str - created_at: str - display_name: str - ends_at: str - errors: List[Dict[str, Any]] - external_type: str - external_type_display_name: str - is_issued: bool - is_latest_desired_state_synced_with_provider: bool - is_managed: bool - is_multi_phone_sync_credential: bool - is_one_time_use: bool - issued_at: str - latest_desired_state_synced_with_provider_at: str - parent_acs_credential_id: str - starts_at: str - user_identity_id: str - visionline_metadata: Dict[str, Any] - warnings: List[Dict[str, Any]] - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return AcsCredential( - access_method=d.get("access_method", None), - acs_credential_id=d.get("acs_credential_id", None), - acs_credential_pool_id=d.get("acs_credential_pool_id", None), - acs_system_id=d.get("acs_system_id", None), - acs_user_id=d.get("acs_user_id", None), - assa_abloy_vostio_metadata=DeepAttrDict( - d.get("assa_abloy_vostio_metadata", None) - ), - card_number=d.get("card_number", None), - code=d.get("code", None), - connected_account_id=d.get("connected_account_id", None), - created_at=d.get("created_at", None), - display_name=d.get("display_name", None), - ends_at=d.get("ends_at", None), - errors=d.get("errors", None), - external_type=d.get("external_type", None), - external_type_display_name=d.get("external_type_display_name", None), - is_issued=d.get("is_issued", None), - is_latest_desired_state_synced_with_provider=d.get( - "is_latest_desired_state_synced_with_provider", None - ), - is_managed=d.get("is_managed", None), - is_multi_phone_sync_credential=d.get( - "is_multi_phone_sync_credential", None - ), - is_one_time_use=d.get("is_one_time_use", None), - issued_at=d.get("issued_at", None), - latest_desired_state_synced_with_provider_at=d.get( - "latest_desired_state_synced_with_provider_at", None - ), - parent_acs_credential_id=d.get("parent_acs_credential_id", None), - starts_at=d.get("starts_at", None), - user_identity_id=d.get("user_identity_id", None), - visionline_metadata=DeepAttrDict(d.get("visionline_metadata", None)), - warnings=d.get("warnings", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class AcsEncoder: - acs_encoder_id: str - acs_system_id: str - connected_account_id: str - created_at: str - display_name: str - errors: List[Dict[str, Any]] - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return AcsEncoder( - acs_encoder_id=d.get("acs_encoder_id", None), - acs_system_id=d.get("acs_system_id", None), - connected_account_id=d.get("connected_account_id", None), - created_at=d.get("created_at", None), - display_name=d.get("display_name", None), - errors=d.get("errors", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class AcsEntrance: - acs_entrance_id: str - acs_system_id: str - akiles_metadata: Dict[str, Any] - assa_abloy_vostio_metadata: Dict[str, Any] - avigilon_alta_metadata: Dict[str, Any] - brivo_metadata: Dict[str, Any] - can_belong_to_reservation: bool - can_unlock_with_card: bool - can_unlock_with_cloud_key: bool - can_unlock_with_code: bool - can_unlock_with_mobile_key: bool - connected_account_id: str - created_at: str - display_name: str - dormakaba_ambiance_metadata: Dict[str, Any] - dormakaba_community_metadata: Dict[str, Any] - errors: List[Dict[str, Any]] - hotek_metadata: Dict[str, Any] - is_locked: bool - latch_metadata: Dict[str, Any] - salto_ks_metadata: Dict[str, Any] - salto_space_metadata: Dict[str, Any] - space_ids: List[str] - visionline_metadata: Dict[str, Any] - warnings: List[Dict[str, Any]] - - @staticmethod - def from_dict(d: Dict[str, Any]): - return AcsEntrance( - acs_entrance_id=d.get("acs_entrance_id", None), - acs_system_id=d.get("acs_system_id", None), - akiles_metadata=DeepAttrDict(d.get("akiles_metadata", None)), - assa_abloy_vostio_metadata=DeepAttrDict( - d.get("assa_abloy_vostio_metadata", None) - ), - avigilon_alta_metadata=DeepAttrDict(d.get("avigilon_alta_metadata", None)), - brivo_metadata=DeepAttrDict(d.get("brivo_metadata", None)), - can_belong_to_reservation=d.get("can_belong_to_reservation", None), - can_unlock_with_card=d.get("can_unlock_with_card", None), - can_unlock_with_cloud_key=d.get("can_unlock_with_cloud_key", None), - can_unlock_with_code=d.get("can_unlock_with_code", None), - can_unlock_with_mobile_key=d.get("can_unlock_with_mobile_key", None), - connected_account_id=d.get("connected_account_id", None), - created_at=d.get("created_at", None), - display_name=d.get("display_name", None), - dormakaba_ambiance_metadata=DeepAttrDict( - d.get("dormakaba_ambiance_metadata", None) - ), - dormakaba_community_metadata=DeepAttrDict( - d.get("dormakaba_community_metadata", None) - ), - errors=d.get("errors", None), - hotek_metadata=DeepAttrDict(d.get("hotek_metadata", None)), - is_locked=d.get("is_locked", None), - latch_metadata=DeepAttrDict(d.get("latch_metadata", None)), - salto_ks_metadata=DeepAttrDict(d.get("salto_ks_metadata", None)), - salto_space_metadata=DeepAttrDict(d.get("salto_space_metadata", None)), - space_ids=d.get("space_ids", None), - visionline_metadata=DeepAttrDict(d.get("visionline_metadata", None)), - warnings=d.get("warnings", None), - ) - - -@dataclass -class AcsSystem: - acs_access_group_count: float - acs_system_id: str - acs_user_count: float - connected_account_id: str - connected_account_ids: List[str] - created_at: str - default_credential_manager_acs_system_id: str - errors: List[Dict[str, Any]] - external_type: str - external_type_display_name: str - image_alt_text: str - image_url: str - is_credential_manager: bool - location: Dict[str, Any] - name: str - system_type: str - system_type_display_name: str - visionline_metadata: Dict[str, Any] - warnings: List[Dict[str, Any]] - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return AcsSystem( - acs_access_group_count=d.get("acs_access_group_count", None), - acs_system_id=d.get("acs_system_id", None), - acs_user_count=d.get("acs_user_count", None), - connected_account_id=d.get("connected_account_id", None), - connected_account_ids=d.get("connected_account_ids", None), - created_at=d.get("created_at", None), - default_credential_manager_acs_system_id=d.get( - "default_credential_manager_acs_system_id", None - ), - errors=d.get("errors", None), - external_type=d.get("external_type", None), - external_type_display_name=d.get("external_type_display_name", None), - image_alt_text=d.get("image_alt_text", None), - image_url=d.get("image_url", None), - is_credential_manager=d.get("is_credential_manager", None), - location=DeepAttrDict(d.get("location", None)), - name=d.get("name", None), - system_type=d.get("system_type", None), - system_type_display_name=d.get("system_type_display_name", None), - visionline_metadata=DeepAttrDict(d.get("visionline_metadata", None)), - warnings=d.get("warnings", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class AcsUser: - access_schedule: Dict[str, Any] - acs_system_id: str - acs_user_id: str - connected_account_id: str - created_at: str - display_name: str - email: str - email_address: str - errors: List[Dict[str, Any]] - external_type: str - external_type_display_name: str - full_name: str - hid_acs_system_id: str - is_managed: bool - is_suspended: bool - pending_mutations: List[Dict[str, Any]] - phone_number: str - salto_ks_metadata: Dict[str, Any] - salto_space_metadata: Dict[str, Any] - user_identity_email_address: str - user_identity_full_name: str - user_identity_id: str - user_identity_phone_number: str - warnings: List[Dict[str, Any]] - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return AcsUser( - access_schedule=DeepAttrDict(d.get("access_schedule", None)), - acs_system_id=d.get("acs_system_id", None), - acs_user_id=d.get("acs_user_id", None), - connected_account_id=d.get("connected_account_id", None), - created_at=d.get("created_at", None), - display_name=d.get("display_name", None), - email=d.get("email", None), - email_address=d.get("email_address", None), - errors=d.get("errors", None), - external_type=d.get("external_type", None), - external_type_display_name=d.get("external_type_display_name", None), - full_name=d.get("full_name", None), - hid_acs_system_id=d.get("hid_acs_system_id", None), - is_managed=d.get("is_managed", None), - is_suspended=d.get("is_suspended", None), - pending_mutations=d.get("pending_mutations", None), - phone_number=d.get("phone_number", None), - salto_ks_metadata=DeepAttrDict(d.get("salto_ks_metadata", None)), - salto_space_metadata=DeepAttrDict(d.get("salto_space_metadata", None)), - user_identity_email_address=d.get("user_identity_email_address", None), - user_identity_full_name=d.get("user_identity_full_name", None), - user_identity_id=d.get("user_identity_id", None), - user_identity_phone_number=d.get("user_identity_phone_number", None), - warnings=d.get("warnings", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class ActionAttempt: - action_attempt_id: str - action_type: str - error: Dict[str, Any] - result: Dict[str, Any] - status: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return ActionAttempt( - action_attempt_id=d.get("action_attempt_id", None), - action_type=d.get("action_type", None), - error=DeepAttrDict(d.get("error", None)), - result=DeepAttrDict(d.get("result", None)), - status=d.get("status", None), - ) - - -@dataclass -class Batch: - access_codes: List[Dict[str, Any]] - access_grants: List[Dict[str, Any]] - access_methods: List[Dict[str, Any]] - acs_access_groups: List[Dict[str, Any]] - acs_credentials: List[Dict[str, Any]] - acs_encoders: List[Dict[str, Any]] - acs_entrances: List[Dict[str, Any]] - acs_systems: List[Dict[str, Any]] - acs_users: List[Dict[str, Any]] - action_attempts: List[Dict[str, Any]] - client_sessions: List[Dict[str, Any]] - connect_webviews: List[Dict[str, Any]] - connected_accounts: List[Dict[str, Any]] - devices: List[Dict[str, Any]] - events: List[Dict[str, Any]] - instant_keys: List[Dict[str, Any]] - noise_thresholds: List[Dict[str, Any]] - spaces: List[Dict[str, Any]] - thermostat_daily_programs: List[Dict[str, Any]] - thermostat_schedules: List[Dict[str, Any]] - unmanaged_access_codes: List[Dict[str, Any]] - unmanaged_devices: List[Dict[str, Any]] - user_identities: List[Dict[str, Any]] - workspaces: List[Dict[str, Any]] - - @staticmethod - def from_dict(d: Dict[str, Any]): - return Batch( - access_codes=d.get("access_codes", None), - access_grants=d.get("access_grants", None), - access_methods=d.get("access_methods", None), - acs_access_groups=d.get("acs_access_groups", None), - acs_credentials=d.get("acs_credentials", None), - acs_encoders=d.get("acs_encoders", None), - acs_entrances=d.get("acs_entrances", None), - acs_systems=d.get("acs_systems", None), - acs_users=d.get("acs_users", None), - action_attempts=d.get("action_attempts", None), - client_sessions=d.get("client_sessions", None), - connect_webviews=d.get("connect_webviews", None), - connected_accounts=d.get("connected_accounts", None), - devices=d.get("devices", None), - events=d.get("events", None), - instant_keys=d.get("instant_keys", None), - noise_thresholds=d.get("noise_thresholds", None), - spaces=d.get("spaces", None), - thermostat_daily_programs=d.get("thermostat_daily_programs", None), - thermostat_schedules=d.get("thermostat_schedules", None), - unmanaged_access_codes=d.get("unmanaged_access_codes", None), - unmanaged_devices=d.get("unmanaged_devices", None), - user_identities=d.get("user_identities", None), - workspaces=d.get("workspaces", None), - ) - - -@dataclass -class ClientSession: - client_session_id: str - connect_webview_ids: List[str] - connected_account_ids: List[str] - created_at: str - customer_key: str - device_count: float - expires_at: str - token: str - user_identifier_key: str - user_identity_id: str - user_identity_ids: List[str] - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return ClientSession( - client_session_id=d.get("client_session_id", None), - connect_webview_ids=d.get("connect_webview_ids", None), - connected_account_ids=d.get("connected_account_ids", None), - created_at=d.get("created_at", None), - customer_key=d.get("customer_key", None), - device_count=d.get("device_count", None), - expires_at=d.get("expires_at", None), - token=d.get("token", None), - user_identifier_key=d.get("user_identifier_key", None), - user_identity_id=d.get("user_identity_id", None), - user_identity_ids=d.get("user_identity_ids", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class ConnectWebview: - accepted_capabilities: List[str] - accepted_providers: List[str] - any_provider_allowed: bool - authorized_at: str - automatically_manage_new_devices: bool - connect_webview_id: str - connected_account_id: str - created_at: str - custom_metadata: Dict[str, Any] - custom_redirect_failure_url: str - custom_redirect_url: str - customer_key: str - device_selection_mode: str - login_successful: bool - selected_provider: str - status: str - url: str - wait_for_device_creation: bool - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return ConnectWebview( - accepted_capabilities=d.get("accepted_capabilities", None), - accepted_providers=d.get("accepted_providers", None), - any_provider_allowed=d.get("any_provider_allowed", None), - authorized_at=d.get("authorized_at", None), - automatically_manage_new_devices=d.get( - "automatically_manage_new_devices", None - ), - connect_webview_id=d.get("connect_webview_id", None), - connected_account_id=d.get("connected_account_id", None), - created_at=d.get("created_at", None), - custom_metadata=DeepAttrDict(d.get("custom_metadata", None)), - custom_redirect_failure_url=d.get("custom_redirect_failure_url", None), - custom_redirect_url=d.get("custom_redirect_url", None), - customer_key=d.get("customer_key", None), - device_selection_mode=d.get("device_selection_mode", None), - login_successful=d.get("login_successful", None), - selected_provider=d.get("selected_provider", None), - status=d.get("status", None), - url=d.get("url", None), - wait_for_device_creation=d.get("wait_for_device_creation", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class ConnectedAccount: - accepted_capabilities: List[str] - account_type: str - account_type_display_name: str - automatically_manage_new_devices: bool - connected_account_id: str - created_at: str - custom_metadata: Dict[str, Any] - customer_key: str - default_checkin_time: str - default_checkout_time: str - display_name: str - errors: List[Dict[str, Any]] - ical_feed_origin: str - ical_url: str - image_url: str - time_zone: str - user_identifier: Dict[str, Any] - warnings: List[Dict[str, Any]] - - @staticmethod - def from_dict(d: Dict[str, Any]): - return ConnectedAccount( - accepted_capabilities=d.get("accepted_capabilities", None), - account_type=d.get("account_type", None), - account_type_display_name=d.get("account_type_display_name", None), - automatically_manage_new_devices=d.get( - "automatically_manage_new_devices", None - ), - connected_account_id=d.get("connected_account_id", None), - created_at=d.get("created_at", None), - custom_metadata=DeepAttrDict(d.get("custom_metadata", None)), - customer_key=d.get("customer_key", None), - default_checkin_time=d.get("default_checkin_time", None), - default_checkout_time=d.get("default_checkout_time", None), - display_name=d.get("display_name", None), - errors=d.get("errors", None), - ical_feed_origin=d.get("ical_feed_origin", None), - ical_url=d.get("ical_url", None), - image_url=d.get("image_url", None), - time_zone=d.get("time_zone", None), - user_identifier=DeepAttrDict(d.get("user_identifier", None)), - warnings=d.get("warnings", None), - ) - - -@dataclass -class CustomerPortal: - created_at: str - customer_key: str - expires_at: str - url: str - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return CustomerPortal( - created_at=d.get("created_at", None), - customer_key=d.get("customer_key", None), - expires_at=d.get("expires_at", None), - url=d.get("url", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class Device: - can_configure_auto_lock: bool - can_hvac_cool: bool - can_hvac_heat: bool - can_hvac_heat_cool: bool - can_program_offline_access_codes: bool - can_program_online_access_codes: bool - can_program_thermostat_programs_as_different_each_day: bool - can_program_thermostat_programs_as_same_each_day: bool - can_program_thermostat_programs_as_weekday_weekend: bool - can_remotely_lock: bool - can_remotely_unlock: bool - can_run_thermostat_programs: bool - can_simulate_connection: bool - can_simulate_disconnection: bool - can_simulate_hub_connection: bool - can_simulate_hub_disconnection: bool - can_simulate_paid_subscription: bool - can_simulate_removal: bool - can_turn_off_hvac: bool - can_unlock_with_code: bool - capabilities_supported: List[str] - connected_account_id: str - created_at: str - custom_metadata: Dict[str, Any] - device_id: str - device_manufacturer: Dict[str, Any] - device_provider: Dict[str, Any] - device_type: str - display_name: str - errors: List[Dict[str, Any]] - is_managed: bool - location: Dict[str, Any] - nickname: str - properties: Dict[str, Any] - space_ids: List[str] - warnings: List[Dict[str, Any]] - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return Device( - can_configure_auto_lock=d.get("can_configure_auto_lock", None), - can_hvac_cool=d.get("can_hvac_cool", None), - can_hvac_heat=d.get("can_hvac_heat", None), - can_hvac_heat_cool=d.get("can_hvac_heat_cool", None), - can_program_offline_access_codes=d.get( - "can_program_offline_access_codes", None - ), - can_program_online_access_codes=d.get( - "can_program_online_access_codes", None - ), - can_program_thermostat_programs_as_different_each_day=d.get( - "can_program_thermostat_programs_as_different_each_day", None - ), - can_program_thermostat_programs_as_same_each_day=d.get( - "can_program_thermostat_programs_as_same_each_day", None - ), - can_program_thermostat_programs_as_weekday_weekend=d.get( - "can_program_thermostat_programs_as_weekday_weekend", None - ), - can_remotely_lock=d.get("can_remotely_lock", None), - can_remotely_unlock=d.get("can_remotely_unlock", None), - can_run_thermostat_programs=d.get("can_run_thermostat_programs", None), - can_simulate_connection=d.get("can_simulate_connection", None), - can_simulate_disconnection=d.get("can_simulate_disconnection", None), - can_simulate_hub_connection=d.get("can_simulate_hub_connection", None), - can_simulate_hub_disconnection=d.get( - "can_simulate_hub_disconnection", None - ), - can_simulate_paid_subscription=d.get( - "can_simulate_paid_subscription", None - ), - can_simulate_removal=d.get("can_simulate_removal", None), - can_turn_off_hvac=d.get("can_turn_off_hvac", None), - can_unlock_with_code=d.get("can_unlock_with_code", None), - capabilities_supported=d.get("capabilities_supported", None), - connected_account_id=d.get("connected_account_id", None), - created_at=d.get("created_at", None), - custom_metadata=DeepAttrDict(d.get("custom_metadata", None)), - device_id=d.get("device_id", None), - device_manufacturer=DeepAttrDict(d.get("device_manufacturer", None)), - device_provider=DeepAttrDict(d.get("device_provider", None)), - device_type=d.get("device_type", None), - display_name=d.get("display_name", None), - errors=d.get("errors", None), - is_managed=d.get("is_managed", None), - location=DeepAttrDict(d.get("location", None)), - nickname=d.get("nickname", None), - properties=DeepAttrDict(d.get("properties", None)), - space_ids=d.get("space_ids", None), - warnings=d.get("warnings", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class DeviceProvider: - can_configure_auto_lock: bool - can_hvac_cool: bool - can_hvac_heat: bool - can_hvac_heat_cool: bool - can_program_offline_access_codes: bool - can_program_online_access_codes: bool - can_program_thermostat_programs_as_different_each_day: bool - can_program_thermostat_programs_as_same_each_day: bool - can_program_thermostat_programs_as_weekday_weekend: bool - can_remotely_lock: bool - can_remotely_unlock: bool - can_run_thermostat_programs: bool - can_simulate_connection: bool - can_simulate_disconnection: bool - can_simulate_hub_connection: bool - can_simulate_hub_disconnection: bool - can_simulate_paid_subscription: bool - can_simulate_removal: bool - can_turn_off_hvac: bool - can_unlock_with_code: bool - device_provider_name: str - display_name: str - image_url: str - provider_categories: List[str] - - @staticmethod - def from_dict(d: Dict[str, Any]): - return DeviceProvider( - can_configure_auto_lock=d.get("can_configure_auto_lock", None), - can_hvac_cool=d.get("can_hvac_cool", None), - can_hvac_heat=d.get("can_hvac_heat", None), - can_hvac_heat_cool=d.get("can_hvac_heat_cool", None), - can_program_offline_access_codes=d.get( - "can_program_offline_access_codes", None - ), - can_program_online_access_codes=d.get( - "can_program_online_access_codes", None - ), - can_program_thermostat_programs_as_different_each_day=d.get( - "can_program_thermostat_programs_as_different_each_day", None - ), - can_program_thermostat_programs_as_same_each_day=d.get( - "can_program_thermostat_programs_as_same_each_day", None - ), - can_program_thermostat_programs_as_weekday_weekend=d.get( - "can_program_thermostat_programs_as_weekday_weekend", None - ), - can_remotely_lock=d.get("can_remotely_lock", None), - can_remotely_unlock=d.get("can_remotely_unlock", None), - can_run_thermostat_programs=d.get("can_run_thermostat_programs", None), - can_simulate_connection=d.get("can_simulate_connection", None), - can_simulate_disconnection=d.get("can_simulate_disconnection", None), - can_simulate_hub_connection=d.get("can_simulate_hub_connection", None), - can_simulate_hub_disconnection=d.get( - "can_simulate_hub_disconnection", None - ), - can_simulate_paid_subscription=d.get( - "can_simulate_paid_subscription", None - ), - can_simulate_removal=d.get("can_simulate_removal", None), - can_turn_off_hvac=d.get("can_turn_off_hvac", None), - can_unlock_with_code=d.get("can_unlock_with_code", None), - device_provider_name=d.get("device_provider_name", None), - display_name=d.get("display_name", None), - image_url=d.get("image_url", None), - provider_categories=d.get("provider_categories", None), - ) - - -@dataclass -class SeamEvent: - access_code_id: str - connected_account_custom_metadata: Dict[str, Any] - connected_account_id: str - created_at: str - device_custom_metadata: Dict[str, Any] - device_id: str - event_description: str - event_id: str - event_type: str - occurred_at: str - workspace_id: str - change_reason: str - changed_properties: List[Dict[str, Any]] - description: str - from_: Dict[str, Any] - to: Dict[str, Any] - requested_mutations: List[Dict[str, Any]] - code: str - access_code_errors: List[Dict[str, Any]] - access_code_warnings: List[Dict[str, Any]] - connected_account_errors: List[Dict[str, Any]] - connected_account_warnings: List[Dict[str, Any]] - device_errors: List[Dict[str, Any]] - device_warnings: List[Dict[str, Any]] - backup_access_code_id: str - access_grant_id: str - acs_entrance_id: str - access_grant_key: str - ends_at: str - starts_at: str - error_message: str - missing_device_ids: List[str] - access_grant_ids: List[str] - access_grant_keys: List[str] - access_method_id: str - is_backup_code: bool - acs_system_id: str - acs_system_errors: List[Dict[str, Any]] - acs_system_warnings: List[Dict[str, Any]] - acs_credential_id: str - acs_user_id: str - acs_encoder_id: str - acs_access_group_id: str - client_session_id: str - connect_webview_id: str - customer_key: str - connected_account_type: str - action_attempt_id: str - action_type: str - status: str - error_code: str - battery_level: float - battery_status: str - device_name: str - minut_metadata: Dict[str, Any] - noise_level_decibels: float - noise_level_nrs: float - noise_threshold_id: str - noise_threshold_name: str - noiseaware_metadata: Dict[str, Any] - access_code_is_managed: bool - is_via_bluetooth: bool - is_via_nfc: bool - method: str - user_identity_id: str - reason: Dict[str, Any] - climate_preset_key: str - is_fallback_climate_preset: bool - thermostat_schedule_id: str - cooling_set_point_celsius: float - cooling_set_point_fahrenheit: float - fan_mode_setting: str - heating_set_point_celsius: float - heating_set_point_fahrenheit: float - hvac_mode_setting: str - lower_limit_celsius: float - lower_limit_fahrenheit: float - temperature_celsius: float - temperature_fahrenheit: float - upper_limit_celsius: float - upper_limit_fahrenheit: float - desired_temperature_celsius: float - desired_temperature_fahrenheit: float - activation_reason: str - image_url: str - motion_sub_type: str - video_url: str - acs_entrance_ids: List[str] - device_ids: List[str] - space_id: str - space_key: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return SeamEvent( - access_code_id=d.get("access_code_id", None), - connected_account_custom_metadata=DeepAttrDict( - d.get("connected_account_custom_metadata", None) - ), - connected_account_id=d.get("connected_account_id", None), - created_at=d.get("created_at", None), - device_custom_metadata=DeepAttrDict(d.get("device_custom_metadata", None)), - device_id=d.get("device_id", None), - event_description=d.get("event_description", None), - event_id=d.get("event_id", None), - event_type=d.get("event_type", None), - occurred_at=d.get("occurred_at", None), - workspace_id=d.get("workspace_id", None), - change_reason=d.get("change_reason", None), - changed_properties=d.get("changed_properties", None), - description=d.get("description", None), - from_=DeepAttrDict(d.get("from", None)), - to=DeepAttrDict(d.get("to", None)), - requested_mutations=d.get("requested_mutations", None), - code=d.get("code", None), - access_code_errors=d.get("access_code_errors", None), - access_code_warnings=d.get("access_code_warnings", None), - connected_account_errors=d.get("connected_account_errors", None), - connected_account_warnings=d.get("connected_account_warnings", None), - device_errors=d.get("device_errors", None), - device_warnings=d.get("device_warnings", None), - backup_access_code_id=d.get("backup_access_code_id", None), - access_grant_id=d.get("access_grant_id", None), - acs_entrance_id=d.get("acs_entrance_id", None), - access_grant_key=d.get("access_grant_key", None), - ends_at=d.get("ends_at", None), - starts_at=d.get("starts_at", None), - error_message=d.get("error_message", None), - missing_device_ids=d.get("missing_device_ids", None), - access_grant_ids=d.get("access_grant_ids", None), - access_grant_keys=d.get("access_grant_keys", None), - access_method_id=d.get("access_method_id", None), - is_backup_code=d.get("is_backup_code", None), - acs_system_id=d.get("acs_system_id", None), - acs_system_errors=d.get("acs_system_errors", None), - acs_system_warnings=d.get("acs_system_warnings", None), - acs_credential_id=d.get("acs_credential_id", None), - acs_user_id=d.get("acs_user_id", None), - acs_encoder_id=d.get("acs_encoder_id", None), - acs_access_group_id=d.get("acs_access_group_id", None), - client_session_id=d.get("client_session_id", None), - connect_webview_id=d.get("connect_webview_id", None), - customer_key=d.get("customer_key", None), - connected_account_type=d.get("connected_account_type", None), - action_attempt_id=d.get("action_attempt_id", None), - action_type=d.get("action_type", None), - status=d.get("status", None), - error_code=d.get("error_code", None), - battery_level=d.get("battery_level", None), - battery_status=d.get("battery_status", None), - device_name=d.get("device_name", None), - minut_metadata=DeepAttrDict(d.get("minut_metadata", None)), - noise_level_decibels=d.get("noise_level_decibels", None), - noise_level_nrs=d.get("noise_level_nrs", None), - noise_threshold_id=d.get("noise_threshold_id", None), - noise_threshold_name=d.get("noise_threshold_name", None), - noiseaware_metadata=DeepAttrDict(d.get("noiseaware_metadata", None)), - access_code_is_managed=d.get("access_code_is_managed", None), - is_via_bluetooth=d.get("is_via_bluetooth", None), - is_via_nfc=d.get("is_via_nfc", None), - method=d.get("method", None), - user_identity_id=d.get("user_identity_id", None), - reason=DeepAttrDict(d.get("reason", None)), - climate_preset_key=d.get("climate_preset_key", None), - is_fallback_climate_preset=d.get("is_fallback_climate_preset", None), - thermostat_schedule_id=d.get("thermostat_schedule_id", None), - cooling_set_point_celsius=d.get("cooling_set_point_celsius", None), - cooling_set_point_fahrenheit=d.get("cooling_set_point_fahrenheit", None), - fan_mode_setting=d.get("fan_mode_setting", None), - heating_set_point_celsius=d.get("heating_set_point_celsius", None), - heating_set_point_fahrenheit=d.get("heating_set_point_fahrenheit", None), - hvac_mode_setting=d.get("hvac_mode_setting", None), - lower_limit_celsius=d.get("lower_limit_celsius", None), - lower_limit_fahrenheit=d.get("lower_limit_fahrenheit", None), - temperature_celsius=d.get("temperature_celsius", None), - temperature_fahrenheit=d.get("temperature_fahrenheit", None), - upper_limit_celsius=d.get("upper_limit_celsius", None), - upper_limit_fahrenheit=d.get("upper_limit_fahrenheit", None), - desired_temperature_celsius=d.get("desired_temperature_celsius", None), - desired_temperature_fahrenheit=d.get( - "desired_temperature_fahrenheit", None - ), - activation_reason=d.get("activation_reason", None), - image_url=d.get("image_url", None), - motion_sub_type=d.get("motion_sub_type", None), - video_url=d.get("video_url", None), - acs_entrance_ids=d.get("acs_entrance_ids", None), - device_ids=d.get("device_ids", None), - space_id=d.get("space_id", None), - space_key=d.get("space_key", None), - ) - - -@dataclass -class InstantKey: - client_session_id: str - created_at: str - customization: Dict[str, Any] - customization_profile_id: str - expires_at: str - instant_key_id: str - instant_key_url: str - user_identity_id: str - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return InstantKey( - client_session_id=d.get("client_session_id", None), - created_at=d.get("created_at", None), - customization=DeepAttrDict(d.get("customization", None)), - customization_profile_id=d.get("customization_profile_id", None), - expires_at=d.get("expires_at", None), - instant_key_id=d.get("instant_key_id", None), - instant_key_url=d.get("instant_key_url", None), - user_identity_id=d.get("user_identity_id", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class NoiseThreshold: - device_id: str - ends_daily_at: str - name: str - noise_threshold_decibels: float - noise_threshold_id: str - noise_threshold_nrs: float - starts_daily_at: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return NoiseThreshold( - device_id=d.get("device_id", None), - ends_daily_at=d.get("ends_daily_at", None), - name=d.get("name", None), - noise_threshold_decibels=d.get("noise_threshold_decibels", None), - noise_threshold_id=d.get("noise_threshold_id", None), - noise_threshold_nrs=d.get("noise_threshold_nrs", None), - starts_daily_at=d.get("starts_daily_at", None), - ) - - -@dataclass -class Pagination: - has_next_page: bool - next_page_cursor: str - next_page_url: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return Pagination( - has_next_page=d.get("has_next_page", None), - next_page_cursor=d.get("next_page_cursor", None), - next_page_url=d.get("next_page_url", None), - ) - - -@dataclass -class Phone: - created_at: str - custom_metadata: Dict[str, Any] - device_id: str - device_type: str - display_name: str - errors: List[Dict[str, Any]] - nickname: str - properties: Dict[str, Any] - warnings: List[Dict[str, Any]] - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return Phone( - created_at=d.get("created_at", None), - custom_metadata=DeepAttrDict(d.get("custom_metadata", None)), - device_id=d.get("device_id", None), - device_type=d.get("device_type", None), - display_name=d.get("display_name", None), - errors=d.get("errors", None), - nickname=d.get("nickname", None), - properties=DeepAttrDict(d.get("properties", None)), - warnings=d.get("warnings", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class Space: - acs_entrance_count: float - created_at: str - customer_data: Dict[str, Any] - customer_key: str - device_count: float - display_name: str - geolocation: Dict[str, Any] - name: str - space_id: str - space_key: str - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return Space( - acs_entrance_count=d.get("acs_entrance_count", None), - created_at=d.get("created_at", None), - customer_data=DeepAttrDict(d.get("customer_data", None)), - customer_key=d.get("customer_key", None), - device_count=d.get("device_count", None), - display_name=d.get("display_name", None), - geolocation=DeepAttrDict(d.get("geolocation", None)), - name=d.get("name", None), - space_id=d.get("space_id", None), - space_key=d.get("space_key", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class ThermostatDailyProgram: - created_at: str - device_id: str - name: str - periods: List[Dict[str, Any]] - thermostat_daily_program_id: str - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return ThermostatDailyProgram( - created_at=d.get("created_at", None), - device_id=d.get("device_id", None), - name=d.get("name", None), - periods=d.get("periods", None), - thermostat_daily_program_id=d.get("thermostat_daily_program_id", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class ThermostatSchedule: - climate_preset_key: str - created_at: str - device_id: str - ends_at: str - errors: List[Dict[str, Any]] - is_override_allowed: bool - max_override_period_minutes: int - name: str - starts_at: str - thermostat_schedule_id: str - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return ThermostatSchedule( - climate_preset_key=d.get("climate_preset_key", None), - created_at=d.get("created_at", None), - device_id=d.get("device_id", None), - ends_at=d.get("ends_at", None), - errors=d.get("errors", None), - is_override_allowed=d.get("is_override_allowed", None), - max_override_period_minutes=d.get("max_override_period_minutes", None), - name=d.get("name", None), - starts_at=d.get("starts_at", None), - thermostat_schedule_id=d.get("thermostat_schedule_id", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class UnmanagedAccessCode: - access_code_id: str - cannot_be_managed: bool - cannot_delete_unmanaged_access_code: bool - code: str - created_at: str - device_id: str - dormakaba_oracode_metadata: Dict[str, Any] - ends_at: str - errors: List[Dict[str, Any]] - is_managed: bool - name: str - starts_at: str - status: str - type: str - warnings: List[Dict[str, Any]] - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return UnmanagedAccessCode( - access_code_id=d.get("access_code_id", None), - cannot_be_managed=d.get("cannot_be_managed", None), - cannot_delete_unmanaged_access_code=d.get( - "cannot_delete_unmanaged_access_code", None - ), - code=d.get("code", None), - created_at=d.get("created_at", None), - device_id=d.get("device_id", None), - dormakaba_oracode_metadata=DeepAttrDict( - d.get("dormakaba_oracode_metadata", None) - ), - ends_at=d.get("ends_at", None), - errors=d.get("errors", None), - is_managed=d.get("is_managed", None), - name=d.get("name", None), - starts_at=d.get("starts_at", None), - status=d.get("status", None), - type=d.get("type", None), - warnings=d.get("warnings", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class UnmanagedDevice: - can_configure_auto_lock: bool - can_hvac_cool: bool - can_hvac_heat: bool - can_hvac_heat_cool: bool - can_program_offline_access_codes: bool - can_program_online_access_codes: bool - can_program_thermostat_programs_as_different_each_day: bool - can_program_thermostat_programs_as_same_each_day: bool - can_program_thermostat_programs_as_weekday_weekend: bool - can_remotely_lock: bool - can_remotely_unlock: bool - can_run_thermostat_programs: bool - can_simulate_connection: bool - can_simulate_disconnection: bool - can_simulate_hub_connection: bool - can_simulate_hub_disconnection: bool - can_simulate_paid_subscription: bool - can_simulate_removal: bool - can_turn_off_hvac: bool - can_unlock_with_code: bool - capabilities_supported: List[str] - connected_account_id: str - created_at: str - custom_metadata: Dict[str, Any] - device_id: str - device_type: str - errors: List[Dict[str, Any]] - is_managed: bool - location: Dict[str, Any] - properties: Dict[str, Any] - warnings: List[Dict[str, Any]] - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return UnmanagedDevice( - can_configure_auto_lock=d.get("can_configure_auto_lock", None), - can_hvac_cool=d.get("can_hvac_cool", None), - can_hvac_heat=d.get("can_hvac_heat", None), - can_hvac_heat_cool=d.get("can_hvac_heat_cool", None), - can_program_offline_access_codes=d.get( - "can_program_offline_access_codes", None - ), - can_program_online_access_codes=d.get( - "can_program_online_access_codes", None - ), - can_program_thermostat_programs_as_different_each_day=d.get( - "can_program_thermostat_programs_as_different_each_day", None - ), - can_program_thermostat_programs_as_same_each_day=d.get( - "can_program_thermostat_programs_as_same_each_day", None - ), - can_program_thermostat_programs_as_weekday_weekend=d.get( - "can_program_thermostat_programs_as_weekday_weekend", None - ), - can_remotely_lock=d.get("can_remotely_lock", None), - can_remotely_unlock=d.get("can_remotely_unlock", None), - can_run_thermostat_programs=d.get("can_run_thermostat_programs", None), - can_simulate_connection=d.get("can_simulate_connection", None), - can_simulate_disconnection=d.get("can_simulate_disconnection", None), - can_simulate_hub_connection=d.get("can_simulate_hub_connection", None), - can_simulate_hub_disconnection=d.get( - "can_simulate_hub_disconnection", None - ), - can_simulate_paid_subscription=d.get( - "can_simulate_paid_subscription", None - ), - can_simulate_removal=d.get("can_simulate_removal", None), - can_turn_off_hvac=d.get("can_turn_off_hvac", None), - can_unlock_with_code=d.get("can_unlock_with_code", None), - capabilities_supported=d.get("capabilities_supported", None), - connected_account_id=d.get("connected_account_id", None), - created_at=d.get("created_at", None), - custom_metadata=DeepAttrDict(d.get("custom_metadata", None)), - device_id=d.get("device_id", None), - device_type=d.get("device_type", None), - errors=d.get("errors", None), - is_managed=d.get("is_managed", None), - location=DeepAttrDict(d.get("location", None)), - properties=DeepAttrDict(d.get("properties", None)), - warnings=d.get("warnings", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class UserIdentity: - acs_user_ids: List[str] - created_at: str - display_name: str - email_address: str - errors: List[Dict[str, Any]] - full_name: str - phone_number: str - user_identity_id: str - user_identity_key: str - warnings: List[Dict[str, Any]] - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return UserIdentity( - acs_user_ids=d.get("acs_user_ids", None), - created_at=d.get("created_at", None), - display_name=d.get("display_name", None), - email_address=d.get("email_address", None), - errors=d.get("errors", None), - full_name=d.get("full_name", None), - phone_number=d.get("phone_number", None), - user_identity_id=d.get("user_identity_id", None), - user_identity_key=d.get("user_identity_key", None), - warnings=d.get("warnings", None), - workspace_id=d.get("workspace_id", None), - ) - - -@dataclass -class Webhook: - event_types: List[str] - secret: str - url: str - webhook_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return Webhook( - event_types=d.get("event_types", None), - secret=d.get("secret", None), - url=d.get("url", None), - webhook_id=d.get("webhook_id", None), - ) - - -@dataclass -class Workspace: - company_name: str - connect_partner_name: str - connect_webview_customization: Dict[str, Any] - is_publishable_key_auth_enabled: bool - is_sandbox: bool - is_suspended: bool - name: str - organization_id: str - publishable_key: str - workspace_id: str - - @staticmethod - def from_dict(d: Dict[str, Any]): - return Workspace( - company_name=d.get("company_name", None), - connect_partner_name=d.get("connect_partner_name", None), - connect_webview_customization=DeepAttrDict( - d.get("connect_webview_customization", None) - ), - is_publishable_key_auth_enabled=d.get( - "is_publishable_key_auth_enabled", None - ), - is_sandbox=d.get("is_sandbox", None), - is_suspended=d.get("is_suspended", None), - name=d.get("name", None), - organization_id=d.get("organization_id", None), - publishable_key=d.get("publishable_key", None), - workspace_id=d.get("workspace_id", None), - ) - - -class AbstractAccessCodesSimulate(abc.ABC): - - @abc.abstractmethod - def create_unmanaged_access_code( - self, *, code: str, device_id: str, name: str - ) -> UnmanagedAccessCode: - raise NotImplementedError() - - -class AbstractAccessCodesUnmanaged(abc.ABC): - - @abc.abstractmethod - def convert_to_managed( - self, - *, - access_code_id: str, - allow_external_modification: Optional[bool] = None, - force: Optional[bool] = None, - is_external_modification_allowed: Optional[bool] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def delete(self, *, access_code_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def get( - self, - *, - access_code_id: Optional[str] = None, - code: Optional[str] = None, - device_id: Optional[str] = None - ) -> UnmanagedAccessCode: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - device_id: str, - limit: Optional[float] = None, - page_cursor: Optional[str] = None, - search: Optional[str] = None, - user_identifier_key: Optional[str] = None - ) -> List[UnmanagedAccessCode]: - raise NotImplementedError() - - @abc.abstractmethod - def update( - self, - *, - access_code_id: str, - is_managed: bool, - allow_external_modification: Optional[bool] = None, - force: Optional[bool] = None, - is_external_modification_allowed: Optional[bool] = None - ) -> None: - raise NotImplementedError() - - -class AbstractAccessGrantsUnmanaged(abc.ABC): - - @abc.abstractmethod - def get(self, *, access_grant_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - acs_entrance_id: Optional[str] = None, - acs_system_id: Optional[str] = None, - limit: Optional[float] = None, - page_cursor: Optional[str] = None, - reservation_key: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def update( - self, - *, - access_grant_id: str, - is_managed: bool, - access_grant_key: Optional[str] = None - ) -> None: - raise NotImplementedError() - - -class AbstractAccessMethodsUnmanaged(abc.ABC): - - @abc.abstractmethod - def get(self, *, access_method_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - access_grant_id: str, - acs_entrance_id: Optional[str] = None, - device_id: Optional[str] = None, - space_id: Optional[str] = None - ) -> None: - raise NotImplementedError() - - -class AbstractAcsAccessGroups(abc.ABC): - - @abc.abstractmethod - def add_user( - self, - *, - acs_access_group_id: str, - acs_user_id: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def delete(self, *, acs_access_group_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def get(self, *, acs_access_group_id: str) -> AcsAccessGroup: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - acs_system_id: Optional[str] = None, - acs_user_id: Optional[str] = None, - search: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> List[AcsAccessGroup]: - raise NotImplementedError() - - @abc.abstractmethod - def list_accessible_entrances( - self, *, acs_access_group_id: str - ) -> List[AcsEntrance]: - raise NotImplementedError() - - @abc.abstractmethod - def list_users(self, *, acs_access_group_id: str) -> List[AcsUser]: - raise NotImplementedError() - - @abc.abstractmethod - def remove_user( - self, - *, - acs_access_group_id: str, - acs_user_id: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> None: - raise NotImplementedError() - - -class AbstractAcsCredentials(abc.ABC): - - @abc.abstractmethod - def assign( - self, - *, - acs_credential_id: str, - acs_user_id: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def create( - self, - *, - access_method: str, - acs_system_id: Optional[str] = None, - acs_user_id: Optional[str] = None, - allowed_acs_entrance_ids: Optional[List[str]] = None, - assa_abloy_vostio_metadata: Optional[Dict[str, Any]] = None, - code: Optional[str] = None, - credential_manager_acs_system_id: Optional[str] = None, - ends_at: Optional[str] = None, - is_multi_phone_sync_credential: Optional[bool] = None, - salto_space_metadata: Optional[Dict[str, Any]] = None, - starts_at: Optional[str] = None, - user_identity_id: Optional[str] = None, - visionline_metadata: Optional[Dict[str, Any]] = None - ) -> AcsCredential: - raise NotImplementedError() - - @abc.abstractmethod - def delete(self, *, acs_credential_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def get(self, *, acs_credential_id: str) -> AcsCredential: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - acs_user_id: Optional[str] = None, - acs_system_id: Optional[str] = None, - user_identity_id: Optional[str] = None, - created_before: Optional[str] = None, - is_multi_phone_sync_credential: Optional[bool] = None, - limit: Optional[float] = None, - page_cursor: Optional[str] = None, - search: Optional[str] = None - ) -> List[AcsCredential]: - raise NotImplementedError() - - @abc.abstractmethod - def list_accessible_entrances(self, *, acs_credential_id: str) -> List[AcsEntrance]: - raise NotImplementedError() - - @abc.abstractmethod - def unassign( - self, - *, - acs_credential_id: str, - acs_user_id: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def update( - self, - *, - acs_credential_id: str, - code: Optional[str] = None, - ends_at: Optional[str] = None - ) -> None: - raise NotImplementedError() - - -class AbstractAcsEncodersSimulate(abc.ABC): - - @abc.abstractmethod - def next_credential_encode_will_fail( - self, - *, - acs_encoder_id: str, - error_code: Optional[str] = None, - acs_credential_id: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def next_credential_encode_will_succeed( - self, *, acs_encoder_id: str, scenario: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def next_credential_scan_will_fail( - self, - *, - acs_encoder_id: str, - error_code: Optional[str] = None, - acs_credential_id_on_seam: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def next_credential_scan_will_succeed( - self, - *, - acs_encoder_id: str, - acs_credential_id_on_seam: Optional[str] = None, - scenario: Optional[str] = None - ) -> None: - raise NotImplementedError() - - -class AbstractAcsEntrances(abc.ABC): - - @abc.abstractmethod - def get(self, *, acs_entrance_id: str) -> AcsEntrance: - raise NotImplementedError() - - @abc.abstractmethod - def grant_access( - self, - *, - acs_entrance_id: str, - acs_user_id: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - acs_credential_id: Optional[str] = None, - acs_entrance_ids: Optional[List[str]] = None, - acs_system_id: Optional[str] = None, - connected_account_id: Optional[str] = None, - customer_key: Optional[str] = None, - limit: Optional[int] = None, - location_id: Optional[str] = None, - page_cursor: Optional[str] = None, - search: Optional[str] = None, - space_id: Optional[str] = None - ) -> List[AcsEntrance]: - raise NotImplementedError() - - @abc.abstractmethod - def list_credentials_with_access( - self, *, acs_entrance_id: str, include_if: Optional[List[str]] = None - ) -> List[AcsCredential]: - raise NotImplementedError() - - @abc.abstractmethod - def unlock( - self, - *, - acs_credential_id: str, - acs_entrance_id: str, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - -class AbstractAcsSystems(abc.ABC): - - @abc.abstractmethod - def get(self, *, acs_system_id: str) -> AcsSystem: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - connected_account_id: Optional[str] = None, - customer_key: Optional[str] = None, - search: Optional[str] = None - ) -> List[AcsSystem]: - raise NotImplementedError() - - @abc.abstractmethod - def list_compatible_credential_manager_acs_systems( - self, *, acs_system_id: str - ) -> List[AcsSystem]: - raise NotImplementedError() - - @abc.abstractmethod - def report_devices( - self, - *, - acs_system_id: str, - acs_encoders: Optional[List[Dict[str, Any]]] = None, - acs_entrances: Optional[List[Dict[str, Any]]] = None - ) -> None: - raise NotImplementedError() - - -class AbstractAcsUsers(abc.ABC): - - @abc.abstractmethod - def add_to_access_group( - self, *, acs_access_group_id: str, acs_user_id: str - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def create( - self, - *, - acs_system_id: str, - full_name: str, - access_schedule: Optional[Dict[str, Any]] = None, - acs_access_group_ids: Optional[List[str]] = None, - email: Optional[str] = None, - email_address: Optional[str] = None, - phone_number: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> AcsUser: - raise NotImplementedError() - - @abc.abstractmethod - def delete( - self, - *, - acs_system_id: Optional[str] = None, - acs_user_id: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def get( - self, - *, - acs_user_id: Optional[str] = None, - acs_system_id: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> AcsUser: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - acs_system_id: Optional[str] = None, - created_before: Optional[str] = None, - limit: Optional[int] = None, - page_cursor: Optional[str] = None, - search: Optional[str] = None, - user_identity_email_address: Optional[str] = None, - user_identity_id: Optional[str] = None, - user_identity_phone_number: Optional[str] = None - ) -> List[AcsUser]: - raise NotImplementedError() - - @abc.abstractmethod - def list_accessible_entrances( - self, - *, - acs_system_id: Optional[str] = None, - acs_user_id: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> List[AcsEntrance]: - raise NotImplementedError() - - @abc.abstractmethod - def remove_from_access_group( - self, - *, - acs_access_group_id: str, - acs_user_id: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def revoke_access_to_all_entrances( - self, - *, - acs_system_id: Optional[str] = None, - acs_user_id: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def suspend( - self, - *, - acs_system_id: Optional[str] = None, - acs_user_id: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def unsuspend( - self, - *, - acs_system_id: Optional[str] = None, - acs_user_id: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def update( - self, - *, - access_schedule: Optional[Dict[str, Any]] = None, - acs_system_id: Optional[str] = None, - acs_user_id: Optional[str] = None, - email: Optional[str] = None, - email_address: Optional[str] = None, - full_name: Optional[str] = None, - hid_acs_system_id: Optional[str] = None, - phone_number: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> None: - raise NotImplementedError() - - -class AbstractActionAttempts(abc.ABC): - - @abc.abstractmethod - def get( - self, - *, - action_attempt_id: str, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - action_attempt_ids: Optional[List[str]] = None, - device_id: Optional[str] = None, - limit: Optional[int] = None, - page_cursor: Optional[str] = None - ) -> List[ActionAttempt]: - raise NotImplementedError() - - -class AbstractClientSessions(abc.ABC): - - @abc.abstractmethod - def create( - self, - *, - connect_webview_ids: Optional[List[str]] = None, - connected_account_ids: Optional[List[str]] = None, - customer_id: Optional[str] = None, - customer_key: Optional[str] = None, - expires_at: Optional[str] = None, - user_identifier_key: Optional[str] = None, - user_identity_id: Optional[str] = None, - user_identity_ids: Optional[List[str]] = None - ) -> ClientSession: - raise NotImplementedError() - - @abc.abstractmethod - def delete(self, *, client_session_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def get( - self, - *, - client_session_id: Optional[str] = None, - user_identifier_key: Optional[str] = None - ) -> ClientSession: - raise NotImplementedError() - - @abc.abstractmethod - def get_or_create( - self, - *, - connect_webview_ids: Optional[List[str]] = None, - connected_account_ids: Optional[List[str]] = None, - expires_at: Optional[str] = None, - user_identifier_key: Optional[str] = None, - user_identity_id: Optional[str] = None, - user_identity_ids: Optional[List[str]] = None - ) -> ClientSession: - raise NotImplementedError() - - @abc.abstractmethod - def grant_access( - self, - *, - client_session_id: Optional[str] = None, - connect_webview_ids: Optional[List[str]] = None, - connected_account_ids: Optional[List[str]] = None, - user_identifier_key: Optional[str] = None, - user_identity_id: Optional[str] = None, - user_identity_ids: Optional[List[str]] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - client_session_id: Optional[str] = None, - connect_webview_id: Optional[str] = None, - user_identifier_key: Optional[str] = None, - user_identity_id: Optional[str] = None, - without_user_identifier_key: Optional[bool] = None - ) -> List[ClientSession]: - raise NotImplementedError() - - @abc.abstractmethod - def revoke(self, *, client_session_id: str) -> None: - raise NotImplementedError() - - -class AbstractConnectWebviews(abc.ABC): - - @abc.abstractmethod - def create( - self, - *, - accepted_capabilities: Optional[List[str]] = None, - accepted_providers: Optional[List[str]] = None, - automatically_manage_new_devices: Optional[bool] = None, - custom_metadata: Optional[Dict[str, Any]] = None, - custom_redirect_failure_url: Optional[str] = None, - custom_redirect_url: Optional[str] = None, - customer_key: Optional[str] = None, - excluded_providers: Optional[List[str]] = None, - provider_category: Optional[str] = None, - wait_for_device_creation: Optional[bool] = None - ) -> ConnectWebview: - raise NotImplementedError() - - @abc.abstractmethod - def delete(self, *, connect_webview_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def get(self, *, connect_webview_id: str) -> ConnectWebview: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - custom_metadata_has: Optional[Dict[str, Any]] = None, - customer_key: Optional[str] = None, - limit: Optional[float] = None, - page_cursor: Optional[str] = None, - search: Optional[str] = None, - user_identifier_key: Optional[str] = None - ) -> List[ConnectWebview]: - raise NotImplementedError() - - -class AbstractConnectedAccountsSimulate(abc.ABC): - - @abc.abstractmethod - def disconnect(self, *, connected_account_id: str) -> None: - raise NotImplementedError() - - -class AbstractCustomers(abc.ABC): - - @abc.abstractmethod - def create_portal( - self, - *, - customer_resources_filters: Optional[List[Dict[str, Any]]] = None, - customization_profile_id: Optional[str] = None, - deep_link: Optional[Dict[str, Any]] = None, - exclude_locale_picker: Optional[bool] = None, - features: Optional[Dict[str, Any]] = None, - is_embedded: Optional[bool] = None, - landing_page: Optional[Dict[str, Any]] = None, - locale: Optional[str] = None, - navigation_mode: Optional[str] = None, - read_only: Optional[bool] = None, - customer_data: Optional[Dict[str, Any]] = None - ) -> CustomerPortal: - raise NotImplementedError() - - @abc.abstractmethod - def delete_data( - self, - *, - access_grant_keys: Optional[List[str]] = None, - booking_keys: Optional[List[str]] = None, - building_keys: Optional[List[str]] = None, - common_area_keys: Optional[List[str]] = None, - customer_keys: Optional[List[str]] = None, - facility_keys: Optional[List[str]] = None, - guest_keys: Optional[List[str]] = None, - listing_keys: Optional[List[str]] = None, - property_keys: Optional[List[str]] = None, - property_listing_keys: Optional[List[str]] = None, - reservation_keys: Optional[List[str]] = None, - resident_keys: Optional[List[str]] = None, - room_keys: Optional[List[str]] = None, - space_keys: Optional[List[str]] = None, - staff_member_keys: Optional[List[str]] = None, - tenant_keys: Optional[List[str]] = None, - unit_keys: Optional[List[str]] = None, - user_identity_keys: Optional[List[str]] = None, - user_keys: Optional[List[str]] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def push_data( - self, - *, - customer_key: str, - access_grants: Optional[List[Dict[str, Any]]] = None, - bookings: Optional[List[Dict[str, Any]]] = None, - buildings: Optional[List[Dict[str, Any]]] = None, - common_areas: Optional[List[Dict[str, Any]]] = None, - facilities: Optional[List[Dict[str, Any]]] = None, - guests: Optional[List[Dict[str, Any]]] = None, - listings: Optional[List[Dict[str, Any]]] = None, - properties: Optional[List[Dict[str, Any]]] = None, - property_listings: Optional[List[Dict[str, Any]]] = None, - reservations: Optional[List[Dict[str, Any]]] = None, - residents: Optional[List[Dict[str, Any]]] = None, - rooms: Optional[List[Dict[str, Any]]] = None, - sites: Optional[List[Dict[str, Any]]] = None, - spaces: Optional[List[Dict[str, Any]]] = None, - staff_members: Optional[List[Dict[str, Any]]] = None, - tenants: Optional[List[Dict[str, Any]]] = None, - units: Optional[List[Dict[str, Any]]] = None, - user_identities: Optional[List[Dict[str, Any]]] = None, - users: Optional[List[Dict[str, Any]]] = None - ) -> None: - raise NotImplementedError() - - -class AbstractDevicesSimulate(abc.ABC): - - @abc.abstractmethod - def connect(self, *, device_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def connect_to_hub(self, *, device_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def disconnect(self, *, device_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def disconnect_from_hub(self, *, device_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def paid_subscription(self, *, device_id: str, is_expired: bool) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def remove(self, *, device_id: str) -> None: - raise NotImplementedError() - - -class AbstractDevicesUnmanaged(abc.ABC): - - @abc.abstractmethod - def get( - self, *, device_id: Optional[str] = None, name: Optional[str] = None - ) -> UnmanagedDevice: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - connect_webview_id: Optional[str] = None, - connected_account_id: Optional[str] = None, - connected_account_ids: Optional[List[str]] = None, - created_before: Optional[str] = None, - custom_metadata_has: Optional[Dict[str, Any]] = None, - customer_key: Optional[str] = None, - device_ids: Optional[List[str]] = None, - device_type: Optional[str] = None, - device_types: Optional[List[str]] = None, - limit: Optional[float] = None, - manufacturer: Optional[str] = None, - page_cursor: Optional[str] = None, - search: Optional[str] = None, - space_id: Optional[str] = None, - unstable_location_id: Optional[str] = None, - user_identifier_key: Optional[str] = None - ) -> List[UnmanagedDevice]: - raise NotImplementedError() - - @abc.abstractmethod - def update( - self, - *, - device_id: str, - custom_metadata: Optional[Dict[str, Any]] = None, - is_managed: Optional[bool] = None - ) -> None: - raise NotImplementedError() - - -class AbstractEvents(abc.ABC): - - @abc.abstractmethod - def get( - self, - *, - event_id: Optional[str] = None, - device_id: Optional[str] = None, - event_type: Optional[str] = None - ) -> SeamEvent: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - access_code_id: Optional[str] = None, - access_code_ids: Optional[List[str]] = None, - access_grant_id: Optional[str] = None, - access_grant_ids: Optional[List[str]] = None, - access_method_id: Optional[str] = None, - access_method_ids: Optional[List[str]] = None, - acs_access_group_id: Optional[str] = None, - acs_credential_id: Optional[str] = None, - acs_encoder_id: Optional[str] = None, - acs_entrance_id: Optional[str] = None, - acs_system_id: Optional[str] = None, - acs_system_ids: Optional[List[str]] = None, - acs_user_id: Optional[str] = None, - between: Optional[List[Dict[str, Any]]] = None, - connect_webview_id: Optional[str] = None, - connected_account_id: Optional[str] = None, - customer_key: Optional[str] = None, - device_id: Optional[str] = None, - device_ids: Optional[List[str]] = None, - event_ids: Optional[List[str]] = None, - event_type: Optional[str] = None, - event_types: Optional[List[str]] = None, - limit: Optional[float] = None, - since: Optional[str] = None, - space_id: Optional[str] = None, - space_ids: Optional[List[str]] = None, - unstable_offset: Optional[float] = None, - user_identity_id: Optional[str] = None - ) -> List[SeamEvent]: - raise NotImplementedError() - - -class AbstractInstantKeys(abc.ABC): - - @abc.abstractmethod - def delete(self, *, instant_key_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def get( - self, - *, - instant_key_id: Optional[str] = None, - instant_key_url: Optional[str] = None - ) -> InstantKey: - raise NotImplementedError() - - @abc.abstractmethod - def list(self, *, user_identity_id: Optional[str] = None) -> List[InstantKey]: - raise NotImplementedError() - - -class AbstractLocksSimulate(abc.ABC): - - @abc.abstractmethod - def keypad_code_entry( - self, - *, - code: str, - device_id: str, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - @abc.abstractmethod - def manual_lock_via_keypad( - self, - *, - device_id: str, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - -class AbstractNoiseSensorsNoiseThresholds(abc.ABC): - - @abc.abstractmethod - def create( - self, - *, - device_id: str, - ends_daily_at: str, - starts_daily_at: str, - name: Optional[str] = None, - noise_threshold_decibels: Optional[float] = None, - noise_threshold_nrs: Optional[float] = None - ) -> NoiseThreshold: - raise NotImplementedError() - - @abc.abstractmethod - def delete(self, *, device_id: str, noise_threshold_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def get(self, *, noise_threshold_id: str) -> NoiseThreshold: - raise NotImplementedError() - - @abc.abstractmethod - def list(self, *, device_id: str) -> List[NoiseThreshold]: - raise NotImplementedError() - - @abc.abstractmethod - def update( - self, - *, - device_id: str, - noise_threshold_id: str, - ends_daily_at: Optional[str] = None, - name: Optional[str] = None, - noise_threshold_decibels: Optional[float] = None, - noise_threshold_nrs: Optional[float] = None, - starts_daily_at: Optional[str] = None - ) -> None: - raise NotImplementedError() - - -class AbstractNoiseSensorsSimulate(abc.ABC): - - @abc.abstractmethod - def trigger_noise_threshold(self, *, device_id: str) -> None: - raise NotImplementedError() - - -class AbstractPhonesSimulate(abc.ABC): - - @abc.abstractmethod - def create_sandbox_phone( - self, - *, - user_identity_id: str, - assa_abloy_metadata: Optional[Dict[str, Any]] = None, - custom_sdk_installation_id: Optional[str] = None, - phone_metadata: Optional[Dict[str, Any]] = None - ) -> Phone: - raise NotImplementedError() - - -class AbstractSpaces(abc.ABC): - - @abc.abstractmethod - def add_acs_entrances(self, *, acs_entrance_ids: List[str], space_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def add_connected_account( - self, *, connected_account_id: str, space_id: str - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def add_devices(self, *, device_ids: List[str], space_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def create( - self, - *, - name: str, - acs_entrance_ids: Optional[List[str]] = None, - connected_account_ids: Optional[List[str]] = None, - customer_data: Optional[Dict[str, Any]] = None, - customer_key: Optional[str] = None, - device_ids: Optional[List[str]] = None, - space_key: Optional[str] = None - ) -> Space: - raise NotImplementedError() - - @abc.abstractmethod - def delete(self, *, space_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def get( - self, *, space_id: Optional[str] = None, space_key: Optional[str] = None - ) -> Space: - raise NotImplementedError() - - @abc.abstractmethod - def get_related( - self, - *, - exclude: Optional[List[str]] = None, - include: Optional[List[str]] = None, - space_ids: Optional[List[str]] = None, - space_keys: Optional[List[str]] = None - ) -> Batch: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - customer_key: Optional[str] = None, - limit: Optional[float] = None, - page_cursor: Optional[str] = None, - search: Optional[str] = None, - space_key: Optional[str] = None - ) -> List[Space]: - raise NotImplementedError() - - @abc.abstractmethod - def remove_acs_entrances( - self, *, acs_entrance_ids: List[str], space_id: str - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def remove_connected_account( - self, *, connected_account_id: str, space_id: str - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def remove_devices(self, *, device_ids: List[str], space_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def update( - self, - *, - acs_entrance_ids: Optional[List[str]] = None, - customer_data: Optional[Dict[str, Any]] = None, - device_ids: Optional[List[str]] = None, - name: Optional[str] = None, - space_id: Optional[str] = None, - space_key: Optional[str] = None - ) -> Space: - raise NotImplementedError() - - -class AbstractThermostatsDailyPrograms(abc.ABC): - - @abc.abstractmethod - def create( - self, *, device_id: str, name: str, periods: List[Dict[str, Any]] - ) -> ThermostatDailyProgram: - raise NotImplementedError() - - @abc.abstractmethod - def delete(self, *, thermostat_daily_program_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def update( - self, - *, - name: str, - periods: List[Dict[str, Any]], - thermostat_daily_program_id: str, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - -class AbstractThermostatsSchedules(abc.ABC): - - @abc.abstractmethod - def create( - self, - *, - climate_preset_key: str, - device_id: str, - ends_at: str, - starts_at: str, - is_override_allowed: Optional[bool] = None, - max_override_period_minutes: Optional[int] = None, - name: Optional[str] = None - ) -> ThermostatSchedule: - raise NotImplementedError() - - @abc.abstractmethod - def delete(self, *, thermostat_schedule_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def get(self, *, thermostat_schedule_id: str) -> ThermostatSchedule: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, *, device_id: str, user_identifier_key: Optional[str] = None - ) -> List[ThermostatSchedule]: - raise NotImplementedError() - - @abc.abstractmethod - def update( - self, - *, - thermostat_schedule_id: str, - climate_preset_key: Optional[str] = None, - ends_at: Optional[str] = None, - is_override_allowed: Optional[bool] = None, - max_override_period_minutes: Optional[int] = None, - name: Optional[str] = None, - starts_at: Optional[str] = None - ) -> None: - raise NotImplementedError() - - -class AbstractThermostatsSimulate(abc.ABC): - - @abc.abstractmethod - def hvac_mode_adjusted( - self, - *, - device_id: str, - hvac_mode: str, - cooling_set_point_celsius: Optional[float] = None, - cooling_set_point_fahrenheit: Optional[float] = None, - heating_set_point_celsius: Optional[float] = None, - heating_set_point_fahrenheit: Optional[float] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def temperature_reached( - self, - *, - device_id: str, - temperature_celsius: Optional[float] = None, - temperature_fahrenheit: Optional[float] = None - ) -> None: - raise NotImplementedError() - - -class AbstractUserIdentitiesUnmanaged(abc.ABC): - - @abc.abstractmethod - def get(self, *, user_identity_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - created_before: Optional[str] = None, - limit: Optional[int] = None, - page_cursor: Optional[str] = None, - search: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def update( - self, - *, - is_managed: bool, - user_identity_id: str, - user_identity_key: Optional[str] = None - ) -> None: - raise NotImplementedError() - - -class AbstractWebhooks(abc.ABC): - - @abc.abstractmethod - def create(self, *, url: str, event_types: Optional[List[str]] = None) -> Webhook: - raise NotImplementedError() - - @abc.abstractmethod - def delete(self, *, webhook_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def get(self, *, webhook_id: str) -> Webhook: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - ) -> List[Webhook]: - raise NotImplementedError() - - @abc.abstractmethod - def update(self, *, event_types: List[str], webhook_id: str) -> None: - raise NotImplementedError() - - -class AbstractWorkspaces(abc.ABC): - - @abc.abstractmethod - def create( - self, - *, - name: str, - company_name: Optional[str] = None, - connect_partner_name: Optional[str] = None, - connect_webview_customization: Optional[Dict[str, Any]] = None, - is_sandbox: Optional[bool] = None, - organization_id: Optional[str] = None, - webview_logo_shape: Optional[str] = None, - webview_primary_button_color: Optional[str] = None, - webview_primary_button_text_color: Optional[str] = None, - webview_success_message: Optional[str] = None - ) -> Workspace: - raise NotImplementedError() - - @abc.abstractmethod - def get( - self, - ) -> Workspace: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - ) -> List[Workspace]: - raise NotImplementedError() - - @abc.abstractmethod - def reset_sandbox( - self, wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - @abc.abstractmethod - def update( - self, - *, - connect_partner_name: Optional[str] = None, - connect_webview_customization: Optional[Dict[str, Any]] = None, - is_publishable_key_auth_enabled: Optional[bool] = None, - is_suspended: Optional[bool] = None, - name: Optional[str] = None, - organization_id: Optional[str] = None - ) -> None: - raise NotImplementedError() - - -class AbstractAccessGrants(abc.ABC): - - @property - @abc.abstractmethod - def unmanaged(self) -> AbstractAccessGrantsUnmanaged: - raise NotImplementedError() - - @abc.abstractmethod - def create( - self, - *, - requested_access_methods: List[Dict[str, Any]], - user_identity_id: Optional[str] = None, - user_identity: Optional[Dict[str, Any]] = None, - access_grant_key: Optional[str] = None, - acs_entrance_ids: Optional[List[str]] = None, - customization_profile_id: Optional[str] = None, - device_ids: Optional[List[str]] = None, - ends_at: Optional[str] = None, - location: Optional[Dict[str, Any]] = None, - location_ids: Optional[List[str]] = None, - name: Optional[str] = None, - reservation_key: Optional[str] = None, - space_ids: Optional[List[str]] = None, - space_keys: Optional[List[str]] = None, - starts_at: Optional[str] = None - ) -> AccessGrant: - raise NotImplementedError() - - @abc.abstractmethod - def delete(self, *, access_grant_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def get( - self, - *, - access_grant_id: Optional[str] = None, - access_grant_key: Optional[str] = None - ) -> AccessGrant: - raise NotImplementedError() - - @abc.abstractmethod - def get_related( - self, - *, - access_grant_ids: Optional[List[str]] = None, - access_grant_keys: Optional[List[str]] = None, - exclude: Optional[List[str]] = None, - include: Optional[List[str]] = None - ) -> Batch: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - access_code_id: Optional[str] = None, - access_grant_ids: Optional[List[str]] = None, - access_grant_key: Optional[str] = None, - acs_entrance_id: Optional[str] = None, - acs_system_id: Optional[str] = None, - customer_key: Optional[str] = None, - device_id: Optional[str] = None, - limit: Optional[float] = None, - location_id: Optional[str] = None, - page_cursor: Optional[str] = None, - reservation_key: Optional[str] = None, - space_id: Optional[str] = None, - user_identity_id: Optional[str] = None - ) -> List[AccessGrant]: - raise NotImplementedError() - - @abc.abstractmethod - def request_access_methods( - self, *, access_grant_id: str, requested_access_methods: List[Dict[str, Any]] - ) -> AccessGrant: - raise NotImplementedError() - - @abc.abstractmethod - def update( - self, - *, - access_grant_id: Optional[str] = None, - access_grant_key: Optional[str] = None, - ends_at: Optional[str] = None, - name: Optional[str] = None, - starts_at: Optional[str] = None - ) -> None: - raise NotImplementedError() - - -class AbstractAccessMethods(abc.ABC): - - @property - @abc.abstractmethod - def unmanaged(self) -> AbstractAccessMethodsUnmanaged: - raise NotImplementedError() - - @abc.abstractmethod - def assign_card( - self, - *, - access_method_id: str, - card_number: str, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - @abc.abstractmethod - def delete( - self, - *, - access_method_id: Optional[str] = None, - access_grant_id: Optional[str] = None, - reservation_key: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def encode( - self, - *, - access_method_id: str, - acs_encoder_id: str, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - @abc.abstractmethod - def get(self, *, access_method_id: str) -> AccessMethod: - raise NotImplementedError() - - @abc.abstractmethod - def get_related( - self, - *, - access_method_ids: List[str], - exclude: Optional[List[str]] = None, - include: Optional[List[str]] = None - ) -> Batch: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - access_code_id: Optional[str] = None, - access_grant_id: Optional[str] = None, - access_grant_key: Optional[str] = None, - acs_entrance_id: Optional[str] = None, - device_id: Optional[str] = None, - space_id: Optional[str] = None - ) -> List[AccessMethod]: - raise NotImplementedError() - - @abc.abstractmethod - def unlock_door( - self, - *, - access_method_id: str, - acs_entrance_id: str, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - -class AbstractAcsEncoders(abc.ABC): - - @property - @abc.abstractmethod - def simulate(self) -> AbstractAcsEncodersSimulate: - raise NotImplementedError() - - @abc.abstractmethod - def encode_credential( - self, - *, - acs_encoder_id: str, - access_method_id: Optional[str] = None, - acs_credential_id: Optional[str] = None, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - @abc.abstractmethod - def get(self, *, acs_encoder_id: str) -> AcsEncoder: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - acs_system_id: Optional[str] = None, - acs_system_ids: Optional[List[str]] = None, - acs_encoder_ids: Optional[List[str]] = None, - limit: Optional[float] = None, - page_cursor: Optional[str] = None - ) -> List[AcsEncoder]: - raise NotImplementedError() - - @abc.abstractmethod - def scan_credential( - self, - *, - acs_encoder_id: str, - salto_ks_metadata: Optional[Dict[str, Any]] = None, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - @abc.abstractmethod - def scan_to_assign_credential( - self, - *, - acs_encoder_id: str, - acs_user_id: Optional[str] = None, - salto_ks_metadata: Optional[Dict[str, Any]] = None, - user_identity_id: Optional[str] = None, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - -class AbstractConnectedAccounts(abc.ABC): - - @property - @abc.abstractmethod - def simulate(self) -> AbstractConnectedAccountsSimulate: - raise NotImplementedError() - - @abc.abstractmethod - def delete(self, *, connected_account_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def get( - self, *, connected_account_id: Optional[str] = None, email: Optional[str] = None - ) -> ConnectedAccount: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - custom_metadata_has: Optional[Dict[str, Any]] = None, - customer_key: Optional[str] = None, - limit: Optional[int] = None, - page_cursor: Optional[str] = None, - search: Optional[str] = None, - space_id: Optional[str] = None, - user_identifier_key: Optional[str] = None - ) -> List[ConnectedAccount]: - raise NotImplementedError() - - @abc.abstractmethod - def sync(self, *, connected_account_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def update( - self, - *, - connected_account_id: str, - accepted_capabilities: Optional[List[str]] = None, - automatically_manage_new_devices: Optional[bool] = None, - custom_metadata: Optional[Dict[str, Any]] = None, - customer_key: Optional[str] = None, - display_name: Optional[str] = None - ) -> None: - raise NotImplementedError() - - -class AbstractLocks(abc.ABC): - - @property - @abc.abstractmethod - def simulate(self) -> AbstractLocksSimulate: - raise NotImplementedError() - - @abc.abstractmethod - def configure_auto_lock( - self, - *, - auto_lock_enabled: bool, - device_id: str, - auto_lock_delay_seconds: Optional[float] = None, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - @abc.abstractmethod - def get( - self, *, device_id: Optional[str] = None, name: Optional[str] = None - ) -> Device: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - connect_webview_id: Optional[str] = None, - connected_account_id: Optional[str] = None, - connected_account_ids: Optional[List[str]] = None, - created_before: Optional[str] = None, - custom_metadata_has: Optional[Dict[str, Any]] = None, - customer_key: Optional[str] = None, - device_ids: Optional[List[str]] = None, - device_type: Optional[str] = None, - device_types: Optional[List[str]] = None, - limit: Optional[float] = None, - manufacturer: Optional[str] = None, - page_cursor: Optional[str] = None, - search: Optional[str] = None, - space_id: Optional[str] = None, - unstable_location_id: Optional[str] = None, - user_identifier_key: Optional[str] = None - ) -> List[Device]: - raise NotImplementedError() - - @abc.abstractmethod - def lock_door( - self, - *, - device_id: str, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - @abc.abstractmethod - def unlock_door( - self, - *, - device_id: str, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - -class AbstractPhones(abc.ABC): - - @property - @abc.abstractmethod - def simulate(self) -> AbstractPhonesSimulate: - raise NotImplementedError() - - @abc.abstractmethod - def deactivate(self, *, device_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def get(self, *, device_id: str) -> Phone: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - acs_credential_id: Optional[str] = None, - owner_user_identity_id: Optional[str] = None - ) -> List[Phone]: - raise NotImplementedError() - - -class AbstractUserIdentities(abc.ABC): - - @property - @abc.abstractmethod - def unmanaged(self) -> AbstractUserIdentitiesUnmanaged: - raise NotImplementedError() - - @abc.abstractmethod - def add_acs_user( - self, - *, - acs_user_id: str, - user_identity_id: Optional[str] = None, - user_identity_key: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def create( - self, - *, - acs_system_ids: Optional[List[str]] = None, - email_address: Optional[str] = None, - full_name: Optional[str] = None, - phone_number: Optional[str] = None, - user_identity_key: Optional[str] = None - ) -> UserIdentity: - raise NotImplementedError() - - @abc.abstractmethod - def delete(self, *, user_identity_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def generate_instant_key( - self, - *, - user_identity_id: str, - customization_profile_id: Optional[str] = None, - max_use_count: Optional[float] = None - ) -> InstantKey: - raise NotImplementedError() - - @abc.abstractmethod - def get( - self, - *, - user_identity_id: Optional[str] = None, - user_identity_key: Optional[str] = None - ) -> UserIdentity: - raise NotImplementedError() - - @abc.abstractmethod - def grant_access_to_device(self, *, device_id: str, user_identity_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - created_before: Optional[str] = None, - credential_manager_acs_system_id: Optional[str] = None, - limit: Optional[int] = None, - page_cursor: Optional[str] = None, - search: Optional[str] = None, - user_identity_ids: Optional[List[str]] = None - ) -> List[UserIdentity]: - raise NotImplementedError() - - @abc.abstractmethod - def list_accessible_devices(self, *, user_identity_id: str) -> List[Device]: - raise NotImplementedError() - - @abc.abstractmethod - def list_accessible_entrances(self, *, user_identity_id: str) -> List[AcsEntrance]: - raise NotImplementedError() - - @abc.abstractmethod - def list_acs_systems(self, *, user_identity_id: str) -> List[AcsSystem]: - raise NotImplementedError() - - @abc.abstractmethod - def list_acs_users(self, *, user_identity_id: str) -> List[AcsUser]: - raise NotImplementedError() - - @abc.abstractmethod - def remove_acs_user(self, *, acs_user_id: str, user_identity_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def revoke_access_to_device(self, *, device_id: str, user_identity_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def update( - self, - *, - user_identity_id: str, - email_address: Optional[str] = None, - full_name: Optional[str] = None, - phone_number: Optional[str] = None, - user_identity_key: Optional[str] = None - ) -> None: - raise NotImplementedError() - - -class AbstractAccessCodes(abc.ABC): - - @property - @abc.abstractmethod - def simulate(self) -> AbstractAccessCodesSimulate: - raise NotImplementedError() - - @property - @abc.abstractmethod - def unmanaged(self) -> AbstractAccessCodesUnmanaged: - raise NotImplementedError() - - @abc.abstractmethod - def create( - self, - *, - device_id: str, - allow_external_modification: Optional[bool] = None, - attempt_for_offline_device: Optional[bool] = None, - code: Optional[str] = None, - common_code_key: Optional[str] = None, - ends_at: Optional[str] = None, - is_external_modification_allowed: Optional[bool] = None, - is_offline_access_code: Optional[bool] = None, - is_one_time_use: Optional[bool] = None, - max_time_rounding: Optional[str] = None, - name: Optional[str] = None, - prefer_native_scheduling: Optional[bool] = None, - preferred_code_length: Optional[float] = None, - starts_at: Optional[str] = None, - use_backup_access_code_pool: Optional[bool] = None, - use_offline_access_code: Optional[bool] = None - ) -> AccessCode: - raise NotImplementedError() - - @abc.abstractmethod - def create_multiple( - self, - *, - device_ids: List[str], - allow_external_modification: Optional[bool] = None, - attempt_for_offline_device: Optional[bool] = None, - behavior_when_code_cannot_be_shared: Optional[str] = None, - code: Optional[str] = None, - ends_at: Optional[str] = None, - is_external_modification_allowed: Optional[bool] = None, - name: Optional[str] = None, - prefer_native_scheduling: Optional[bool] = None, - preferred_code_length: Optional[float] = None, - starts_at: Optional[str] = None, - use_backup_access_code_pool: Optional[bool] = None - ) -> List[AccessCode]: - raise NotImplementedError() - - @abc.abstractmethod - def delete(self, *, access_code_id: str, device_id: Optional[str] = None) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def generate_code(self, *, device_id: str) -> AccessCode: - raise NotImplementedError() - - @abc.abstractmethod - def get( - self, - *, - access_code_id: Optional[str] = None, - code: Optional[str] = None, - device_id: Optional[str] = None - ) -> AccessCode: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - access_code_ids: Optional[List[str]] = None, - access_grant_id: Optional[str] = None, - access_grant_key: Optional[str] = None, - access_method_id: Optional[str] = None, - customer_key: Optional[str] = None, - device_id: Optional[str] = None, - limit: Optional[float] = None, - page_cursor: Optional[str] = None, - search: Optional[str] = None, - user_identifier_key: Optional[str] = None - ) -> List[AccessCode]: - raise NotImplementedError() - - @abc.abstractmethod - def pull_backup_access_code(self, *, access_code_id: str) -> AccessCode: - raise NotImplementedError() - - @abc.abstractmethod - def report_device_constraints( - self, - *, - device_id: str, - max_code_length: Optional[int] = None, - min_code_length: Optional[int] = None, - supported_code_lengths: Optional[List[float]] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def update( - self, - *, - access_code_id: str, - allow_external_modification: Optional[bool] = None, - attempt_for_offline_device: Optional[bool] = None, - code: Optional[str] = None, - device_id: Optional[str] = None, - ends_at: Optional[str] = None, - is_external_modification_allowed: Optional[bool] = None, - is_managed: Optional[bool] = None, - is_offline_access_code: Optional[bool] = None, - is_one_time_use: Optional[bool] = None, - max_time_rounding: Optional[str] = None, - name: Optional[str] = None, - prefer_native_scheduling: Optional[bool] = None, - preferred_code_length: Optional[float] = None, - starts_at: Optional[str] = None, - type: Optional[str] = None, - use_backup_access_code_pool: Optional[bool] = None, - use_offline_access_code: Optional[bool] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def update_multiple( - self, - *, - common_code_key: str, - ends_at: Optional[str] = None, - name: Optional[str] = None, - starts_at: Optional[str] = None - ) -> None: - raise NotImplementedError() - - -class AbstractDevices(abc.ABC): - - @property - @abc.abstractmethod - def simulate(self) -> AbstractDevicesSimulate: - raise NotImplementedError() - - @property - @abc.abstractmethod - def unmanaged(self) -> AbstractDevicesUnmanaged: - raise NotImplementedError() - - @abc.abstractmethod - def get( - self, *, device_id: Optional[str] = None, name: Optional[str] = None - ) -> Device: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - connect_webview_id: Optional[str] = None, - connected_account_id: Optional[str] = None, - connected_account_ids: Optional[List[str]] = None, - created_before: Optional[str] = None, - custom_metadata_has: Optional[Dict[str, Any]] = None, - customer_key: Optional[str] = None, - device_ids: Optional[List[str]] = None, - device_type: Optional[str] = None, - device_types: Optional[List[str]] = None, - limit: Optional[float] = None, - manufacturer: Optional[str] = None, - page_cursor: Optional[str] = None, - search: Optional[str] = None, - space_id: Optional[str] = None, - unstable_location_id: Optional[str] = None, - user_identifier_key: Optional[str] = None - ) -> List[Device]: - raise NotImplementedError() - - @abc.abstractmethod - def list_device_providers( - self, *, provider_category: Optional[str] = None - ) -> List[DeviceProvider]: - raise NotImplementedError() - - @abc.abstractmethod - def report_provider_metadata(self, *, devices: List[Dict[str, Any]]) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def update( - self, - *, - device_id: str, - backup_access_code_pool_enabled: Optional[bool] = None, - custom_metadata: Optional[Dict[str, Any]] = None, - is_managed: Optional[bool] = None, - name: Optional[str] = None, - properties: Optional[Dict[str, Any]] = None - ) -> None: - raise NotImplementedError() - - -class AbstractNoiseSensors(abc.ABC): - - @property - @abc.abstractmethod - def noise_thresholds(self) -> AbstractNoiseSensorsNoiseThresholds: - raise NotImplementedError() - - @property - @abc.abstractmethod - def simulate(self) -> AbstractNoiseSensorsSimulate: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - connect_webview_id: Optional[str] = None, - connected_account_id: Optional[str] = None, - connected_account_ids: Optional[List[str]] = None, - created_before: Optional[str] = None, - custom_metadata_has: Optional[Dict[str, Any]] = None, - customer_key: Optional[str] = None, - device_ids: Optional[List[str]] = None, - device_type: Optional[str] = None, - device_types: Optional[List[str]] = None, - limit: Optional[float] = None, - manufacturer: Optional[str] = None, - page_cursor: Optional[str] = None, - search: Optional[str] = None, - space_id: Optional[str] = None, - unstable_location_id: Optional[str] = None, - user_identifier_key: Optional[str] = None - ) -> List[Device]: - raise NotImplementedError() - - -class AbstractThermostats(abc.ABC): - - @property - @abc.abstractmethod - def daily_programs(self) -> AbstractThermostatsDailyPrograms: - raise NotImplementedError() - - @property - @abc.abstractmethod - def schedules(self) -> AbstractThermostatsSchedules: - raise NotImplementedError() - - @property - @abc.abstractmethod - def simulate(self) -> AbstractThermostatsSimulate: - raise NotImplementedError() - - @abc.abstractmethod - def activate_climate_preset( - self, - *, - climate_preset_key: str, - device_id: str, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - @abc.abstractmethod - def cool( - self, - *, - device_id: str, - cooling_set_point_celsius: Optional[float] = None, - cooling_set_point_fahrenheit: Optional[float] = None, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - @abc.abstractmethod - def create_climate_preset( - self, - *, - climate_preset_key: str, - device_id: str, - climate_preset_mode: Optional[str] = None, - cooling_set_point_celsius: Optional[float] = None, - cooling_set_point_fahrenheit: Optional[float] = None, - ecobee_metadata: Optional[Dict[str, Any]] = None, - fan_mode_setting: Optional[str] = None, - heating_set_point_celsius: Optional[float] = None, - heating_set_point_fahrenheit: Optional[float] = None, - hvac_mode_setting: Optional[str] = None, - manual_override_allowed: Optional[bool] = None, - name: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def delete_climate_preset(self, *, climate_preset_key: str, device_id: str) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def heat( - self, - *, - device_id: str, - heating_set_point_celsius: Optional[float] = None, - heating_set_point_fahrenheit: Optional[float] = None, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - @abc.abstractmethod - def heat_cool( - self, - *, - device_id: str, - cooling_set_point_celsius: Optional[float] = None, - cooling_set_point_fahrenheit: Optional[float] = None, - heating_set_point_celsius: Optional[float] = None, - heating_set_point_fahrenheit: Optional[float] = None, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - @abc.abstractmethod - def list( - self, - *, - connect_webview_id: Optional[str] = None, - connected_account_id: Optional[str] = None, - connected_account_ids: Optional[List[str]] = None, - created_before: Optional[str] = None, - custom_metadata_has: Optional[Dict[str, Any]] = None, - customer_key: Optional[str] = None, - device_ids: Optional[List[str]] = None, - device_type: Optional[str] = None, - device_types: Optional[List[str]] = None, - limit: Optional[float] = None, - manufacturer: Optional[str] = None, - page_cursor: Optional[str] = None, - search: Optional[str] = None, - space_id: Optional[str] = None, - unstable_location_id: Optional[str] = None, - user_identifier_key: Optional[str] = None - ) -> List[Device]: - raise NotImplementedError() - - @abc.abstractmethod - def off( - self, - *, - device_id: str, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - @abc.abstractmethod - def set_fallback_climate_preset( - self, *, climate_preset_key: str, device_id: str - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def set_fan_mode( - self, - *, - device_id: str, - fan_mode: Optional[str] = None, - fan_mode_setting: Optional[str] = None, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - @abc.abstractmethod - def set_hvac_mode( - self, - *, - device_id: str, - hvac_mode_setting: str, - cooling_set_point_celsius: Optional[float] = None, - cooling_set_point_fahrenheit: Optional[float] = None, - heating_set_point_celsius: Optional[float] = None, - heating_set_point_fahrenheit: Optional[float] = None, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - @abc.abstractmethod - def set_temperature_threshold( - self, - *, - device_id: str, - lower_limit_celsius: Optional[float] = None, - lower_limit_fahrenheit: Optional[float] = None, - upper_limit_celsius: Optional[float] = None, - upper_limit_fahrenheit: Optional[float] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def update_climate_preset( - self, - *, - climate_preset_key: str, - device_id: str, - climate_preset_mode: Optional[str] = None, - cooling_set_point_celsius: Optional[float] = None, - cooling_set_point_fahrenheit: Optional[float] = None, - ecobee_metadata: Optional[Dict[str, Any]] = None, - fan_mode_setting: Optional[str] = None, - heating_set_point_celsius: Optional[float] = None, - heating_set_point_fahrenheit: Optional[float] = None, - hvac_mode_setting: Optional[str] = None, - manual_override_allowed: Optional[bool] = None, - name: Optional[str] = None - ) -> None: - raise NotImplementedError() - - @abc.abstractmethod - def update_weekly_program( - self, - *, - device_id: str, - friday_program_id: Optional[str] = None, - monday_program_id: Optional[str] = None, - saturday_program_id: Optional[str] = None, - sunday_program_id: Optional[str] = None, - thursday_program_id: Optional[str] = None, - tuesday_program_id: Optional[str] = None, - wednesday_program_id: Optional[str] = None, - wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None - ) -> ActionAttempt: - raise NotImplementedError() - - -class AbstractAcs(abc.ABC): - - @property - @abc.abstractmethod - def access_groups(self) -> AbstractAcsAccessGroups: - raise NotImplementedError() - - @property - @abc.abstractmethod - def credentials(self) -> AbstractAcsCredentials: - raise NotImplementedError() - - @property - @abc.abstractmethod - def encoders(self) -> AbstractAcsEncoders: - raise NotImplementedError() - - @property - @abc.abstractmethod - def entrances(self) -> AbstractAcsEntrances: - raise NotImplementedError() - - @property - @abc.abstractmethod - def systems(self) -> AbstractAcsSystems: - raise NotImplementedError() - - @property - @abc.abstractmethod - def users(self) -> AbstractAcsUsers: - raise NotImplementedError() - - -@dataclass -class AbstractRoutes(abc.ABC): - access_codes: AbstractAccessCodes - access_grants: AbstractAccessGrants - access_methods: AbstractAccessMethods - acs: AbstractAcs - action_attempts: AbstractActionAttempts - client_sessions: AbstractClientSessions - connect_webviews: AbstractConnectWebviews - connected_accounts: AbstractConnectedAccounts - customers: AbstractCustomers - devices: AbstractDevices - events: AbstractEvents - instant_keys: AbstractInstantKeys - locks: AbstractLocks - noise_sensors: AbstractNoiseSensors - phones: AbstractPhones - spaces: AbstractSpaces - thermostats: AbstractThermostats - user_identities: AbstractUserIdentities - webhooks: AbstractWebhooks - workspaces: AbstractWorkspaces diff --git a/seam/routes/noise_sensors.py b/seam/routes/noise_sensors.py index e53451b3..ef307b96 100644 --- a/seam/routes/noise_sensors.py +++ b/seam/routes/noise_sensors.py @@ -1,8 +1,48 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractNoiseSensors, Device -from .noise_sensors_noise_thresholds import NoiseSensorsNoiseThresholds -from .noise_sensors_simulate import NoiseSensorsSimulate +from ..resources import Device +from .noise_sensors_noise_thresholds import ( + AbstractNoiseSensorsNoiseThresholds, + NoiseSensorsNoiseThresholds, +) +from .noise_sensors_simulate import AbstractNoiseSensorsSimulate, NoiseSensorsSimulate + + +class AbstractNoiseSensors(abc.ABC): + + @property + @abc.abstractmethod + def noise_thresholds(self) -> AbstractNoiseSensorsNoiseThresholds: + raise NotImplementedError() + + @property + @abc.abstractmethod + def simulate(self) -> AbstractNoiseSensorsSimulate: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + connect_webview_id: Optional[str] = None, + connected_account_id: Optional[str] = None, + connected_account_ids: Optional[List[str]] = None, + created_before: Optional[str] = None, + custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_key: Optional[str] = None, + device_ids: Optional[List[str]] = None, + device_type: Optional[str] = None, + device_types: Optional[List[str]] = None, + limit: Optional[float] = None, + manufacturer: Optional[str] = None, + page_cursor: Optional[str] = None, + search: Optional[str] = None, + space_id: Optional[str] = None, + unstable_location_id: Optional[str] = None, + user_identifier_key: Optional[str] = None + ) -> List[Device]: + raise NotImplementedError() class NoiseSensors(AbstractNoiseSensors): diff --git a/seam/routes/noise_sensors_noise_thresholds.py b/seam/routes/noise_sensors_noise_thresholds.py index 9716f3ef..034300af 100644 --- a/seam/routes/noise_sensors_noise_thresholds.py +++ b/seam/routes/noise_sensors_noise_thresholds.py @@ -1,6 +1,49 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractNoiseSensorsNoiseThresholds, NoiseThreshold +from ..resources import NoiseThreshold + + +class AbstractNoiseSensorsNoiseThresholds(abc.ABC): + + @abc.abstractmethod + def create( + self, + *, + device_id: str, + ends_daily_at: str, + starts_daily_at: str, + name: Optional[str] = None, + noise_threshold_decibels: Optional[float] = None, + noise_threshold_nrs: Optional[float] = None + ) -> NoiseThreshold: + raise NotImplementedError() + + @abc.abstractmethod + def delete(self, *, device_id: str, noise_threshold_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def get(self, *, noise_threshold_id: str) -> NoiseThreshold: + raise NotImplementedError() + + @abc.abstractmethod + def list(self, *, device_id: str) -> List[NoiseThreshold]: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + device_id: str, + noise_threshold_id: str, + ends_daily_at: Optional[str] = None, + name: Optional[str] = None, + noise_threshold_decibels: Optional[float] = None, + noise_threshold_nrs: Optional[float] = None, + starts_daily_at: Optional[str] = None + ) -> None: + raise NotImplementedError() class NoiseSensorsNoiseThresholds(AbstractNoiseSensorsNoiseThresholds): diff --git a/seam/routes/noise_sensors_simulate.py b/seam/routes/noise_sensors_simulate.py index d69e2f38..2c1a2cf3 100644 --- a/seam/routes/noise_sensors_simulate.py +++ b/seam/routes/noise_sensors_simulate.py @@ -1,6 +1,13 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractNoiseSensorsSimulate + + +class AbstractNoiseSensorsSimulate(abc.ABC): + + @abc.abstractmethod + def trigger_noise_threshold(self, *, device_id: str) -> None: + raise NotImplementedError() class NoiseSensorsSimulate(AbstractNoiseSensorsSimulate): diff --git a/seam/routes/phones.py b/seam/routes/phones.py index 7126f4d9..6b1896ac 100644 --- a/seam/routes/phones.py +++ b/seam/routes/phones.py @@ -1,7 +1,33 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractPhones, Phone -from .phones_simulate import PhonesSimulate +from ..resources import Phone +from .phones_simulate import AbstractPhonesSimulate, PhonesSimulate + + +class AbstractPhones(abc.ABC): + + @property + @abc.abstractmethod + def simulate(self) -> AbstractPhonesSimulate: + raise NotImplementedError() + + @abc.abstractmethod + def deactivate(self, *, device_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def get(self, *, device_id: str) -> Phone: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + acs_credential_id: Optional[str] = None, + owner_user_identity_id: Optional[str] = None + ) -> List[Phone]: + raise NotImplementedError() class Phones(AbstractPhones): diff --git a/seam/routes/phones_simulate.py b/seam/routes/phones_simulate.py index 9140964d..e5b3871e 100644 --- a/seam/routes/phones_simulate.py +++ b/seam/routes/phones_simulate.py @@ -1,6 +1,21 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractPhonesSimulate, Phone +from ..resources import Phone + + +class AbstractPhonesSimulate(abc.ABC): + + @abc.abstractmethod + def create_sandbox_phone( + self, + *, + user_identity_id: str, + assa_abloy_metadata: Optional[Dict[str, Any]] = None, + custom_sdk_installation_id: Optional[str] = None, + phone_metadata: Optional[Dict[str, Any]] = None + ) -> Phone: + raise NotImplementedError() class PhonesSimulate(AbstractPhonesSimulate): diff --git a/seam/routes/spaces.py b/seam/routes/spaces.py index 337a2a22..238f4aca 100644 --- a/seam/routes/spaces.py +++ b/seam/routes/spaces.py @@ -1,6 +1,100 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractSpaces, Space, Batch +from ..resources import Space, Batch + + +class AbstractSpaces(abc.ABC): + + @abc.abstractmethod + def add_acs_entrances(self, *, acs_entrance_ids: List[str], space_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def add_connected_account( + self, *, connected_account_id: str, space_id: str + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def add_devices(self, *, device_ids: List[str], space_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def create( + self, + *, + name: str, + acs_entrance_ids: Optional[List[str]] = None, + connected_account_ids: Optional[List[str]] = None, + customer_data: Optional[Dict[str, Any]] = None, + customer_key: Optional[str] = None, + device_ids: Optional[List[str]] = None, + space_key: Optional[str] = None + ) -> Space: + raise NotImplementedError() + + @abc.abstractmethod + def delete(self, *, space_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def get( + self, *, space_id: Optional[str] = None, space_key: Optional[str] = None + ) -> Space: + raise NotImplementedError() + + @abc.abstractmethod + def get_related( + self, + *, + exclude: Optional[List[str]] = None, + include: Optional[List[str]] = None, + space_ids: Optional[List[str]] = None, + space_keys: Optional[List[str]] = None + ) -> Batch: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + customer_key: Optional[str] = None, + limit: Optional[float] = None, + page_cursor: Optional[str] = None, + search: Optional[str] = None, + space_key: Optional[str] = None + ) -> List[Space]: + raise NotImplementedError() + + @abc.abstractmethod + def remove_acs_entrances( + self, *, acs_entrance_ids: List[str], space_id: str + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def remove_connected_account( + self, *, connected_account_id: str, space_id: str + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def remove_devices(self, *, device_ids: List[str], space_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + acs_entrance_ids: Optional[List[str]] = None, + customer_data: Optional[Dict[str, Any]] = None, + device_ids: Optional[List[str]] = None, + name: Optional[str] = None, + space_id: Optional[str] = None, + space_key: Optional[str] = None + ) -> Space: + raise NotImplementedError() class Spaces(AbstractSpaces): diff --git a/seam/routes/thermostats.py b/seam/routes/thermostats.py index 5e1392c6..d1eb2d1b 100644 --- a/seam/routes/thermostats.py +++ b/seam/routes/thermostats.py @@ -1,12 +1,212 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractThermostats, ActionAttempt, Device -from .thermostats_daily_programs import ThermostatsDailyPrograms -from .thermostats_schedules import ThermostatsSchedules -from .thermostats_simulate import ThermostatsSimulate +from ..resources import ActionAttempt, Device +from .thermostats_daily_programs import ( + AbstractThermostatsDailyPrograms, + ThermostatsDailyPrograms, +) +from .thermostats_schedules import AbstractThermostatsSchedules, ThermostatsSchedules +from .thermostats_simulate import AbstractThermostatsSimulate, ThermostatsSimulate from ..modules.action_attempts import resolve_action_attempt +class AbstractThermostats(abc.ABC): + + @property + @abc.abstractmethod + def daily_programs(self) -> AbstractThermostatsDailyPrograms: + raise NotImplementedError() + + @property + @abc.abstractmethod + def schedules(self) -> AbstractThermostatsSchedules: + raise NotImplementedError() + + @property + @abc.abstractmethod + def simulate(self) -> AbstractThermostatsSimulate: + raise NotImplementedError() + + @abc.abstractmethod + def activate_climate_preset( + self, + *, + climate_preset_key: str, + device_id: str, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + @abc.abstractmethod + def cool( + self, + *, + device_id: str, + cooling_set_point_celsius: Optional[float] = None, + cooling_set_point_fahrenheit: Optional[float] = None, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + @abc.abstractmethod + def create_climate_preset( + self, + *, + climate_preset_key: str, + device_id: str, + climate_preset_mode: Optional[str] = None, + cooling_set_point_celsius: Optional[float] = None, + cooling_set_point_fahrenheit: Optional[float] = None, + ecobee_metadata: Optional[Dict[str, Any]] = None, + fan_mode_setting: Optional[str] = None, + heating_set_point_celsius: Optional[float] = None, + heating_set_point_fahrenheit: Optional[float] = None, + hvac_mode_setting: Optional[str] = None, + manual_override_allowed: Optional[bool] = None, + name: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def delete_climate_preset(self, *, climate_preset_key: str, device_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def heat( + self, + *, + device_id: str, + heating_set_point_celsius: Optional[float] = None, + heating_set_point_fahrenheit: Optional[float] = None, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + @abc.abstractmethod + def heat_cool( + self, + *, + device_id: str, + cooling_set_point_celsius: Optional[float] = None, + cooling_set_point_fahrenheit: Optional[float] = None, + heating_set_point_celsius: Optional[float] = None, + heating_set_point_fahrenheit: Optional[float] = None, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + connect_webview_id: Optional[str] = None, + connected_account_id: Optional[str] = None, + connected_account_ids: Optional[List[str]] = None, + created_before: Optional[str] = None, + custom_metadata_has: Optional[Dict[str, Any]] = None, + customer_key: Optional[str] = None, + device_ids: Optional[List[str]] = None, + device_type: Optional[str] = None, + device_types: Optional[List[str]] = None, + limit: Optional[float] = None, + manufacturer: Optional[str] = None, + page_cursor: Optional[str] = None, + search: Optional[str] = None, + space_id: Optional[str] = None, + unstable_location_id: Optional[str] = None, + user_identifier_key: Optional[str] = None + ) -> List[Device]: + raise NotImplementedError() + + @abc.abstractmethod + def off( + self, + *, + device_id: str, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + @abc.abstractmethod + def set_fallback_climate_preset( + self, *, climate_preset_key: str, device_id: str + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def set_fan_mode( + self, + *, + device_id: str, + fan_mode: Optional[str] = None, + fan_mode_setting: Optional[str] = None, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + @abc.abstractmethod + def set_hvac_mode( + self, + *, + device_id: str, + hvac_mode_setting: str, + cooling_set_point_celsius: Optional[float] = None, + cooling_set_point_fahrenheit: Optional[float] = None, + heating_set_point_celsius: Optional[float] = None, + heating_set_point_fahrenheit: Optional[float] = None, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + @abc.abstractmethod + def set_temperature_threshold( + self, + *, + device_id: str, + lower_limit_celsius: Optional[float] = None, + lower_limit_fahrenheit: Optional[float] = None, + upper_limit_celsius: Optional[float] = None, + upper_limit_fahrenheit: Optional[float] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def update_climate_preset( + self, + *, + climate_preset_key: str, + device_id: str, + climate_preset_mode: Optional[str] = None, + cooling_set_point_celsius: Optional[float] = None, + cooling_set_point_fahrenheit: Optional[float] = None, + ecobee_metadata: Optional[Dict[str, Any]] = None, + fan_mode_setting: Optional[str] = None, + heating_set_point_celsius: Optional[float] = None, + heating_set_point_fahrenheit: Optional[float] = None, + hvac_mode_setting: Optional[str] = None, + manual_override_allowed: Optional[bool] = None, + name: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def update_weekly_program( + self, + *, + device_id: str, + friday_program_id: Optional[str] = None, + monday_program_id: Optional[str] = None, + saturday_program_id: Optional[str] = None, + sunday_program_id: Optional[str] = None, + thursday_program_id: Optional[str] = None, + tuesday_program_id: Optional[str] = None, + wednesday_program_id: Optional[str] = None, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + class Thermostats(AbstractThermostats): def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): self.client = client diff --git a/seam/routes/thermostats_daily_programs.py b/seam/routes/thermostats_daily_programs.py index a0985169..dbe80dda 100644 --- a/seam/routes/thermostats_daily_programs.py +++ b/seam/routes/thermostats_daily_programs.py @@ -1,14 +1,34 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import ( - AbstractThermostatsDailyPrograms, - ThermostatDailyProgram, - ActionAttempt, -) - +from ..resources import ThermostatDailyProgram, ActionAttempt from ..modules.action_attempts import resolve_action_attempt +class AbstractThermostatsDailyPrograms(abc.ABC): + + @abc.abstractmethod + def create( + self, *, device_id: str, name: str, periods: List[Dict[str, Any]] + ) -> ThermostatDailyProgram: + raise NotImplementedError() + + @abc.abstractmethod + def delete(self, *, thermostat_daily_program_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + name: str, + periods: List[Dict[str, Any]], + thermostat_daily_program_id: str, + wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + class ThermostatsDailyPrograms(AbstractThermostatsDailyPrograms): def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): self.client = client diff --git a/seam/routes/thermostats_schedules.py b/seam/routes/thermostats_schedules.py index 1632d587..e6fcb8ae 100644 --- a/seam/routes/thermostats_schedules.py +++ b/seam/routes/thermostats_schedules.py @@ -1,6 +1,52 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractThermostatsSchedules, ThermostatSchedule +from ..resources import ThermostatSchedule + + +class AbstractThermostatsSchedules(abc.ABC): + + @abc.abstractmethod + def create( + self, + *, + climate_preset_key: str, + device_id: str, + ends_at: str, + starts_at: str, + is_override_allowed: Optional[bool] = None, + max_override_period_minutes: Optional[int] = None, + name: Optional[str] = None + ) -> ThermostatSchedule: + raise NotImplementedError() + + @abc.abstractmethod + def delete(self, *, thermostat_schedule_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def get(self, *, thermostat_schedule_id: str) -> ThermostatSchedule: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, *, device_id: str, user_identifier_key: Optional[str] = None + ) -> List[ThermostatSchedule]: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + thermostat_schedule_id: str, + climate_preset_key: Optional[str] = None, + ends_at: Optional[str] = None, + is_override_allowed: Optional[bool] = None, + max_override_period_minutes: Optional[int] = None, + name: Optional[str] = None, + starts_at: Optional[str] = None + ) -> None: + raise NotImplementedError() class ThermostatsSchedules(AbstractThermostatsSchedules): diff --git a/seam/routes/thermostats_simulate.py b/seam/routes/thermostats_simulate.py index d738b3b4..b1155f9e 100644 --- a/seam/routes/thermostats_simulate.py +++ b/seam/routes/thermostats_simulate.py @@ -1,6 +1,32 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractThermostatsSimulate + + +class AbstractThermostatsSimulate(abc.ABC): + + @abc.abstractmethod + def hvac_mode_adjusted( + self, + *, + device_id: str, + hvac_mode: str, + cooling_set_point_celsius: Optional[float] = None, + cooling_set_point_fahrenheit: Optional[float] = None, + heating_set_point_celsius: Optional[float] = None, + heating_set_point_fahrenheit: Optional[float] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def temperature_reached( + self, + *, + device_id: str, + temperature_celsius: Optional[float] = None, + temperature_fahrenheit: Optional[float] = None + ) -> None: + raise NotImplementedError() class ThermostatsSimulate(AbstractThermostatsSimulate): diff --git a/seam/routes/user_identities.py b/seam/routes/user_identities.py index fb138dbe..d906c607 100644 --- a/seam/routes/user_identities.py +++ b/seam/routes/user_identities.py @@ -1,7 +1,7 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import ( - AbstractUserIdentities, +from ..resources import ( UserIdentity, InstantKey, Device, @@ -9,7 +9,116 @@ AcsSystem, AcsUser, ) -from .user_identities_unmanaged import UserIdentitiesUnmanaged +from .user_identities_unmanaged import ( + AbstractUserIdentitiesUnmanaged, + UserIdentitiesUnmanaged, +) + + +class AbstractUserIdentities(abc.ABC): + + @property + @abc.abstractmethod + def unmanaged(self) -> AbstractUserIdentitiesUnmanaged: + raise NotImplementedError() + + @abc.abstractmethod + def add_acs_user( + self, + *, + acs_user_id: str, + user_identity_id: Optional[str] = None, + user_identity_key: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def create( + self, + *, + acs_system_ids: Optional[List[str]] = None, + email_address: Optional[str] = None, + full_name: Optional[str] = None, + phone_number: Optional[str] = None, + user_identity_key: Optional[str] = None + ) -> UserIdentity: + raise NotImplementedError() + + @abc.abstractmethod + def delete(self, *, user_identity_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def generate_instant_key( + self, + *, + user_identity_id: str, + customization_profile_id: Optional[str] = None, + max_use_count: Optional[float] = None + ) -> InstantKey: + raise NotImplementedError() + + @abc.abstractmethod + def get( + self, + *, + user_identity_id: Optional[str] = None, + user_identity_key: Optional[str] = None + ) -> UserIdentity: + raise NotImplementedError() + + @abc.abstractmethod + def grant_access_to_device(self, *, device_id: str, user_identity_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + created_before: Optional[str] = None, + credential_manager_acs_system_id: Optional[str] = None, + limit: Optional[int] = None, + page_cursor: Optional[str] = None, + search: Optional[str] = None, + user_identity_ids: Optional[List[str]] = None + ) -> List[UserIdentity]: + raise NotImplementedError() + + @abc.abstractmethod + def list_accessible_devices(self, *, user_identity_id: str) -> List[Device]: + raise NotImplementedError() + + @abc.abstractmethod + def list_accessible_entrances(self, *, user_identity_id: str) -> List[AcsEntrance]: + raise NotImplementedError() + + @abc.abstractmethod + def list_acs_systems(self, *, user_identity_id: str) -> List[AcsSystem]: + raise NotImplementedError() + + @abc.abstractmethod + def list_acs_users(self, *, user_identity_id: str) -> List[AcsUser]: + raise NotImplementedError() + + @abc.abstractmethod + def remove_acs_user(self, *, acs_user_id: str, user_identity_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def revoke_access_to_device(self, *, device_id: str, user_identity_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + user_identity_id: str, + email_address: Optional[str] = None, + full_name: Optional[str] = None, + phone_number: Optional[str] = None, + user_identity_key: Optional[str] = None + ) -> None: + raise NotImplementedError() class UserIdentities(AbstractUserIdentities): diff --git a/seam/routes/user_identities_unmanaged.py b/seam/routes/user_identities_unmanaged.py index 70b503b8..ab881443 100644 --- a/seam/routes/user_identities_unmanaged.py +++ b/seam/routes/user_identities_unmanaged.py @@ -1,6 +1,34 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractUserIdentitiesUnmanaged + + +class AbstractUserIdentitiesUnmanaged(abc.ABC): + + @abc.abstractmethod + def get(self, *, user_identity_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + *, + created_before: Optional[str] = None, + limit: Optional[int] = None, + page_cursor: Optional[str] = None, + search: Optional[str] = None + ) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + is_managed: bool, + user_identity_id: str, + user_identity_key: Optional[str] = None + ) -> None: + raise NotImplementedError() class UserIdentitiesUnmanaged(AbstractUserIdentitiesUnmanaged): diff --git a/seam/routes/webhooks.py b/seam/routes/webhooks.py index 3de62fe9..4d11effa 100644 --- a/seam/routes/webhooks.py +++ b/seam/routes/webhooks.py @@ -1,6 +1,32 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractWebhooks, Webhook +from ..resources import Webhook + + +class AbstractWebhooks(abc.ABC): + + @abc.abstractmethod + def create(self, *, url: str, event_types: Optional[List[str]] = None) -> Webhook: + raise NotImplementedError() + + @abc.abstractmethod + def delete(self, *, webhook_id: str) -> None: + raise NotImplementedError() + + @abc.abstractmethod + def get(self, *, webhook_id: str) -> Webhook: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + ) -> List[Webhook]: + raise NotImplementedError() + + @abc.abstractmethod + def update(self, *, event_types: List[str], webhook_id: str) -> None: + raise NotImplementedError() class Webhooks(AbstractWebhooks): diff --git a/seam/routes/workspaces.py b/seam/routes/workspaces.py index c622a14a..75ecded4 100644 --- a/seam/routes/workspaces.py +++ b/seam/routes/workspaces.py @@ -1,10 +1,61 @@ from typing import Optional, Any, List, Dict, Union +import abc from ..client import SeamHttpClient -from .models import AbstractWorkspaces, Workspace, ActionAttempt - +from ..resources import Workspace, ActionAttempt from ..modules.action_attempts import resolve_action_attempt +class AbstractWorkspaces(abc.ABC): + + @abc.abstractmethod + def create( + self, + *, + name: str, + company_name: Optional[str] = None, + connect_partner_name: Optional[str] = None, + connect_webview_customization: Optional[Dict[str, Any]] = None, + is_sandbox: Optional[bool] = None, + organization_id: Optional[str] = None, + webview_logo_shape: Optional[str] = None, + webview_primary_button_color: Optional[str] = None, + webview_primary_button_text_color: Optional[str] = None, + webview_success_message: Optional[str] = None + ) -> Workspace: + raise NotImplementedError() + + @abc.abstractmethod + def get( + self, + ) -> Workspace: + raise NotImplementedError() + + @abc.abstractmethod + def list( + self, + ) -> List[Workspace]: + raise NotImplementedError() + + @abc.abstractmethod + def reset_sandbox( + self, wait_for_action_attempt: Optional[Union[bool, Dict[str, float]]] = None + ) -> ActionAttempt: + raise NotImplementedError() + + @abc.abstractmethod + def update( + self, + *, + connect_partner_name: Optional[str] = None, + connect_webview_customization: Optional[Dict[str, Any]] = None, + is_publishable_key_auth_enabled: Optional[bool] = None, + is_suspended: Optional[bool] = None, + name: Optional[str] = None, + organization_id: Optional[str] = None + ) -> None: + raise NotImplementedError() + + class Workspaces(AbstractWorkspaces): def __init__(self, client: SeamHttpClient, defaults: Dict[str, Any]): self.client = client diff --git a/seam/seam_webhook.py b/seam/seam_webhook.py index 2fb64619..2a56c631 100644 --- a/seam/seam_webhook.py +++ b/seam/seam_webhook.py @@ -1,6 +1,6 @@ from typing import Dict from svix.webhooks import Webhook -from .routes.models import SeamEvent +from .resources import SeamEvent class SeamWebhook: