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 +52 -0
- clockster/_client.py +96 -0
- clockster/_generated/__init__.py +1 -0
- clockster/_generated/api.py +2420 -0
- clockster/_generated/models.py +1489 -0
- clockster/_transport.py +221 -0
- clockster/errors.py +85 -0
- clockster/models.py +12 -0
- clockster/pagination.py +76 -0
- clockster/py.typed +0 -0
- clockster/webhooks.py +116 -0
- clockster-0.1.0.dist-info/METADATA +239 -0
- clockster-0.1.0.dist-info/RECORD +15 -0
- clockster-0.1.0.dist-info/WHEEL +4 -0
- clockster-0.1.0.dist-info/licenses/LICENSE +21 -0
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."""
|