Skip to content

Commit 9015b25

Browse files
Copilotrnovatorov
andcommitted
Implement Sites API client with CRUD operations
Co-authored-by: rnovatorov <20299819+rnovatorov@users.noreply.github.com>
1 parent b76d8fd commit 9015b25

File tree

5 files changed

+99
-3
lines changed

5 files changed

+99
-3
lines changed

src/enapter/http/api/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
from .config import Config
33
from .errors import Error, MultiError, check_error
44

5-
from . import devices # isort: skip
5+
from . import devices, sites # isort: skip
66

7-
__all__ = ["Client", "Config", "devices", "Error", "MultiError", "check_error"]
7+
__all__ = ["Client", "Config", "devices", "sites", "Error", "MultiError", "check_error"]

src/enapter/http/api/client.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import httpx
44

5-
from enapter.http.api import devices
5+
from enapter.http.api import devices, sites
66

77
from .config import Config
88

@@ -33,3 +33,7 @@ async def __aexit__(self, *exc) -> None:
3333
@property
3434
def devices(self) -> devices.Client:
3535
return devices.Client(client=self._client)
36+
37+
@property
38+
def sites(self) -> sites.Client:
39+
return sites.Client(client=self._client)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from .client import Client
2+
from .site import Site
3+
4+
__all__ = [
5+
"Client",
6+
"Site",
7+
]
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from typing import AsyncGenerator
2+
3+
import httpx
4+
5+
from enapter import async_
6+
from enapter.http import api
7+
8+
from .site import Site
9+
10+
11+
class Client:
12+
13+
def __init__(self, client: httpx.AsyncClient) -> None:
14+
self._client = client
15+
16+
async def create(self, name: str) -> Site:
17+
url = "v3/sites"
18+
response = await self._client.post(url, json={"name": name})
19+
api.check_error(response)
20+
return Site.from_dto(response.json()["site"])
21+
22+
async def get(self, site_id: str) -> Site:
23+
url = f"v3/sites/{site_id}"
24+
response = await self._client.get(url)
25+
api.check_error(response)
26+
return Site.from_dto(response.json()["site"])
27+
28+
@async_.generator
29+
async def list(self) -> AsyncGenerator[Site, None]:
30+
url = "v3/sites"
31+
limit = 50
32+
offset = 0
33+
while True:
34+
response = await self._client.get(
35+
url, params={"limit": limit, "offset": offset}
36+
)
37+
api.check_error(response)
38+
payload = response.json()
39+
if not payload["sites"]:
40+
return
41+
for dto in payload["sites"]:
42+
yield Site.from_dto(dto)
43+
offset += limit
44+
45+
async def update(self, site_id: str, name: str | None = None) -> Site:
46+
if name is None:
47+
return await self.get(site_id)
48+
url = f"v3/sites/{site_id}"
49+
response = await self._client.patch(url, json={"name": name})
50+
api.check_error(response)
51+
return Site.from_dto(response.json()["site"])
52+
53+
async def delete(self, site_id: str) -> None:
54+
url = f"v3/sites/{site_id}"
55+
response = await self._client.delete(url)
56+
api.check_error(response)

src/enapter/http/api/sites/site.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import dataclasses
2+
import datetime
3+
from typing import Any, Self
4+
5+
6+
@dataclasses.dataclass
7+
class Site:
8+
9+
id: str
10+
name: str
11+
created_at: datetime.datetime
12+
updated_at: datetime.datetime
13+
14+
@classmethod
15+
def from_dto(cls, dto: dict[str, Any]) -> Self:
16+
return cls(
17+
id=dto["id"],
18+
name=dto["name"],
19+
created_at=datetime.datetime.fromisoformat(dto["created_at"]),
20+
updated_at=datetime.datetime.fromisoformat(dto["updated_at"]),
21+
)
22+
23+
def to_dto(self) -> dict[str, Any]:
24+
return {
25+
"id": self.id,
26+
"name": self.name,
27+
"created_at": self.created_at.isoformat(),
28+
"updated_at": self.updated_at.isoformat(),
29+
}

0 commit comments

Comments
 (0)