python-open-router 0.3.2__py3-none-any.whl → 0.4.0__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.
- python_open_router/__init__.py +18 -4
- python_open_router/models.py +143 -20
- python_open_router/open_router.py +157 -9
- {python_open_router-0.3.2.dist-info → python_open_router-0.4.0.dist-info}/METADATA +1 -1
- python_open_router-0.4.0.dist-info/RECORD +9 -0
- {python_open_router-0.3.2.dist-info → python_open_router-0.4.0.dist-info}/WHEEL +1 -1
- python_open_router-0.3.2.dist-info/RECORD +0 -9
- {python_open_router-0.3.2.dist-info → python_open_router-0.4.0.dist-info}/licenses/LICENSE.md +0 -0
python_open_router/__init__.py
CHANGED
|
@@ -6,34 +6,48 @@ from python_open_router.exceptions import (
|
|
|
6
6
|
OpenRouterError,
|
|
7
7
|
)
|
|
8
8
|
from python_open_router.models import (
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
DefaultParameters,
|
|
10
|
+
DeletedKeyResponse,
|
|
11
11
|
Key,
|
|
12
|
+
KeyCreateResponse,
|
|
12
13
|
KeyData,
|
|
13
14
|
KeyDataWrapper,
|
|
15
|
+
KeyResponseWrapper,
|
|
14
16
|
KeysDataWrapper,
|
|
15
17
|
Modality,
|
|
16
18
|
Model,
|
|
17
19
|
ModelArchitecture,
|
|
20
|
+
ModelLinks,
|
|
21
|
+
ModelResponseWrapper,
|
|
18
22
|
ModelsDataWrapper,
|
|
23
|
+
PerRequestLimits,
|
|
24
|
+
PublicPricing,
|
|
19
25
|
SupportedParameter,
|
|
26
|
+
TopProviderInfo,
|
|
20
27
|
)
|
|
21
28
|
from python_open_router.open_router import OpenRouterClient
|
|
22
29
|
|
|
23
30
|
__all__ = [
|
|
24
|
-
"
|
|
25
|
-
"
|
|
31
|
+
"DefaultParameters",
|
|
32
|
+
"DeletedKeyResponse",
|
|
26
33
|
"Key",
|
|
34
|
+
"KeyCreateResponse",
|
|
27
35
|
"KeyData",
|
|
28
36
|
"KeyDataWrapper",
|
|
37
|
+
"KeyResponseWrapper",
|
|
29
38
|
"KeysDataWrapper",
|
|
30
39
|
"Modality",
|
|
31
40
|
"Model",
|
|
32
41
|
"ModelArchitecture",
|
|
42
|
+
"ModelLinks",
|
|
43
|
+
"ModelResponseWrapper",
|
|
33
44
|
"ModelsDataWrapper",
|
|
34
45
|
"OpenRouterAuthenticationError",
|
|
35
46
|
"OpenRouterClient",
|
|
36
47
|
"OpenRouterConnectionError",
|
|
37
48
|
"OpenRouterError",
|
|
49
|
+
"PerRequestLimits",
|
|
50
|
+
"PublicPricing",
|
|
38
51
|
"SupportedParameter",
|
|
52
|
+
"TopProviderInfo",
|
|
39
53
|
]
|
python_open_router/models.py
CHANGED
|
@@ -24,10 +24,23 @@ class KeyData(DataClassORJSONMixin):
|
|
|
24
24
|
"""The OpenRouter key data."""
|
|
25
25
|
|
|
26
26
|
label: str
|
|
27
|
-
usage:
|
|
27
|
+
usage: float
|
|
28
28
|
is_provisioning_key: bool
|
|
29
|
-
limit_remaining:
|
|
29
|
+
limit_remaining: float | None
|
|
30
30
|
is_free_tier: bool
|
|
31
|
+
limit: float | None = None
|
|
32
|
+
limit_reset: str | None = None
|
|
33
|
+
usage_daily: float = 0.0
|
|
34
|
+
usage_weekly: float = 0.0
|
|
35
|
+
usage_monthly: float = 0.0
|
|
36
|
+
byok_usage: float = 0.0
|
|
37
|
+
byok_usage_daily: float = 0.0
|
|
38
|
+
byok_usage_weekly: float = 0.0
|
|
39
|
+
byok_usage_monthly: float = 0.0
|
|
40
|
+
include_byok_in_limit: bool = False
|
|
41
|
+
is_management_key: bool = False
|
|
42
|
+
creator_user_id: str | None = None
|
|
43
|
+
expires_at: str | None = None
|
|
31
44
|
|
|
32
45
|
|
|
33
46
|
@dataclass
|
|
@@ -38,10 +51,11 @@ class KeysDataWrapper(DataClassORJSONMixin):
|
|
|
38
51
|
|
|
39
52
|
|
|
40
53
|
@dataclass
|
|
41
|
-
class
|
|
42
|
-
"""
|
|
54
|
+
class KeyCreateResponse(DataClassORJSONMixin):
|
|
55
|
+
"""Response from creating a key."""
|
|
43
56
|
|
|
44
|
-
data:
|
|
57
|
+
data: Key
|
|
58
|
+
key: str
|
|
45
59
|
|
|
46
60
|
|
|
47
61
|
@dataclass
|
|
@@ -52,15 +66,44 @@ class Key(DataClassORJSONMixin):
|
|
|
52
66
|
name: str
|
|
53
67
|
label: str
|
|
54
68
|
disabled: bool
|
|
55
|
-
limit: float
|
|
69
|
+
limit: float | None = None
|
|
56
70
|
usage: float = 0.0
|
|
71
|
+
created_at: str = ""
|
|
72
|
+
updated_at: str | None = None
|
|
73
|
+
limit_remaining: float | None = None
|
|
74
|
+
limit_reset: str | None = None
|
|
75
|
+
workspace_id: str = ""
|
|
76
|
+
expires_at: str | None = None
|
|
77
|
+
usage_daily: float = 0.0
|
|
78
|
+
usage_weekly: float = 0.0
|
|
79
|
+
usage_monthly: float = 0.0
|
|
80
|
+
byok_usage: float = 0.0
|
|
81
|
+
byok_usage_daily: float = 0.0
|
|
82
|
+
byok_usage_weekly: float = 0.0
|
|
83
|
+
byok_usage_monthly: float = 0.0
|
|
84
|
+
include_byok_in_limit: bool = False
|
|
85
|
+
creator_user_id: str | None = None
|
|
57
86
|
|
|
58
87
|
|
|
59
|
-
@dataclass
|
|
60
|
-
class
|
|
61
|
-
"""
|
|
88
|
+
@dataclass
|
|
89
|
+
class KeyResponseWrapper(DataClassORJSONMixin):
|
|
90
|
+
"""Wrapper for single key response."""
|
|
91
|
+
|
|
92
|
+
data: Key
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@dataclass
|
|
96
|
+
class DeletedKeyResponse(DataClassORJSONMixin):
|
|
97
|
+
"""Response after deleting a key."""
|
|
98
|
+
|
|
99
|
+
deleted: bool
|
|
62
100
|
|
|
63
|
-
|
|
101
|
+
|
|
102
|
+
@dataclass
|
|
103
|
+
class ModelResponseWrapper(DataClassORJSONMixin):
|
|
104
|
+
"""Wrapper for single OpenRouter model response."""
|
|
105
|
+
|
|
106
|
+
data: Model
|
|
64
107
|
|
|
65
108
|
|
|
66
109
|
@dataclass
|
|
@@ -75,25 +118,29 @@ class SupportedParameter(StrEnum):
|
|
|
75
118
|
|
|
76
119
|
TEMPERATURE = "temperature"
|
|
77
120
|
TOP_P = "top_p"
|
|
121
|
+
TOP_K = "top_k"
|
|
78
122
|
MAX_TOKENS = "max_tokens"
|
|
123
|
+
MAX_COMPLETION_TOKENS = "max_completion_tokens"
|
|
79
124
|
REASONING = "reasoning"
|
|
125
|
+
REASONING_EFFORT = "reasoning_effort"
|
|
80
126
|
INCLUDE_REASONING = "include_reasoning"
|
|
81
127
|
STOP = "stop"
|
|
82
|
-
TOK_K = "top_k"
|
|
83
128
|
SEED = "seed"
|
|
84
129
|
RESPONSE_FORMAT = "response_format"
|
|
130
|
+
STRUCTURED_OUTPUTS = "structured_outputs"
|
|
85
131
|
TOOLS = "tools"
|
|
86
132
|
TOOL_CHOICE = "tool_choice"
|
|
133
|
+
PARALLEL_TOOL_CALLS = "parallel_tool_calls"
|
|
87
134
|
FREQUENCY_PENALTY = "frequency_penalty"
|
|
88
135
|
PRESENCE_PENALTY = "presence_penalty"
|
|
89
|
-
MIN_P = "min_p"
|
|
90
136
|
REPETITION_PENALTY = "repetition_penalty"
|
|
137
|
+
MIN_P = "min_p"
|
|
138
|
+
TOP_A = "top_a"
|
|
91
139
|
LOGPROBS = "logprobs"
|
|
92
140
|
LOGIT_BIAS = "logit_bias"
|
|
93
141
|
TOP_LOGPROBS = "top_logprobs"
|
|
94
|
-
STRUCTURED_OUTPUTS = "structured_outputs"
|
|
95
142
|
WEB_SEARCH_OPTIONS = "web_search_options"
|
|
96
|
-
|
|
143
|
+
VERBOSITY = "verbosity"
|
|
97
144
|
|
|
98
145
|
|
|
99
146
|
class Modality(StrEnum):
|
|
@@ -104,14 +151,78 @@ class Modality(StrEnum):
|
|
|
104
151
|
IMAGE = "image"
|
|
105
152
|
FILE = "file"
|
|
106
153
|
EMBEDDINGS = "embeddings"
|
|
154
|
+
VIDEO = "video"
|
|
155
|
+
RERANK = "rerank"
|
|
156
|
+
SPEECH = "speech"
|
|
157
|
+
TRANSCRIPTION = "transcription"
|
|
107
158
|
|
|
108
159
|
|
|
109
160
|
@dataclass(kw_only=True)
|
|
110
161
|
class ModelArchitecture(DataClassORJSONMixin):
|
|
111
|
-
"""Model data."""
|
|
162
|
+
"""Model architecture data."""
|
|
112
163
|
|
|
113
164
|
input_modalities: list[Modality]
|
|
114
165
|
output_modalities: list[Modality]
|
|
166
|
+
modality: str | None = None
|
|
167
|
+
instruct_type: str | None = None
|
|
168
|
+
tokenizer: str | None = None
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@dataclass(kw_only=True)
|
|
172
|
+
class PublicPricing(DataClassORJSONMixin):
|
|
173
|
+
"""Model pricing data."""
|
|
174
|
+
|
|
175
|
+
completion: str
|
|
176
|
+
prompt: str
|
|
177
|
+
audio: str | None = None
|
|
178
|
+
audio_output: str | None = None
|
|
179
|
+
image: str | None = None
|
|
180
|
+
image_output: str | None = None
|
|
181
|
+
image_token: str | None = None
|
|
182
|
+
input_audio_cache: str | None = None
|
|
183
|
+
input_cache_read: str | None = None
|
|
184
|
+
input_cache_write: str | None = None
|
|
185
|
+
input_cache_write_1h: str | None = None
|
|
186
|
+
internal_reasoning: str | None = None
|
|
187
|
+
request: str | None = None
|
|
188
|
+
web_search: str | None = None
|
|
189
|
+
discount: float | None = None
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
@dataclass(kw_only=True)
|
|
193
|
+
class TopProviderInfo(DataClassORJSONMixin):
|
|
194
|
+
"""Top provider information."""
|
|
195
|
+
|
|
196
|
+
is_moderated: bool
|
|
197
|
+
context_length: int | None = None
|
|
198
|
+
max_completion_tokens: int | None = None
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
@dataclass(kw_only=True)
|
|
202
|
+
class DefaultParameters(DataClassORJSONMixin):
|
|
203
|
+
"""Default model parameters."""
|
|
204
|
+
|
|
205
|
+
temperature: float | None = None
|
|
206
|
+
top_p: float | None = None
|
|
207
|
+
top_k: int | None = None
|
|
208
|
+
frequency_penalty: float | None = None
|
|
209
|
+
presence_penalty: float | None = None
|
|
210
|
+
repetition_penalty: float | None = None
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
@dataclass(kw_only=True)
|
|
214
|
+
class PerRequestLimits(DataClassORJSONMixin):
|
|
215
|
+
"""Per-request limits."""
|
|
216
|
+
|
|
217
|
+
completion_tokens: float
|
|
218
|
+
prompt_tokens: float
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
@dataclass(kw_only=True)
|
|
222
|
+
class ModelLinks(DataClassORJSONMixin):
|
|
223
|
+
"""Model links."""
|
|
224
|
+
|
|
225
|
+
details: str
|
|
115
226
|
|
|
116
227
|
|
|
117
228
|
@dataclass(kw_only=True)
|
|
@@ -120,24 +231,34 @@ class Model(DataClassORJSONMixin):
|
|
|
120
231
|
|
|
121
232
|
id: str
|
|
122
233
|
canonical_slug: str
|
|
123
|
-
hugging_face_id: str | None
|
|
124
234
|
name: str
|
|
125
|
-
|
|
126
|
-
context_length: int
|
|
235
|
+
context_length: int | None
|
|
127
236
|
architecture: ModelArchitecture
|
|
128
237
|
supported_parameters: list[SupportedParameter]
|
|
238
|
+
pricing: PublicPricing
|
|
239
|
+
top_provider: TopProviderInfo
|
|
240
|
+
hugging_face_id: str | None = None
|
|
241
|
+
description: str | None = None
|
|
242
|
+
created: int | None = None
|
|
243
|
+
default_parameters: DefaultParameters | None = None
|
|
244
|
+
links: ModelLinks | None = None
|
|
245
|
+
per_request_limits: PerRequestLimits | None = None
|
|
246
|
+
supported_voices: list[str] | None = None
|
|
247
|
+
expiration_date: str | None = None
|
|
248
|
+
knowledge_cutoff: str | None = None
|
|
129
249
|
|
|
130
250
|
@classmethod
|
|
131
251
|
def __pre_deserialize__(cls, d: dict[str, Any]) -> dict[str, Any]:
|
|
132
252
|
"""Pre deserialize hook."""
|
|
133
253
|
parameters = d.get("supported_parameters", [])
|
|
254
|
+
supported = set(SupportedParameter)
|
|
255
|
+
d["supported_parameters"] = [p for p in parameters if p in supported]
|
|
134
256
|
for parameter in parameters:
|
|
135
|
-
if parameter not in
|
|
257
|
+
if parameter not in supported:
|
|
136
258
|
_LOGGER.warning(
|
|
137
259
|
"Unsupported parameter: %s. Please report at https://github.com/joostlek/python-open-router/issues.",
|
|
138
260
|
parameter,
|
|
139
261
|
)
|
|
140
|
-
parameters.remove(parameter)
|
|
141
262
|
return d
|
|
142
263
|
|
|
143
264
|
@classmethod
|
|
@@ -145,4 +266,6 @@ class Model(DataClassORJSONMixin):
|
|
|
145
266
|
"""Post deserialize hook."""
|
|
146
267
|
if obj.hugging_face_id == "":
|
|
147
268
|
obj.hugging_face_id = None
|
|
269
|
+
if obj.description == "":
|
|
270
|
+
obj.description = None
|
|
148
271
|
return obj
|
|
@@ -9,17 +9,24 @@ import socket
|
|
|
9
9
|
from typing import TYPE_CHECKING, Any
|
|
10
10
|
|
|
11
11
|
from aiohttp import ClientError, ClientResponseError, ClientSession
|
|
12
|
-
from aiohttp.hdrs import METH_GET, METH_POST
|
|
12
|
+
from aiohttp.hdrs import METH_DELETE, METH_GET, METH_PATCH, METH_POST
|
|
13
|
+
import orjson
|
|
13
14
|
from yarl import URL
|
|
14
15
|
|
|
15
|
-
from python_open_router.exceptions import
|
|
16
|
+
from python_open_router.exceptions import (
|
|
17
|
+
OpenRouterAuthenticationError,
|
|
18
|
+
OpenRouterConnectionError,
|
|
19
|
+
)
|
|
16
20
|
from python_open_router.models import (
|
|
17
|
-
|
|
21
|
+
DeletedKeyResponse,
|
|
18
22
|
Key,
|
|
23
|
+
KeyCreateResponse,
|
|
19
24
|
KeyData,
|
|
20
25
|
KeyDataWrapper,
|
|
26
|
+
KeyResponseWrapper,
|
|
21
27
|
KeysDataWrapper,
|
|
22
28
|
Model,
|
|
29
|
+
ModelResponseWrapper,
|
|
23
30
|
ModelsDataWrapper,
|
|
24
31
|
)
|
|
25
32
|
|
|
@@ -81,6 +88,10 @@ class OpenRouterClient:
|
|
|
81
88
|
msg = "Error occurred while communicating with the service"
|
|
82
89
|
raise OpenRouterConnectionError(msg) from exception
|
|
83
90
|
|
|
91
|
+
if response.status == 401:
|
|
92
|
+
msg = "Authentication failed"
|
|
93
|
+
raise OpenRouterAuthenticationError(msg)
|
|
94
|
+
|
|
84
95
|
if response.status >= 400:
|
|
85
96
|
content_type = response.headers.get("Content-Type", "")
|
|
86
97
|
text = await response.text()
|
|
@@ -97,25 +108,162 @@ class OpenRouterClient:
|
|
|
97
108
|
response = await self._request(METH_GET, "key")
|
|
98
109
|
return KeyDataWrapper.from_json(response).data
|
|
99
110
|
|
|
100
|
-
async def get_keys(
|
|
111
|
+
async def get_keys(
|
|
112
|
+
self,
|
|
113
|
+
*,
|
|
114
|
+
include_disabled: bool | None = None,
|
|
115
|
+
offset: int | None = None,
|
|
116
|
+
workspace_id: str | None = None,
|
|
117
|
+
) -> list[Key]:
|
|
101
118
|
"""Get all keys."""
|
|
102
|
-
|
|
119
|
+
params: dict[str, Any] = {}
|
|
120
|
+
if include_disabled is not None:
|
|
121
|
+
params["include_disabled"] = str(include_disabled).lower()
|
|
122
|
+
if offset is not None:
|
|
123
|
+
params["offset"] = str(offset)
|
|
124
|
+
if workspace_id is not None:
|
|
125
|
+
params["workspace_id"] = workspace_id
|
|
126
|
+
response = await self._request(METH_GET, "keys", params=params or None)
|
|
103
127
|
return KeysDataWrapper.from_json(response).data
|
|
104
128
|
|
|
105
|
-
async def create_key(
|
|
129
|
+
async def create_key(
|
|
130
|
+
self,
|
|
131
|
+
name: str,
|
|
132
|
+
limit: float | None = None,
|
|
133
|
+
*,
|
|
134
|
+
limit_reset: str | None = None,
|
|
135
|
+
workspace_id: str | None = None,
|
|
136
|
+
expires_at: str | None = None,
|
|
137
|
+
include_byok_in_limit: bool | None = None,
|
|
138
|
+
) -> Key:
|
|
106
139
|
"""Create a new key."""
|
|
107
140
|
data: dict[str, Any] = {"name": name}
|
|
108
141
|
if limit is not None:
|
|
109
142
|
data["limit"] = limit
|
|
143
|
+
if limit_reset is not None:
|
|
144
|
+
data["limit_reset"] = limit_reset
|
|
145
|
+
if workspace_id is not None:
|
|
146
|
+
data["workspace_id"] = workspace_id
|
|
147
|
+
if expires_at is not None:
|
|
148
|
+
data["expires_at"] = expires_at
|
|
149
|
+
if include_byok_in_limit is not None:
|
|
150
|
+
data["include_byok_in_limit"] = include_byok_in_limit
|
|
110
151
|
|
|
111
152
|
response = await self._request(METH_POST, "keys", data=data)
|
|
112
|
-
return
|
|
153
|
+
return KeyCreateResponse.from_json(response).data
|
|
154
|
+
|
|
155
|
+
async def get_key(self, key_hash: str) -> Key:
|
|
156
|
+
"""Get a single key by hash."""
|
|
157
|
+
response = await self._request(METH_GET, f"keys/{key_hash}")
|
|
158
|
+
return KeyResponseWrapper.from_json(response).data
|
|
159
|
+
|
|
160
|
+
async def update_key(
|
|
161
|
+
self,
|
|
162
|
+
key_hash: str,
|
|
163
|
+
*,
|
|
164
|
+
name: str | None = None,
|
|
165
|
+
disabled: bool | None = None,
|
|
166
|
+
limit: float | None = None,
|
|
167
|
+
limit_reset: str | None = None,
|
|
168
|
+
include_byok_in_limit: bool | None = None,
|
|
169
|
+
) -> Key:
|
|
170
|
+
"""Update an existing key."""
|
|
171
|
+
data: dict[str, Any] = {}
|
|
172
|
+
if name is not None:
|
|
173
|
+
data["name"] = name
|
|
174
|
+
if disabled is not None:
|
|
175
|
+
data["disabled"] = disabled
|
|
176
|
+
if limit is not None:
|
|
177
|
+
data["limit"] = limit
|
|
178
|
+
if limit_reset is not None:
|
|
179
|
+
data["limit_reset"] = limit_reset
|
|
180
|
+
if include_byok_in_limit is not None:
|
|
181
|
+
data["include_byok_in_limit"] = include_byok_in_limit
|
|
182
|
+
|
|
183
|
+
response = await self._request(METH_PATCH, f"keys/{key_hash}", data=data)
|
|
184
|
+
return KeyResponseWrapper.from_json(response).data
|
|
185
|
+
|
|
186
|
+
async def delete_key(self, key_hash: str) -> bool:
|
|
187
|
+
"""Delete a key by hash."""
|
|
188
|
+
response = await self._request(METH_DELETE, f"keys/{key_hash}")
|
|
189
|
+
return DeletedKeyResponse.from_json(response).deleted
|
|
190
|
+
|
|
191
|
+
async def get_model(self, author: str, slug: str) -> Model:
|
|
192
|
+
"""Get a single model by author and slug."""
|
|
193
|
+
response = await self._request(METH_GET, f"model/{author}/{slug}")
|
|
194
|
+
return ModelResponseWrapper.from_json(response).data
|
|
195
|
+
|
|
196
|
+
@staticmethod
|
|
197
|
+
def _filter_model_params(
|
|
198
|
+
kwargs: dict[str, Any],
|
|
199
|
+
*,
|
|
200
|
+
numeric_keys: frozenset[str] = frozenset(),
|
|
201
|
+
) -> dict[str, Any]:
|
|
202
|
+
"""Filter None values and convert numeric params to strings."""
|
|
203
|
+
params = {k: v for k, v in kwargs.items() if v is not None}
|
|
204
|
+
for key in numeric_keys:
|
|
205
|
+
if key in params:
|
|
206
|
+
params[key] = str(params[key])
|
|
207
|
+
return params
|
|
113
208
|
|
|
114
|
-
async def get_models(
|
|
209
|
+
async def get_models( # pylint: disable=too-many-locals
|
|
210
|
+
self,
|
|
211
|
+
*,
|
|
212
|
+
category: str | None = None,
|
|
213
|
+
supported_parameters: str | None = None,
|
|
214
|
+
output_modalities: str | None = None,
|
|
215
|
+
sort: str | None = None,
|
|
216
|
+
q: str | None = None,
|
|
217
|
+
input_modalities: str | None = None,
|
|
218
|
+
context: int | None = None,
|
|
219
|
+
min_price: float | None = None,
|
|
220
|
+
max_price: float | None = None,
|
|
221
|
+
arch: str | None = None,
|
|
222
|
+
model_authors: str | None = None,
|
|
223
|
+
providers: str | None = None,
|
|
224
|
+
distillable: str | None = None,
|
|
225
|
+
zdr: str | None = None,
|
|
226
|
+
region: str | None = None,
|
|
227
|
+
) -> list[Model]:
|
|
115
228
|
"""Get all available models."""
|
|
116
|
-
|
|
229
|
+
numeric = frozenset({"context", "min_price", "max_price"})
|
|
230
|
+
params = self._filter_model_params(
|
|
231
|
+
{
|
|
232
|
+
"category": category,
|
|
233
|
+
"supported_parameters": supported_parameters,
|
|
234
|
+
"output_modalities": output_modalities,
|
|
235
|
+
"sort": sort,
|
|
236
|
+
"q": q,
|
|
237
|
+
"input_modalities": input_modalities,
|
|
238
|
+
"context": context,
|
|
239
|
+
"min_price": min_price,
|
|
240
|
+
"max_price": max_price,
|
|
241
|
+
"arch": arch,
|
|
242
|
+
"model_authors": model_authors,
|
|
243
|
+
"providers": providers,
|
|
244
|
+
"distillable": distillable,
|
|
245
|
+
"zdr": zdr,
|
|
246
|
+
"region": region,
|
|
247
|
+
},
|
|
248
|
+
numeric_keys=numeric,
|
|
249
|
+
)
|
|
250
|
+
response = await self._request(METH_GET, "models", params=params or None)
|
|
117
251
|
return ModelsDataWrapper.from_json(response).data
|
|
118
252
|
|
|
253
|
+
async def count_models(
|
|
254
|
+
self,
|
|
255
|
+
*,
|
|
256
|
+
output_modalities: str | None = None,
|
|
257
|
+
) -> int:
|
|
258
|
+
"""Get total count of available models."""
|
|
259
|
+
params: dict[str, Any] = {}
|
|
260
|
+
if output_modalities is not None:
|
|
261
|
+
params["output_modalities"] = output_modalities
|
|
262
|
+
response = await self._request(METH_GET, "models/count", params=params or None)
|
|
263
|
+
result: dict[str, Any] = orjson.loads(response) # pylint: disable=no-member
|
|
264
|
+
count: int = result.get("data", {}).get("count", 0)
|
|
265
|
+
return count
|
|
266
|
+
|
|
119
267
|
async def close(self) -> None:
|
|
120
268
|
"""Close open client session."""
|
|
121
269
|
if self.session and self._close_session:
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
python_open_router/__init__.py,sha256=9a8JXk66oCsPUc-XxgHBI29sVi6QbjlnUuCUxLDJUfo,1166
|
|
2
|
+
python_open_router/exceptions.py,sha256=68nskqNdXNMIK4iA1XOE1E5P5rbhAf27DDACkk-ZVwU,312
|
|
3
|
+
python_open_router/models.py,sha256=oVEE8q195laYFa7WXSYOKI6FiTqvJ6lPSTzTphj8eHI,6943
|
|
4
|
+
python_open_router/open_router.py,sha256=JB_2fu1akGJ8niuP7FOlExWTV3ytDvmH_sXWKY5iO6I,9520
|
|
5
|
+
python_open_router/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
python_open_router-0.4.0.dist-info/METADATA,sha256=Iv2GN34OuueJ3t0rUj_ELgoEFu-aHPYX7TvCm1XvSqU,6055
|
|
7
|
+
python_open_router-0.4.0.dist-info/WHEEL,sha256=EGEvSphFYqXKs23-kQBeyNoJP1nrT8ZJKQoi5p5DYL8,88
|
|
8
|
+
python_open_router-0.4.0.dist-info/licenses/LICENSE.md,sha256=Xbw7n2Ic30r4j8_MDNND4ss_sdoj9IGeIkEWc2Hsfs8,1077
|
|
9
|
+
python_open_router-0.4.0.dist-info/RECORD,,
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
python_open_router/__init__.py,sha256=UQt6SpcnmQkS2wiyjwA_Ggvvzu7Ucx8BOCyZLZ_F2uA,840
|
|
2
|
-
python_open_router/exceptions.py,sha256=68nskqNdXNMIK4iA1XOE1E5P5rbhAf27DDACkk-ZVwU,312
|
|
3
|
-
python_open_router/models.py,sha256=-9e0k_8jmiaCdkiIJSKdm70389EeePnHgiRA5Phby3s,3359
|
|
4
|
-
python_open_router/open_router.py,sha256=zq7aleWZfNFqbBb69Qp3_3jed95cwxtgGMlYFhDzYKw,4148
|
|
5
|
-
python_open_router/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
python_open_router-0.3.2.dist-info/METADATA,sha256=tMbVeQcyCmNwxFUjfH7OmXrL1Ki4s9kisuvW2epnuPs,6055
|
|
7
|
-
python_open_router-0.3.2.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
8
|
-
python_open_router-0.3.2.dist-info/licenses/LICENSE.md,sha256=Xbw7n2Ic30r4j8_MDNND4ss_sdoj9IGeIkEWc2Hsfs8,1077
|
|
9
|
-
python_open_router-0.3.2.dist-info/RECORD,,
|
{python_open_router-0.3.2.dist-info → python_open_router-0.4.0.dist-info}/licenses/LICENSE.md
RENAMED
|
File without changes
|