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

Commit f443d39

Browse files
author
Tristan Brewster
committed
fix #33: Implement event.list() and Event
- `events.py`: - Introduced the `Events` class which inherits from the new `AbstractEvents` abstract class. - As the Seam API does, this only implements a `list()` method. See the file for information about parameters, errors, and return types. - `seam.py`: - Added the `Events` class and `events` object to the main API. - `types.py`: - Added the `Event` dataclass based on the definition from the Seam API. - Added an `AbstractEvents` class - `test_events.py` - New test file which checks all events since 2021 and asserts that the `event_type` == `device.connected`
1 parent 8db1c04 commit f443d39

File tree

4 files changed

+129
-0
lines changed

4 files changed

+129
-0
lines changed

seamapi/events.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
from seamapi.types import (
2+
Event,
3+
AbstractEvents,
4+
AbstractSeam as Seam,
5+
)
6+
from typing import List, Optional
7+
import requests
8+
9+
10+
class Events(AbstractEvents):
11+
"""
12+
A class to interact with events through the Seam API
13+
14+
...
15+
16+
Attributes
17+
----------
18+
seam : Seam
19+
Initial seam class
20+
21+
Methods
22+
-------
23+
list(since, device_id=None, device_ids=None, event_type=None, event_types=None)
24+
Gets a list of events
25+
"""
26+
27+
seam: Seam
28+
29+
def __init__(self, seam: Seam):
30+
"""
31+
Parameters
32+
----------
33+
seam : Seam
34+
Intial seam class
35+
"""
36+
self.seam = seam
37+
38+
def list(
39+
self,
40+
since: str,
41+
device_id: Optional[str] = None,
42+
device_ids: Optional[list] = None,
43+
event_type: Optional[str] = None,
44+
event_types: Optional[list] = None
45+
) -> List[Event]:
46+
"""Gets a list of events.
47+
48+
Parameters
49+
----------
50+
since : str
51+
ISO 8601 timestamp of the earliest event to return
52+
device_id : Optional[str]
53+
Device ID to filter events by
54+
device_ids : Optional[list]
55+
Device IDs to filter events by
56+
event_type : Optional[str]
57+
Event type to filter events by
58+
event_types : Optional[list]
59+
Event types to filter events by
60+
61+
Raises
62+
------
63+
Exception
64+
If the API request wasn't successful.
65+
66+
Returns
67+
------
68+
A list of events.
69+
"""
70+
if not since:
71+
raise Exception("'since' is required")
72+
73+
params = {
74+
"since": since,
75+
}
76+
77+
arguments = {
78+
"device_id": device_id,
79+
"device_ids": device_ids,
80+
"event_type": event_type,
81+
"event_types": event_types
82+
}
83+
84+
for name in arguments:
85+
if arguments[name]:
86+
params.update({name: arguments[name]})
87+
88+
res = requests.get(
89+
f"{self.seam.api_url}/events/list",
90+
params=params,
91+
headers={"Authorization": f"Bearer {self.seam.api_key}"},
92+
)
93+
if not res.ok:
94+
raise Exception(res.text)
95+
96+
events = res.json()["events"]
97+
return events

seamapi/seam.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from typing import Optional, cast
33
from .workspaces import Workspaces
44
from .devices import Devices
5+
from .events import Events
56
from .connected_accounts import ConnectedAccounts
67
from .connect_webviews import ConnectWebviews
78
from .locks import Locks
@@ -30,6 +31,8 @@ class Seam(AbstractSeam):
3031
Connect webviews class
3132
devices : Devices
3233
Devices class
34+
events : Events
35+
Events class
3336
locks : Locks
3437
Locks class
3538
access_codes : AccessCodes
@@ -69,6 +72,7 @@ def __init__(
6972
self.connected_accounts = ConnectedAccounts(seam=self)
7073
self.connect_webviews = ConnectWebviews(seam=self)
7174
self.devices = Devices(seam=self)
75+
self.events = Events(seam=self)
7276
self.locks = Locks(seam=self)
7377
self.access_codes = AccessCodes(seam=self)
7478
self.action_attempts = ActionAttempts(seam=self)

seamapi/types.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,19 @@ def from_dict(d: Dict[str, Any]):
5353
errors=d["errors"],
5454
)
5555

56+
@dataclass
57+
class Event:
58+
event_id: str
59+
noiseaware_id: str
60+
activity_zone_id: str
61+
event_class: Union[str, None]
62+
event_type: Union[str, None]
63+
duration: Union[int, None]
64+
local_end_time: Union[str, None]
65+
local_start_time: Union[str, None]
66+
start_time: Union[str, None]
67+
end_time: Union[str, None]
68+
created_at: Union[str, None]
5669

5770
@dataclass_json
5871
@dataclass
@@ -197,6 +210,10 @@ def get(
197210
) -> Device:
198211
raise NotImplementedError
199212

213+
class AbstractEvents(abc.ABC):
214+
@abc.abstractmethod
215+
def list(self) -> List[Event]:
216+
raise NotImplementedError
200217

201218
class AbstractWorkspaces(abc.ABC):
202219
@abc.abstractmethod

tests/events/test_events.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from seamapi import Seam
2+
from tests.fixtures.run_august_factory import run_august_factory
3+
4+
SINCE="2021-01-01T00:00:00.000Z"
5+
EVENT_TYPE = "device.connected"
6+
7+
def test_events(seam: Seam):
8+
run_august_factory(seam)
9+
10+
events = seam.events.list(since=SINCE)
11+
assert events[0]['event_type'] == EVENT_TYPE

0 commit comments

Comments
 (0)