Skip to content
This repository was archived by the owner on Jun 28, 2024. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 182 additions & 0 deletions seamapi/access_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from seamapi.types import (
WaitForAccessCodeFailedException,
AbstractAccessCodes,
AbstractUnmanagedAccessCodes,
AccessCode,
AccessCodeId,
ActionAttempt,
Expand All @@ -15,6 +16,186 @@
from seamapi.utils.convert_to_id import to_access_code_id, to_device_id
from seamapi.utils.report_error import report_error

class UnmanagedAccessCodes(AbstractUnmanagedAccessCodes):
"""
A class used to retreive unmanaged access code data
through interaction with Seam API

...

Attributes
----------
seam : Seam
Initial seam class

Methods
-------
list(device)
Gets a list of unmanaged access codes for a device
get(access_code=None, device=None)
Gets a certain unmanaged access code of a device
delete(access_code, device=None)
Deletes an unmanaged access code on a device
update(access_code)
Updates an unmanaged access code to convert it to managed
"""

seam: Seam

def __init__(self, seam: Seam):
"""
Parameters
----------
seam : Seam
Intial seam class
"""

self.seam = seam

@report_error
def list(self, device: Union[DeviceId, Device]) -> List[AccessCode]:
"""Gets a list of unmanaged access codes for a device.

Parameters
----------
device : DeviceId or Device
Device id or Device to list unmanaged access codes for

Raises
------
Exception
If the API request wasn't successful.

Returns
------
A list of unmanaged access codes for a device.
"""

device_id = to_device_id(device)
res = self.seam.make_request(
"GET",
"/access_codes/unmanaged/list",
params={"device_id": device_id},
)
access_codes = res["access_codes"]

return [AccessCode.from_dict(ac) for ac in access_codes]

@report_error
def get(
self,
access_code: Optional[Union[AccessCodeId, AccessCode]] = None,
device: Optional[Union[DeviceId, AccessCode]] = None,
code: Optional[str] = None,
) -> AccessCode:
"""Gets a certain unmanaged access code for a device.

Parameters
----------
access_code : AccessCodeId or AccessCode, optional
Access code id or AccessCode to get latest version of
device : DeviceId or Device, optional
Device id or Device to get an unmanaged access code for

Raises
------
Exception
If the API request wasn't successful.

Returns
------
AccessCode
"""

params = {}
if access_code:
params["access_code_id"] = to_access_code_id(access_code)
if device:
params["device_id"] = to_device_id(device)
if code:
params["code"] = code

res = self.seam.make_request(
"GET",
"/access_codes/unmanaged/get",
params=params,
)

return AccessCode.from_dict(res["access_code"])

@report_error
def update(
self,
access_code: Union[AccessCodeId, AccessCode],
is_managed: bool = True,
) -> None:
"""Updates an unmanaged access code on a device to convert it to managed.

Parameters
----------
access_code: AccessCodeId or AccessCode
Access code id or Access code to update
is_managed : bool, optional
Whether to convert to managed

Raises
------
Exception
If the API request wasn't successful.

Returns
------
None
"""

access_code_id = to_access_code_id(access_code)
update_payload = {"access_code_id": access_code_id}
update_payload["is_managed"] = is_managed

res = self.seam.make_request(
"POST",
"/access_codes/unmanaged/update",
json=update_payload,
)

@report_error
def delete(
self,
access_code: Union[AccessCodeId, AccessCode],
) -> ActionAttempt:
"""Deletes an unmanaged access code on a device.

Parameters
----------
access_code : AccessCodeId or AccessCode
Access code id or AccessCode to delete it

Raises
------
Exception
If the API request wasn't successful.
Exception
If action attempt failed.

Returns
------
ActionAttempt
"""

access_code_id = to_access_code_id(access_code)
create_payload = {"access_code_id": access_code_id}

res = self.seam.make_request(
"DELETE",
"/access_codes/unmanaged/delete",
json=create_payload,
)

action_attempt = self.seam.action_attempts.poll_until_ready(
res["action_attempt"]["action_attempt_id"]
)

return action_attempt

class AccessCodes(AbstractAccessCodes):
"""
Expand Down Expand Up @@ -51,6 +232,7 @@ def __init__(self, seam: Seam):
"""

self.seam = seam
self.unmanaged = UnmanagedAccessCodes(seam=seam)

@report_error
def list(self, device: Union[DeviceId, Device]) -> List[AccessCode]:
Expand Down
30 changes: 30 additions & 0 deletions seamapi/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,38 @@ def lock_door(self, device: Union[DeviceId, Device]) -> ActionAttempt:
def unlock_door(self, device: Union[DeviceId, Device]) -> ActionAttempt:
raise NotImplementedError

class AbstractUnmanagedAccessCodes(abc.ABC):
@abc.abstractmethod
def list(self, device: Union[DeviceId, Device]) -> List[AccessCode]:
raise NotImplementedError

@abc.abstractmethod
def get(
self,
access_code: Union[AccessCodeId, AccessCode],
device: Optional[Union[DeviceId, Device]] = None,
code: Optional[str] = None,
) -> AccessCode:
raise NotImplementedError

@abc.abstractmethod
def update(
self,
access_code: Union[AccessCodeId, AccessCode],
is_managed: bool = True,
) -> None:
raise NotImplementedError

@abc.abstractmethod
def delete(
self,
access_code: Union[AccessCodeId, AccessCode],
) -> ActionAttempt:
raise NotImplementedError

class AbstractAccessCodes(abc.ABC):
unmanaged: AbstractUnmanagedAccessCodes

@abc.abstractmethod
def list(self, device: Union[DeviceId, Device]) -> List[AccessCode]:
raise NotImplementedError
Expand Down
17 changes: 17 additions & 0 deletions tests/access_codes/test_access_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,23 @@ def test_access_codes(seam: Seam):
assert len(all_devices) > 1
assert len(set([ac.common_code_key for ac in access_codes])) == 1

def test_unmanaged_access_codes(seam: Seam):
run_august_factory(seam)

all_devices = seam.devices.list()
some_device = all_devices[0]

unmanaged_access_codes = seam.access_codes.unmanaged.list(some_device.device_id)
assert len(unmanaged_access_codes) == 1

unmanaged_access_code = seam.access_codes.unmanaged.get(created_access_code.access_code_id)
assert unmanaged_access_code.code == "4444"

delete_action_attempt = seam.access_codes.unmanaged.delete(created_access_code)
assert delete_action_attempt.status == "success"

unmanaged_access_codes = seam.access_codes.unmanaged.list(some_device.device_id)
assert len(unmanaged_access_codes) == 0

def test_access_codes_create_wait_for_code(seam: Seam):
run_august_factory(seam)
Expand Down