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,58 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Optional
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
|
|
7
|
+
from .vision__api__vision.sync_client import SyncVisionVisionAPI
|
|
8
|
+
from .logger import APILogger, LoggerConfig
|
|
9
|
+
from .retry import RetryConfig, RetryAsyncClient
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SyncAPIClient:
|
|
13
|
+
"""
|
|
14
|
+
Synchronous API client for SDKRouter API.
|
|
15
|
+
|
|
16
|
+
Usage:
|
|
17
|
+
>>> with SyncAPIClient(base_url='https://api.example.com') as client:
|
|
18
|
+
... users = client.users.list()
|
|
19
|
+
... post = client.posts.create(data=new_post)
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
base_url: str,
|
|
25
|
+
logger_config: Optional[LoggerConfig] = None,
|
|
26
|
+
**kwargs: Any,
|
|
27
|
+
):
|
|
28
|
+
"""
|
|
29
|
+
Initialize sync API client.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
base_url: Base API URL (e.g., 'https://api.example.com')
|
|
33
|
+
logger_config: Logger configuration (None to disable logging)
|
|
34
|
+
**kwargs: Additional httpx.Client kwargs
|
|
35
|
+
"""
|
|
36
|
+
self.base_url = base_url.rstrip('/')
|
|
37
|
+
self._client = httpx.Client(
|
|
38
|
+
base_url=self.base_url,
|
|
39
|
+
**kwargs,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Initialize logger
|
|
43
|
+
self.logger: Optional[APILogger] = None
|
|
44
|
+
if logger_config is not None:
|
|
45
|
+
self.logger = APILogger(logger_config)
|
|
46
|
+
|
|
47
|
+
# Initialize sub-clients
|
|
48
|
+
self.vision_vision = SyncVisionVisionAPI(self._client)
|
|
49
|
+
|
|
50
|
+
def __enter__(self) -> 'SyncAPIClient':
|
|
51
|
+
return self
|
|
52
|
+
|
|
53
|
+
def __exit__(self, *args: Any) -> None:
|
|
54
|
+
self._client.close()
|
|
55
|
+
|
|
56
|
+
def close(self) -> None:
|
|
57
|
+
"""Close HTTP client."""
|
|
58
|
+
self._client.close()
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import httpx
|
|
4
|
+
|
|
5
|
+
from .models import *
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class VisionVisionAPI:
|
|
9
|
+
"""API endpoints for Vision."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, client: httpx.AsyncClient):
|
|
12
|
+
"""Initialize sub-client with shared httpx client."""
|
|
13
|
+
self._client = client
|
|
14
|
+
|
|
15
|
+
async def analyze_create(self, data: VisionAnalyzeRequestRequest) -> VisionAnalyzeResponse:
|
|
16
|
+
"""
|
|
17
|
+
Analyze image
|
|
18
|
+
|
|
19
|
+
Analyze an image with vision model.
|
|
20
|
+
"""
|
|
21
|
+
url = "/api/vision/analyze/"
|
|
22
|
+
response = await self._client.post(url, json=data.model_dump(exclude_unset=True))
|
|
23
|
+
if not response.is_success:
|
|
24
|
+
try:
|
|
25
|
+
error_body = response.json()
|
|
26
|
+
except Exception:
|
|
27
|
+
error_body = response.text
|
|
28
|
+
raise httpx.HTTPStatusError(f"{response.status_code}: {error_body}", request=response.request, response=response)
|
|
29
|
+
return VisionAnalyzeResponse.model_validate(response.json())
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
async def models_retrieve(self) -> VisionModelsResponse:
|
|
33
|
+
"""
|
|
34
|
+
Get vision models
|
|
35
|
+
|
|
36
|
+
Get supported vision models.
|
|
37
|
+
"""
|
|
38
|
+
url = "/api/vision/models/"
|
|
39
|
+
response = await self._client.get(url)
|
|
40
|
+
if not response.is_success:
|
|
41
|
+
try:
|
|
42
|
+
error_body = response.json()
|
|
43
|
+
except Exception:
|
|
44
|
+
error_body = response.text
|
|
45
|
+
raise httpx.HTTPStatusError(f"{response.status_code}: {error_body}", request=response.request, response=response)
|
|
46
|
+
return VisionModelsResponse.model_validate(response.json())
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
async def ocr_create(self, data: OCRRequestRequest) -> OCRResponse:
|
|
50
|
+
"""
|
|
51
|
+
OCR extraction
|
|
52
|
+
|
|
53
|
+
Extract text from image using OCR.
|
|
54
|
+
"""
|
|
55
|
+
url = "/api/vision/ocr/"
|
|
56
|
+
response = await self._client.post(url, json=data.model_dump(exclude_unset=True))
|
|
57
|
+
if not response.is_success:
|
|
58
|
+
try:
|
|
59
|
+
error_body = response.json()
|
|
60
|
+
except Exception:
|
|
61
|
+
error_body = response.text
|
|
62
|
+
raise httpx.HTTPStatusError(f"{response.status_code}: {error_body}", request=response.request, response=response)
|
|
63
|
+
return OCRResponse.model_validate(response.json())
|
|
64
|
+
|
|
65
|
+
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Auto-generated by DjangoCFG - see CLAUDE.md
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
8
|
+
|
|
9
|
+
from ..enums import OCRRequestRequestMode, VisionAnalyzeRequestRequestModelQuality
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class VisionAnalyzeRequestRequest(BaseModel):
|
|
13
|
+
"""
|
|
14
|
+
Request serializer for vision analysis.
|
|
15
|
+
|
|
16
|
+
Request model (no read-only fields).
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
model_config = ConfigDict(
|
|
20
|
+
validate_assignment=True,
|
|
21
|
+
extra="allow",
|
|
22
|
+
frozen=False,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
image: str | None = Field(None, description='Base64 encoded image data')
|
|
26
|
+
image_url: str | None = Field(None, description='URL of the image to analyze')
|
|
27
|
+
prompt: str | None = Field(None, description='Custom prompt for analysis (optional)', max_length=2000)
|
|
28
|
+
model: str | None = Field(None, description="Specific model to use (e.g., 'openai/gpt-4o')", max_length=100)
|
|
29
|
+
model_quality: VisionAnalyzeRequestRequestModelQuality | None = Field(None, description='Model quality tier (fast, balanced, best)\n\n* `fast` - Fast - lower quality, cheaper\n* `balanced` - Balanced - good quality, reasonable cost\n* `best` - Best - highest quality, most expensive')
|
|
30
|
+
fetch_image: bool | None = Field(None, description='Whether to fetch image from URL (default: True)')
|
|
31
|
+
max_tokens: int | None = Field(None, description='Maximum tokens in response', ge=1, le=4096)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class Usage(BaseModel):
|
|
36
|
+
"""
|
|
37
|
+
Token usage statistics.
|
|
38
|
+
|
|
39
|
+
Response model (includes read-only fields).
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
model_config = ConfigDict(
|
|
43
|
+
validate_assignment=True,
|
|
44
|
+
extra="allow",
|
|
45
|
+
frozen=False,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
prompt_tokens: int = Field(description='Tokens in prompt')
|
|
49
|
+
completion_tokens: int = Field(description='Tokens in completion')
|
|
50
|
+
total_tokens: int = Field(description='Total tokens used')
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class VisionAnalyzeResponse(BaseModel):
|
|
55
|
+
"""
|
|
56
|
+
Response serializer for vision analysis.
|
|
57
|
+
|
|
58
|
+
Response model (includes read-only fields).
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
model_config = ConfigDict(
|
|
62
|
+
validate_assignment=True,
|
|
63
|
+
extra="allow",
|
|
64
|
+
frozen=False,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
extracted_text: str = Field(description='Text extracted from the image')
|
|
68
|
+
description: str = Field(description='Description/analysis of the image')
|
|
69
|
+
language: str | None = Field(None, description='Detected language of text in image')
|
|
70
|
+
model: str = Field(description='Model used for analysis')
|
|
71
|
+
usage: Usage | None = None
|
|
72
|
+
cost_usd: float = Field(description='Cost of this request in USD')
|
|
73
|
+
cached: bool | None = Field(None, description='Whether result was from cache')
|
|
74
|
+
request_uuid: str | None = Field(None, description='UUID of the tracked request')
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class VisionModelsResponse(BaseModel):
|
|
79
|
+
"""
|
|
80
|
+
Response serializer for supported vision models.
|
|
81
|
+
|
|
82
|
+
Response model (includes read-only fields).
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
model_config = ConfigDict(
|
|
86
|
+
validate_assignment=True,
|
|
87
|
+
extra="allow",
|
|
88
|
+
frozen=False,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
vision_models: dict[str, Any] = Field(description='Vision models by quality tier. Options: fast, balanced, best')
|
|
92
|
+
ocr_models: dict[str, Any] = Field(description='OCR models by mode. Options: tiny, small, base, maximum')
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class OCRRequestRequest(BaseModel):
|
|
97
|
+
"""
|
|
98
|
+
Request serializer for OCR extraction.
|
|
99
|
+
|
|
100
|
+
Request model (no read-only fields).
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
model_config = ConfigDict(
|
|
104
|
+
validate_assignment=True,
|
|
105
|
+
extra="allow",
|
|
106
|
+
frozen=False,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
image: str | None = Field(None, description='Base64 encoded image data')
|
|
110
|
+
image_url: str | None = Field(None, description='URL of the image for OCR')
|
|
111
|
+
mode: OCRRequestRequestMode | None = Field(None, description='OCR mode affecting quality and speed\n\n* `tiny` - Tiny - fastest, basic text extraction\n* `small` - Small - fast, good for simple text\n* `base` - Base - balanced speed and accuracy\n* `maximum` - Maximum - best accuracy, slower')
|
|
112
|
+
language_hint: str | None = Field(None, description="Hint for expected language (e.g., 'ko', 'en', 'zh')", max_length=10)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class OCRResponse(BaseModel):
|
|
117
|
+
"""
|
|
118
|
+
Response serializer for OCR extraction.
|
|
119
|
+
|
|
120
|
+
Response model (includes read-only fields).
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
model_config = ConfigDict(
|
|
124
|
+
validate_assignment=True,
|
|
125
|
+
extra="allow",
|
|
126
|
+
frozen=False,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
text: str = Field(description='Extracted text from the image')
|
|
130
|
+
confidence: float | None = Field(None, description='Confidence score of OCR extraction', ge=0.0, le=1.0)
|
|
131
|
+
language: str | None = Field(None, description='Detected language of extracted text')
|
|
132
|
+
model: str = Field(description='OCR model used')
|
|
133
|
+
cost_usd: float = Field(description='Cost of this request in USD')
|
|
134
|
+
cached: bool | None = Field(None, description='Whether result was from cache')
|
|
135
|
+
request_uuid: str | None = Field(None, description='UUID of the tracked request')
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import httpx
|
|
4
|
+
|
|
5
|
+
from .models import *
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SyncVisionVisionAPI:
|
|
9
|
+
"""Synchronous API endpoints for Vision."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, client: httpx.Client):
|
|
12
|
+
"""Initialize sync sub-client with shared httpx client."""
|
|
13
|
+
self._client = client
|
|
14
|
+
|
|
15
|
+
def analyze_create(self, data: VisionAnalyzeRequestRequest) -> VisionAnalyzeResponse:
|
|
16
|
+
"""
|
|
17
|
+
Analyze image
|
|
18
|
+
|
|
19
|
+
Analyze an image with vision model.
|
|
20
|
+
"""
|
|
21
|
+
url = "/api/vision/analyze/"
|
|
22
|
+
response = self._client.post(url, json=data.model_dump(exclude_unset=True))
|
|
23
|
+
if not response.is_success:
|
|
24
|
+
try:
|
|
25
|
+
error_body = response.json()
|
|
26
|
+
except Exception:
|
|
27
|
+
error_body = response.text
|
|
28
|
+
raise httpx.HTTPStatusError(f"{response.status_code}: {error_body}", request=response.request, response=response)
|
|
29
|
+
return VisionAnalyzeResponse.model_validate(response.json())
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def models_retrieve(self) -> VisionModelsResponse:
|
|
33
|
+
"""
|
|
34
|
+
Get vision models
|
|
35
|
+
|
|
36
|
+
Get supported vision models.
|
|
37
|
+
"""
|
|
38
|
+
url = "/api/vision/models/"
|
|
39
|
+
response = self._client.get(url)
|
|
40
|
+
if not response.is_success:
|
|
41
|
+
try:
|
|
42
|
+
error_body = response.json()
|
|
43
|
+
except Exception:
|
|
44
|
+
error_body = response.text
|
|
45
|
+
raise httpx.HTTPStatusError(f"{response.status_code}: {error_body}", request=response.request, response=response)
|
|
46
|
+
return VisionModelsResponse.model_validate(response.json())
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def ocr_create(self, data: OCRRequestRequest) -> OCRResponse:
|
|
50
|
+
"""
|
|
51
|
+
OCR extraction
|
|
52
|
+
|
|
53
|
+
Extract text from image using OCR.
|
|
54
|
+
"""
|
|
55
|
+
url = "/api/vision/ocr/"
|
|
56
|
+
response = self._client.post(url, json=data.model_dump(exclude_unset=True))
|
|
57
|
+
if not response.is_success:
|
|
58
|
+
try:
|
|
59
|
+
error_body = response.json()
|
|
60
|
+
except Exception:
|
|
61
|
+
error_body = response.text
|
|
62
|
+
raise httpx.HTTPStatusError(f"{response.status_code}: {error_body}", request=response.request, response=response)
|
|
63
|
+
return OCRResponse.model_validate(response.json())
|
|
64
|
+
|
|
65
|
+
|