schedule-bit 0.1.0__tar.gz
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.
- schedule_bit-0.1.0/.gitignore +7 -0
- schedule_bit-0.1.0/CHANGELOG.md +19 -0
- schedule_bit-0.1.0/LICENSE +21 -0
- schedule_bit-0.1.0/PKG-INFO +119 -0
- schedule_bit-0.1.0/README.md +91 -0
- schedule_bit-0.1.0/pyproject.toml +81 -0
- schedule_bit-0.1.0/src/schedule_bit/__init__.py +57 -0
- schedule_bit-0.1.0/src/schedule_bit/_client.py +444 -0
- schedule_bit-0.1.0/src/schedule_bit/_generated/__init__.py +2 -0
- schedule_bit-0.1.0/src/schedule_bit/_generated/models.py +2218 -0
- schedule_bit-0.1.0/src/schedule_bit/_generated/operations.py +588 -0
- schedule_bit-0.1.0/src/schedule_bit/_options.py +26 -0
- schedule_bit-0.1.0/src/schedule_bit/_redact.py +40 -0
- schedule_bit-0.1.0/src/schedule_bit/_version.py +1 -0
- schedule_bit-0.1.0/src/schedule_bit/_wire.py +46 -0
- schedule_bit-0.1.0/src/schedule_bit/errors.py +110 -0
- schedule_bit-0.1.0/src/schedule_bit/local_time.py +84 -0
- schedule_bit-0.1.0/src/schedule_bit/masks.py +125 -0
- schedule_bit-0.1.0/src/schedule_bit/py.typed +0 -0
- schedule_bit-0.1.0/src/schedule_bit/rate_limit.py +87 -0
- schedule_bit-0.1.0/src/schedule_bit/retry.py +87 -0
- schedule_bit-0.1.0/src/schedule_bit/watch.py +296 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
The first release.
|
|
6
|
+
|
|
7
|
+
- One method per API operation (sync `Client`, async `AsyncClient`), typed with
|
|
8
|
+
models generated from the OpenAPI contract.
|
|
9
|
+
- 429 and 503 are retried, and network failures and other 5xx where it is safe,
|
|
10
|
+
with jittered back-off that honours `Retry-After` and `RateLimit-Reset`.
|
|
11
|
+
- The writes that take an `Idempotency-Key` get one automatically, the same
|
|
12
|
+
across a call's retries.
|
|
13
|
+
- `RateLimit-*` headers are read on every answer; an optional client-side pacer
|
|
14
|
+
keeps you under a rate.
|
|
15
|
+
- Typed errors: `Refusal` (409), `LocalTimeError` (422), `RateLimited`,
|
|
16
|
+
`NetworkError`, `TimeoutError`. `try_claim` returns a refusal instead of raising.
|
|
17
|
+
- `Slots` for hex masks; `local_day`, `local_hour` and `local_slot` for local time.
|
|
18
|
+
- `watch()` is a resuming WebSocket iterator (`schedule-bit[watch]`); `assist()`
|
|
19
|
+
streams the Director's events.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ontology.io
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: schedule-bit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for the schedule-bit API: read and write time as bitmasks, with retries, rate limits and live watches handled.
|
|
5
|
+
Project-URL: Homepage, https://schedule-bit.io
|
|
6
|
+
Project-URL: Documentation, https://api.schedule-bit.io/v1/docs
|
|
7
|
+
Project-URL: Source, https://github.com/ontology-io/schedule-bit/tree/main/sdks/python
|
|
8
|
+
Project-URL: Changelog, https://github.com/ontology-io/schedule-bit/blob/main/sdks/python/CHANGELOG.md
|
|
9
|
+
Author: Ontology.io
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: api,bitmask,booking,calendar,schedule,scheduling,sdk
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: httpx<1,>=0.27
|
|
24
|
+
Requires-Dist: pydantic<3,>=2.7
|
|
25
|
+
Provides-Extra: watch
|
|
26
|
+
Requires-Dist: websockets<16,>=13; extra == 'watch'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# schedule-bit for Python
|
|
30
|
+
|
|
31
|
+
The [schedule-bit](https://schedule-bit.io) API from Python. It keeps time as bitmasks, so claiming a resource never double-books it. This SDK covers every operation, sync and async. Retries, rate limits, idempotency and live updates are handled for you.
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
pip install schedule-bit # or: uv add schedule-bit
|
|
35
|
+
pip install "schedule-bit[watch]" # adds live watching over WebSocket
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Python 3.10 or newer.
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from schedule_bit import Client, Refusal, Slots
|
|
44
|
+
|
|
45
|
+
with Client() as api: # key from SCHEDULE_BIT_API_KEY
|
|
46
|
+
api.create_world(name="room-1", preset="temporal-hour")
|
|
47
|
+
api.declare_occupier("room-1", name="omar")
|
|
48
|
+
api.declare_occupier("room-1", name="sara")
|
|
49
|
+
|
|
50
|
+
receipt = api.claim("room-1", who="omar", date="2026-11-12", slots=Slots.range(9, 11))
|
|
51
|
+
print(receipt.slots) # [9, 10]
|
|
52
|
+
|
|
53
|
+
outcome = api.try_claim("room-1", who="sara", date="2026-11-12", slots=[10])
|
|
54
|
+
if isinstance(outcome, Refusal):
|
|
55
|
+
print(outcome.by, outcome.detail) # held, "slot 10 is held by omar"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Async is the same, with `await`:
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from schedule_bit import AsyncClient
|
|
62
|
+
|
|
63
|
+
async with AsyncClient() as api:
|
|
64
|
+
free = await api.offered("room-1", date="2026-11-12")
|
|
65
|
+
print(free.slots)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Every operation in the [API reference](https://api.schedule-bit.io/v1/docs) is a method here in `snake_case`, for example `explainClaim` is `explain_claim`. Body fields are keyword arguments, in Python or API spelling. Answers are typed models in `schedule_bit.models`.
|
|
69
|
+
|
|
70
|
+
## What the client does for you
|
|
71
|
+
|
|
72
|
+
| | |
|
|
73
|
+
|---|---|
|
|
74
|
+
| **Retries** | 429 and 503 always, and network failures or other 5xx when the call is safe to repeat (a read, `explain_claim`, or a write with an idempotency key). Waits use jittered back-off that honours `Retry-After` and `RateLimit-Reset`. The default is 4 retries; set `max_retries=0` to turn them off. |
|
|
75
|
+
| **Idempotency** | Writes that accept an `Idempotency-Key` get one, the same across that call's retries, so a retried claim never claims twice. To pass your own, use `options=RequestOptions(idempotency_key=…)`. |
|
|
76
|
+
| **Rate limits** | `api.rate_limit` holds the latest `RateLimit-*` headers, `on_rate_limit=` is called with each one, and `rate_limit_per_minute=` paces requests on the client side. |
|
|
77
|
+
| **Timeouts** | 30 s per attempt, which you can change per client (`timeout=`) or per call (`RequestOptions(timeout=…)`). A sync call can be cancelled with `RequestOptions(cancel=threading.Event())`; an async call is cancelled by cancelling its task. |
|
|
78
|
+
| **Errors** | `Refusal` (409, the engine said no, `.by` names why), `LocalTimeError` (422, with `.candidates`), `RateLimited`, `ApiError` for any other problem, and `NetworkError` / `TimeoutError` with the last cause attached. |
|
|
79
|
+
| **Secrets** | Keys never appear in errors, reprs or logs. |
|
|
80
|
+
|
|
81
|
+
## Masks and local time
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from datetime import datetime
|
|
85
|
+
from zoneinfo import ZoneInfo
|
|
86
|
+
from schedule_bit import Slots, local_slot
|
|
87
|
+
|
|
88
|
+
Slots.from_hex("0x600").list() # [9, 10]
|
|
89
|
+
(Slots.range(9, 12) - [10]).hex # "0xa00"
|
|
90
|
+
|
|
91
|
+
at = datetime(2026, 10, 25, 1, 30, tzinfo=ZoneInfo("Europe/London"), fold=1)
|
|
92
|
+
api.claim("room-1", who="omar", **local_slot(at)) # the second 01:30 that night
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
At a clock change, Python's `fold` says which of a repeated time you mean, and `local_slot` sends it as `occurrence`. Without it, the API answers with a `LocalTimeError` that lists the candidates.
|
|
96
|
+
|
|
97
|
+
## Watching a World
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
with api.watch("room-1") as frames:
|
|
101
|
+
for frame in frames:
|
|
102
|
+
print(frame.type) # hello, claim.made, claim.released, …
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
If the connection drops, the watch reconnects with the same back-off. It catches up from the journal, so no commit is missed, and it yields each event once.
|
|
106
|
+
|
|
107
|
+
## Development
|
|
108
|
+
|
|
109
|
+
```sh
|
|
110
|
+
uv sync
|
|
111
|
+
uv run python scripts/generate.py # after the contract changes
|
|
112
|
+
uv run pytest # unit tests (a fake server, no sleeping)
|
|
113
|
+
SCHEDULE_BIT_LIVE=1 uv run pytest -m live # the shared scenarios against the dev API
|
|
114
|
+
uv run ruff check && uv run mypy
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
`src/schedule_bit/_generated/` is generated from `sdks/spec/openapi.json`, so don't edit it by hand. A unit test fails when it is stale. The behaviour every SDK shares is in [`sdks/POLICY.md`](../POLICY.md).
|
|
118
|
+
|
|
119
|
+
MIT licensed.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# schedule-bit for Python
|
|
2
|
+
|
|
3
|
+
The [schedule-bit](https://schedule-bit.io) API from Python. It keeps time as bitmasks, so claiming a resource never double-books it. This SDK covers every operation, sync and async. Retries, rate limits, idempotency and live updates are handled for you.
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
pip install schedule-bit # or: uv add schedule-bit
|
|
7
|
+
pip install "schedule-bit[watch]" # adds live watching over WebSocket
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Python 3.10 or newer.
|
|
11
|
+
|
|
12
|
+
## Quick start
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
from schedule_bit import Client, Refusal, Slots
|
|
16
|
+
|
|
17
|
+
with Client() as api: # key from SCHEDULE_BIT_API_KEY
|
|
18
|
+
api.create_world(name="room-1", preset="temporal-hour")
|
|
19
|
+
api.declare_occupier("room-1", name="omar")
|
|
20
|
+
api.declare_occupier("room-1", name="sara")
|
|
21
|
+
|
|
22
|
+
receipt = api.claim("room-1", who="omar", date="2026-11-12", slots=Slots.range(9, 11))
|
|
23
|
+
print(receipt.slots) # [9, 10]
|
|
24
|
+
|
|
25
|
+
outcome = api.try_claim("room-1", who="sara", date="2026-11-12", slots=[10])
|
|
26
|
+
if isinstance(outcome, Refusal):
|
|
27
|
+
print(outcome.by, outcome.detail) # held, "slot 10 is held by omar"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Async is the same, with `await`:
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from schedule_bit import AsyncClient
|
|
34
|
+
|
|
35
|
+
async with AsyncClient() as api:
|
|
36
|
+
free = await api.offered("room-1", date="2026-11-12")
|
|
37
|
+
print(free.slots)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Every operation in the [API reference](https://api.schedule-bit.io/v1/docs) is a method here in `snake_case`, for example `explainClaim` is `explain_claim`. Body fields are keyword arguments, in Python or API spelling. Answers are typed models in `schedule_bit.models`.
|
|
41
|
+
|
|
42
|
+
## What the client does for you
|
|
43
|
+
|
|
44
|
+
| | |
|
|
45
|
+
|---|---|
|
|
46
|
+
| **Retries** | 429 and 503 always, and network failures or other 5xx when the call is safe to repeat (a read, `explain_claim`, or a write with an idempotency key). Waits use jittered back-off that honours `Retry-After` and `RateLimit-Reset`. The default is 4 retries; set `max_retries=0` to turn them off. |
|
|
47
|
+
| **Idempotency** | Writes that accept an `Idempotency-Key` get one, the same across that call's retries, so a retried claim never claims twice. To pass your own, use `options=RequestOptions(idempotency_key=…)`. |
|
|
48
|
+
| **Rate limits** | `api.rate_limit` holds the latest `RateLimit-*` headers, `on_rate_limit=` is called with each one, and `rate_limit_per_minute=` paces requests on the client side. |
|
|
49
|
+
| **Timeouts** | 30 s per attempt, which you can change per client (`timeout=`) or per call (`RequestOptions(timeout=…)`). A sync call can be cancelled with `RequestOptions(cancel=threading.Event())`; an async call is cancelled by cancelling its task. |
|
|
50
|
+
| **Errors** | `Refusal` (409, the engine said no, `.by` names why), `LocalTimeError` (422, with `.candidates`), `RateLimited`, `ApiError` for any other problem, and `NetworkError` / `TimeoutError` with the last cause attached. |
|
|
51
|
+
| **Secrets** | Keys never appear in errors, reprs or logs. |
|
|
52
|
+
|
|
53
|
+
## Masks and local time
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from datetime import datetime
|
|
57
|
+
from zoneinfo import ZoneInfo
|
|
58
|
+
from schedule_bit import Slots, local_slot
|
|
59
|
+
|
|
60
|
+
Slots.from_hex("0x600").list() # [9, 10]
|
|
61
|
+
(Slots.range(9, 12) - [10]).hex # "0xa00"
|
|
62
|
+
|
|
63
|
+
at = datetime(2026, 10, 25, 1, 30, tzinfo=ZoneInfo("Europe/London"), fold=1)
|
|
64
|
+
api.claim("room-1", who="omar", **local_slot(at)) # the second 01:30 that night
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
At a clock change, Python's `fold` says which of a repeated time you mean, and `local_slot` sends it as `occurrence`. Without it, the API answers with a `LocalTimeError` that lists the candidates.
|
|
68
|
+
|
|
69
|
+
## Watching a World
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
with api.watch("room-1") as frames:
|
|
73
|
+
for frame in frames:
|
|
74
|
+
print(frame.type) # hello, claim.made, claim.released, …
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
If the connection drops, the watch reconnects with the same back-off. It catches up from the journal, so no commit is missed, and it yields each event once.
|
|
78
|
+
|
|
79
|
+
## Development
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
uv sync
|
|
83
|
+
uv run python scripts/generate.py # after the contract changes
|
|
84
|
+
uv run pytest # unit tests (a fake server, no sleeping)
|
|
85
|
+
SCHEDULE_BIT_LIVE=1 uv run pytest -m live # the shared scenarios against the dev API
|
|
86
|
+
uv run ruff check && uv run mypy
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`src/schedule_bit/_generated/` is generated from `sdks/spec/openapi.json`, so don't edit it by hand. A unit test fails when it is stale. The behaviour every SDK shares is in [`sdks/POLICY.md`](../POLICY.md).
|
|
90
|
+
|
|
91
|
+
MIT licensed.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "schedule-bit"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Python SDK for the schedule-bit API: read and write time as bitmasks, with retries, rate limits and live watches handled."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
authors = [{ name = "Ontology.io" }]
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"httpx>=0.27,<1",
|
|
12
|
+
"pydantic>=2.7,<3",
|
|
13
|
+
]
|
|
14
|
+
keywords = ["schedule", "scheduling", "bitmask", "calendar", "booking", "api", "sdk"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.10",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Programming Language :: Python :: 3.13",
|
|
23
|
+
"Programming Language :: Python :: 3.14",
|
|
24
|
+
"Typing :: Typed",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.optional-dependencies]
|
|
28
|
+
watch = ["websockets>=13,<16"]
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
Homepage = "https://schedule-bit.io"
|
|
32
|
+
Documentation = "https://api.schedule-bit.io/v1/docs"
|
|
33
|
+
Source = "https://github.com/ontology-io/schedule-bit/tree/main/sdks/python"
|
|
34
|
+
Changelog = "https://github.com/ontology-io/schedule-bit/blob/main/sdks/python/CHANGELOG.md"
|
|
35
|
+
|
|
36
|
+
[dependency-groups]
|
|
37
|
+
dev = [
|
|
38
|
+
"pytest>=8",
|
|
39
|
+
"pytest-asyncio>=0.24",
|
|
40
|
+
"ruff>=0.6",
|
|
41
|
+
"mypy>=1.11",
|
|
42
|
+
"websockets>=13,<16",
|
|
43
|
+
"datamodel-code-generator==0.83.0",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[build-system]
|
|
47
|
+
requires = ["hatchling>=1.27"]
|
|
48
|
+
build-backend = "hatchling.build"
|
|
49
|
+
|
|
50
|
+
[tool.hatch.build.targets.wheel]
|
|
51
|
+
packages = ["src/schedule_bit"]
|
|
52
|
+
|
|
53
|
+
[tool.hatch.build.targets.sdist]
|
|
54
|
+
include = ["src", "README.md", "CHANGELOG.md", "LICENSE", "pyproject.toml"]
|
|
55
|
+
|
|
56
|
+
[tool.pytest.ini_options]
|
|
57
|
+
testpaths = ["tests"]
|
|
58
|
+
asyncio_mode = "auto"
|
|
59
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
60
|
+
markers = ["live: runs against the deployed dev API (needs an operator key)"]
|
|
61
|
+
addopts = "-m 'not live'"
|
|
62
|
+
|
|
63
|
+
[tool.ruff]
|
|
64
|
+
line-length = 120
|
|
65
|
+
target-version = "py310"
|
|
66
|
+
extend-exclude = ["src/schedule_bit/_generated"]
|
|
67
|
+
|
|
68
|
+
[tool.ruff.lint]
|
|
69
|
+
select = ["E", "F", "W", "I", "B", "UP", "SIM", "RUF"]
|
|
70
|
+
ignore = ["RUF001", "RUF002", "RUF003"]
|
|
71
|
+
|
|
72
|
+
[tool.mypy]
|
|
73
|
+
python_version = "3.10"
|
|
74
|
+
strict = true
|
|
75
|
+
plugins = ["pydantic.mypy"]
|
|
76
|
+
files = ["src/schedule_bit"]
|
|
77
|
+
exclude = ["src/schedule_bit/_generated/"]
|
|
78
|
+
|
|
79
|
+
[[tool.mypy.overrides]]
|
|
80
|
+
module = ["schedule_bit._generated.*"]
|
|
81
|
+
ignore_errors = true
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""The schedule-bit API from Python.
|
|
2
|
+
|
|
3
|
+
from schedule_bit import Client, Slots
|
|
4
|
+
|
|
5
|
+
with Client() as api: # key from SCHEDULE_BIT_API_KEY
|
|
6
|
+
api.create_world(name="room-1", preset="temporal-hour")
|
|
7
|
+
api.declare_occupier("room-1", name="omar")
|
|
8
|
+
receipt = api.claim("room-1", who="omar", date="2026-10-15", slots=Slots.range(9, 11))
|
|
9
|
+
|
|
10
|
+
See https://api.schedule-bit.io/v1/docs for every operation; each one is a method
|
|
11
|
+
here, in ``snake_case`` (``explainClaim`` is ``explain_claim``).
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from ._client import DEFAULT_BASE_URL, AsyncClient, Client
|
|
15
|
+
from ._generated import models
|
|
16
|
+
from ._options import RequestOptions
|
|
17
|
+
from ._redact import redact
|
|
18
|
+
from ._version import __version__
|
|
19
|
+
from .errors import (
|
|
20
|
+
ApiError,
|
|
21
|
+
Cancelled,
|
|
22
|
+
LocalTimeError,
|
|
23
|
+
NetworkError,
|
|
24
|
+
RateLimited,
|
|
25
|
+
Refusal,
|
|
26
|
+
ScheduleBitError,
|
|
27
|
+
TimeoutError,
|
|
28
|
+
)
|
|
29
|
+
from .local_time import local_day, local_hour, local_slot
|
|
30
|
+
from .masks import Slots
|
|
31
|
+
from .rate_limit import RateLimit, TokenBucket
|
|
32
|
+
from .retry import RetryPolicy
|
|
33
|
+
|
|
34
|
+
__all__ = [
|
|
35
|
+
"DEFAULT_BASE_URL",
|
|
36
|
+
"ApiError",
|
|
37
|
+
"AsyncClient",
|
|
38
|
+
"Cancelled",
|
|
39
|
+
"Client",
|
|
40
|
+
"LocalTimeError",
|
|
41
|
+
"NetworkError",
|
|
42
|
+
"RateLimit",
|
|
43
|
+
"RateLimited",
|
|
44
|
+
"Refusal",
|
|
45
|
+
"RequestOptions",
|
|
46
|
+
"RetryPolicy",
|
|
47
|
+
"ScheduleBitError",
|
|
48
|
+
"Slots",
|
|
49
|
+
"TimeoutError",
|
|
50
|
+
"TokenBucket",
|
|
51
|
+
"__version__",
|
|
52
|
+
"local_day",
|
|
53
|
+
"local_hour",
|
|
54
|
+
"local_slot",
|
|
55
|
+
"models",
|
|
56
|
+
"redact",
|
|
57
|
+
]
|