zorveus 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.
- zorveus-0.1.0/.github/workflows/publish.yml +53 -0
- zorveus-0.1.0/.gitignore +10 -0
- zorveus-0.1.0/.python-version +1 -0
- zorveus-0.1.0/DOCUMENTATION.md +453 -0
- zorveus-0.1.0/Makefile +36 -0
- zorveus-0.1.0/PKG-INFO +230 -0
- zorveus-0.1.0/README.md +208 -0
- zorveus-0.1.0/examples/.env +13 -0
- zorveus-0.1.0/examples/.env.example +14 -0
- zorveus-0.1.0/examples/_env.py +34 -0
- zorveus-0.1.0/examples/basic_inference.py +30 -0
- zorveus-0.1.0/examples/oauth_pkce_flow.py +97 -0
- zorveus-0.1.0/examples/openai_adapter_demo.py +32 -0
- zorveus-0.1.0/examples/user_management.py +34 -0
- zorveus-0.1.0/pyproject.toml +44 -0
- zorveus-0.1.0/python_specificatoin.md +455 -0
- zorveus-0.1.0/src/zorveus/__init__.py +41 -0
- zorveus-0.1.0/src/zorveus/_client.py +62 -0
- zorveus-0.1.0/src/zorveus/_oauth.py +117 -0
- zorveus-0.1.0/src/zorveus/_service_client.py +53 -0
- zorveus-0.1.0/src/zorveus/_version.py +1 -0
- zorveus-0.1.0/src/zorveus/errors.py +33 -0
- zorveus-0.1.0/src/zorveus/http/__init__.py +10 -0
- zorveus-0.1.0/src/zorveus/http/async_transport.py +109 -0
- zorveus-0.1.0/src/zorveus/http/sse.py +38 -0
- zorveus-0.1.0/src/zorveus/http/transport.py +142 -0
- zorveus-0.1.0/src/zorveus/openai.py +272 -0
- zorveus-0.1.0/src/zorveus/resources/__init__.py +15 -0
- zorveus-0.1.0/src/zorveus/resources/chat.py +183 -0
- zorveus-0.1.0/src/zorveus/resources/models.py +32 -0
- zorveus-0.1.0/src/zorveus/resources/product_users.py +138 -0
- zorveus-0.1.0/src/zorveus/resources/provider_credentials.py +64 -0
- zorveus-0.1.0/src/zorveus/types/__init__.py +44 -0
- zorveus-0.1.0/src/zorveus/types/chat.py +42 -0
- zorveus-0.1.0/src/zorveus/types/models.py +12 -0
- zorveus-0.1.0/src/zorveus/types/product_users.py +44 -0
- zorveus-0.1.0/src/zorveus/types/provider_credentials.py +15 -0
- zorveus-0.1.0/src/zorveus/types/usage.py +9 -0
- zorveus-0.1.0/src/zorveus/utils/__init__.py +9 -0
- zorveus-0.1.0/src/zorveus/utils/decimal.py +16 -0
- zorveus-0.1.0/src/zorveus/utils/pkce.py +18 -0
- zorveus-0.1.0/tests/__init__.py +1 -0
- zorveus-0.1.0/tests/test_chat.py +95 -0
- zorveus-0.1.0/tests/test_errors.py +64 -0
- zorveus-0.1.0/tests/test_oauth.py +72 -0
- zorveus-0.1.0/tests/test_openai.py +76 -0
- zorveus-0.1.0/tests/test_product_users.py +70 -0
- zorveus-0.1.0/tests/test_provider_credentials.py +46 -0
- zorveus-0.1.0/uv.lock +1224 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
name: Run test suite
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v5
|
|
21
|
+
with:
|
|
22
|
+
enable-cache: true
|
|
23
|
+
|
|
24
|
+
- name: Set up Python
|
|
25
|
+
uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.12"
|
|
28
|
+
|
|
29
|
+
- name: Run tests
|
|
30
|
+
run: uv run --extra dev --extra openai pytest
|
|
31
|
+
|
|
32
|
+
publish:
|
|
33
|
+
name: Build and publish to PyPI
|
|
34
|
+
needs: test
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
environment:
|
|
37
|
+
name: pypi
|
|
38
|
+
url: https://pypi.org/p/zorveus
|
|
39
|
+
permissions:
|
|
40
|
+
id-token: write
|
|
41
|
+
steps:
|
|
42
|
+
- uses: actions/checkout@v4
|
|
43
|
+
|
|
44
|
+
- name: Install uv
|
|
45
|
+
uses: astral-sh/setup-uv@v5
|
|
46
|
+
with:
|
|
47
|
+
enable-cache: true
|
|
48
|
+
|
|
49
|
+
- name: Build distribution packages
|
|
50
|
+
run: uv build
|
|
51
|
+
|
|
52
|
+
- name: Publish package distributions to PyPI
|
|
53
|
+
run: uv publish --trusted-publishing always
|
zorveus-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.13
|
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
# Zorveus Python SDK (`zorveus`) codebase documentation
|
|
2
|
+
|
|
3
|
+
Comprehensive reference documentation for the `zorveus` Python SDK, covering installation, environment setup, architecture, Data Plane inference clients, OpenAI SDK integration, Control Plane administration, OAuth 2.0 PKCE utilities, error handling, and Pydantic v2 schemas.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Overview and platform architecture
|
|
8
|
+
|
|
9
|
+
The `zorveus` SDK provides Python 3.9+ developers with typed, synchronous, and asynchronous interfaces for the Zorveus AI Infrastructure Platform.
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
+-------------------------------------------------------------------------------+
|
|
13
|
+
| Zorveus Platform API |
|
|
14
|
+
+---------------------------------------+---------------------------------------+
|
|
15
|
+
|
|
|
16
|
+
+----------------------------------+----------------------------------+
|
|
17
|
+
| |
|
|
18
|
+
v v
|
|
19
|
+
+---------------------------------------+ +---------------------------------------+
|
|
20
|
+
| AI Gateway (Data Plane) | | Control Plane (Management API) |
|
|
21
|
+
| https://api.zorveus.com/v1 | | https://api.zorveus.com |
|
|
22
|
+
| (Inference Key / User OAuth Token) | | (Organization Service Key) |
|
|
23
|
+
+---------------------------------------+ +---------------------------------------+
|
|
24
|
+
| • POST /v1/chat/completions | | • PUT /product-users/by-external-id |
|
|
25
|
+
| • GET /v1/models | | • GET /product-users/by-external-id |
|
|
26
|
+
| • GET /v1/inference-keys/usage | | • POST /product-users/.../grants |
|
|
27
|
+
| | | • POST /provider-credentials |
|
|
28
|
+
| | | • POST /oauth/token |
|
|
29
|
+
+---------------------------------------+ +---------------------------------------+
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 2. Installation and environment variables
|
|
35
|
+
|
|
36
|
+
### 2.1 Installation
|
|
37
|
+
|
|
38
|
+
Standard installation:
|
|
39
|
+
```bash
|
|
40
|
+
pip install zorveus
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
With official OpenAI SDK adapter extra:
|
|
44
|
+
```bash
|
|
45
|
+
pip install zorveus[openai]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Development dependencies:
|
|
49
|
+
```bash
|
|
50
|
+
pip install zorveus[dev]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 2.2 Environment variables
|
|
54
|
+
|
|
55
|
+
| Variable | Type | Description | Default |
|
|
56
|
+
| :--- | :--- | :--- | :--- |
|
|
57
|
+
| `ZORVEUS_INFERENCE_KEY` | `str` | Inference API Key (`zrv_live_...`) for Data Plane | `None` |
|
|
58
|
+
| `ZORVEUS_GATEWAY_URL` | `str` | Data Plane gateway endpoint URL | `https://api.zorveus.com/v1` |
|
|
59
|
+
| `ZORVEUS_SERVICE_KEY` | `str` | Organization Service Key (`zrv_svc_...`) for Control Plane | `None` |
|
|
60
|
+
| `ZORVEUS_BASE_URL` | `str` | Control Plane platform endpoint URL | `https://api.zorveus.com` |
|
|
61
|
+
| `ZORVEUS_CLIENT_ID` | `str` | OAuth 2.0 application client ID | `None` |
|
|
62
|
+
| `ZORVEUS_CLIENT_SECRET` | `str` | OAuth 2.0 application client secret | `None` |
|
|
63
|
+
| `ZORVEUS_REDIRECT_URI` | `str` | OAuth 2.0 redirect URL | `None` |
|
|
64
|
+
|
|
65
|
+
Environment template file: [examples/.env.example](file:///Users/peterakande/DevProjects/SDKs/zorveus-python/examples/.env.example)
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 3. Data Plane inference client (`Zorveus` and `AsyncZorveus`)
|
|
70
|
+
|
|
71
|
+
Module: `zorveus._client`
|
|
72
|
+
|
|
73
|
+
### 3.1 Synchronous client (`Zorveus`)
|
|
74
|
+
|
|
75
|
+
#### Constructor
|
|
76
|
+
```python
|
|
77
|
+
Zorveus(
|
|
78
|
+
api_key: Optional[str] = None,
|
|
79
|
+
*,
|
|
80
|
+
gateway_url: Optional[str] = None,
|
|
81
|
+
timeout: float = 60.0
|
|
82
|
+
)
|
|
83
|
+
```
|
|
84
|
+
If `api_key` is omitted, reads `ZORVEUS_INFERENCE_KEY` from `os.environ`.
|
|
85
|
+
If `gateway_url` is omitted, reads `ZORVEUS_GATEWAY_URL` or defaults to `https://api.zorveus.com/v1`.
|
|
86
|
+
|
|
87
|
+
#### Chat completions (`client.chat.completions.create`)
|
|
88
|
+
```python
|
|
89
|
+
client.chat.completions.create(
|
|
90
|
+
*,
|
|
91
|
+
model: str,
|
|
92
|
+
messages: List[Union[ChatMessage, Dict[str, Any]]],
|
|
93
|
+
stream: bool = False,
|
|
94
|
+
temperature: Optional[float] = None,
|
|
95
|
+
top_p: Optional[float] = None,
|
|
96
|
+
max_tokens: Optional[int] = None,
|
|
97
|
+
zorveus_metadata: Optional[Dict[str, Any]] = None,
|
|
98
|
+
**extra_kwargs: Any
|
|
99
|
+
) -> Union[ChatCompletionResponse, Iterator[ChatCompletionChunk]]
|
|
100
|
+
```
|
|
101
|
+
- When `stream=False` (default): Returns `ChatCompletionResponse`.
|
|
102
|
+
- When `stream=True`: Returns `Iterator[ChatCompletionChunk]` parsing Server-Sent Events (SSE).
|
|
103
|
+
|
|
104
|
+
Example:
|
|
105
|
+
```python
|
|
106
|
+
from zorveus import Zorveus
|
|
107
|
+
|
|
108
|
+
client = Zorveus(api_key="zrv_live_123...")
|
|
109
|
+
|
|
110
|
+
# Non-streaming
|
|
111
|
+
resp = client.chat.completions.create(
|
|
112
|
+
model="openai/gpt-4.1-mini",
|
|
113
|
+
messages=[{"role": "user", "content": "Explain quantum computing."}],
|
|
114
|
+
zorveus_metadata={"external_user_id": "usr_101"}
|
|
115
|
+
)
|
|
116
|
+
print(resp.choices[0].message.content)
|
|
117
|
+
|
|
118
|
+
# Streaming
|
|
119
|
+
stream = client.chat.completions.create(
|
|
120
|
+
model="openai/gpt-4.1-mini",
|
|
121
|
+
messages=[{"role": "user", "content": "Count from 1 to 5."}],
|
|
122
|
+
stream=True
|
|
123
|
+
)
|
|
124
|
+
for chunk in stream:
|
|
125
|
+
print(chunk.choices[0].delta.content or "", end="", flush=True)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### Model discovery (`client.models`)
|
|
129
|
+
- `client.models.list() -> ModelListResponse`: Returns list of available models.
|
|
130
|
+
- `client.models.get(model_id: str) -> ModelObject`: Retrieves metadata for a single model.
|
|
131
|
+
|
|
132
|
+
#### Live spend queries (`client.get_usage()`)
|
|
133
|
+
```python
|
|
134
|
+
usage = client.get_usage()
|
|
135
|
+
# UsageResponse fields:
|
|
136
|
+
# - key_id: Optional[str]
|
|
137
|
+
# - spend_cap: Optional[str]
|
|
138
|
+
# - period_spend: Optional[str]
|
|
139
|
+
# - remaining_allowance: Optional[str]
|
|
140
|
+
# - currency: str ("USD")
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### 3.2 Asynchronous client (`AsyncZorveus`)
|
|
146
|
+
|
|
147
|
+
Equivalent asynchronous interface powered by `httpx.AsyncClient`.
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
import asyncio
|
|
151
|
+
from zorveus import AsyncZorveus
|
|
152
|
+
|
|
153
|
+
async def main():
|
|
154
|
+
client = AsyncZorveus(api_key="zrv_live_123...")
|
|
155
|
+
|
|
156
|
+
resp = await client.chat.completions.create(
|
|
157
|
+
model="openai/gpt-4.1-mini",
|
|
158
|
+
messages=[{"role": "user", "content": "Hello async!"}]
|
|
159
|
+
)
|
|
160
|
+
print(resp.choices[0].message.content)
|
|
161
|
+
|
|
162
|
+
usage = await client.get_usage()
|
|
163
|
+
print("Spend cap:", usage.spend_cap)
|
|
164
|
+
|
|
165
|
+
await client.close()
|
|
166
|
+
|
|
167
|
+
asyncio.run(main())
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## 4. OpenAI SDK integration (`ZorveusOpenAI` and `AsyncZorveusOpenAI`)
|
|
173
|
+
|
|
174
|
+
Module: `zorveus.openai`
|
|
175
|
+
|
|
176
|
+
`ZorveusOpenAI` and `AsyncZorveusOpenAI` inherit directly from official `openai.OpenAI` and `openai.AsyncOpenAI` classes. They allow developers using the `openai` package to route requests through Zorveus while returning native OpenAI types.
|
|
177
|
+
|
|
178
|
+
### Constructor
|
|
179
|
+
```python
|
|
180
|
+
ZorveusOpenAI(
|
|
181
|
+
api_key: Optional[str] = None,
|
|
182
|
+
*,
|
|
183
|
+
gateway_url: Optional[str] = None,
|
|
184
|
+
external_user_id: Optional[str] = None,
|
|
185
|
+
display_name: Optional[str] = None,
|
|
186
|
+
email: Optional[str] = None,
|
|
187
|
+
user_metadata: Optional[Dict[str, Any]] = None,
|
|
188
|
+
default_headers: Optional[Mapping[str, str]] = None,
|
|
189
|
+
**kwargs: Any
|
|
190
|
+
)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Supported endpoints
|
|
194
|
+
- `client.chat.completions.create(...)`
|
|
195
|
+
- `client.responses.create(...)` (OpenAI Responses API `/v1/responses`)
|
|
196
|
+
|
|
197
|
+
### User metadata payload translation
|
|
198
|
+
`ZorveusOpenAI` automatically translates client-level or per-request parameters (`external_user_id`, `display_name`, `email`, `user_metadata`) into the JSON request body `extra_body["metadata"]`:
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
from zorveus.openai import ZorveusOpenAI
|
|
202
|
+
|
|
203
|
+
client = ZorveusOpenAI(
|
|
204
|
+
api_key="zrv_live_123...",
|
|
205
|
+
external_user_id="cus_12345",
|
|
206
|
+
display_name="Ada Lovelace",
|
|
207
|
+
email="ada@example.com",
|
|
208
|
+
user_metadata={"plan": "pro", "workspace_id": "workspace_789"}
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
response = client.chat.completions.create(
|
|
212
|
+
model="openai/gpt-4.1-mini",
|
|
213
|
+
messages=[{"role": "user", "content": "Hello from OpenAI wrapper!"}]
|
|
214
|
+
)
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Dispatched JSON HTTP request body:
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"model": "openai/gpt-4.1-mini",
|
|
221
|
+
"messages": [{"role": "user", "content": "Hello from OpenAI wrapper!"}],
|
|
222
|
+
"metadata": {
|
|
223
|
+
"external_user_id": "cus_12345",
|
|
224
|
+
"product_user": {
|
|
225
|
+
"display_name": "Ada Lovelace",
|
|
226
|
+
"email": "ada@example.com",
|
|
227
|
+
"metadata": {
|
|
228
|
+
"plan": "pro",
|
|
229
|
+
"workspace_id": "workspace_789"
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Per-request override:
|
|
237
|
+
```python
|
|
238
|
+
response = client.chat.completions.create(
|
|
239
|
+
model="openai/gpt-4.1-mini",
|
|
240
|
+
messages=[{"role": "user", "content": "Hi"}],
|
|
241
|
+
external_user_id="cus_99999",
|
|
242
|
+
display_name="Grace Hopper",
|
|
243
|
+
email="grace@example.com",
|
|
244
|
+
user_metadata={"plan": "enterprise"}
|
|
245
|
+
)
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## 5. Control Plane administration client (`ZorveusServiceClient`)
|
|
251
|
+
|
|
252
|
+
Module: `zorveus._service_client`
|
|
253
|
+
|
|
254
|
+
Used by backend applications to manage product end-users, issue credit grants, and administer provider credentials via Organization Service Keys (`zrv_svc_...`).
|
|
255
|
+
|
|
256
|
+
### 5.1 Product users resource (`service.product_users`)
|
|
257
|
+
|
|
258
|
+
#### Profile upsert (`create_or_update`)
|
|
259
|
+
```python
|
|
260
|
+
service.product_users.create_or_update(
|
|
261
|
+
*,
|
|
262
|
+
app_id: str,
|
|
263
|
+
external_user_id: str,
|
|
264
|
+
display_name: Optional[str] = None,
|
|
265
|
+
email: Optional[str] = None
|
|
266
|
+
) -> ProductUserResponse
|
|
267
|
+
```
|
|
268
|
+
PUT `/product-users/by-external-id`
|
|
269
|
+
|
|
270
|
+
#### Profile fetch (`get_by_external_id`)
|
|
271
|
+
```python
|
|
272
|
+
service.product_users.get_by_external_id(
|
|
273
|
+
*,
|
|
274
|
+
app_id: str,
|
|
275
|
+
external_user_id: str
|
|
276
|
+
) -> ProductUserResponse
|
|
277
|
+
```
|
|
278
|
+
GET `/product-users/by-external-id`
|
|
279
|
+
|
|
280
|
+
#### Credit grant (`grant_credit_by_external_id`)
|
|
281
|
+
```python
|
|
282
|
+
service.product_users.grant_credit_by_external_id(
|
|
283
|
+
*,
|
|
284
|
+
app_id: str,
|
|
285
|
+
external_user_id: str,
|
|
286
|
+
amount: str,
|
|
287
|
+
source: Optional[str] = None,
|
|
288
|
+
reason: Optional[str] = None
|
|
289
|
+
) -> GrantCreditResponse
|
|
290
|
+
```
|
|
291
|
+
POST `/product-users/by-external-id/grants`
|
|
292
|
+
|
|
293
|
+
> [!IMPORTANT]
|
|
294
|
+
> The `amount` parameter requires high-precision string validation (up to 12 decimal places, e.g. `"25.000000000000"`). Invalid decimal formats raise `InvalidDecimalError`.
|
|
295
|
+
|
|
296
|
+
Example:
|
|
297
|
+
```python
|
|
298
|
+
from zorveus import ZorveusServiceClient
|
|
299
|
+
|
|
300
|
+
service = ZorveusServiceClient(api_key="zrv_svc_123...")
|
|
301
|
+
|
|
302
|
+
grant = service.product_users.grant_credit_by_external_id(
|
|
303
|
+
app_id="app_123",
|
|
304
|
+
external_user_id="usr_101",
|
|
305
|
+
amount="25.000000000000",
|
|
306
|
+
source="promotion",
|
|
307
|
+
reason="Welcome Bonus"
|
|
308
|
+
)
|
|
309
|
+
print("Available balance:", grant.credit_summary.available_credits)
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
### 5.2 Provider credentials resource (`service.provider_credentials`)
|
|
315
|
+
|
|
316
|
+
#### Register credential (`create`)
|
|
317
|
+
```python
|
|
318
|
+
service.provider_credentials.create(
|
|
319
|
+
*,
|
|
320
|
+
app_id: str,
|
|
321
|
+
provider: str,
|
|
322
|
+
api_key: str
|
|
323
|
+
) -> ProviderCredentialResponse
|
|
324
|
+
```
|
|
325
|
+
POST `/provider-credentials`
|
|
326
|
+
|
|
327
|
+
#### List credentials (`list`)
|
|
328
|
+
```python
|
|
329
|
+
service.provider_credentials.list(
|
|
330
|
+
*,
|
|
331
|
+
app_id: str
|
|
332
|
+
) -> ProviderCredentialListResponse
|
|
333
|
+
```
|
|
334
|
+
GET `/provider-credentials`
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## 6. OAuth 2.0 PKCE helper (`ZorveusOAuth`)
|
|
339
|
+
|
|
340
|
+
Module: `zorveus._oauth`
|
|
341
|
+
|
|
342
|
+
Helper class for implementing RFC 7636 OAuth 2.0 Authorization Code Flow with PKCE.
|
|
343
|
+
|
|
344
|
+
### 6.1 PKCE generation (`generate_pkce`)
|
|
345
|
+
```python
|
|
346
|
+
ZorveusOAuth.generate_pkce(byte_length: int = 32) -> PKCEData
|
|
347
|
+
```
|
|
348
|
+
Returns `PKCEData` object containing `code_verifier`, `code_challenge` (S256), and `state`.
|
|
349
|
+
|
|
350
|
+
### 6.2 Authorization URL construction (`get_authorization_url`)
|
|
351
|
+
```python
|
|
352
|
+
ZorveusOAuth.get_authorization_url(
|
|
353
|
+
client_id: str,
|
|
354
|
+
redirect_uri: str,
|
|
355
|
+
state: str,
|
|
356
|
+
code_challenge: str,
|
|
357
|
+
*,
|
|
358
|
+
scopes: Optional[List[str]] = None,
|
|
359
|
+
base_url: str = "https://api.zorveus.com"
|
|
360
|
+
) -> str
|
|
361
|
+
```
|
|
362
|
+
Returns OAuth 2.0 authorization URL (`/oauth/authorize`).
|
|
363
|
+
|
|
364
|
+
### 6.3 Callback validation (`validate_callback`)
|
|
365
|
+
```python
|
|
366
|
+
ZorveusOAuth.validate_callback(
|
|
367
|
+
url_or_query: str,
|
|
368
|
+
expected_state: Optional[str] = None
|
|
369
|
+
) -> ValidationResult
|
|
370
|
+
```
|
|
371
|
+
Parses redirect URL or query string. Validates CSRF `state` parameter and extracts authorization `code`.
|
|
372
|
+
|
|
373
|
+
### 6.4 Access token exchange (`exchange_token`)
|
|
374
|
+
```python
|
|
375
|
+
ZorveusOAuth.exchange_token(
|
|
376
|
+
client_id: str,
|
|
377
|
+
code: str,
|
|
378
|
+
code_verifier: str,
|
|
379
|
+
redirect_uri: str,
|
|
380
|
+
*,
|
|
381
|
+
client_secret: Optional[str] = None,
|
|
382
|
+
base_url: str = "https://api.zorveus.com"
|
|
383
|
+
) -> TokenResponse
|
|
384
|
+
```
|
|
385
|
+
POST `/oauth/token`. Returns `TokenResponse` containing `access_token`, `token_type`, `app_connection_id`, and `funding_org_id`.
|
|
386
|
+
|
|
387
|
+
Example interactive script: [examples/oauth_pkce_flow.py](file:///Users/peterakande/DevProjects/SDKs/zorveus-python/examples/oauth_pkce_flow.py)
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
## 7. Exception hierarchy
|
|
392
|
+
|
|
393
|
+
Module: `zorveus.errors`
|
|
394
|
+
|
|
395
|
+
```text
|
|
396
|
+
ZorveusError (base exception)
|
|
397
|
+
├── AuthenticationError (HTTP 401)
|
|
398
|
+
├── PermissionDeniedError (HTTP 403)
|
|
399
|
+
├── NotFoundError (HTTP 404)
|
|
400
|
+
├── UnprocessableEntityError (HTTP 422)
|
|
401
|
+
├── RateLimitError (HTTP 429)
|
|
402
|
+
└── InvalidDecimalError (Credit string decimal validation failure)
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
Attributes on `ZorveusError`:
|
|
406
|
+
- `message: str`
|
|
407
|
+
- `status_code: Optional[int]`
|
|
408
|
+
- `raw_body: Optional[Dict[str, Any]]`
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
## 8. Pydantic v2 models reference
|
|
413
|
+
|
|
414
|
+
Module: `zorveus.types`
|
|
415
|
+
|
|
416
|
+
### Chat completion models
|
|
417
|
+
- `ChatMessage`: `role`, `content`, `name`, `tool_calls`
|
|
418
|
+
- `ChatCompletionUsage`: `prompt_tokens`, `completion_tokens`, `total_tokens`
|
|
419
|
+
- `ChatCompletionChoice`: `index`, `message`, `finish_reason`
|
|
420
|
+
- `ChatCompletionResponse`: `id`, `object`, `created`, `model`, `choices`, `usage`
|
|
421
|
+
- `ChatCompletionChunkDelta`: `role`, `content`
|
|
422
|
+
- `ChatCompletionChunkChoice`: `index`, `delta`, `finish_reason`
|
|
423
|
+
- `ChatCompletionChunk`: `id`, `object`, `created`, `model`, `choices`
|
|
424
|
+
|
|
425
|
+
### Model discovery models
|
|
426
|
+
- `ModelObject`: `id`, `object`, `created`, `owned_by`
|
|
427
|
+
- `ModelListResponse`: `object`, `data: List[ModelObject]`
|
|
428
|
+
|
|
429
|
+
### Product users & credit models
|
|
430
|
+
- `ProductUser`: `id`, `app_id`, `external_user_id`, `display_name`, `email`, `created_at`, `updated_at`
|
|
431
|
+
- `CreditSummary`: `available_credits`, `total_granted`, `total_spent`, `currency`
|
|
432
|
+
- `CreditGrant`: `id`, `product_user_id`, `amount`, `source`, `reason`, `created_at`
|
|
433
|
+
- `ProductUserResponse`: `product_user`, `credit_summary`
|
|
434
|
+
- `GrantCreditResponse`: `credit_grant`, `credit_summary`
|
|
435
|
+
|
|
436
|
+
### Provider credentials models
|
|
437
|
+
- `ProviderCredential`: `id`, `app_id`, `provider`, `created_at`, `updated_at`
|
|
438
|
+
- `ProviderCredentialResponse`: `provider_credential`
|
|
439
|
+
- `ProviderCredentialListResponse`: `data: List[ProviderCredential]`
|
|
440
|
+
|
|
441
|
+
### Usage tracking model
|
|
442
|
+
- `UsageResponse`: `key_id`, `spend_cap`, `period_spend`, `remaining_allowance`, `currency`
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
446
|
+
## 9. Runnable examples
|
|
447
|
+
|
|
448
|
+
The `examples/` directory contains runnable reference scripts:
|
|
449
|
+
|
|
450
|
+
- [examples/basic_inference.py](file:///Users/peterakande/DevProjects/SDKs/zorveus-python/examples/basic_inference.py): Synchronous and streaming chat completions.
|
|
451
|
+
- [examples/user_management.py](file:///Users/peterakande/DevProjects/SDKs/zorveus-python/examples/user_management.py): User provisioning and 12-decimal credit grants.
|
|
452
|
+
- [examples/oauth_pkce_flow.py](file:///Users/peterakande/DevProjects/SDKs/zorveus-python/examples/oauth_pkce_flow.py): Interactive CLI PKCE flow.
|
|
453
|
+
- [examples/openai_adapter_demo.py](file:///Users/peterakande/DevProjects/SDKs/zorveus-python/examples/openai_adapter_demo.py): OpenAI adapter integration (`ZorveusOpenAI`).
|
zorveus-0.1.0/Makefile
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
.PHONY: help dev test build release clean
|
|
2
|
+
|
|
3
|
+
VERSION ?= $(v)
|
|
4
|
+
UV := $(shell command -v uv 2>/dev/null || echo "$$HOME/.local/bin/uv")
|
|
5
|
+
|
|
6
|
+
help:
|
|
7
|
+
@echo "Available Makefile targets:"
|
|
8
|
+
@echo " make dev - Sync dev and optional dependencies"
|
|
9
|
+
@echo " make test - Run pytest test suite"
|
|
10
|
+
@echo " make build - Build distribution packages in dist/"
|
|
11
|
+
@echo " make release VERSION=0.2.0 - Bump version, commit, tag v0.2.0, and push"
|
|
12
|
+
|
|
13
|
+
dev:
|
|
14
|
+
$(UV) sync --extra dev --extra openai
|
|
15
|
+
|
|
16
|
+
test:
|
|
17
|
+
$(UV) run --extra dev --extra openai pytest
|
|
18
|
+
|
|
19
|
+
build: clean
|
|
20
|
+
$(UV) build
|
|
21
|
+
|
|
22
|
+
clean:
|
|
23
|
+
rm -rf dist/ build/ *.egg-info
|
|
24
|
+
|
|
25
|
+
release: test
|
|
26
|
+
ifndef VERSION
|
|
27
|
+
$(error Usage: make release VERSION=X.Y.Z)
|
|
28
|
+
endif
|
|
29
|
+
@echo "Bumping version to $(VERSION)..."
|
|
30
|
+
@python3 -c "import re; p='src/zorveus/_version.py'; content=open(p).read(); open(p,'w').write(re.sub(r'__version__\s*=\s*\".*?\"', f'__version__ = \"$(VERSION)\"', content))"
|
|
31
|
+
$(UV) build
|
|
32
|
+
git add src/zorveus/_version.py pyproject.toml Makefile .github/workflows/publish.yml
|
|
33
|
+
@git diff-index --quiet HEAD || git commit -m "release: v$(VERSION)"
|
|
34
|
+
git tag -f -a "v$(VERSION)" -m "Release v$(VERSION)"
|
|
35
|
+
git push origin main --tags -f
|
|
36
|
+
@echo "Release v$(VERSION) tagged and pushed! GitHub Actions will trigger PyPI publish."
|