Skip to content

Commit 521bf92

Browse files
committed
feat: support for provider endpoints
1 parent a86d1f2 commit 521bf92

6 files changed

Lines changed: 449 additions & 0 deletions

File tree

portkey_ai/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@
129129
AsyncIntegrationsWorkspaces,
130130
IntegrationsModels,
131131
AsyncIntegrationsModels,
132+
Providers,
133+
AsyncProviders,
132134
)
133135

134136
from portkey_ai.version import VERSION
@@ -277,4 +279,6 @@
277279
"AsyncIntegrationsWorkspaces",
278280
"IntegrationsModels",
279281
"AsyncIntegrationsModels",
282+
"Providers",
283+
"AsyncProviders",
280284
]

portkey_ai/api_resources/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@
117117
AsyncIntegrationsWorkspaces,
118118
IntegrationsModels,
119119
AsyncIntegrationsModels,
120+
Providers,
121+
AsyncProviders,
120122
)
121123
from .utils import (
122124
Modes,
@@ -269,4 +271,6 @@
269271
"AsyncIntegrationsWorkspaces",
270272
"IntegrationsModels",
271273
"AsyncIntegrationsModels",
274+
"Providers",
275+
"AsyncProviders",
272276
]

portkey_ai/api_resources/apis/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@
148148
AsyncIntegrationsModels,
149149
)
150150

151+
from .providers import (
152+
Providers,
153+
AsyncProviders,
154+
)
155+
151156
sys.modules["openai"] = vendored_openai # For pydantic v1 and v2 compatibility
152157

153158
__all__ = [
@@ -278,4 +283,6 @@
278283
"AsyncIntegrationsWorkspaces",
279284
"IntegrationsModels",
280285
"AsyncIntegrationsModels",
286+
"Providers",
287+
"AsyncProviders",
281288
]
Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
from typing import Any, Dict, Optional
2+
from portkey_ai.api_resources.base_client import APIClient, AsyncAPIClient
3+
from urllib.parse import urlencode
4+
from portkey_ai.api_resources.apis.api_resource import APIResource, AsyncAPIResource
5+
from portkey_ai.api_resources.types.providers_type import (
6+
ProviderListResponse,
7+
ProviderDetailResponse,
8+
ProviderCreateResponse,
9+
ProviderUpdateResponse,
10+
)
11+
from portkey_ai.api_resources.utils import GenericResponse
12+
from portkey_ai.api_resources.utils import PortkeyApiPaths
13+
14+
15+
class Providers(APIResource):
16+
def __init__(self, client: APIClient) -> None:
17+
super().__init__(client)
18+
19+
def create(
20+
self,
21+
*,
22+
name: str,
23+
integration_id: str,
24+
workspace_id: Optional[str] = None,
25+
slug: Optional[str] = None,
26+
note: Optional[str] = None,
27+
usage_limits: Optional[Dict[str, Any]] = None,
28+
rate_limits: Optional[Dict[str, Any]] = None,
29+
expires_at: Optional[str] = None,
30+
**kwargs: Any,
31+
) -> ProviderCreateResponse:
32+
body = {
33+
"name": name,
34+
"integration_id": integration_id,
35+
"workspace_id": workspace_id,
36+
"slug": slug,
37+
"note": note,
38+
"usage_limits": usage_limits,
39+
"rate_limits": rate_limits,
40+
"expires_at": expires_at,
41+
**kwargs,
42+
}
43+
return self._post(
44+
f"{PortkeyApiPaths.PROVIDERS_API}",
45+
body=body,
46+
params=None,
47+
cast_to=ProviderCreateResponse,
48+
stream=False,
49+
stream_cls=None,
50+
headers={},
51+
)
52+
53+
def list(
54+
self,
55+
*,
56+
current_page: Optional[int] = 0,
57+
page_size: Optional[int] = 50,
58+
workspace_id: Optional[str] = None,
59+
) -> ProviderListResponse:
60+
query = {
61+
"current_page": current_page,
62+
"page_size": page_size,
63+
"workspace_id": workspace_id,
64+
}
65+
filtered_query = {k: v for k, v in query.items() if v is not None}
66+
query_string = urlencode(filtered_query)
67+
return self._get(
68+
f"{PortkeyApiPaths.PROVIDERS_API}?{query_string}",
69+
params=None,
70+
body=None,
71+
cast_to=ProviderListResponse,
72+
stream=False,
73+
stream_cls=None,
74+
headers={},
75+
)
76+
77+
def retrieve(
78+
self,
79+
*,
80+
slug: str,
81+
workspace_id: Optional[str] = None,
82+
) -> ProviderDetailResponse:
83+
query = {
84+
"workspace_id": workspace_id,
85+
}
86+
filtered_query = {k: v for k, v in query.items() if v is not None}
87+
query_string = urlencode(filtered_query)
88+
path = f"{PortkeyApiPaths.PROVIDERS_API}/{slug}"
89+
if query_string:
90+
path = f"{path}?{query_string}"
91+
return self._get(
92+
path,
93+
params=None,
94+
body=None,
95+
cast_to=ProviderDetailResponse,
96+
stream=False,
97+
stream_cls=None,
98+
headers={},
99+
)
100+
101+
def update(
102+
self,
103+
*,
104+
slug: str,
105+
workspace_id: Optional[str] = None,
106+
name: Optional[str] = None,
107+
note: Optional[str] = None,
108+
usage_limits: Optional[Dict[str, Any]] = None,
109+
rate_limits: Optional[Dict[str, Any]] = None,
110+
expires_at: Optional[str] = None,
111+
reset_usage: Optional[bool] = None,
112+
**kwargs: Any,
113+
) -> ProviderUpdateResponse:
114+
body = {
115+
"name": name,
116+
"note": note,
117+
"usage_limits": usage_limits,
118+
"rate_limits": rate_limits,
119+
"expires_at": expires_at,
120+
"reset_usage": reset_usage,
121+
**kwargs,
122+
}
123+
query = {
124+
"workspace_id": workspace_id,
125+
}
126+
filtered_query = {k: v for k, v in query.items() if v is not None}
127+
query_string = urlencode(filtered_query)
128+
path = f"{PortkeyApiPaths.PROVIDERS_API}/{slug}"
129+
if query_string:
130+
path = f"{path}?{query_string}"
131+
return self._put(
132+
path,
133+
body=body,
134+
params=None,
135+
cast_to=ProviderUpdateResponse,
136+
stream=False,
137+
stream_cls=None,
138+
headers={},
139+
)
140+
141+
def delete(
142+
self,
143+
*,
144+
slug: str,
145+
workspace_id: Optional[str] = None,
146+
) -> GenericResponse:
147+
query = {
148+
"workspace_id": workspace_id,
149+
}
150+
filtered_query = {k: v for k, v in query.items() if v is not None}
151+
query_string = urlencode(filtered_query)
152+
path = f"{PortkeyApiPaths.PROVIDERS_API}/{slug}"
153+
if query_string:
154+
path = f"{path}?{query_string}"
155+
return self._delete(
156+
path,
157+
params=None,
158+
body=None,
159+
cast_to=GenericResponse,
160+
stream=False,
161+
stream_cls=None,
162+
headers={},
163+
)
164+
165+
166+
class AsyncProviders(AsyncAPIResource):
167+
def __init__(self, client: AsyncAPIClient) -> None:
168+
super().__init__(client)
169+
170+
async def create(
171+
self,
172+
*,
173+
name: str,
174+
integration_id: str,
175+
workspace_id: Optional[str] = None,
176+
slug: Optional[str] = None,
177+
note: Optional[str] = None,
178+
usage_limits: Optional[Dict[str, Any]] = None,
179+
rate_limits: Optional[Dict[str, Any]] = None,
180+
expires_at: Optional[str] = None,
181+
**kwargs: Any,
182+
) -> ProviderCreateResponse:
183+
body = {
184+
"name": name,
185+
"integration_id": integration_id,
186+
"workspace_id": workspace_id,
187+
"slug": slug,
188+
"note": note,
189+
"usage_limits": usage_limits,
190+
"rate_limits": rate_limits,
191+
"expires_at": expires_at,
192+
**kwargs,
193+
}
194+
return await self._post(
195+
f"{PortkeyApiPaths.PROVIDERS_API}",
196+
body=body,
197+
params=None,
198+
cast_to=ProviderCreateResponse,
199+
stream=False,
200+
stream_cls=None,
201+
headers={},
202+
)
203+
204+
async def list(
205+
self,
206+
*,
207+
current_page: Optional[int] = 0,
208+
page_size: Optional[int] = 50,
209+
workspace_id: Optional[str] = None,
210+
) -> ProviderListResponse:
211+
query = {
212+
"current_page": current_page,
213+
"page_size": page_size,
214+
"workspace_id": workspace_id,
215+
}
216+
filtered_query = {k: v for k, v in query.items() if v is not None}
217+
query_string = urlencode(filtered_query)
218+
return await self._get(
219+
f"{PortkeyApiPaths.PROVIDERS_API}?{query_string}",
220+
params=None,
221+
body=None,
222+
cast_to=ProviderListResponse,
223+
stream=False,
224+
stream_cls=None,
225+
headers={},
226+
)
227+
228+
async def retrieve(
229+
self,
230+
*,
231+
slug: str,
232+
workspace_id: Optional[str] = None,
233+
) -> ProviderDetailResponse:
234+
query = {
235+
"workspace_id": workspace_id,
236+
}
237+
filtered_query = {k: v for k, v in query.items() if v is not None}
238+
query_string = urlencode(filtered_query)
239+
path = f"{PortkeyApiPaths.PROVIDERS_API}/{slug}"
240+
if query_string:
241+
path = f"{path}?{query_string}"
242+
return await self._get(
243+
path,
244+
params=None,
245+
body=None,
246+
cast_to=ProviderDetailResponse,
247+
stream=False,
248+
stream_cls=None,
249+
headers={},
250+
)
251+
252+
async def update(
253+
self,
254+
*,
255+
slug: str,
256+
workspace_id: Optional[str] = None,
257+
name: Optional[str] = None,
258+
note: Optional[str] = None,
259+
usage_limits: Optional[Dict[str, Any]] = None,
260+
rate_limits: Optional[Dict[str, Any]] = None,
261+
expires_at: Optional[str] = None,
262+
reset_usage: Optional[bool] = None,
263+
**kwargs: Any,
264+
) -> ProviderUpdateResponse:
265+
body = {
266+
"name": name,
267+
"note": note,
268+
"usage_limits": usage_limits,
269+
"rate_limits": rate_limits,
270+
"expires_at": expires_at,
271+
"reset_usage": reset_usage,
272+
**kwargs,
273+
}
274+
query = {
275+
"workspace_id": workspace_id,
276+
}
277+
filtered_query = {k: v for k, v in query.items() if v is not None}
278+
query_string = urlencode(filtered_query)
279+
path = f"{PortkeyApiPaths.PROVIDERS_API}/{slug}"
280+
if query_string:
281+
path = f"{path}?{query_string}"
282+
return await self._put(
283+
path,
284+
body=body,
285+
params=None,
286+
cast_to=ProviderUpdateResponse,
287+
stream=False,
288+
stream_cls=None,
289+
headers={},
290+
)
291+
292+
async def delete(
293+
self,
294+
*,
295+
slug: str,
296+
workspace_id: Optional[str] = None,
297+
) -> GenericResponse:
298+
query = {
299+
"workspace_id": workspace_id,
300+
}
301+
filtered_query = {k: v for k, v in query.items() if v is not None}
302+
query_string = urlencode(filtered_query)
303+
path = f"{PortkeyApiPaths.PROVIDERS_API}/{slug}"
304+
if query_string:
305+
path = f"{path}?{query_string}"
306+
return await self._delete(
307+
path,
308+
params=None,
309+
body=None,
310+
cast_to=GenericResponse,
311+
stream=False,
312+
stream_cls=None,
313+
headers={},
314+
)

portkey_ai/api_resources/client.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class Portkey(APIClient):
3636
labels: apis.Labels
3737
collections: apis.Collections
3838
integrations: apis.Integrations
39+
providers: apis.Providers
3940

4041
class beta:
4142
assistants: apis.Assistants
@@ -177,6 +178,7 @@ def __init__(
177178
self.labels = apis.Labels(self)
178179
self.collections = apis.Collections(self)
179180
self.integrations = apis.Integrations(self)
181+
self.providers = apis.Providers(self)
180182
self.beta = self.beta(self) # type: ignore
181183

182184
if self.instrumentation:
@@ -355,6 +357,7 @@ class AsyncPortkey(AsyncAPIClient):
355357
labels: apis.AsyncLabels
356358
collections: apis.AsyncCollections
357359
integrations: apis.AsyncIntegrations
360+
providers: apis.AsyncProviders
358361

359362
class beta:
360363
assistants: apis.AsyncAssistants
@@ -496,6 +499,7 @@ def __init__(
496499
self.labels = apis.AsyncLabels(self)
497500
self.collections = apis.AsyncCollections(self)
498501
self.integrations = apis.AsyncIntegrations(self)
502+
self.providers = apis.AsyncProviders(self)
499503
self.beta = self.beta(self) # type: ignore
500504

501505
if self.instrumentation:

0 commit comments

Comments
 (0)