magic_hour 0.36.2__py3-none-any.whl → 0.38.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.
Potentially problematic release.
This version of magic_hour might be problematic. Click here for more details.
- magic_hour/__init__.py +1 -1
- magic_hour/client.py +1 -1
- magic_hour/environment.py +1 -1
- magic_hour/resources/v1/ai_clothes_changer/client.py +8 -8
- magic_hour/resources/v1/ai_face_editor/client.py +8 -8
- magic_hour/resources/v1/ai_gif_generator/client.py +26 -11
- magic_hour/resources/v1/ai_headshot_generator/client.py +8 -8
- magic_hour/resources/v1/ai_image_editor/client.py +8 -8
- magic_hour/resources/v1/ai_image_generator/client.py +7 -7
- magic_hour/resources/v1/ai_image_upscaler/client.py +8 -8
- magic_hour/resources/v1/ai_meme_generator/client.py +7 -7
- magic_hour/resources/v1/ai_photo_editor/client.py +8 -8
- magic_hour/resources/v1/ai_qr_code_generator/client.py +7 -7
- magic_hour/resources/v1/ai_talking_photo/client.py +8 -8
- magic_hour/resources/v1/animation/client.py +8 -8
- magic_hour/resources/v1/auto_subtitle_generator/client.py +8 -8
- magic_hour/resources/v1/client.py +1 -1
- magic_hour/resources/v1/face_detection/client.py +5 -5
- magic_hour/resources/v1/face_swap/client.py +8 -8
- magic_hour/resources/v1/face_swap_photo/client.py +8 -8
- magic_hour/resources/v1/files/client.py +1 -1
- magic_hour/resources/v1/files/upload_urls/client.py +2 -2
- magic_hour/resources/v1/image_background_remover/client.py +8 -8
- magic_hour/resources/v1/image_projects/client.py +4 -4
- magic_hour/resources/v1/image_to_video/client.py +8 -8
- magic_hour/resources/v1/lip_sync/client.py +8 -8
- magic_hour/resources/v1/photo_colorizer/client.py +8 -8
- magic_hour/resources/v1/text_to_video/client.py +7 -7
- magic_hour/resources/v1/video_projects/client.py +4 -4
- magic_hour/resources/v1/video_to_video/client.py +8 -8
- magic_hour/types/params/v1_ai_gif_generator_create_body.py +10 -0
- magic_hour/types/params/v1_ai_talking_photo_create_body_style.py +4 -3
- {magic_hour-0.36.2.dist-info → magic_hour-0.38.0.dist-info}/METADATA +2 -5
- {magic_hour-0.36.2.dist-info → magic_hour-0.38.0.dist-info}/RECORD +36 -46
- magic_hour/core/__init__.py +0 -50
- magic_hour/core/api_error.py +0 -56
- magic_hour/core/auth.py +0 -354
- magic_hour/core/base_client.py +0 -627
- magic_hour/core/binary_response.py +0 -23
- magic_hour/core/query.py +0 -124
- magic_hour/core/request.py +0 -162
- magic_hour/core/response.py +0 -297
- magic_hour/core/type_utils.py +0 -28
- magic_hour/core/utils.py +0 -55
- {magic_hour-0.36.2.dist-info → magic_hour-0.38.0.dist-info}/LICENSE +0 -0
- {magic_hour-0.36.2.dist-info → magic_hour-0.38.0.dist-info}/WHEEL +0 -0
magic_hour/core/base_client.py
DELETED
|
@@ -1,627 +0,0 @@
|
|
|
1
|
-
from typing import (
|
|
2
|
-
Any,
|
|
3
|
-
List,
|
|
4
|
-
TypeVar,
|
|
5
|
-
Dict,
|
|
6
|
-
Optional,
|
|
7
|
-
Type,
|
|
8
|
-
Union,
|
|
9
|
-
cast,
|
|
10
|
-
)
|
|
11
|
-
from typing_extensions import TypeGuard
|
|
12
|
-
|
|
13
|
-
import httpx
|
|
14
|
-
from pydantic import BaseModel
|
|
15
|
-
|
|
16
|
-
from .api_error import ApiError
|
|
17
|
-
from .auth import AuthProvider
|
|
18
|
-
from .request import RequestConfig, RequestOptions, default_request_options
|
|
19
|
-
from .query import QueryParams
|
|
20
|
-
from .response import from_encodable, AsyncStreamResponse, StreamResponse
|
|
21
|
-
from .utils import get_response_type, filter_binary_response
|
|
22
|
-
from .binary_response import BinaryResponse
|
|
23
|
-
|
|
24
|
-
NoneType = type(None)
|
|
25
|
-
T = TypeVar(
|
|
26
|
-
"T",
|
|
27
|
-
bound=Union[object, None, str, "BaseModel", List[Any], Dict[str, Any], Any],
|
|
28
|
-
)
|
|
29
|
-
_DEFAULT_SERVICE_NAME = "__default_service__"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class BaseClient:
|
|
33
|
-
"""Base client class providing core HTTP client functionality.
|
|
34
|
-
|
|
35
|
-
Handles authentication, request building, and response processing for HTTP API clients.
|
|
36
|
-
Serves as the foundation for both synchronous and asynchronous client implementations.
|
|
37
|
-
|
|
38
|
-
Attributes:
|
|
39
|
-
_auths: Dictionary mapping auth provider IDs to AuthProvider instances
|
|
40
|
-
"""
|
|
41
|
-
|
|
42
|
-
def __init__(
|
|
43
|
-
self,
|
|
44
|
-
base_url: Union[str, Dict[str, str]],
|
|
45
|
-
auths: Optional[Dict[str, AuthProvider]] = None,
|
|
46
|
-
):
|
|
47
|
-
"""Initialize the base client"""
|
|
48
|
-
self._base_url = (
|
|
49
|
-
base_url
|
|
50
|
-
if isinstance(base_url, dict)
|
|
51
|
-
else {_DEFAULT_SERVICE_NAME: base_url}
|
|
52
|
-
)
|
|
53
|
-
self._auths: Dict[str, AuthProvider] = auths or {}
|
|
54
|
-
|
|
55
|
-
def register_auth(self, auth_id: str, provider: AuthProvider) -> None:
|
|
56
|
-
"""Register an authentication provider.
|
|
57
|
-
|
|
58
|
-
Args:
|
|
59
|
-
auth_id: Unique identifier for the auth provider
|
|
60
|
-
provider: AuthProvider instance to handle authentication
|
|
61
|
-
"""
|
|
62
|
-
self._auths[auth_id] = provider
|
|
63
|
-
|
|
64
|
-
def default_headers(self) -> Dict[str, str]:
|
|
65
|
-
"""Get default headers for requests.
|
|
66
|
-
|
|
67
|
-
Returns:
|
|
68
|
-
Dictionary of default headers
|
|
69
|
-
"""
|
|
70
|
-
headers: Dict[str, str] = {
|
|
71
|
-
"x-sideko-sdk-language": "Python",
|
|
72
|
-
}
|
|
73
|
-
return headers
|
|
74
|
-
|
|
75
|
-
def build_url(self, path: str, service_name: Optional[str] = None) -> str:
|
|
76
|
-
"""Build a complete URL by combining base URL and path.
|
|
77
|
-
|
|
78
|
-
Args:
|
|
79
|
-
path: API endpoint path
|
|
80
|
-
|
|
81
|
-
Returns:
|
|
82
|
-
Complete URL string
|
|
83
|
-
"""
|
|
84
|
-
base_url = self._base_url.get(service_name or _DEFAULT_SERVICE_NAME, "")
|
|
85
|
-
if base_url.endswith("/"):
|
|
86
|
-
base_url = base_url[:-1]
|
|
87
|
-
if path.startswith("/"):
|
|
88
|
-
path = path[1:]
|
|
89
|
-
|
|
90
|
-
return f"{base_url}/{path}"
|
|
91
|
-
|
|
92
|
-
def _cast_to_raw_response(
|
|
93
|
-
self, res: httpx.Response, cast_to: Union[Type[T], Any]
|
|
94
|
-
) -> TypeGuard[T]:
|
|
95
|
-
"""Determines if the provided cast_to is an httpx.Response"""
|
|
96
|
-
try:
|
|
97
|
-
return issubclass(cast_to, httpx.Response)
|
|
98
|
-
except TypeError:
|
|
99
|
-
return False
|
|
100
|
-
|
|
101
|
-
def _apply_auth(
|
|
102
|
-
self, *, cfg: RequestConfig, auth_names: List[str]
|
|
103
|
-
) -> RequestConfig:
|
|
104
|
-
"""Apply authentication to the request configuration.
|
|
105
|
-
|
|
106
|
-
Args:
|
|
107
|
-
cfg: Request configuration to modify
|
|
108
|
-
auth_names: List of auth provider IDs to apply
|
|
109
|
-
|
|
110
|
-
Returns:
|
|
111
|
-
Modified request configuration
|
|
112
|
-
"""
|
|
113
|
-
for auth_name in auth_names:
|
|
114
|
-
auth_provider = self._auths.get(auth_name)
|
|
115
|
-
if auth_provider is not None:
|
|
116
|
-
cfg = auth_provider.add_to_request(cfg)
|
|
117
|
-
|
|
118
|
-
return cfg
|
|
119
|
-
|
|
120
|
-
def _apply_headers(
|
|
121
|
-
self,
|
|
122
|
-
*,
|
|
123
|
-
cfg: RequestConfig,
|
|
124
|
-
opts: RequestOptions,
|
|
125
|
-
content_type: Optional[str] = None,
|
|
126
|
-
explicit_headers: Optional[Dict[str, str]] = None,
|
|
127
|
-
) -> RequestConfig:
|
|
128
|
-
"""Apply headers to the request configuration.
|
|
129
|
-
|
|
130
|
-
Args:
|
|
131
|
-
cfg: Request configuration to modify
|
|
132
|
-
opts: Request options containing additional headers
|
|
133
|
-
content_type: Optional content type header
|
|
134
|
-
explicit_headers: Optional explicitly specified headers
|
|
135
|
-
|
|
136
|
-
Returns:
|
|
137
|
-
Modified request configuration
|
|
138
|
-
"""
|
|
139
|
-
headers = cfg.get("headers", {})
|
|
140
|
-
headers.update(self.default_headers())
|
|
141
|
-
|
|
142
|
-
if content_type is not None:
|
|
143
|
-
headers["content-type"] = content_type
|
|
144
|
-
|
|
145
|
-
if explicit_headers is not None:
|
|
146
|
-
headers.update(explicit_headers)
|
|
147
|
-
|
|
148
|
-
additional_headers = opts.get("additional_headers", None)
|
|
149
|
-
if additional_headers is not None:
|
|
150
|
-
headers.update(additional_headers)
|
|
151
|
-
|
|
152
|
-
if len(headers) > 0:
|
|
153
|
-
cfg["headers"] = headers
|
|
154
|
-
|
|
155
|
-
return cfg
|
|
156
|
-
|
|
157
|
-
def _apply_query_params(
|
|
158
|
-
self,
|
|
159
|
-
*,
|
|
160
|
-
cfg: RequestConfig,
|
|
161
|
-
opts: RequestOptions,
|
|
162
|
-
query_params: Optional[QueryParams] = None,
|
|
163
|
-
) -> RequestConfig:
|
|
164
|
-
"""Apply query parameters to the request configuration.
|
|
165
|
-
|
|
166
|
-
Args:
|
|
167
|
-
cfg: Request configuration to modify
|
|
168
|
-
opts: Request options containing additional parameters
|
|
169
|
-
query_params: Optional query parameters to add
|
|
170
|
-
|
|
171
|
-
Returns:
|
|
172
|
-
Modified request configuration
|
|
173
|
-
"""
|
|
174
|
-
params = cfg.get("params", {})
|
|
175
|
-
|
|
176
|
-
if query_params is not None:
|
|
177
|
-
params.update(query_params)
|
|
178
|
-
|
|
179
|
-
additional_params = opts.get("additional_params", None)
|
|
180
|
-
if additional_params is not None:
|
|
181
|
-
params.update(additional_params)
|
|
182
|
-
|
|
183
|
-
if len(params) > 0:
|
|
184
|
-
cfg["params"] = params
|
|
185
|
-
|
|
186
|
-
return cfg
|
|
187
|
-
|
|
188
|
-
def _apply_timeout(
|
|
189
|
-
self,
|
|
190
|
-
*,
|
|
191
|
-
cfg: RequestConfig,
|
|
192
|
-
opts: RequestOptions,
|
|
193
|
-
) -> RequestConfig:
|
|
194
|
-
"""Apply timeout settings to the request configuration.
|
|
195
|
-
|
|
196
|
-
Args:
|
|
197
|
-
cfg: Request configuration to modify
|
|
198
|
-
opts: Request options containing timeout settings
|
|
199
|
-
|
|
200
|
-
Returns:
|
|
201
|
-
Modified request configuration
|
|
202
|
-
"""
|
|
203
|
-
timeout = opts.get("timeout", None)
|
|
204
|
-
|
|
205
|
-
if timeout is not None:
|
|
206
|
-
cfg["timeout"] = timeout
|
|
207
|
-
|
|
208
|
-
return cfg
|
|
209
|
-
|
|
210
|
-
def _apply_body(
|
|
211
|
-
self,
|
|
212
|
-
*,
|
|
213
|
-
cfg: RequestConfig,
|
|
214
|
-
data: Optional[httpx._types.RequestData] = None,
|
|
215
|
-
files: Optional[httpx._types.RequestFiles] = None,
|
|
216
|
-
json: Optional[Any] = None,
|
|
217
|
-
content: Optional[httpx._types.RequestContent] = None,
|
|
218
|
-
) -> RequestConfig:
|
|
219
|
-
"""Apply request body content to the request configuration.
|
|
220
|
-
|
|
221
|
-
Args:
|
|
222
|
-
cfg: Request configuration to modify
|
|
223
|
-
data: Optional form data
|
|
224
|
-
files: Optional files to upload
|
|
225
|
-
json: Optional JSON data
|
|
226
|
-
content: Optional raw content
|
|
227
|
-
|
|
228
|
-
Returns:
|
|
229
|
-
Modified request configuration
|
|
230
|
-
"""
|
|
231
|
-
if data is not None:
|
|
232
|
-
cfg["data"] = data
|
|
233
|
-
|
|
234
|
-
if files is not None:
|
|
235
|
-
cfg["files"] = files
|
|
236
|
-
|
|
237
|
-
if json is not None:
|
|
238
|
-
cfg["json"] = json
|
|
239
|
-
|
|
240
|
-
if content is not None:
|
|
241
|
-
cfg["content"] = content
|
|
242
|
-
|
|
243
|
-
return cfg
|
|
244
|
-
|
|
245
|
-
def build_request(
|
|
246
|
-
self,
|
|
247
|
-
*,
|
|
248
|
-
method: str,
|
|
249
|
-
path: str,
|
|
250
|
-
service_name: Optional[str] = None,
|
|
251
|
-
auth_names: Optional[List[str]] = None,
|
|
252
|
-
query_params: Optional[QueryParams] = None,
|
|
253
|
-
headers: Optional[Dict[str, str]] = None,
|
|
254
|
-
data: Optional[httpx._types.RequestData] = None,
|
|
255
|
-
files: Optional[httpx._types.RequestFiles] = None,
|
|
256
|
-
json: Optional[Any] = None,
|
|
257
|
-
content_type: Optional[str] = None,
|
|
258
|
-
content: Optional[httpx._types.RequestContent] = None,
|
|
259
|
-
request_options: Optional[RequestOptions] = None,
|
|
260
|
-
) -> RequestConfig:
|
|
261
|
-
"""Build a complete request configuration.
|
|
262
|
-
|
|
263
|
-
Args:
|
|
264
|
-
method: HTTP method
|
|
265
|
-
path: API endpoint path
|
|
266
|
-
auth_names: List of auth provider IDs
|
|
267
|
-
query_params: Query parameters
|
|
268
|
-
headers: Request headers
|
|
269
|
-
data: Form data
|
|
270
|
-
files: Files to upload
|
|
271
|
-
json: JSON data
|
|
272
|
-
content_type: Content type header
|
|
273
|
-
content: Raw content
|
|
274
|
-
request_options: Additional request options
|
|
275
|
-
|
|
276
|
-
Returns:
|
|
277
|
-
Complete request configuration
|
|
278
|
-
"""
|
|
279
|
-
opts = request_options or default_request_options()
|
|
280
|
-
req_cfg: RequestConfig = {
|
|
281
|
-
"method": method,
|
|
282
|
-
"url": self.build_url(path, service_name=service_name),
|
|
283
|
-
}
|
|
284
|
-
req_cfg = self._apply_auth(cfg=req_cfg, auth_names=auth_names or [])
|
|
285
|
-
req_cfg = self._apply_headers(
|
|
286
|
-
cfg=req_cfg, opts=opts, content_type=content_type, explicit_headers=headers
|
|
287
|
-
)
|
|
288
|
-
req_cfg = self._apply_query_params(
|
|
289
|
-
cfg=req_cfg, opts=opts, query_params=query_params
|
|
290
|
-
)
|
|
291
|
-
req_cfg = self._apply_body(
|
|
292
|
-
cfg=req_cfg, data=data, files=files, json=json, content=content
|
|
293
|
-
)
|
|
294
|
-
req_cfg = self._apply_timeout(cfg=req_cfg, opts=opts)
|
|
295
|
-
|
|
296
|
-
return req_cfg
|
|
297
|
-
|
|
298
|
-
def process_response(
|
|
299
|
-
self,
|
|
300
|
-
*,
|
|
301
|
-
response: httpx.Response,
|
|
302
|
-
cast_to: Union[Type[T], Any],
|
|
303
|
-
) -> T:
|
|
304
|
-
"""Process an HTTP response and convert it to the desired type.
|
|
305
|
-
|
|
306
|
-
Args:
|
|
307
|
-
response: HTTP response to process
|
|
308
|
-
cast_to: Type to cast the response data to
|
|
309
|
-
|
|
310
|
-
Returns:
|
|
311
|
-
Processed response data of the specified type
|
|
312
|
-
|
|
313
|
-
Raises:
|
|
314
|
-
ApiError: If the response indicates an error
|
|
315
|
-
"""
|
|
316
|
-
|
|
317
|
-
if response.status_code == 204 or cast_to == NoneType:
|
|
318
|
-
return cast(T, None)
|
|
319
|
-
elif cast_to == BinaryResponse:
|
|
320
|
-
return cast(
|
|
321
|
-
T,
|
|
322
|
-
BinaryResponse(content=response.content, headers=response.headers),
|
|
323
|
-
)
|
|
324
|
-
|
|
325
|
-
response_type = get_response_type(response.headers)
|
|
326
|
-
|
|
327
|
-
if response_type == "json":
|
|
328
|
-
if cast_to is type(Any):
|
|
329
|
-
return response.json() # type: ignore[no-any-return]
|
|
330
|
-
return from_encodable( # type: ignore[no-any-return]
|
|
331
|
-
data=response.json(), load_with=filter_binary_response(cast_to=cast_to)
|
|
332
|
-
)
|
|
333
|
-
elif response_type == "text":
|
|
334
|
-
return cast(T, response.text)
|
|
335
|
-
else:
|
|
336
|
-
return cast(
|
|
337
|
-
T,
|
|
338
|
-
BinaryResponse(content=response.content, headers=response.headers),
|
|
339
|
-
)
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
class SyncBaseClient(BaseClient):
|
|
343
|
-
"""Synchronous HTTP client implementation.
|
|
344
|
-
|
|
345
|
-
Provides synchronous HTTP request capabilities building on the base client functionality.
|
|
346
|
-
"""
|
|
347
|
-
|
|
348
|
-
def __init__(
|
|
349
|
-
self,
|
|
350
|
-
*,
|
|
351
|
-
base_url: Union[str, Dict[str, str]],
|
|
352
|
-
httpx_client: httpx.Client,
|
|
353
|
-
auths: Optional[Dict[str, AuthProvider]] = None,
|
|
354
|
-
):
|
|
355
|
-
"""Initialize the synchronous client.
|
|
356
|
-
|
|
357
|
-
Args:
|
|
358
|
-
httpx_client: Synchronous HTTPX client instance
|
|
359
|
-
"""
|
|
360
|
-
super().__init__(base_url=base_url, auths=auths)
|
|
361
|
-
self.httpx_client = httpx_client
|
|
362
|
-
|
|
363
|
-
def request(
|
|
364
|
-
self,
|
|
365
|
-
*,
|
|
366
|
-
method: str,
|
|
367
|
-
path: str,
|
|
368
|
-
cast_to: Union[Type[T], Any],
|
|
369
|
-
service_name: Optional[str] = None,
|
|
370
|
-
auth_names: Optional[List[str]] = None,
|
|
371
|
-
query_params: Optional[QueryParams] = None,
|
|
372
|
-
headers: Optional[Dict[str, str]] = None,
|
|
373
|
-
data: Optional[httpx._types.RequestData] = None,
|
|
374
|
-
files: Optional[httpx._types.RequestFiles] = None,
|
|
375
|
-
json: Optional[Any] = None,
|
|
376
|
-
content_type: Optional[str] = None,
|
|
377
|
-
content: Optional[httpx._types.RequestContent] = None,
|
|
378
|
-
request_options: Optional[RequestOptions] = None,
|
|
379
|
-
) -> T:
|
|
380
|
-
"""Make a synchronous HTTP request.
|
|
381
|
-
|
|
382
|
-
Args:
|
|
383
|
-
method: HTTP method
|
|
384
|
-
path: API endpoint path
|
|
385
|
-
cast_to: Type to cast the response to
|
|
386
|
-
auth_names: List of auth provider IDs
|
|
387
|
-
service_name: The name of the API service to make the request to
|
|
388
|
-
query_params: Query parameters
|
|
389
|
-
headers: Request headers
|
|
390
|
-
data: Form data
|
|
391
|
-
files: Files to upload
|
|
392
|
-
json: JSON data
|
|
393
|
-
content_type: Content type header
|
|
394
|
-
content: Raw content
|
|
395
|
-
request_options: Additional request options
|
|
396
|
-
|
|
397
|
-
Returns:
|
|
398
|
-
Response data of the specified type
|
|
399
|
-
|
|
400
|
-
Raises:
|
|
401
|
-
ApiError: If the request fails
|
|
402
|
-
"""
|
|
403
|
-
req_cfg = self.build_request(
|
|
404
|
-
method=method,
|
|
405
|
-
path=path,
|
|
406
|
-
service_name=service_name,
|
|
407
|
-
auth_names=auth_names,
|
|
408
|
-
query_params=query_params,
|
|
409
|
-
headers=headers,
|
|
410
|
-
data=data,
|
|
411
|
-
files=files,
|
|
412
|
-
json=json,
|
|
413
|
-
content_type=content_type,
|
|
414
|
-
content=content,
|
|
415
|
-
request_options=request_options,
|
|
416
|
-
)
|
|
417
|
-
response = self.httpx_client.request(**req_cfg)
|
|
418
|
-
|
|
419
|
-
if not response.is_success:
|
|
420
|
-
raise ApiError(response=response)
|
|
421
|
-
|
|
422
|
-
if self._cast_to_raw_response(res=response, cast_to=cast_to):
|
|
423
|
-
return response
|
|
424
|
-
|
|
425
|
-
return self.process_response(response=response, cast_to=cast_to)
|
|
426
|
-
|
|
427
|
-
def stream_request(
|
|
428
|
-
self,
|
|
429
|
-
*,
|
|
430
|
-
method: str,
|
|
431
|
-
path: str,
|
|
432
|
-
cast_to: Union[Type[T], Any],
|
|
433
|
-
service_name: Optional[str] = None,
|
|
434
|
-
auth_names: Optional[List[str]] = None,
|
|
435
|
-
query_params: Optional[QueryParams] = None,
|
|
436
|
-
headers: Optional[Dict[str, str]] = None,
|
|
437
|
-
data: Optional[httpx._types.RequestData] = None,
|
|
438
|
-
files: Optional[httpx._types.RequestFiles] = None,
|
|
439
|
-
json: Optional[Any] = None,
|
|
440
|
-
content_type: Optional[str] = None,
|
|
441
|
-
content: Optional[httpx._types.RequestContent] = None,
|
|
442
|
-
request_options: Optional[RequestOptions] = None,
|
|
443
|
-
) -> StreamResponse[T]:
|
|
444
|
-
"""Make a streaming synchronous HTTP request.
|
|
445
|
-
|
|
446
|
-
Args:
|
|
447
|
-
method: HTTP method
|
|
448
|
-
path: API endpoint path
|
|
449
|
-
cast_to: Type to cast the response to
|
|
450
|
-
auth_names: List of auth provider IDs
|
|
451
|
-
service_name: The name of the API service to make the request to
|
|
452
|
-
query_params: Query parameters
|
|
453
|
-
headers: Request headers
|
|
454
|
-
data: Form data
|
|
455
|
-
files: Files to upload
|
|
456
|
-
json: JSON data
|
|
457
|
-
content_type: Content type header
|
|
458
|
-
content: Raw content
|
|
459
|
-
request_options: Additional request options
|
|
460
|
-
|
|
461
|
-
Returns:
|
|
462
|
-
StreamResponse containing the streaming response
|
|
463
|
-
|
|
464
|
-
Raises:
|
|
465
|
-
ApiError: If the request fails
|
|
466
|
-
"""
|
|
467
|
-
req_cfg = self.build_request(
|
|
468
|
-
method=method,
|
|
469
|
-
path=path,
|
|
470
|
-
service_name=service_name,
|
|
471
|
-
auth_names=auth_names,
|
|
472
|
-
query_params=query_params,
|
|
473
|
-
headers=headers,
|
|
474
|
-
data=data,
|
|
475
|
-
files=files,
|
|
476
|
-
json=json,
|
|
477
|
-
content_type=content_type,
|
|
478
|
-
content=content,
|
|
479
|
-
request_options=request_options,
|
|
480
|
-
)
|
|
481
|
-
context = self.httpx_client.stream(**req_cfg)
|
|
482
|
-
response = context.__enter__()
|
|
483
|
-
return StreamResponse(response, context, cast_to)
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
class AsyncBaseClient(BaseClient):
|
|
487
|
-
"""Asynchronous HTTP client implementation.
|
|
488
|
-
|
|
489
|
-
Provides asynchronous HTTP request capabilities building on the base client functionality.
|
|
490
|
-
"""
|
|
491
|
-
|
|
492
|
-
def __init__(
|
|
493
|
-
self,
|
|
494
|
-
*,
|
|
495
|
-
base_url: Union[str, Dict[str, str]],
|
|
496
|
-
httpx_client: httpx.AsyncClient,
|
|
497
|
-
auths: Optional[Dict[str, AuthProvider]] = None,
|
|
498
|
-
):
|
|
499
|
-
"""Initialize the asynchronous client.
|
|
500
|
-
|
|
501
|
-
Args:
|
|
502
|
-
httpx_client: Asynchronous HTTPX client instance
|
|
503
|
-
"""
|
|
504
|
-
super().__init__(base_url=base_url, auths=auths)
|
|
505
|
-
self.httpx_client = httpx_client
|
|
506
|
-
|
|
507
|
-
async def request(
|
|
508
|
-
self,
|
|
509
|
-
*,
|
|
510
|
-
method: str,
|
|
511
|
-
path: str,
|
|
512
|
-
cast_to: Union[Type[T], Any],
|
|
513
|
-
service_name: Optional[str] = None,
|
|
514
|
-
auth_names: Optional[List[str]] = None,
|
|
515
|
-
query_params: Optional[QueryParams] = None,
|
|
516
|
-
headers: Optional[Dict[str, str]] = None,
|
|
517
|
-
data: Optional[httpx._types.RequestData] = None,
|
|
518
|
-
files: Optional[httpx._types.RequestFiles] = None,
|
|
519
|
-
json: Optional[Any] = None,
|
|
520
|
-
content_type: Optional[str] = None,
|
|
521
|
-
content: Optional[httpx._types.RequestContent] = None,
|
|
522
|
-
request_options: Optional[RequestOptions] = None,
|
|
523
|
-
) -> T:
|
|
524
|
-
"""Make an asynchronous HTTP request.
|
|
525
|
-
|
|
526
|
-
Args:
|
|
527
|
-
method: HTTP method
|
|
528
|
-
path: API endpoint path
|
|
529
|
-
cast_to: Type to cast the response to
|
|
530
|
-
auth_names: List of auth provider IDs
|
|
531
|
-
service_name: The name of the API service to make the request to
|
|
532
|
-
query_params: Query parameters
|
|
533
|
-
headers: Request headers
|
|
534
|
-
data: Form data
|
|
535
|
-
files: Files to upload
|
|
536
|
-
json: JSON data
|
|
537
|
-
content_type: Content type header
|
|
538
|
-
content: Raw content
|
|
539
|
-
request_options: Additional request options
|
|
540
|
-
|
|
541
|
-
Returns:
|
|
542
|
-
Response data of the specified type
|
|
543
|
-
|
|
544
|
-
Raises:
|
|
545
|
-
ApiError: If the request fails
|
|
546
|
-
"""
|
|
547
|
-
req_cfg = self.build_request(
|
|
548
|
-
method=method,
|
|
549
|
-
path=path,
|
|
550
|
-
service_name=service_name,
|
|
551
|
-
auth_names=auth_names,
|
|
552
|
-
query_params=query_params,
|
|
553
|
-
headers=headers,
|
|
554
|
-
data=data,
|
|
555
|
-
files=files,
|
|
556
|
-
json=json,
|
|
557
|
-
content_type=content_type,
|
|
558
|
-
content=content,
|
|
559
|
-
request_options=request_options,
|
|
560
|
-
)
|
|
561
|
-
response = await self.httpx_client.request(**req_cfg)
|
|
562
|
-
|
|
563
|
-
if not response.is_success:
|
|
564
|
-
raise ApiError(response=response)
|
|
565
|
-
|
|
566
|
-
if self._cast_to_raw_response(res=response, cast_to=cast_to):
|
|
567
|
-
return response
|
|
568
|
-
|
|
569
|
-
return self.process_response(response=response, cast_to=cast_to)
|
|
570
|
-
|
|
571
|
-
async def stream_request(
|
|
572
|
-
self,
|
|
573
|
-
*,
|
|
574
|
-
method: str,
|
|
575
|
-
path: str,
|
|
576
|
-
cast_to: Union[Type[T], Any],
|
|
577
|
-
service_name: Optional[str] = None,
|
|
578
|
-
auth_names: Optional[List[str]] = None,
|
|
579
|
-
query_params: Optional[QueryParams] = None,
|
|
580
|
-
headers: Optional[Dict[str, str]] = None,
|
|
581
|
-
data: Optional[httpx._types.RequestData] = None,
|
|
582
|
-
files: Optional[httpx._types.RequestFiles] = None,
|
|
583
|
-
json: Optional[Any] = None,
|
|
584
|
-
content_type: Optional[str] = None,
|
|
585
|
-
content: Optional[httpx._types.RequestContent] = None,
|
|
586
|
-
request_options: Optional[RequestOptions] = None,
|
|
587
|
-
) -> AsyncStreamResponse[T]:
|
|
588
|
-
"""Make a streaming asynchronous HTTP request.
|
|
589
|
-
|
|
590
|
-
Args:
|
|
591
|
-
method: HTTP method
|
|
592
|
-
path: API endpoint path
|
|
593
|
-
cast_to: Type to cast the response to
|
|
594
|
-
auth_names: List of auth provider IDs
|
|
595
|
-
service_name: The name of the API service to make the request to
|
|
596
|
-
query_params: Query parameters
|
|
597
|
-
headers: Request headers
|
|
598
|
-
data: Form data
|
|
599
|
-
files: Files to upload
|
|
600
|
-
json: JSON data
|
|
601
|
-
content_type: Content type header
|
|
602
|
-
content: Raw content
|
|
603
|
-
request_options: Additional request options
|
|
604
|
-
|
|
605
|
-
Returns:
|
|
606
|
-
AsyncStreamResponse containing the streaming response
|
|
607
|
-
|
|
608
|
-
Raises:
|
|
609
|
-
ApiError: If the request fails
|
|
610
|
-
"""
|
|
611
|
-
req_cfg = self.build_request(
|
|
612
|
-
method=method,
|
|
613
|
-
path=path,
|
|
614
|
-
service_name=service_name,
|
|
615
|
-
auth_names=auth_names,
|
|
616
|
-
query_params=query_params,
|
|
617
|
-
headers=headers,
|
|
618
|
-
data=data,
|
|
619
|
-
files=files,
|
|
620
|
-
json=json,
|
|
621
|
-
content_type=content_type,
|
|
622
|
-
content=content,
|
|
623
|
-
request_options=request_options,
|
|
624
|
-
)
|
|
625
|
-
context = self.httpx_client.stream(**req_cfg)
|
|
626
|
-
response = await context.__aenter__()
|
|
627
|
-
return AsyncStreamResponse(response, context, cast_to)
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
from httpx._models import Headers
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class BinaryResponse:
|
|
5
|
-
"""
|
|
6
|
-
Represents a binary HTTP response.
|
|
7
|
-
|
|
8
|
-
A lightweight wrapper for binary content and its associated HTTP headers,
|
|
9
|
-
typically used for handling file downloads or raw binary data from HTTP requests.
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
content: bytes
|
|
13
|
-
headers: Headers
|
|
14
|
-
|
|
15
|
-
def __init__(self, content: bytes, headers: Headers) -> None:
|
|
16
|
-
"""
|
|
17
|
-
Initialize a binary response with content and headers.
|
|
18
|
-
|
|
19
|
-
The content represents the raw binary data received in the response,
|
|
20
|
-
while headers contain the associated HTTP response headers.
|
|
21
|
-
"""
|
|
22
|
-
self.content = content
|
|
23
|
-
self.headers = headers
|