Skip to content
This repository was archived by the owner on Jun 28, 2024. It is now read-only.

Commit fb7ba4d

Browse files
Add access_code_ids param to access_codes.list and type param to access_codes.update (#113)
1 parent b0919df commit fb7ba4d

File tree

3 files changed

+68
-20
lines changed

3 files changed

+68
-20
lines changed

seamapi/access_codes.py

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,21 @@ def __init__(self, seam: Seam):
5353
self.seam = seam
5454

5555
@report_error
56-
def list(self, device: Union[DeviceId, Device]) -> List[AccessCode]:
56+
def list(
57+
self,
58+
device: Optional[Union[DeviceId, Device]] = None,
59+
access_codes: Optional[
60+
Union[List[AccessCode], List[AccessCodeId]]
61+
] = None,
62+
) -> List[AccessCode]:
5763
"""Gets a list of access codes for a device.
5864
5965
Parameters
6066
----------
61-
device : DeviceId or Device
67+
device : Union[DeviceId, Device], optional
6268
Device id or Device to list access codes for
69+
access_codes : Union[List[AccessCode], List[AccessCodeId]], optional
70+
Access Code IDs or Access Codes to filter access_codes by
6371
6472
Raises
6573
------
@@ -71,15 +79,22 @@ def list(self, device: Union[DeviceId, Device]) -> List[AccessCode]:
7179
A list of access codes for a device.
7280
"""
7381

74-
device_id = to_device_id(device)
82+
params = {}
83+
if device:
84+
params["device_id"] = to_device_id(device)
85+
if access_codes:
86+
params["access_code_ids"] = [
87+
to_access_code_id(ac) for ac in access_codes
88+
]
89+
7590
res = self.seam.make_request(
7691
"GET",
7792
"/access_codes/list",
78-
params={"device_id": device_id},
93+
params=params,
7994
)
80-
access_codes = res["access_codes"]
95+
res_access_codes = res["access_codes"]
8196

82-
return [AccessCode.from_dict(ac) for ac in access_codes]
97+
return [AccessCode.from_dict(ac) for ac in res_access_codes]
8398

8499
@report_error
85100
def get(
@@ -180,13 +195,19 @@ def create(
180195
if common_code_key is not None:
181196
create_payload["common_code_key"] = common_code_key
182197
if attempt_for_offline_device is not None:
183-
create_payload["attempt_for_offline_device"] = attempt_for_offline_device
198+
create_payload[
199+
"attempt_for_offline_device"
200+
] = attempt_for_offline_device
184201

185-
if (wait_for_code
202+
if (
203+
wait_for_code
186204
and starts_at is not None
187-
and datetime.fromisoformat(starts_at) > datetime.now() + timedelta(seconds=5)
205+
and datetime.fromisoformat(starts_at)
206+
> datetime.now() + timedelta(seconds=5)
188207
):
189-
raise RuntimeError("Cannot use wait_for_code with a future time bound code")
208+
raise RuntimeError(
209+
"Cannot use wait_for_code with a future time bound code"
210+
)
190211

191212
res = self.seam.make_request(
192213
"POST",
@@ -199,25 +220,25 @@ def create(
199220
duration = 0
200221
poll_interval = 0.25
201222
if wait_for_code:
202-
while (access_code.code is None):
203-
if (access_code.status == "unknown"):
223+
while access_code.code is None:
224+
if access_code.status == "unknown":
204225
raise WaitForAccessCodeFailedException(
205226
"Access code status returned unknown",
206-
access_code_id=access_code.access_code_id
227+
access_code_id=access_code.access_code_id,
207228
)
208-
if (len(access_code.errors) > 0):
229+
if len(access_code.errors) > 0:
209230
raise WaitForAccessCodeFailedException(
210231
"Access code returned errors",
211232
access_code_id=access_code.access_code_id,
212-
errors=access_code.errors
233+
errors=access_code.errors,
213234
)
214235
time.sleep(poll_interval)
215236
duration += poll_interval
216-
if (duration > timeout):
237+
if duration > timeout:
217238
raise WaitForAccessCodeFailedException(
218239
f"Gave up after waiting the maximum timeout of {timeout} seconds",
219240
access_code_id=access_code.access_code_id,
220-
errors=access_code.errors
241+
errors=access_code.errors,
221242
)
222243

223244
access_code = access_codes.get(access_code)
@@ -294,6 +315,7 @@ def update(
294315
code: Optional[str] = None,
295316
starts_at: Optional[str] = None,
296317
ends_at: Optional[str] = None,
318+
type: Optional[str] = None,
297319
) -> AccessCode:
298320
"""Updates an access code on a device.
299321
@@ -311,6 +333,8 @@ def update(
311333
Time when access code becomes effective
312334
ends_at : str, optional
313335
Time when access code ceases to be effective
336+
type : str, optional
337+
Access code type eg. ongoing or time_bound
314338
315339
Raises
316340
------
@@ -334,6 +358,8 @@ def update(
334358
update_payload["starts_at"] = starts_at
335359
if ends_at is not None:
336360
update_payload["ends_at"] = ends_at
361+
if type is not None:
362+
update_payload["type"] = type
337363

338364
res = self.seam.make_request(
339365
"POST",

seamapi/types.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,13 @@ def unlock_door(self, device: Union[DeviceId, Device]) -> ActionAttempt:
293293

294294
class AbstractAccessCodes(abc.ABC):
295295
@abc.abstractmethod
296-
def list(self, device: Union[DeviceId, Device]) -> List[AccessCode]:
296+
def list(
297+
self,
298+
device: Optional[Union[DeviceId, Device]] = None,
299+
access_codes: Optional[
300+
Union[List[AccessCode], List[AccessCodeId]]
301+
] = None,
302+
) -> List[AccessCode]:
297303
raise NotImplementedError
298304

299305
@abc.abstractmethod
@@ -336,7 +342,7 @@ def update(
336342
code: Optional[str] = None,
337343
starts_at: Optional[str] = None,
338344
ends_at: Optional[str] = None,
339-
status: Optional[str] = None,
345+
type: Optional[str] = None,
340346
) -> AccessCode:
341347
raise NotImplementedError
342348

tests/access_codes/test_access_codes.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,34 @@ def test_access_codes(seam: Seam):
1616
assert created_access_code.name == "Test code"
1717
assert created_access_code.status == "setting"
1818

19+
seam.access_codes.create(some_device.device_id, "Test code 2", "5555")
20+
1921
access_codes = seam.access_codes.list(some_device.device_id)
22+
assert len(access_codes) == 2
23+
access_codes = seam.access_codes.list(
24+
some_device, access_codes=[created_access_code]
25+
)
2026
assert len(access_codes) == 1
2127

2228
access_code = seam.access_codes.get(created_access_code.access_code_id)
2329
assert access_code.code == "4444"
2430

2531
with pytest.raises(SeamAPIException):
26-
seam.access_codes.create(some_device.device_id, "Duplicate Access Code", "4444")
32+
seam.access_codes.create(
33+
some_device.device_id, "Duplicate Access Code", "4444"
34+
)
2735

2836
access_code = seam.access_codes.update(access_code, name="Updated name")
2937
assert access_code.name == "Updated name"
3038

39+
access_code = seam.access_codes.update(
40+
access_code,
41+
type="time_bound",
42+
starts_at="3001-01-01",
43+
ends_at="3001-01-03",
44+
)
45+
assert access_code.type == "time_bound"
46+
3147
delete_action_attempt = seam.access_codes.delete(created_access_code)
3248
assert delete_action_attempt.status == "success"
3349

0 commit comments

Comments
 (0)