Skip to content

Commit 9895ffb

Browse files
authored
docs: add examples for centralized SDK docs (#12)
1 parent ef92a55 commit 9895ffb

8 files changed

Lines changed: 426 additions & 11 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ jobs:
2727
- name: Sync dependencies
2828
run: |
2929
uv sync --all-groups
30-
- name: Static code check
31-
run: uv run poe ci_checker
30+
- name: Code quality check
31+
run: uv run poe cq-check
3232
- name: Unit tests
3333
run: uv run pytest tests/ -v -m 'not (account or basin or stream or metrics)'
3434
- name: Check docs build
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
"""Documentation examples for Account and Basins page.
2+
3+
These snippets are extracted by the docs build script.
4+
5+
Run with: python examples/docs/account_and_basins.py
6+
Requires: S2_ACCESS_TOKEN, S2_BASIN environment variables
7+
8+
Note: These examples create resources with hardcoded names.
9+
They may fail on repeated runs if resources already exist.
10+
"""
11+
12+
import asyncio
13+
import os
14+
from datetime import datetime, timezone
15+
16+
from s2_sdk import (
17+
S2,
18+
AccessTokenScope,
19+
OperationGroupPermissions,
20+
Permission,
21+
PrefixMatch,
22+
)
23+
24+
access_token = os.environ["S2_ACCESS_TOKEN"]
25+
basin_name = os.environ["S2_BASIN"]
26+
27+
28+
async def main():
29+
async with S2(access_token) as client:
30+
# ANCHOR: basin-operations
31+
# List basins
32+
basins = await client.list_basins()
33+
34+
# Create a basin
35+
await client.create_basin("my-events")
36+
37+
# Get configuration
38+
config = await client.get_basin_config("my-events")
39+
40+
# Delete
41+
await client.delete_basin("my-events")
42+
# ANCHOR_END: basin-operations
43+
print(f"Basins: {len(basins.items)} found, config: {config}")
44+
45+
basin = client.basin(basin_name)
46+
47+
# ANCHOR: stream-operations
48+
# List streams
49+
streams = await basin.list_streams(prefix="user-")
50+
51+
# Create a stream
52+
await basin.create_stream(
53+
"user-actions",
54+
# config=StreamConfig(...) # optional
55+
)
56+
57+
# Get configuration
58+
config = await basin.get_stream_config("user-actions")
59+
60+
# Delete
61+
await basin.delete_stream("user-actions")
62+
# ANCHOR_END: stream-operations
63+
print(f"Streams: {len(streams.items)} found, config: {config}")
64+
65+
# ANCHOR: access-token-basic
66+
# List tokens (returns metadata, not the secret)
67+
tokens = await client.list_access_tokens()
68+
69+
# Issue a token scoped to streams under "users/1234/"
70+
issued_token = await client.issue_access_token(
71+
"user-1234-rw-token",
72+
scope=AccessTokenScope(
73+
basins=PrefixMatch(""), # all basins
74+
streams=PrefixMatch("users/1234/"),
75+
op_groups=OperationGroupPermissions(
76+
stream=Permission.READ_WRITE,
77+
),
78+
),
79+
expires_at=datetime(2027, 1, 1, tzinfo=timezone.utc),
80+
)
81+
82+
# Revoke a token
83+
await client.revoke_access_token("user-1234-rw-token")
84+
# ANCHOR_END: access-token-basic
85+
print(f"Tokens: {len(tokens.items)} found, issued: {bool(issued_token)}")
86+
87+
# ANCHOR: pagination
88+
# Iterate through all streams with automatic pagination
89+
async for stream in basin.list_all_streams():
90+
print(stream.name)
91+
# ANCHOR_END: pagination
92+
93+
# ANCHOR: pagination-filtering
94+
# List streams with a prefix filter
95+
async for stream in basin.list_all_streams(prefix="events/"):
96+
print(stream.name)
97+
# ANCHOR_END: pagination-filtering
98+
99+
# ANCHOR: pagination-deleted
100+
# Include streams that are being deleted
101+
async for stream in basin.list_all_streams(include_deleted=True):
102+
print(stream.name, stream.deleted_at)
103+
# ANCHOR_END: pagination-deleted
104+
105+
print("Account and basins examples completed")
106+
107+
108+
if __name__ == "__main__":
109+
asyncio.run(main())

examples/docs/configuration.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
"""Documentation examples for Configuration page.
2+
3+
These snippets are extracted by the docs build script.
4+
5+
Run with: python examples/docs/configuration.py
6+
Requires: S2_ACCESS_TOKEN environment variable
7+
"""
8+
9+
import asyncio
10+
import os
11+
from datetime import timedelta
12+
13+
from s2_sdk import S2, Endpoints, Retry, Timeout
14+
15+
16+
async def main():
17+
# ANCHOR: custom-endpoints
18+
client = S2(
19+
"local-token",
20+
endpoints=Endpoints(
21+
account="http://localhost:8080",
22+
basin="http://localhost:8080",
23+
),
24+
)
25+
# ANCHOR_END: custom-endpoints
26+
await client.close()
27+
28+
access_token = os.environ["S2_ACCESS_TOKEN"]
29+
30+
# ANCHOR: retry-config
31+
client = S2(
32+
access_token,
33+
retry=Retry(
34+
max_attempts=5,
35+
min_base_delay=timedelta(milliseconds=100),
36+
max_base_delay=timedelta(seconds=2),
37+
),
38+
)
39+
# ANCHOR_END: retry-config
40+
await client.close()
41+
42+
# ANCHOR: timeout-config
43+
client = S2(
44+
access_token,
45+
timeout=Timeout(
46+
connection=timedelta(seconds=5),
47+
request=timedelta(seconds=10),
48+
),
49+
)
50+
# ANCHOR_END: timeout-config
51+
await client.close()
52+
53+
print("Configuration examples loaded")
54+
55+
56+
if __name__ == "__main__":
57+
asyncio.run(main())

examples/docs/metrics.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
"""Documentation examples for Metrics page.
2+
3+
These snippets are extracted by the docs build script.
4+
5+
Run with: python examples/docs/metrics.py
6+
Requires: S2_ACCESS_TOKEN environment variable
7+
"""
8+
9+
import asyncio
10+
import os
11+
import time
12+
13+
from s2_sdk import (
14+
S2,
15+
AccountMetricSet,
16+
BasinMetricSet,
17+
StreamMetricSet,
18+
TimeseriesInterval,
19+
)
20+
21+
access_token = os.environ["S2_ACCESS_TOKEN"]
22+
23+
24+
async def main():
25+
async with S2(access_token) as client:
26+
# ANCHOR: metrics
27+
now = int(time.time())
28+
thirty_days_ago = now - 30 * 24 * 3600
29+
six_hours_ago = now - 6 * 3600
30+
hour_ago = now - 3600
31+
32+
# Account-level: active basins over the last 30 days
33+
account_metrics = await client.account_metrics(
34+
set=AccountMetricSet.ACTIVE_BASINS,
35+
start=thirty_days_ago,
36+
end=now,
37+
)
38+
39+
# Basin-level: storage usage with hourly resolution
40+
basin_metrics = await client.basin_metrics(
41+
"events",
42+
set=BasinMetricSet.STORAGE,
43+
start=six_hours_ago,
44+
end=now,
45+
interval=TimeseriesInterval.HOUR,
46+
)
47+
48+
# Stream-level: storage for a specific stream
49+
stream_metrics = await client.stream_metrics(
50+
"events",
51+
"user-actions",
52+
set=StreamMetricSet.STORAGE,
53+
start=hour_ago,
54+
end=now,
55+
interval=TimeseriesInterval.MINUTE,
56+
)
57+
# ANCHOR_END: metrics
58+
59+
print(account_metrics, basin_metrics, stream_metrics)
60+
61+
62+
if __name__ == "__main__":
63+
asyncio.run(main())

examples/docs/overview.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
"""Documentation examples for SDK Overview page.
2+
3+
These snippets are extracted by the docs build script.
4+
5+
Run with: python examples/docs/overview.py
6+
Requires: S2_ACCESS_TOKEN environment variable
7+
"""
8+
9+
# ANCHOR: create-client
10+
import os
11+
12+
from s2_sdk import S2
13+
14+
client = S2(os.environ["S2_ACCESS_TOKEN"])
15+
16+
basin = client.basin("my-basin")
17+
stream = basin.stream("my-stream")
18+
# ANCHOR_END: create-client
19+
20+
print("Client created successfully")

0 commit comments

Comments
 (0)