clockster 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
clockster/__init__.py ADDED
@@ -0,0 +1,52 @@
1
+ """Official Python SDK for the Clockster Company API.
2
+
3
+ from clockster import Clockster
4
+
5
+ clockster = Clockster(token=os.environ["CLOCKSTER_TOKEN"])
6
+ users = clockster.users.list(per_page=100, include=["location"])
7
+
8
+ Typed from https://api.clockster.com/openapi/v3.json. The answer is the parsed body, nothing is
9
+ validated on the way in, and a refusal is raised as a `ClocksterError`.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from importlib.metadata import PackageNotFoundError, version
15
+
16
+ from ._client import AsyncClockster, Clockster
17
+ from ._transport import DEFAULT_BASE_URL
18
+ from .errors import (
19
+ AuthenticationError,
20
+ ClocksterError,
21
+ ConflictError,
22
+ ForbiddenError,
23
+ NotFoundError,
24
+ RateLimitError,
25
+ ServerError,
26
+ ValidationError,
27
+ )
28
+ from .pagination import paginate, paginate_async
29
+ from .webhooks import WebhookVerificationError, verify_webhook
30
+
31
+ __all__ = [
32
+ "DEFAULT_BASE_URL",
33
+ "AsyncClockster",
34
+ "AuthenticationError",
35
+ "Clockster",
36
+ "ClocksterError",
37
+ "ConflictError",
38
+ "ForbiddenError",
39
+ "NotFoundError",
40
+ "RateLimitError",
41
+ "ServerError",
42
+ "ValidationError",
43
+ "WebhookVerificationError",
44
+ "paginate",
45
+ "paginate_async",
46
+ "verify_webhook",
47
+ ]
48
+
49
+ try:
50
+ __version__ = version("clockster")
51
+ except PackageNotFoundError: # pragma: no cover - a source tree nobody installed
52
+ __version__ = "0.0.0"
clockster/_client.py ADDED
@@ -0,0 +1,96 @@
1
+ """The client a caller constructs. Everything below the constructor is generated."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from types import TracebackType
6
+
7
+ import httpx
8
+
9
+ from ._generated.api import _AsyncClocksterApi, _ClocksterApi
10
+ from ._transport import DEFAULT_BASE_URL, DEFAULT_TIMEOUT, _AsyncTransport, _SyncTransport
11
+
12
+
13
+ class Clockster(_ClocksterApi):
14
+ """The Company API, one token to one company.
15
+
16
+ The key is issued in the web application, under Settings, API.
17
+
18
+ clockster = Clockster(token=os.environ["CLOCKSTER_TOKEN"])
19
+ me = clockster.me()
20
+ users = clockster.users.list(per_page=100, include=["location"])
21
+
22
+ Every method answers the parsed body — `users["data"]` is the rows — and raises
23
+ `ClocksterError` on a refusal. Deliveries are verified with `verify_webhook`.
24
+ """
25
+
26
+ def __init__(
27
+ self,
28
+ token: str,
29
+ *,
30
+ base_url: str = DEFAULT_BASE_URL,
31
+ timeout: float = DEFAULT_TIMEOUT,
32
+ client: httpx.Client | None = None,
33
+ ) -> None:
34
+ """
35
+ :param token: the company API key.
36
+ :param base_url: point at a demo stand instead of production.
37
+ :param timeout: seconds, applied to each request.
38
+ :param client: your own httpx client — a proxy, a retrying transport, a recording one.
39
+ Supplying one leaves closing it to you.
40
+ """
41
+ self._sync_transport = _SyncTransport(
42
+ token, base_url=base_url, timeout=timeout, client=client
43
+ )
44
+
45
+ super().__init__(self._sync_transport)
46
+
47
+ def close(self) -> None:
48
+ """Close the connection pool, unless the httpx client came from outside."""
49
+ self._sync_transport.close()
50
+
51
+ def __enter__(self) -> Clockster:
52
+ return self
53
+
54
+ def __exit__(
55
+ self,
56
+ exc_type: type[BaseException] | None,
57
+ exc: BaseException | None,
58
+ traceback: TracebackType | None,
59
+ ) -> None:
60
+ self.close()
61
+
62
+
63
+ class AsyncClockster(_AsyncClocksterApi):
64
+ """The same API, awaited.
65
+
66
+ async with AsyncClockster(token=...) as clockster:
67
+ users = await clockster.users.list(per_page=100)
68
+ """
69
+
70
+ def __init__(
71
+ self,
72
+ token: str,
73
+ *,
74
+ base_url: str = DEFAULT_BASE_URL,
75
+ timeout: float = DEFAULT_TIMEOUT,
76
+ client: httpx.AsyncClient | None = None,
77
+ ) -> None:
78
+ self._async_transport = _AsyncTransport(
79
+ token, base_url=base_url, timeout=timeout, client=client
80
+ )
81
+
82
+ super().__init__(self._async_transport)
83
+
84
+ async def aclose(self) -> None:
85
+ await self._async_transport.aclose()
86
+
87
+ async def __aenter__(self) -> AsyncClockster:
88
+ return self
89
+
90
+ async def __aexit__(
91
+ self,
92
+ exc_type: type[BaseException] | None,
93
+ exc: BaseException | None,
94
+ traceback: TracebackType | None,
95
+ ) -> None:
96
+ await self.aclose()
@@ -0,0 +1 @@
1
+ """Generated from the specification; do not edit by hand."""