sdkrouter 0.1.1__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.
- sdkrouter/__init__.py +110 -0
- sdkrouter/_api/__init__.py +28 -0
- sdkrouter/_api/client.py +204 -0
- sdkrouter/_api/generated/__init__.py +21 -0
- sdkrouter/_api/generated/cdn/__init__.py +209 -0
- sdkrouter/_api/generated/cdn/cdn__api__cdn/__init__.py +7 -0
- sdkrouter/_api/generated/cdn/cdn__api__cdn/client.py +133 -0
- sdkrouter/_api/generated/cdn/cdn__api__cdn/models.py +163 -0
- sdkrouter/_api/generated/cdn/cdn__api__cdn/sync_client.py +132 -0
- sdkrouter/_api/generated/cdn/client.py +75 -0
- sdkrouter/_api/generated/cdn/logger.py +256 -0
- sdkrouter/_api/generated/cdn/pyproject.toml +55 -0
- sdkrouter/_api/generated/cdn/retry.py +272 -0
- sdkrouter/_api/generated/cdn/sync_client.py +58 -0
- sdkrouter/_api/generated/cleaner/__init__.py +212 -0
- sdkrouter/_api/generated/cleaner/cleaner__api__cleaner/__init__.py +7 -0
- sdkrouter/_api/generated/cleaner/cleaner__api__cleaner/client.py +83 -0
- sdkrouter/_api/generated/cleaner/cleaner__api__cleaner/models.py +117 -0
- sdkrouter/_api/generated/cleaner/cleaner__api__cleaner/sync_client.py +82 -0
- sdkrouter/_api/generated/cleaner/client.py +75 -0
- sdkrouter/_api/generated/cleaner/enums.py +55 -0
- sdkrouter/_api/generated/cleaner/logger.py +256 -0
- sdkrouter/_api/generated/cleaner/pyproject.toml +55 -0
- sdkrouter/_api/generated/cleaner/retry.py +272 -0
- sdkrouter/_api/generated/cleaner/sync_client.py +58 -0
- sdkrouter/_api/generated/keys/__init__.py +212 -0
- sdkrouter/_api/generated/keys/client.py +75 -0
- sdkrouter/_api/generated/keys/enums.py +64 -0
- sdkrouter/_api/generated/keys/keys__api__keys/__init__.py +7 -0
- sdkrouter/_api/generated/keys/keys__api__keys/client.py +150 -0
- sdkrouter/_api/generated/keys/keys__api__keys/models.py +152 -0
- sdkrouter/_api/generated/keys/keys__api__keys/sync_client.py +149 -0
- sdkrouter/_api/generated/keys/logger.py +256 -0
- sdkrouter/_api/generated/keys/pyproject.toml +55 -0
- sdkrouter/_api/generated/keys/retry.py +272 -0
- sdkrouter/_api/generated/keys/sync_client.py +58 -0
- sdkrouter/_api/generated/models/__init__.py +209 -0
- sdkrouter/_api/generated/models/client.py +75 -0
- sdkrouter/_api/generated/models/logger.py +256 -0
- sdkrouter/_api/generated/models/models__api__llm_models/__init__.py +7 -0
- sdkrouter/_api/generated/models/models__api__llm_models/client.py +99 -0
- sdkrouter/_api/generated/models/models__api__llm_models/models.py +206 -0
- sdkrouter/_api/generated/models/models__api__llm_models/sync_client.py +99 -0
- sdkrouter/_api/generated/models/pyproject.toml +55 -0
- sdkrouter/_api/generated/models/retry.py +272 -0
- sdkrouter/_api/generated/models/sync_client.py +58 -0
- sdkrouter/_api/generated/shortlinks/__init__.py +209 -0
- sdkrouter/_api/generated/shortlinks/client.py +75 -0
- sdkrouter/_api/generated/shortlinks/logger.py +256 -0
- sdkrouter/_api/generated/shortlinks/pyproject.toml +55 -0
- sdkrouter/_api/generated/shortlinks/retry.py +272 -0
- sdkrouter/_api/generated/shortlinks/shortlinks__api__shortlinks/__init__.py +7 -0
- sdkrouter/_api/generated/shortlinks/shortlinks__api__shortlinks/client.py +137 -0
- sdkrouter/_api/generated/shortlinks/shortlinks__api__shortlinks/models.py +153 -0
- sdkrouter/_api/generated/shortlinks/shortlinks__api__shortlinks/sync_client.py +136 -0
- sdkrouter/_api/generated/shortlinks/sync_client.py +58 -0
- sdkrouter/_api/generated/vision/__init__.py +212 -0
- sdkrouter/_api/generated/vision/client.py +75 -0
- sdkrouter/_api/generated/vision/enums.py +40 -0
- sdkrouter/_api/generated/vision/logger.py +256 -0
- sdkrouter/_api/generated/vision/pyproject.toml +55 -0
- sdkrouter/_api/generated/vision/retry.py +272 -0
- sdkrouter/_api/generated/vision/sync_client.py +58 -0
- sdkrouter/_api/generated/vision/vision__api__vision/__init__.py +7 -0
- sdkrouter/_api/generated/vision/vision__api__vision/client.py +65 -0
- sdkrouter/_api/generated/vision/vision__api__vision/models.py +138 -0
- sdkrouter/_api/generated/vision/vision__api__vision/sync_client.py +65 -0
- sdkrouter/_client.py +432 -0
- sdkrouter/_config.py +74 -0
- sdkrouter/_constants.py +21 -0
- sdkrouter/_internal/__init__.py +1 -0
- sdkrouter/_types/__init__.py +30 -0
- sdkrouter/_types/cdn.py +27 -0
- sdkrouter/_types/models.py +26 -0
- sdkrouter/_types/ocr.py +24 -0
- sdkrouter/_types/parsed.py +101 -0
- sdkrouter/_types/shortlinks.py +27 -0
- sdkrouter/_types/vision.py +29 -0
- sdkrouter/_version.py +3 -0
- sdkrouter/helpers/__init__.py +13 -0
- sdkrouter/helpers/formatting.py +15 -0
- sdkrouter/helpers/html.py +100 -0
- sdkrouter/helpers/json_cleaner.py +53 -0
- sdkrouter/tools/__init__.py +129 -0
- sdkrouter/tools/cdn.py +285 -0
- sdkrouter/tools/cleaner.py +186 -0
- sdkrouter/tools/keys.py +215 -0
- sdkrouter/tools/models.py +196 -0
- sdkrouter/tools/shortlinks.py +165 -0
- sdkrouter/tools/vision.py +173 -0
- sdkrouter/utils/__init__.py +27 -0
- sdkrouter/utils/parsing.py +109 -0
- sdkrouter/utils/tokens.py +375 -0
- sdkrouter-0.1.1.dist-info/METADATA +411 -0
- sdkrouter-0.1.1.dist-info/RECORD +96 -0
- sdkrouter-0.1.1.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sdkrouter
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Unified SDK for AI services with OpenAI compatibility
|
|
5
|
+
Project-URL: Homepage, https://github.com/markolofsen/sdkrouter
|
|
6
|
+
Project-URL: Documentation, https://sdkrouter.com
|
|
7
|
+
Project-URL: Repository, https://github.com/markolofsen/sdkrouter
|
|
8
|
+
Author-email: markolofsen <dev@markolofsen.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Keywords: ai,api,cdn,llm,ocr,openai,sdk,vision
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Requires-Dist: beautifulsoup4>=4.12.0
|
|
21
|
+
Requires-Dist: httpx<1.0.0,>=0.25.0
|
|
22
|
+
Requires-Dist: lxml>=5.0.0
|
|
23
|
+
Requires-Dist: markdownify>=0.14.0
|
|
24
|
+
Requires-Dist: openai<3.0.0,>=1.0.0
|
|
25
|
+
Requires-Dist: pydantic-settings>=2.0.0
|
|
26
|
+
Requires-Dist: pydantic<3.0.0,>=2.0.0
|
|
27
|
+
Requires-Dist: rich>=14.0.0
|
|
28
|
+
Requires-Dist: tenacity>=9.0.0
|
|
29
|
+
Requires-Dist: tiktoken>=0.5.0
|
|
30
|
+
Requires-Dist: toon-python>=0.1.2
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: build>=1.0.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: mypy>=1.13.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: questionary>=2.0.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: ruff>=0.8.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: toml>=0.10.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: twine>=5.0.0; extra == 'dev'
|
|
41
|
+
Description-Content-Type: text/markdown
|
|
42
|
+
|
|
43
|
+
# SDKRouter
|
|
44
|
+
|
|
45
|
+
Unified Python SDK for AI services with OpenAI compatibility. Access 300+ LLM models through a single interface, plus vision analysis, CDN, URL shortening, and HTML cleaning tools.
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install sdkrouter
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Quick Start
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
from sdkrouter import SDKRouter
|
|
57
|
+
|
|
58
|
+
client = SDKRouter(api_key="your-api-key")
|
|
59
|
+
|
|
60
|
+
# OpenAI-compatible chat completions
|
|
61
|
+
response = client.chat.completions.create(
|
|
62
|
+
model="openai/gpt-4o",
|
|
63
|
+
messages=[{"role": "user", "content": "Hello!"}]
|
|
64
|
+
)
|
|
65
|
+
print(response.choices[0].message.content)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Features
|
|
69
|
+
|
|
70
|
+
### Chat Completions (OpenAI-Compatible)
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
# Non-streaming
|
|
74
|
+
response = client.chat.completions.create(
|
|
75
|
+
model="anthropic/claude-3.5-sonnet",
|
|
76
|
+
messages=[{"role": "user", "content": "Explain quantum computing"}],
|
|
77
|
+
max_tokens=500,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
# Streaming
|
|
81
|
+
for chunk in client.chat.completions.create(
|
|
82
|
+
model="openai/gpt-4o",
|
|
83
|
+
messages=[{"role": "user", "content": "Count to 5"}],
|
|
84
|
+
stream=True,
|
|
85
|
+
):
|
|
86
|
+
print(chunk.choices[0].delta.content or "", end="")
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Structured Output (Pydantic)
|
|
90
|
+
|
|
91
|
+
Get type-safe responses with automatic JSON schema generation:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from pydantic import BaseModel, Field
|
|
95
|
+
from sdkrouter import SDKRouter
|
|
96
|
+
|
|
97
|
+
class Step(BaseModel):
|
|
98
|
+
explanation: str = Field(description="Explanation of the step")
|
|
99
|
+
result: str = Field(description="Result of this step")
|
|
100
|
+
|
|
101
|
+
class MathSolution(BaseModel):
|
|
102
|
+
steps: list[Step] = Field(description="Solution steps")
|
|
103
|
+
final_answer: float = Field(description="The final answer")
|
|
104
|
+
|
|
105
|
+
client = SDKRouter()
|
|
106
|
+
result = client.parse(
|
|
107
|
+
model="openai/gpt-4o",
|
|
108
|
+
messages=[
|
|
109
|
+
{"role": "system", "content": "You are a math tutor. Show your work."},
|
|
110
|
+
{"role": "user", "content": "Solve: 3x + 7 = 22"},
|
|
111
|
+
],
|
|
112
|
+
response_format=MathSolution,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
solution = result.choices[0].message.parsed
|
|
116
|
+
for i, step in enumerate(solution.steps, 1):
|
|
117
|
+
print(f"{i}. {step.explanation} → {step.result}")
|
|
118
|
+
print(f"Answer: x = {solution.final_answer}")
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Vision Analysis
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
result = client.vision.analyze(
|
|
125
|
+
image_url="https://example.com/image.jpg",
|
|
126
|
+
prompt="Describe this image",
|
|
127
|
+
)
|
|
128
|
+
print(result.description)
|
|
129
|
+
print(f"Cost: ${result.cost_usd:.6f}")
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
#### Quality Tiers
|
|
133
|
+
|
|
134
|
+
| Tier | Model | Use Case |
|
|
135
|
+
|------|-------|----------|
|
|
136
|
+
| `fast` | gpt-4o-mini | Quick analysis, lower cost |
|
|
137
|
+
| `balanced` | gpt-4o | Default, good quality/cost ratio |
|
|
138
|
+
| `best` | claude-3.5-sonnet | Highest accuracy |
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
result = client.vision.analyze(
|
|
142
|
+
image_url="https://example.com/image.jpg",
|
|
143
|
+
model_quality="best", # fast | balanced | best
|
|
144
|
+
)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### OCR (Text Extraction)
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
result = client.vision.ocr(
|
|
151
|
+
image_url="https://example.com/document.jpg",
|
|
152
|
+
language_hint="en", # optional
|
|
153
|
+
)
|
|
154
|
+
print(result.text)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### OCR Modes
|
|
158
|
+
|
|
159
|
+
| Mode | Speed | Accuracy | Use Case |
|
|
160
|
+
|------|-------|----------|----------|
|
|
161
|
+
| `tiny` | Fastest | Basic | Simple text, receipts |
|
|
162
|
+
| `small` | Fast | Good | Standard documents |
|
|
163
|
+
| `base` | Medium | High | Default, balanced |
|
|
164
|
+
| `maximum` | Slow | Best | Complex layouts, handwriting |
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
result = client.vision.ocr(
|
|
168
|
+
image_url="https://example.com/document.jpg",
|
|
169
|
+
mode="maximum", # tiny | small | base | maximum
|
|
170
|
+
)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### CDN File Storage
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
# Upload bytes
|
|
177
|
+
file = client.cdn.upload(
|
|
178
|
+
b"file content",
|
|
179
|
+
filename="document.txt",
|
|
180
|
+
is_public=True,
|
|
181
|
+
)
|
|
182
|
+
print(file.url)
|
|
183
|
+
print(file.short_url)
|
|
184
|
+
|
|
185
|
+
# Upload from URL
|
|
186
|
+
file = client.cdn.upload(
|
|
187
|
+
url="https://example.com/image.png",
|
|
188
|
+
filename="image.png",
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
# List files
|
|
192
|
+
files = client.cdn.list(page=1, page_size=20)
|
|
193
|
+
for f in files.results:
|
|
194
|
+
print(f"{f.filename}: {f.size_bytes} bytes")
|
|
195
|
+
|
|
196
|
+
# Get file details
|
|
197
|
+
file = client.cdn.get("file-uuid")
|
|
198
|
+
|
|
199
|
+
# Delete file
|
|
200
|
+
client.cdn.delete("file-uuid")
|
|
201
|
+
|
|
202
|
+
# Statistics
|
|
203
|
+
stats = client.cdn.stats()
|
|
204
|
+
print(f"Total files: {stats.total_files}")
|
|
205
|
+
print(f"Total size: {stats.total_size_bytes} bytes")
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### URL Shortener
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
# Create short link
|
|
212
|
+
link = client.shortlinks.create(
|
|
213
|
+
target_url="https://example.com/very-long-url-here",
|
|
214
|
+
custom_slug="my-link", # optional
|
|
215
|
+
max_hits=1000, # optional limit
|
|
216
|
+
)
|
|
217
|
+
print(link.short_url)
|
|
218
|
+
print(link.code)
|
|
219
|
+
|
|
220
|
+
# List links
|
|
221
|
+
links = client.shortlinks.list()
|
|
222
|
+
for link in links.results:
|
|
223
|
+
print(f"{link.code}: {link.hit_count} hits")
|
|
224
|
+
|
|
225
|
+
# Statistics
|
|
226
|
+
stats = client.shortlinks.stats()
|
|
227
|
+
print(f"Total links: {stats.total_links}")
|
|
228
|
+
print(f"Total hits: {stats.total_hits}")
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### HTML Cleaner
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
result = client.cleaner.clean(
|
|
235
|
+
html_content,
|
|
236
|
+
output_format="markdown", # html | markdown | text
|
|
237
|
+
remove_scripts=True,
|
|
238
|
+
remove_styles=True,
|
|
239
|
+
max_tokens=4000, # optional token limit
|
|
240
|
+
)
|
|
241
|
+
print(result.cleaned_html)
|
|
242
|
+
print(f"Original: {result.original_size} bytes")
|
|
243
|
+
print(f"Cleaned: {result.cleaned_size} bytes")
|
|
244
|
+
print(f"Compression: {result.compression_ratio:.1f}x")
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### LLM Models API
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
# List available models with pagination
|
|
251
|
+
models = client.models.list(page=1, page_size=50)
|
|
252
|
+
for m in models.results:
|
|
253
|
+
print(f"{m.model_id}: context={m.context_length}")
|
|
254
|
+
|
|
255
|
+
# Get model details
|
|
256
|
+
model = client.models.get("openai/gpt-4o")
|
|
257
|
+
print(f"Context: {model.context_length} tokens")
|
|
258
|
+
print(f"Vision: {model.supports_vision}")
|
|
259
|
+
print(f"Price: ${model.pricing.prompt}/M input")
|
|
260
|
+
|
|
261
|
+
# List providers
|
|
262
|
+
providers = client.models.providers()
|
|
263
|
+
for p in providers.providers:
|
|
264
|
+
print(f"{p.name}: {p.model_count} models")
|
|
265
|
+
|
|
266
|
+
# Calculate cost
|
|
267
|
+
cost = client.models.calculate_cost(
|
|
268
|
+
"openai/gpt-4o",
|
|
269
|
+
input_tokens=1000,
|
|
270
|
+
output_tokens=500,
|
|
271
|
+
)
|
|
272
|
+
print(f"Input: ${cost.input_cost_usd:.6f}")
|
|
273
|
+
print(f"Output: ${cost.output_cost_usd:.6f}")
|
|
274
|
+
print(f"Total: ${cost.total_cost_usd:.6f}")
|
|
275
|
+
|
|
276
|
+
# Statistics
|
|
277
|
+
stats = client.models.stats()
|
|
278
|
+
print(f"Total models: {stats.total_models}")
|
|
279
|
+
print(f"Vision models: {stats.vision_models}")
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Token Utilities
|
|
283
|
+
|
|
284
|
+
```python
|
|
285
|
+
from sdkrouter.utils import count_tokens, count_messages_tokens
|
|
286
|
+
|
|
287
|
+
# Count tokens in text
|
|
288
|
+
tokens = count_tokens("Hello, world!")
|
|
289
|
+
print(f"Tokens: {tokens}")
|
|
290
|
+
|
|
291
|
+
# Count tokens in messages
|
|
292
|
+
messages = [
|
|
293
|
+
{"role": "system", "content": "You are helpful."},
|
|
294
|
+
{"role": "user", "content": "Hello!"},
|
|
295
|
+
]
|
|
296
|
+
tokens = count_messages_tokens(messages)
|
|
297
|
+
print(f"Message tokens: {tokens}")
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Async Support
|
|
301
|
+
|
|
302
|
+
All features support async operations:
|
|
303
|
+
|
|
304
|
+
```python
|
|
305
|
+
from sdkrouter import AsyncSDKRouter
|
|
306
|
+
import asyncio
|
|
307
|
+
|
|
308
|
+
async def main():
|
|
309
|
+
client = AsyncSDKRouter(api_key="your-api-key")
|
|
310
|
+
|
|
311
|
+
# Async chat
|
|
312
|
+
response = await client.chat.completions.create(
|
|
313
|
+
model="openai/gpt-4o",
|
|
314
|
+
messages=[{"role": "user", "content": "Hello!"}]
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
# Async structured output
|
|
318
|
+
result = await client.parse(
|
|
319
|
+
model="openai/gpt-4o",
|
|
320
|
+
messages=[...],
|
|
321
|
+
response_format=MyModel,
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
# Parallel requests
|
|
325
|
+
results = await asyncio.gather(
|
|
326
|
+
client.vision.analyze(image_url="..."),
|
|
327
|
+
client.cdn.list(),
|
|
328
|
+
client.models.stats(),
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
asyncio.run(main())
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Configuration
|
|
335
|
+
|
|
336
|
+
```python
|
|
337
|
+
from sdkrouter import SDKRouter
|
|
338
|
+
|
|
339
|
+
# Environment variables (auto-loaded)
|
|
340
|
+
# SDKROUTER_API_KEY - API key
|
|
341
|
+
# SDKROUTER_BASE_URL - Custom base URL
|
|
342
|
+
|
|
343
|
+
# Direct configuration
|
|
344
|
+
client = SDKRouter(
|
|
345
|
+
api_key="your-key",
|
|
346
|
+
base_url="https://your-server.com",
|
|
347
|
+
timeout=60.0,
|
|
348
|
+
max_retries=3,
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
# Use OpenRouter directly
|
|
352
|
+
client = SDKRouter(
|
|
353
|
+
openrouter_api_key="your-openrouter-key",
|
|
354
|
+
use_self_hosted=False,
|
|
355
|
+
)
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Type Safety
|
|
359
|
+
|
|
360
|
+
All responses are fully typed with Pydantic models:
|
|
361
|
+
|
|
362
|
+
```python
|
|
363
|
+
from sdkrouter.tools import (
|
|
364
|
+
VisionAnalyzeResponse,
|
|
365
|
+
OCRResponse,
|
|
366
|
+
CDNFileDetail,
|
|
367
|
+
ShortLinkDetail,
|
|
368
|
+
CleanResponse,
|
|
369
|
+
LLMModelDetail,
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
# IDE autocomplete works
|
|
373
|
+
result: VisionAnalyzeResponse = client.vision.analyze(...)
|
|
374
|
+
result.description # str
|
|
375
|
+
result.cost_usd # float
|
|
376
|
+
result.usage.total_tokens # int
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
## Examples
|
|
380
|
+
|
|
381
|
+
See the [examples](./examples/) directory for complete working examples:
|
|
382
|
+
|
|
383
|
+
| Example | Description |
|
|
384
|
+
|---------|-------------|
|
|
385
|
+
| `01_quickstart.py` | Quick start with all features |
|
|
386
|
+
| `02_chat.py` | Chat completions, streaming, multi-turn |
|
|
387
|
+
| `03_structured_output.py` | Pydantic structured output |
|
|
388
|
+
| `04_vision.py` | Vision analysis with quality tiers |
|
|
389
|
+
| `05_cdn.py` | File upload, download, management |
|
|
390
|
+
| `06_shortlinks.py` | URL shortening |
|
|
391
|
+
| `07_models.py` | LLM models listing, cost calculation |
|
|
392
|
+
| `08_cleaner.py` | HTML cleaning and compression |
|
|
393
|
+
| `09_keys.py` | API key management |
|
|
394
|
+
| `10_tokens.py` | Token counting utilities |
|
|
395
|
+
| `11_async.py` | Advanced async patterns |
|
|
396
|
+
|
|
397
|
+
## Supported Models
|
|
398
|
+
|
|
399
|
+
Access 300+ models from providers:
|
|
400
|
+
|
|
401
|
+
- **OpenAI**: GPT-4o, GPT-4 Turbo, GPT-4o-mini, o1, o1-mini
|
|
402
|
+
- **Anthropic**: Claude 3.5 Sonnet, Claude 3 Opus, Claude 3 Haiku
|
|
403
|
+
- **Google**: Gemini 2.0 Flash, Gemini 1.5 Pro
|
|
404
|
+
- **Meta**: Llama 3.3, Llama 3.2, Llama 3.1
|
|
405
|
+
- **Mistral**: Mistral Large, Mixtral, Codestral
|
|
406
|
+
- **DeepSeek**: DeepSeek V3, DeepSeek R1
|
|
407
|
+
- And many more via OpenRouter
|
|
408
|
+
|
|
409
|
+
## License
|
|
410
|
+
|
|
411
|
+
MIT
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
sdkrouter/__init__.py,sha256=UqMKtjTKHSJRFdppUN-gA8qfalZ6XBwz-VkXZehIMEE,2744
|
|
2
|
+
sdkrouter/_client.py,sha256=Z0EUu-yn1fsK3AO4UP0uL9vw771XFZ-95jhnVYbOU1c,13549
|
|
3
|
+
sdkrouter/_config.py,sha256=BPPLRvzbXXjTO5DrhDqD3Uk3ccpc-41d0LecXijMAlI,1727
|
|
4
|
+
sdkrouter/_constants.py,sha256=AHnmlB8b4D-hZBxKBfHMTSxiBYls2qFI0c5NzDhCa40,646
|
|
5
|
+
sdkrouter/_version.py,sha256=HOmU5sgXU14tXjdvSe0iIIyluugGL0Y7R8eo1JaeyxE,50
|
|
6
|
+
sdkrouter/_api/__init__.py,sha256=aSF9FQUefSGFxQJZbJF6ymHVyx3PG_WpjbVdtRrn8Ic,689
|
|
7
|
+
sdkrouter/_api/client.py,sha256=OHyLwLjaU5Bv_QbUKqRiMlHPqOeYEiI6cPwAajfx828,6338
|
|
8
|
+
sdkrouter/_api/generated/__init__.py,sha256=RAmJClmGx8ydM7FojH81kck3CIq03TRPRday5DTVTHk,337
|
|
9
|
+
sdkrouter/_api/generated/cdn/__init__.py,sha256=pP7ZcfvzE1vuRWuERiGmn8Vbj6oNRYtXMOwW6mYqYoA,5762
|
|
10
|
+
sdkrouter/_api/generated/cdn/client.py,sha256=ONlIKg31OO8qU02tIZcJW15jeFX14qcCp2AJpZVz8lM,2302
|
|
11
|
+
sdkrouter/_api/generated/cdn/logger.py,sha256=K-HR1NHAou-rgjEasPAqdjeVWmqtbnRXUXp5jLdTBI4,7657
|
|
12
|
+
sdkrouter/_api/generated/cdn/pyproject.toml,sha256=gG2iN-lj5KNWObYjzORobhyzy8O1QwNBqyKe2yTZLks,1287
|
|
13
|
+
sdkrouter/_api/generated/cdn/retry.py,sha256=M8s4OiWZDcnjPa300zkgJ2Ws7vHfx4qF-WQZ9MSVM8s,8186
|
|
14
|
+
sdkrouter/_api/generated/cdn/sync_client.py,sha256=RjhZFJMpJhcIYejBByM5a1W-ypFjb10-fLY646HGhdk,1549
|
|
15
|
+
sdkrouter/_api/generated/cdn/cdn__api__cdn/__init__.py,sha256=ijXjXU-jXEluawhdMNe7NPGfphvJFBtJaf1SJIYc2-Y,129
|
|
16
|
+
sdkrouter/_api/generated/cdn/cdn__api__cdn/client.py,sha256=_j9Y_018rBfUyvQwlAU8dMFTg5OLzCiUQQTfLIgOn60,5357
|
|
17
|
+
sdkrouter/_api/generated/cdn/cdn__api__cdn/models.py,sha256=qe-NoptWzSPx43f-IvYnd6CY4gHbccgI5Pn0pLda84s,5481
|
|
18
|
+
sdkrouter/_api/generated/cdn/cdn__api__cdn/sync_client.py,sha256=g4xkbUYWszFJ8KsWnG-QCq1ZzRypjcClbiv6dezYW4I,5269
|
|
19
|
+
sdkrouter/_api/generated/cleaner/__init__.py,sha256=WilObcZ3Fvi06cqeJZFYI7dqC_WOO0fNdJlbIJNDc8g,6032
|
|
20
|
+
sdkrouter/_api/generated/cleaner/client.py,sha256=rAj-GyZOv3Wdj1NekztS4NOz1fPSeDjh-dkSrcvdbTA,2334
|
|
21
|
+
sdkrouter/_api/generated/cleaner/enums.py,sha256=STQuEcvNgcH1LcGfbaRsn7M-1q9TjNSTbdR85ezEpLo,1052
|
|
22
|
+
sdkrouter/_api/generated/cleaner/logger.py,sha256=K-HR1NHAou-rgjEasPAqdjeVWmqtbnRXUXp5jLdTBI4,7657
|
|
23
|
+
sdkrouter/_api/generated/cleaner/pyproject.toml,sha256=gG2iN-lj5KNWObYjzORobhyzy8O1QwNBqyKe2yTZLks,1287
|
|
24
|
+
sdkrouter/_api/generated/cleaner/retry.py,sha256=M8s4OiWZDcnjPa300zkgJ2Ws7vHfx4qF-WQZ9MSVM8s,8186
|
|
25
|
+
sdkrouter/_api/generated/cleaner/sync_client.py,sha256=qYX8QYGtiMZzS0962-7YXF1111QFmIVjl8esvk3VYGM,1581
|
|
26
|
+
sdkrouter/_api/generated/cleaner/cleaner__api__cleaner/__init__.py,sha256=KbCnQFMaFet5dhqmmgEdkGVcVhQVt9uRdBnLr98bWN8,145
|
|
27
|
+
sdkrouter/_api/generated/cleaner/cleaner__api__cleaner/client.py,sha256=UOwKQS4yKJRa0WC2RTU9tIFsU31-g23PMbxPiiF9E8A,2735
|
|
28
|
+
sdkrouter/_api/generated/cleaner/cleaner__api__cleaner/models.py,sha256=MQGBVDootbBP-OGsGDXk8cRPicCGoQKGSDqLPQ9Kf6Y,3606
|
|
29
|
+
sdkrouter/_api/generated/cleaner/cleaner__api__cleaner/sync_client.py,sha256=7osVWKhA01Z_nnHljQflMIeLOV7ObxDReAjRCJqfA6c,2683
|
|
30
|
+
sdkrouter/_api/generated/keys/__init__.py,sha256=liBIAQThozQQXauirSreKttuItb8_C0oCRZy7rsY44s,6011
|
|
31
|
+
sdkrouter/_api/generated/keys/client.py,sha256=GsnmV3xO-7qQt6-_VRxhIywlXOW1ksQaQPOivId2YSo,2310
|
|
32
|
+
sdkrouter/_api/generated/keys/enums.py,sha256=6Wmww_MJH1xYkX8odw-smGJzym9P5vtzC71l9FdmhXE,1127
|
|
33
|
+
sdkrouter/_api/generated/keys/logger.py,sha256=K-HR1NHAou-rgjEasPAqdjeVWmqtbnRXUXp5jLdTBI4,7657
|
|
34
|
+
sdkrouter/_api/generated/keys/pyproject.toml,sha256=gG2iN-lj5KNWObYjzORobhyzy8O1QwNBqyKe2yTZLks,1287
|
|
35
|
+
sdkrouter/_api/generated/keys/retry.py,sha256=M8s4OiWZDcnjPa300zkgJ2Ws7vHfx4qF-WQZ9MSVM8s,8186
|
|
36
|
+
sdkrouter/_api/generated/keys/sync_client.py,sha256=VO1Bcjir_GX6cRsgEQGfRHkk0dgPSCsdq67u_pbJthc,1557
|
|
37
|
+
sdkrouter/_api/generated/keys/keys__api__keys/__init__.py,sha256=GDxmzQ-cJYF589LxYqq5xeT02et8MCT-GfCdOBDFFFs,133
|
|
38
|
+
sdkrouter/_api/generated/keys/keys__api__keys/client.py,sha256=ATf48XVfdgbetg4dHiygca8RMxcQhS62wnLYsP-LDqE,6210
|
|
39
|
+
sdkrouter/_api/generated/keys/keys__api__keys/models.py,sha256=StlPBP8gzVz-NJcooxeQs27EXLHvSpUyr5hdcRde29A,6236
|
|
40
|
+
sdkrouter/_api/generated/keys/keys__api__keys/sync_client.py,sha256=_reHLgT97uRkyqcaZxEPEGt0O2S2UCkG9-WKE-qGXEU,6110
|
|
41
|
+
sdkrouter/_api/generated/models/__init__.py,sha256=52fZpK96mh_6z0Bf-W2yfEq_OwDeetRWiqhVl0D-bSg,5817
|
|
42
|
+
sdkrouter/_api/generated/models/client.py,sha256=vHntHUDA-6nt_4732mMMbrpb2Bs1M6QChhAfsYIbIaE,2340
|
|
43
|
+
sdkrouter/_api/generated/models/logger.py,sha256=K-HR1NHAou-rgjEasPAqdjeVWmqtbnRXUXp5jLdTBI4,7657
|
|
44
|
+
sdkrouter/_api/generated/models/pyproject.toml,sha256=gG2iN-lj5KNWObYjzORobhyzy8O1QwNBqyKe2yTZLks,1287
|
|
45
|
+
sdkrouter/_api/generated/models/retry.py,sha256=M8s4OiWZDcnjPa300zkgJ2Ws7vHfx4qF-WQZ9MSVM8s,8186
|
|
46
|
+
sdkrouter/_api/generated/models/sync_client.py,sha256=MslmRs1Bwdzet2cqwJshKjXA_KQJ02blZ55ZXMokrz0,1587
|
|
47
|
+
sdkrouter/_api/generated/models/models__api__llm_models/__init__.py,sha256=oUueTlLHl8_GPos1FQUDPMIlL5vhhBy98hoGPm_mDLg,147
|
|
48
|
+
sdkrouter/_api/generated/models/models__api__llm_models/client.py,sha256=3GKvPBTl4Txtw0YEgp03JsU4OZsew7Ox4Q-tMhtcDdM,3600
|
|
49
|
+
sdkrouter/_api/generated/models/models__api__llm_models/models.py,sha256=FunYI27mhiAo9tpuic7uj0ZiV5PwrVpUdc1RChQYbOA,6911
|
|
50
|
+
sdkrouter/_api/generated/models/models__api__llm_models/sync_client.py,sha256=r_nVuntylyD-m6gmVK4FONwEohfc6_lybL_qIWj4giI,3556
|
|
51
|
+
sdkrouter/_api/generated/shortlinks/__init__.py,sha256=gqVupuKvtZMmdkB0tMZ9GnWfJaieL8jvwNEAxjlzu9c,5839
|
|
52
|
+
sdkrouter/_api/generated/shortlinks/client.py,sha256=07HQCbeUUJgWAdRdR8YuxlN5syceD31eL3xwvvzf2Hs,2358
|
|
53
|
+
sdkrouter/_api/generated/shortlinks/logger.py,sha256=K-HR1NHAou-rgjEasPAqdjeVWmqtbnRXUXp5jLdTBI4,7657
|
|
54
|
+
sdkrouter/_api/generated/shortlinks/pyproject.toml,sha256=gG2iN-lj5KNWObYjzORobhyzy8O1QwNBqyKe2yTZLks,1287
|
|
55
|
+
sdkrouter/_api/generated/shortlinks/retry.py,sha256=M8s4OiWZDcnjPa300zkgJ2Ws7vHfx4qF-WQZ9MSVM8s,8186
|
|
56
|
+
sdkrouter/_api/generated/shortlinks/sync_client.py,sha256=K8W11uYsQtVSv59lyPdjPxOjc4RFpiihfRgMIVE50y0,1605
|
|
57
|
+
sdkrouter/_api/generated/shortlinks/shortlinks__api__shortlinks/__init__.py,sha256=1M1Wf4nOBRFYp28PUsb3ZWsg57UpDaThWik6RU6O9No,157
|
|
58
|
+
sdkrouter/_api/generated/shortlinks/shortlinks__api__shortlinks/client.py,sha256=whiwTZpCGnJ1sdPu_34IdOXheoBjClYr4YPg9QM_wdA,5736
|
|
59
|
+
sdkrouter/_api/generated/shortlinks/shortlinks__api__shortlinks/models.py,sha256=Bp7ar1bD0d1mw61AE-oJLISDMJkk9uGZxowp7bo3zSo,4700
|
|
60
|
+
sdkrouter/_api/generated/shortlinks/shortlinks__api__shortlinks/sync_client.py,sha256=feftSTM3HK2AVHK58EeeKCaQpjA3GcyI0Z4Rry-kQUQ,5648
|
|
61
|
+
sdkrouter/_api/generated/vision/__init__.py,sha256=Qb54nP46wKTrAkiMoV7SgHJuS1B4f71uAu1WFjvyvqc,5995
|
|
62
|
+
sdkrouter/_api/generated/vision/client.py,sha256=6Gajk-gb6LQoyLafYLI3c_8nkHa16eruKNUNJxq014E,2326
|
|
63
|
+
sdkrouter/_api/generated/vision/enums.py,sha256=fQ570frlDg7_-l1vDBSUOF0w-QbM3QGbvkROMM9pgZM,1008
|
|
64
|
+
sdkrouter/_api/generated/vision/logger.py,sha256=K-HR1NHAou-rgjEasPAqdjeVWmqtbnRXUXp5jLdTBI4,7657
|
|
65
|
+
sdkrouter/_api/generated/vision/pyproject.toml,sha256=gG2iN-lj5KNWObYjzORobhyzy8O1QwNBqyKe2yTZLks,1287
|
|
66
|
+
sdkrouter/_api/generated/vision/retry.py,sha256=M8s4OiWZDcnjPa300zkgJ2Ws7vHfx4qF-WQZ9MSVM8s,8186
|
|
67
|
+
sdkrouter/_api/generated/vision/sync_client.py,sha256=TuroZp4eFTyD23CukQLct32XDUVbD3Qt517ni0JaYNM,1573
|
|
68
|
+
sdkrouter/_api/generated/vision/vision__api__vision/__init__.py,sha256=jRqx8ZNhfr3FgswhjksUl2Z1Qr0b_Sg8qdKj5tl3u98,141
|
|
69
|
+
sdkrouter/_api/generated/vision/vision__api__vision/client.py,sha256=xj_0GRBULHbDnL2ojXtTUbdhp6rDS3gbb7BAxEtIqNA,2203
|
|
70
|
+
sdkrouter/_api/generated/vision/vision__api__vision/models.py,sha256=0B0FvmRGQEioesS3xaB720lnD4Q9-yJMQaEVgRmbWHM,4862
|
|
71
|
+
sdkrouter/_api/generated/vision/vision__api__vision/sync_client.py,sha256=NjQON5S-av2h6r5tUuEj7sYocBuM2ElN_y9QkNTzFFs,2183
|
|
72
|
+
sdkrouter/_internal/__init__.py,sha256=xDPv3bEpN-trOAI6awa1kN0REZuWs_6lX2z3mPoSv44,49
|
|
73
|
+
sdkrouter/_types/__init__.py,sha256=8lelczoKONcZgU3wXbEIxUavfb92z3uxAk2Nt82Mqi8,752
|
|
74
|
+
sdkrouter/_types/cdn.py,sha256=DXAdfoYSRFxWYuLjVa-W7NYZzA0rWKqwu_snW3EJxso,1035
|
|
75
|
+
sdkrouter/_types/models.py,sha256=maK2bjLZ81t0rmpuv6Wq3z7iekkOQqhsH6JHakxDOn0,981
|
|
76
|
+
sdkrouter/_types/ocr.py,sha256=0KCQWhKUNiBIJrOwnhwsR9cCqm6KHVP6_eTtWed3AGw,774
|
|
77
|
+
sdkrouter/_types/parsed.py,sha256=rW-YOXJvOd8o9xhOcD_Bdhhz8Jaj4LAPPF-R1q-3q20,3119
|
|
78
|
+
sdkrouter/_types/shortlinks.py,sha256=VSPiHUs1CVXgNeyxuOtkYd8xhXU-Zt07W7C-OwYYyR0,1051
|
|
79
|
+
sdkrouter/_types/vision.py,sha256=svXUeCwVAW2MJYrCkMXPMDs9eGIrv-Ad4CJ166Q8Z80,1273
|
|
80
|
+
sdkrouter/helpers/__init__.py,sha256=gM7KEW7_u3nLXB_BS5szlNg7wRB1cnZTjWoNGlN-Gbw,325
|
|
81
|
+
sdkrouter/helpers/formatting.py,sha256=lLYUEyzZLUSXq2xHB2w3i72QoP_baHjtFpP-7mb-V-s,341
|
|
82
|
+
sdkrouter/helpers/html.py,sha256=3gtVivqAT3Yj8hZk1F8-xgbZrrvUwQ1cWoiU0HfCM7c,2400
|
|
83
|
+
sdkrouter/helpers/json_cleaner.py,sha256=3XWB3KpRSMgJ1Go0G7rE9bgDGy1bshk9PtWWB6pL7AU,1792
|
|
84
|
+
sdkrouter/tools/__init__.py,sha256=43zU2unEcWkUpKLdycSEUc706VQ-QhYLjEVJIn1LZlM,3033
|
|
85
|
+
sdkrouter/tools/cdn.py,sha256=uXB__KRCEw0PIT1TmYa2JHGn4MvJItT8Bsgy-xzomx8,9349
|
|
86
|
+
sdkrouter/tools/cleaner.py,sha256=-OLZopvy9P_OzcjR7Jwl3-7pKleNwyxglxJIXCwM_Qg,6280
|
|
87
|
+
sdkrouter/tools/keys.py,sha256=z0r-D4Qy7HbLeZ6YsOy_PeJlTWxE4swez7sMwphXkPE,6465
|
|
88
|
+
sdkrouter/tools/models.py,sha256=v1XyWoAuDn7vHC0qkFxOhHgfwngS45CFejOWotclQNE,5219
|
|
89
|
+
sdkrouter/tools/shortlinks.py,sha256=ONhwXN9Di99Z768sa0G5V1DuzvwdR9MnCi5I2Szo40M,4713
|
|
90
|
+
sdkrouter/tools/vision.py,sha256=kKpCye7BarrSvbPo0EvbB5_Y77PPn8APEjrOSo5Bdc8,5482
|
|
91
|
+
sdkrouter/utils/__init__.py,sha256=qb9daG3XkXpqjzLGChJ-iqwdDlSzeoM9IPg5TE9T7cA,587
|
|
92
|
+
sdkrouter/utils/parsing.py,sha256=iQcJhIMj8QWk2RlnuVCJUzAGt7KI_F5_JkDYfSDVWl4,3056
|
|
93
|
+
sdkrouter/utils/tokens.py,sha256=h_CGa_30bAM2hZof3JtqPFzmnfUC_rlh1qgpRfS69FQ,9774
|
|
94
|
+
sdkrouter-0.1.1.dist-info/METADATA,sha256=Sw1-v96Gonz1V5CrlmxZCF7A1AiBstDtcKDsp0splzM,10549
|
|
95
|
+
sdkrouter-0.1.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
96
|
+
sdkrouter-0.1.1.dist-info/RECORD,,
|