redc 0.1.1.dev1__cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.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.
- redc/__init__.py +22 -0
- redc/callback.py +19 -0
- redc/callbacks.py +81 -0
- redc/client.py +796 -0
- redc/codes.py +151 -0
- redc/exceptions/__init__.py +22 -0
- redc/ext/redc.cpp +362 -0
- redc/ext/redc.h +91 -0
- redc/ext/utils/concurrentqueue.h +3747 -0
- redc/ext/utils/curl_utils.h +84 -0
- redc/redc_ext.cpython-313t-x86_64-linux-gnu.so +0 -0
- redc/response.py +68 -0
- redc/utils/__init__.py +5 -0
- redc/utils/headers.py +60 -0
- redc/utils/http.py +12 -0
- redc/utils/json_encoder.py +17 -0
- redc-0.1.1.dev1.dist-info/METADATA +64 -0
- redc-0.1.1.dev1.dist-info/RECORD +27 -0
- redc-0.1.1.dev1.dist-info/WHEEL +6 -0
- redc-0.1.1.dev1.dist-info/licenses/LICENSE +21 -0
- redc.libs/libcrypto-cff6b41d.so.3 +0 -0
- redc.libs/libcurl-bf2af365.so.4.8.0 +0 -0
- redc.libs/libicudata-cb3ba60c.so.50.2 +0 -0
- redc.libs/libicuuc-1796a535.so.50.2 +0 -0
- redc.libs/libnghttp2-cc579893.so.14.17.0 +0 -0
- redc.libs/libpsl-9527e555.so.0.2.4 +0 -0
- redc.libs/libssl-ebec6e5c.so.3 +0 -0
redc/client.py
ADDED
@@ -0,0 +1,796 @@
|
|
1
|
+
from urllib.parse import urlencode
|
2
|
+
|
3
|
+
from .callbacks import StreamCallback, ProgressCallback
|
4
|
+
from .redc_ext import RedC
|
5
|
+
from .response import Response
|
6
|
+
from .utils import json_dumps, parse_base_url, Headers
|
7
|
+
|
8
|
+
import asyncio
|
9
|
+
import redc
|
10
|
+
|
11
|
+
|
12
|
+
class Client:
|
13
|
+
"""RedC client for making HTTP requests"""
|
14
|
+
|
15
|
+
def __init__(
|
16
|
+
self,
|
17
|
+
base_url: str = None,
|
18
|
+
buffer_size: int = 16384,
|
19
|
+
headers: dict = None,
|
20
|
+
timeout: tuple = (30.0, 0.0),
|
21
|
+
ca_cert_path: str = None,
|
22
|
+
force_verbose: bool = None,
|
23
|
+
raise_for_status: bool = False,
|
24
|
+
json_encoder=json_dumps,
|
25
|
+
):
|
26
|
+
"""
|
27
|
+
Initialize the RedC client
|
28
|
+
|
29
|
+
Example:
|
30
|
+
.. code-block:: python
|
31
|
+
|
32
|
+
>>> client = Client(base_url="https://example.com")
|
33
|
+
>>> response = await client.get("/api/data")
|
34
|
+
|
35
|
+
Parameters:
|
36
|
+
base_url (``str``, *optional*):
|
37
|
+
The base URL for the client. Default is ``None``
|
38
|
+
|
39
|
+
buffer_size (``int``, *optional*):
|
40
|
+
The buffer size for libcurl. Must be greater than ``1024`` bytes. Default is ``16384`` (16KB)
|
41
|
+
|
42
|
+
headers (``dict``, *optional*):
|
43
|
+
Headers to include in every request. Default is ``None``
|
44
|
+
|
45
|
+
timeout (``tuple``, *optional*):
|
46
|
+
A tuple of `(total_timeout, connect_timeout)` in seconds to include in every request. Default is ``(30.0, 0.0)``
|
47
|
+
|
48
|
+
ca_cert_path (``str``, *optional*):
|
49
|
+
Path to a CA certificate bundle file for SSL/TLS verification. Default is ``None``
|
50
|
+
|
51
|
+
force_verbose (``bool``, *optional*):
|
52
|
+
Force verbose output for all requests. Default is ``None``
|
53
|
+
|
54
|
+
raise_for_status (``bool``, *optional*):
|
55
|
+
If ``True``, automatically raises an :class:`redc.HTTPError` for responses with HTTP status codes
|
56
|
+
indicating an error (i.e., 4xx or 5xx) or for CURL errors (e.g., network issues, timeouts). Default is ``False``
|
57
|
+
|
58
|
+
json_encoder (``Callable`` , *optional*):
|
59
|
+
A callable for encoding JSON data. Default is :class:`redc.utils.json_dumps`
|
60
|
+
"""
|
61
|
+
|
62
|
+
assert isinstance(base_url, (str, type(None))), "base_url must be string"
|
63
|
+
assert isinstance(buffer_size, int), "buffer_size must be int"
|
64
|
+
assert isinstance(ca_cert_path, (str, type(None))), (
|
65
|
+
"ca_cert_path must be string"
|
66
|
+
)
|
67
|
+
assert isinstance(timeout, tuple) and len(timeout) == 2, (
|
68
|
+
"timeout must be a tuple of (total_timeout, connect_timeout)"
|
69
|
+
)
|
70
|
+
assert isinstance(force_verbose, (bool, type(None))), (
|
71
|
+
"force_verbose must be bool or None"
|
72
|
+
)
|
73
|
+
assert isinstance(raise_for_status, bool), "raise_for_status must be bool"
|
74
|
+
|
75
|
+
assert buffer_size >= 1024, "buffer_size must be bigger than 1024 bytes"
|
76
|
+
|
77
|
+
self.force_verbose = force_verbose
|
78
|
+
self.raise_for_status = raise_for_status
|
79
|
+
|
80
|
+
self.__base_url = (
|
81
|
+
parse_base_url(base_url) if isinstance(base_url, str) else None
|
82
|
+
)
|
83
|
+
self.__default_headers = Headers(headers if isinstance(headers, dict) else {})
|
84
|
+
self.__timeout = timeout
|
85
|
+
self.__ca_cert_path = ca_cert_path if isinstance(ca_cert_path, str) else ""
|
86
|
+
self.__json_encoder = json_encoder
|
87
|
+
self.__loop = asyncio.get_event_loop()
|
88
|
+
self.__redc_ext = RedC(buffer_size)
|
89
|
+
|
90
|
+
self.__set_default_headers()
|
91
|
+
|
92
|
+
async def __aenter__(self):
|
93
|
+
return self
|
94
|
+
|
95
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
96
|
+
await self.close()
|
97
|
+
|
98
|
+
@property
|
99
|
+
def is_running(self):
|
100
|
+
"""Checks if RedC is currently running
|
101
|
+
|
102
|
+
Returns:
|
103
|
+
``bool``: ``True`` if RedC is running, False otherwise
|
104
|
+
"""
|
105
|
+
|
106
|
+
return self.__redc_ext.is_running()
|
107
|
+
|
108
|
+
@property
|
109
|
+
def default_headers(self):
|
110
|
+
"""Returns default headers that are set on all requests"""
|
111
|
+
|
112
|
+
return self.__default_headers
|
113
|
+
|
114
|
+
async def request(
|
115
|
+
self,
|
116
|
+
method: str,
|
117
|
+
url: str,
|
118
|
+
form: dict = None,
|
119
|
+
json: dict = None,
|
120
|
+
data: dict[str, str] = None,
|
121
|
+
files: dict[str, str] = None,
|
122
|
+
headers: dict[str, str] = None,
|
123
|
+
timeout: tuple = None,
|
124
|
+
allow_redirect: bool = True,
|
125
|
+
proxy_url: str = "",
|
126
|
+
verify: bool = True,
|
127
|
+
stream_callback: StreamCallback = None,
|
128
|
+
progress_callback: ProgressCallback = None,
|
129
|
+
verbose: bool = False,
|
130
|
+
):
|
131
|
+
"""
|
132
|
+
Make an HTTP request with the specified method and parameters
|
133
|
+
|
134
|
+
Example:
|
135
|
+
.. code-block:: python
|
136
|
+
|
137
|
+
>>> response = await client.request("GET", "/api/data", headers={"Authorization": "Bearer token"})
|
138
|
+
|
139
|
+
Parameters:
|
140
|
+
method (``str``):
|
141
|
+
The HTTP method to use (e.g., "GET", "POST")
|
142
|
+
|
143
|
+
url (``str``):
|
144
|
+
The URL to send the request to or path if ``base_url`` is specified in ``Client``
|
145
|
+
|
146
|
+
form (``dict``, *optional*):
|
147
|
+
Form data to send in the request body. Default is ``None``
|
148
|
+
|
149
|
+
json (``dict``, *optional*):
|
150
|
+
JSON data to send in the request body. Default is ``None``
|
151
|
+
|
152
|
+
data (``dict[str, str]``, *optional*):
|
153
|
+
Multipart form data to send in the request body. Default is ``None``
|
154
|
+
|
155
|
+
files (``dict[str, str]``, *optional*):
|
156
|
+
A dictionary specifying files to upload as part of a multipart form request, ``key`` is the form field and ``value`` is string containing the file path
|
157
|
+
|
158
|
+
headers (``dict[str, str]``, *optional*):
|
159
|
+
Headers to include in the request. Default is ``None``
|
160
|
+
|
161
|
+
timeout (``tuple``, *optional*):
|
162
|
+
A tuple of ``(total_timeout, connect_timeout)`` in seconds to override the default timeout.
|
163
|
+
If ``None``, the default timeout specified in ``Client`` is used.
|
164
|
+
|
165
|
+
allow_redirect (``bool``, *optional*):
|
166
|
+
Whether to allow redirects. Default is ``True``
|
167
|
+
|
168
|
+
proxy_url (``str``, *optional*):
|
169
|
+
The proxy URL to use for the request
|
170
|
+
|
171
|
+
verify (``bool``, *optional*):
|
172
|
+
Whether to verify SSL certificates. Default is ``True``
|
173
|
+
|
174
|
+
stream_callback (:class:`redc.StreamCallback`, *optional*):
|
175
|
+
Callback for streaming response data. Default is ``None``
|
176
|
+
|
177
|
+
progress_callback (:class:`redc.ProgressCallback`, *optional*):
|
178
|
+
Callback for tracking upload and download progress. Default is ``None``
|
179
|
+
|
180
|
+
verbose (``bool``, *optional*):
|
181
|
+
Whether to enable verbose output for the request. Default is ``False``
|
182
|
+
|
183
|
+
Returns:
|
184
|
+
:class:`redc.Response`
|
185
|
+
"""
|
186
|
+
|
187
|
+
if stream_callback is not None:
|
188
|
+
if not isinstance(stream_callback, StreamCallback):
|
189
|
+
raise TypeError("stream_callback must be of type StreamCallback")
|
190
|
+
|
191
|
+
stream_callback = stream_callback.callback
|
192
|
+
|
193
|
+
if progress_callback is not None:
|
194
|
+
if not isinstance(progress_callback, ProgressCallback):
|
195
|
+
raise TypeError("progress_callback must be of type ProgressCallback")
|
196
|
+
|
197
|
+
progress_callback = progress_callback.callback
|
198
|
+
|
199
|
+
if form is not None:
|
200
|
+
if isinstance(form, dict):
|
201
|
+
form = urlencode(form)
|
202
|
+
else:
|
203
|
+
raise TypeError("form must be of type dict[str, str]")
|
204
|
+
|
205
|
+
if json is not None:
|
206
|
+
if isinstance(json, dict):
|
207
|
+
json = self.__json_encoder(json)
|
208
|
+
if headers is None:
|
209
|
+
headers = {}
|
210
|
+
headers["Content-Type"] = "application/json"
|
211
|
+
else:
|
212
|
+
raise TypeError("json must be of type dict[str, str]")
|
213
|
+
|
214
|
+
if data is not None:
|
215
|
+
if not isinstance(data, dict):
|
216
|
+
raise TypeError("data must be of type dict[str, str]")
|
217
|
+
|
218
|
+
if files is not None:
|
219
|
+
if not isinstance(files, dict):
|
220
|
+
raise TypeError("files must be of type dict[str, str]")
|
221
|
+
|
222
|
+
timeout, connect_timeout = timeout if timeout is not None else self.__timeout
|
223
|
+
|
224
|
+
if timeout <= 0:
|
225
|
+
raise ValueError("timeout must be greater than 0")
|
226
|
+
|
227
|
+
if connect_timeout < 0:
|
228
|
+
raise ValueError("connect_timeout must be 0 or greater")
|
229
|
+
elif connect_timeout > timeout:
|
230
|
+
raise ValueError("connect_timeout must be less than `timeout` argument")
|
231
|
+
|
232
|
+
if headers is not None:
|
233
|
+
if isinstance(headers, dict):
|
234
|
+
headers = {**self.__default_headers, **headers}
|
235
|
+
headers = [f"{k}: {v}" for k, v in headers.items()]
|
236
|
+
else:
|
237
|
+
raise TypeError("headers must be of type dict[str, str]")
|
238
|
+
else:
|
239
|
+
headers = [f"{k}: {v}" for k, v in self.__default_headers.items()]
|
240
|
+
|
241
|
+
if self.__base_url:
|
242
|
+
url = f"{self.__base_url}{url.lstrip('/')}"
|
243
|
+
|
244
|
+
return Response(
|
245
|
+
*(
|
246
|
+
await self.__redc_ext.request(
|
247
|
+
method=method,
|
248
|
+
url=url,
|
249
|
+
raw_data=form or json or "",
|
250
|
+
data=data,
|
251
|
+
files=files,
|
252
|
+
headers=headers,
|
253
|
+
timeout_ms=int(timeout * 1000),
|
254
|
+
connect_timeout_ms=int(connect_timeout * 1000),
|
255
|
+
allow_redirect=allow_redirect,
|
256
|
+
proxy_url=proxy_url,
|
257
|
+
verify=verify,
|
258
|
+
ca_cert_path=self.__ca_cert_path,
|
259
|
+
stream_callback=stream_callback,
|
260
|
+
progress_callback=progress_callback,
|
261
|
+
verbose=self.force_verbose or verbose,
|
262
|
+
)
|
263
|
+
),
|
264
|
+
raise_for_status=self.raise_for_status,
|
265
|
+
)
|
266
|
+
|
267
|
+
async def get(
|
268
|
+
self,
|
269
|
+
url: str,
|
270
|
+
headers: dict[str, str] = None,
|
271
|
+
timeout: tuple = None,
|
272
|
+
allow_redirect: bool = True,
|
273
|
+
proxy_url: str = "",
|
274
|
+
verify: bool = True,
|
275
|
+
stream_callback: StreamCallback = None,
|
276
|
+
progress_callback: ProgressCallback = None,
|
277
|
+
verbose: bool = False,
|
278
|
+
):
|
279
|
+
"""
|
280
|
+
Make a GET request
|
281
|
+
|
282
|
+
Example:
|
283
|
+
.. code-block:: python
|
284
|
+
|
285
|
+
>>> response = await client.get("/api/data", headers={"Authorization": "Bearer token"})
|
286
|
+
|
287
|
+
Parameters:
|
288
|
+
url (``str``):
|
289
|
+
The URL to send the GET request to or path if ``base_url`` is specified in ``Client``
|
290
|
+
|
291
|
+
headers (``dict[str, str]``, *optional*):
|
292
|
+
Headers to include in the request. Default is ``None``
|
293
|
+
|
294
|
+
timeout (``tuple``, *optional*):
|
295
|
+
A tuple of ``(total_timeout, connect_timeout)`` in seconds to override the default timeout.
|
296
|
+
If ``None``, the default timeout specified in ``Client`` is used.
|
297
|
+
|
298
|
+
allow_redirect (``bool``, *optional*):
|
299
|
+
Whether to allow redirects. Default is ``True``
|
300
|
+
|
301
|
+
proxy_url (``str``, *optional*):
|
302
|
+
The proxy URL to use for the request
|
303
|
+
|
304
|
+
verify (``bool``, *optional*):
|
305
|
+
Whether to verify SSL certificates. Default is ``True``
|
306
|
+
|
307
|
+
stream_callback (:class:`redc.StreamCallback`, *optional*):
|
308
|
+
Callback for streaming response data. Default is ``None``
|
309
|
+
|
310
|
+
progress_callback (:class:`redc.ProgressCallback`, *optional*):
|
311
|
+
Callback for tracking upload and download progress. Default is ``None``
|
312
|
+
|
313
|
+
verbose (``bool``, *optional*):
|
314
|
+
Whether to enable verbose output for the request. Default is ``False``
|
315
|
+
|
316
|
+
Returns:
|
317
|
+
:class:`redc.Response`
|
318
|
+
"""
|
319
|
+
|
320
|
+
return await self.request(
|
321
|
+
method="GET",
|
322
|
+
url=url,
|
323
|
+
headers=headers,
|
324
|
+
timeout=timeout,
|
325
|
+
allow_redirect=allow_redirect,
|
326
|
+
proxy_url=proxy_url,
|
327
|
+
verify=verify,
|
328
|
+
stream_callback=stream_callback,
|
329
|
+
progress_callback=progress_callback,
|
330
|
+
verbose=self.force_verbose or verbose,
|
331
|
+
)
|
332
|
+
|
333
|
+
async def head(
|
334
|
+
self,
|
335
|
+
url: str,
|
336
|
+
headers: dict[str, str] = None,
|
337
|
+
timeout: tuple = None,
|
338
|
+
allow_redirect: bool = True,
|
339
|
+
proxy_url: str = "",
|
340
|
+
verify: bool = True,
|
341
|
+
verbose: bool = False,
|
342
|
+
):
|
343
|
+
"""
|
344
|
+
Make a HEAD request
|
345
|
+
|
346
|
+
Example:
|
347
|
+
.. code-block:: python
|
348
|
+
|
349
|
+
>>> response = await client.head("/api/data", headers={"Authorization": "Bearer token"})
|
350
|
+
|
351
|
+
Parameters:
|
352
|
+
url (``str``):
|
353
|
+
The URL to send the HEAD request to or path if ``base_url`` is specified in ``Client``
|
354
|
+
|
355
|
+
headers (``dict[str, str]``, *optional*):
|
356
|
+
Headers to include in the request. Default is ``None``
|
357
|
+
|
358
|
+
timeout (``tuple``, *optional*):
|
359
|
+
A tuple of ``(total_timeout, connect_timeout)`` in seconds to override the default timeout.
|
360
|
+
If ``None``, the default timeout specified in ``Client`` is used.
|
361
|
+
|
362
|
+
allow_redirect (``bool``, *optional*):
|
363
|
+
Whether to allow redirects. Default is ``True``
|
364
|
+
|
365
|
+
proxy_url (``str``, *optional*):
|
366
|
+
The proxy URL to use for the request
|
367
|
+
|
368
|
+
verify (``bool``, *optional*):
|
369
|
+
Whether to verify SSL certificates. Default is ``True``
|
370
|
+
|
371
|
+
verbose (``bool``, *optional*):
|
372
|
+
Whether to enable verbose output for the request. Default is ``False``
|
373
|
+
|
374
|
+
Returns:
|
375
|
+
:class:`redc.Response`
|
376
|
+
"""
|
377
|
+
|
378
|
+
return await self.request(
|
379
|
+
method="HEAD",
|
380
|
+
url=url,
|
381
|
+
headers=headers,
|
382
|
+
timeout=timeout,
|
383
|
+
allow_redirect=allow_redirect,
|
384
|
+
proxy_url=proxy_url,
|
385
|
+
verify=verify,
|
386
|
+
verbose=self.force_verbose or verbose,
|
387
|
+
)
|
388
|
+
|
389
|
+
async def post(
|
390
|
+
self,
|
391
|
+
url: str,
|
392
|
+
form: dict = None,
|
393
|
+
json: dict = None,
|
394
|
+
data: dict[str, str] = None,
|
395
|
+
files: dict[str, str] = None,
|
396
|
+
headers: dict[str, str] = None,
|
397
|
+
timeout: tuple = None,
|
398
|
+
allow_redirect: bool = True,
|
399
|
+
proxy_url: str = "",
|
400
|
+
verify: bool = True,
|
401
|
+
stream_callback: StreamCallback = None,
|
402
|
+
progress_callback: ProgressCallback = None,
|
403
|
+
verbose: bool = False,
|
404
|
+
):
|
405
|
+
"""
|
406
|
+
Make a POST request
|
407
|
+
|
408
|
+
Example:
|
409
|
+
.. code-block:: python
|
410
|
+
|
411
|
+
>>> response = await client.post(
|
412
|
+
... "/api/data",
|
413
|
+
... json={"key": "value"},
|
414
|
+
... headers={"Authorization": "Bearer token"}
|
415
|
+
... )
|
416
|
+
|
417
|
+
Parameters:
|
418
|
+
url (``str``):
|
419
|
+
The URL to send the POST request to or path if ``base_url`` is specified in ``Client``
|
420
|
+
|
421
|
+
form (``dict``, *optional*):
|
422
|
+
Form data to send in the request body. Default is ``None``
|
423
|
+
|
424
|
+
json (``dict``, *optional*):
|
425
|
+
JSON data to send in the request body. Default is ``None``
|
426
|
+
|
427
|
+
data (``dict[str, str]``, *optional*):
|
428
|
+
Multipart form data to send in the request body. Default is ``None``
|
429
|
+
|
430
|
+
files (``dict[str, str]``, *optional*):
|
431
|
+
A dictionary specifying files to upload as part of a multipart form request, ``key`` is the form field and ``value`` is string containing the file path
|
432
|
+
|
433
|
+
headers (``dict[str, str]``, *optional*):
|
434
|
+
Headers to include in the request. Default is ``None``
|
435
|
+
|
436
|
+
timeout (``tuple``, *optional*):
|
437
|
+
A tuple of ``(total_timeout, connect_timeout)`` in seconds to override the default timeout.
|
438
|
+
If ``None``, the default timeout specified in ``Client`` is used.
|
439
|
+
|
440
|
+
allow_redirect (``bool``, *optional*):
|
441
|
+
Whether to allow redirects. Default is ``True``
|
442
|
+
|
443
|
+
proxy_url (``str``, *optional*):
|
444
|
+
The proxy URL to use for the request
|
445
|
+
|
446
|
+
verify (``bool``, *optional*):
|
447
|
+
Whether to verify SSL certificates. Default is ``True``
|
448
|
+
|
449
|
+
stream_callback (:class:`redc.StreamCallback`, *optional*):
|
450
|
+
Callback for streaming response data. Default is ``None``
|
451
|
+
|
452
|
+
progress_callback (:class:`redc.ProgressCallback`, *optional*):
|
453
|
+
Callback for tracking upload and download progress. Default is ``None``
|
454
|
+
|
455
|
+
verbose (``bool``, *optional*):
|
456
|
+
Whether to enable verbose output for the request. Default is ``False``
|
457
|
+
|
458
|
+
Returns:
|
459
|
+
:class:`redc.Response`
|
460
|
+
"""
|
461
|
+
|
462
|
+
return await self.request(
|
463
|
+
method="POST",
|
464
|
+
url=url,
|
465
|
+
form=form,
|
466
|
+
json=json,
|
467
|
+
data=data,
|
468
|
+
files=files,
|
469
|
+
headers=headers,
|
470
|
+
timeout=timeout,
|
471
|
+
allow_redirect=allow_redirect,
|
472
|
+
proxy_url=proxy_url,
|
473
|
+
verify=verify,
|
474
|
+
stream_callback=stream_callback,
|
475
|
+
progress_callback=progress_callback,
|
476
|
+
verbose=self.force_verbose or verbose,
|
477
|
+
)
|
478
|
+
|
479
|
+
async def put(
|
480
|
+
self,
|
481
|
+
url: str,
|
482
|
+
form: dict = None,
|
483
|
+
json: dict = None,
|
484
|
+
data: dict[str, str] = None,
|
485
|
+
files: dict[str, str] = None,
|
486
|
+
headers: dict[str, str] = None,
|
487
|
+
timeout: tuple = None,
|
488
|
+
allow_redirect: bool = True,
|
489
|
+
proxy_url: str = "",
|
490
|
+
verify: bool = True,
|
491
|
+
stream_callback: StreamCallback = None,
|
492
|
+
progress_callback: ProgressCallback = None,
|
493
|
+
verbose: bool = False,
|
494
|
+
):
|
495
|
+
"""
|
496
|
+
Make a PUT request
|
497
|
+
|
498
|
+
Example:
|
499
|
+
.. code-block:: python
|
500
|
+
|
501
|
+
>>> response = await client.put(
|
502
|
+
... "/api/data/1",
|
503
|
+
... json={"key": "new_value"},
|
504
|
+
... headers={"Authorization": "Bearer token"}
|
505
|
+
... )
|
506
|
+
|
507
|
+
Parameters:
|
508
|
+
url (``str``):
|
509
|
+
The URL to send the PUT request to or path if ``base_url`` is specified in ``Client``
|
510
|
+
|
511
|
+
form (``dict``, *optional*):
|
512
|
+
Form data to send in the request body. Default is ``None``
|
513
|
+
|
514
|
+
json (``dict``, *optional*):
|
515
|
+
JSON data to send in the request body. Default is ``None``
|
516
|
+
|
517
|
+
data (``dict[str, str]``, *optional*):
|
518
|
+
Multipart form data to send in the request body. Default is ``None``
|
519
|
+
|
520
|
+
files (``dict[str, str]``, *optional*):
|
521
|
+
A dictionary specifying files to upload as part of a multipart form request, ``key`` is the form field and ``value`` is string containing the file path
|
522
|
+
|
523
|
+
headers (``dict[str, str]``, *optional*):
|
524
|
+
Headers to include in the request. Default is ``None``
|
525
|
+
|
526
|
+
timeout (``tuple``, *optional*):
|
527
|
+
A tuple of ``(total_timeout, connect_timeout)`` in seconds to override the default timeout.
|
528
|
+
If ``None``, the default timeout specified in ``Client`` is used.
|
529
|
+
|
530
|
+
allow_redirect (``bool``, *optional*):
|
531
|
+
Whether to allow redirects. Default is ``True``
|
532
|
+
|
533
|
+
proxy_url (``str``, *optional*):
|
534
|
+
The proxy URL to use for the request
|
535
|
+
|
536
|
+
verify (``bool``, *optional*):
|
537
|
+
Whether to verify SSL certificates. Default is ``True``
|
538
|
+
|
539
|
+
stream_callback (:class:`redc.StreamCallback`, *optional*):
|
540
|
+
Callback for streaming response data. Default is ``None``
|
541
|
+
|
542
|
+
progress_callback (:class:`redc.ProgressCallback`, *optional*):
|
543
|
+
Callback for tracking upload and download progress. Default is ``None``
|
544
|
+
|
545
|
+
verbose (``bool``, *optional*):
|
546
|
+
Whether to enable verbose output for the request. Default is ``False``
|
547
|
+
|
548
|
+
Returns:
|
549
|
+
:class:`redc.Response`
|
550
|
+
"""
|
551
|
+
|
552
|
+
return await self.request(
|
553
|
+
method="PUT",
|
554
|
+
url=url,
|
555
|
+
form=form,
|
556
|
+
json=json,
|
557
|
+
data=data,
|
558
|
+
files=files,
|
559
|
+
headers=headers,
|
560
|
+
timeout=timeout,
|
561
|
+
allow_redirect=allow_redirect,
|
562
|
+
proxy_url=proxy_url,
|
563
|
+
verify=verify,
|
564
|
+
stream_callback=stream_callback,
|
565
|
+
progress_callback=progress_callback,
|
566
|
+
verbose=self.force_verbose or verbose,
|
567
|
+
)
|
568
|
+
|
569
|
+
async def patch(
|
570
|
+
self,
|
571
|
+
url: str,
|
572
|
+
form: dict = None,
|
573
|
+
json: dict = None,
|
574
|
+
data: dict[str, str] = None,
|
575
|
+
files: dict[str, str] = None,
|
576
|
+
headers: dict[str, str] = None,
|
577
|
+
timeout: tuple = None,
|
578
|
+
allow_redirect: bool = True,
|
579
|
+
proxy_url: str = "",
|
580
|
+
verify: bool = True,
|
581
|
+
stream_callback: StreamCallback = None,
|
582
|
+
progress_callback: ProgressCallback = None,
|
583
|
+
verbose: bool = False,
|
584
|
+
):
|
585
|
+
"""
|
586
|
+
Make a PATCH request
|
587
|
+
|
588
|
+
Example:
|
589
|
+
.. code-block:: python
|
590
|
+
|
591
|
+
>>> response = await client.patch(
|
592
|
+
... "/api/data/1",
|
593
|
+
... json={"key": "updated_value"},
|
594
|
+
... headers={"Authorization": "Bearer token"}
|
595
|
+
... )
|
596
|
+
|
597
|
+
Parameters:
|
598
|
+
url (``str``):
|
599
|
+
The URL to send the PATCH request to or path if ``base_url`` is specified in ``Client``
|
600
|
+
|
601
|
+
form (``dict``, *optional*):
|
602
|
+
Form data to send in the request body. Default is ``None``
|
603
|
+
|
604
|
+
json (``dict``, *optional*):
|
605
|
+
JSON data to send in the request body. Default is ``None``
|
606
|
+
|
607
|
+
data (``dict[str, str]``, *optional*):
|
608
|
+
Multipart form data to send in the request body. Default is ``None``
|
609
|
+
|
610
|
+
files (``dict[str, str]``, *optional*):
|
611
|
+
A dictionary specifying files to upload as part of a multipart form request, ``key`` is the form field and ``value`` is string containing the file path
|
612
|
+
|
613
|
+
headers (``dict[str, str]``, *optional*):
|
614
|
+
Headers to include in the request. Default is ``None``
|
615
|
+
|
616
|
+
timeout (``tuple``, *optional*):
|
617
|
+
A tuple of ``(total_timeout, connect_timeout)`` in seconds to override the default timeout.
|
618
|
+
If ``None``, the default timeout specified in ``Client`` is used.
|
619
|
+
|
620
|
+
allow_redirect (``bool``, *optional*):
|
621
|
+
Whether to allow redirects. Default is ``True``
|
622
|
+
|
623
|
+
proxy_url (``str``, *optional*):
|
624
|
+
The proxy URL to use for the request
|
625
|
+
|
626
|
+
verify (``bool``, *optional*):
|
627
|
+
Whether to verify SSL certificates. Default is ``True``
|
628
|
+
|
629
|
+
stream_callback (:class:`redc.StreamCallback`, *optional*):
|
630
|
+
Callback for streaming response data. Default is ``None``
|
631
|
+
|
632
|
+
progress_callback (:class:`redc.ProgressCallback`, *optional*):
|
633
|
+
Callback for tracking upload and download progress. Default is ``None``
|
634
|
+
|
635
|
+
verbose (``bool``, *optional*):
|
636
|
+
Whether to enable verbose output for the request. Default is ``False``
|
637
|
+
|
638
|
+
Returns:
|
639
|
+
:class:`redc.Response`
|
640
|
+
"""
|
641
|
+
|
642
|
+
return await self.request(
|
643
|
+
method="PATCH",
|
644
|
+
url=url,
|
645
|
+
form=form,
|
646
|
+
json=json,
|
647
|
+
data=data,
|
648
|
+
files=files,
|
649
|
+
headers=headers,
|
650
|
+
timeout=timeout,
|
651
|
+
allow_redirect=allow_redirect,
|
652
|
+
proxy_url=proxy_url,
|
653
|
+
verify=verify,
|
654
|
+
stream_callback=stream_callback,
|
655
|
+
progress_callback=progress_callback,
|
656
|
+
verbose=self.force_verbose or verbose,
|
657
|
+
)
|
658
|
+
|
659
|
+
async def delete(
|
660
|
+
self,
|
661
|
+
url: str,
|
662
|
+
headers: dict[str, str] = None,
|
663
|
+
timeout: tuple = None,
|
664
|
+
allow_redirect: bool = True,
|
665
|
+
proxy_url: str = "",
|
666
|
+
verify: bool = True,
|
667
|
+
stream_callback: StreamCallback = None,
|
668
|
+
progress_callback: ProgressCallback = None,
|
669
|
+
verbose: bool = False,
|
670
|
+
):
|
671
|
+
"""
|
672
|
+
Make a DELETE request
|
673
|
+
|
674
|
+
Example:
|
675
|
+
.. code-block:: python
|
676
|
+
|
677
|
+
>>> response = await client.delete("/api/data/1", headers={"Authorization": "Bearer token"})
|
678
|
+
|
679
|
+
Parameters:
|
680
|
+
url (``str``):
|
681
|
+
The URL to send the DELETE request to or path if ``base_url`` is specified in ``Client``
|
682
|
+
|
683
|
+
headers (``dict[str, str]``, *optional*):
|
684
|
+
Headers to include in the request. Default is ``None``
|
685
|
+
|
686
|
+
timeout (``tuple``, *optional*):
|
687
|
+
A tuple of ``(total_timeout, connect_timeout)`` in seconds to override the default timeout.
|
688
|
+
If ``None``, the default timeout specified in ``Client`` is used.
|
689
|
+
|
690
|
+
allow_redirect (``bool``, *optional*):
|
691
|
+
Whether to allow redirects. Default is ``True``
|
692
|
+
|
693
|
+
proxy_url (``str``, *optional*):
|
694
|
+
The proxy URL to use for the request
|
695
|
+
|
696
|
+
verify (``bool``, *optional*):
|
697
|
+
Whether to verify SSL certificates. Default is ``True``
|
698
|
+
|
699
|
+
stream_callback (:class:`redc.StreamCallback`, *optional*):
|
700
|
+
Callback for streaming response data. Default is ``None``
|
701
|
+
|
702
|
+
progress_callback (:class:`redc.ProgressCallback`, *optional*):
|
703
|
+
Callback for tracking upload and download progress. Default is ``None``
|
704
|
+
|
705
|
+
verbose (``bool``, *optional*):
|
706
|
+
Whether to enable verbose output for the request. Default is ``False``
|
707
|
+
|
708
|
+
Returns:
|
709
|
+
:class:`redc.Response`
|
710
|
+
"""
|
711
|
+
|
712
|
+
return await self.request(
|
713
|
+
method="DELETE",
|
714
|
+
url=url,
|
715
|
+
headers=headers,
|
716
|
+
timeout=timeout,
|
717
|
+
allow_redirect=allow_redirect,
|
718
|
+
proxy_url=proxy_url,
|
719
|
+
verify=verify,
|
720
|
+
stream_callback=stream_callback,
|
721
|
+
progress_callback=progress_callback,
|
722
|
+
verbose=self.force_verbose or verbose,
|
723
|
+
)
|
724
|
+
|
725
|
+
async def options(
|
726
|
+
self,
|
727
|
+
url: str,
|
728
|
+
headers: dict[str, str] = None,
|
729
|
+
timeout: tuple = None,
|
730
|
+
allow_redirect: bool = True,
|
731
|
+
proxy_url: str = "",
|
732
|
+
verify: bool = True,
|
733
|
+
verbose: bool = False,
|
734
|
+
):
|
735
|
+
"""
|
736
|
+
Make an OPTIONS request
|
737
|
+
|
738
|
+
Example:
|
739
|
+
.. code-block:: python
|
740
|
+
|
741
|
+
>>> response = await client.options("/api/data", headers={"Authorization": "Bearer token"})
|
742
|
+
|
743
|
+
Parameters:
|
744
|
+
url (``str``):
|
745
|
+
The URL to send the OPTIONS request to or path if ``base_url`` is specified in ``Client``
|
746
|
+
|
747
|
+
headers (``dict[str, str]``, *optional*):
|
748
|
+
Headers to include in the request. Default is ``None``
|
749
|
+
|
750
|
+
timeout (``tuple``, *optional*):
|
751
|
+
A tuple of ``(total_timeout, connect_timeout)`` in seconds to override the default timeout.
|
752
|
+
If ``None``, the default timeout specified in ``Client`` is used.
|
753
|
+
|
754
|
+
allow_redirect (``bool``, *optional*):
|
755
|
+
Whether to allow redirects. Default is ``True``
|
756
|
+
|
757
|
+
proxy_url (``str``, *optional*):
|
758
|
+
The proxy URL to use for the request
|
759
|
+
|
760
|
+
verify (``bool``, *optional*):
|
761
|
+
Whether to verify SSL certificates. Default is ``True``
|
762
|
+
|
763
|
+
verbose (``bool``, *optional*):
|
764
|
+
Whether to enable verbose output for the request. Default is ``False``
|
765
|
+
|
766
|
+
Returns:
|
767
|
+
:class:`redc.Response`
|
768
|
+
"""
|
769
|
+
|
770
|
+
return await self.request(
|
771
|
+
method="OPTIONS",
|
772
|
+
url=url,
|
773
|
+
headers=headers,
|
774
|
+
timeout=timeout,
|
775
|
+
allow_redirect=allow_redirect,
|
776
|
+
proxy_url=proxy_url,
|
777
|
+
verify=verify,
|
778
|
+
verbose=self.force_verbose or verbose,
|
779
|
+
)
|
780
|
+
|
781
|
+
async def close(self):
|
782
|
+
"""
|
783
|
+
Close the RedC client and free up resources.
|
784
|
+
|
785
|
+
This method must be called when the client is no longer needed to avoid memory leaks
|
786
|
+
or unexpected behavior
|
787
|
+
"""
|
788
|
+
|
789
|
+
return await self.__loop.run_in_executor(None, self.__redc_ext.close)
|
790
|
+
|
791
|
+
def __set_default_headers(self):
|
792
|
+
if "user-agent" not in self.__default_headers:
|
793
|
+
self.__default_headers["user-agent"] = f"redc/{redc.__version__}"
|
794
|
+
|
795
|
+
if "connection" not in self.__default_headers:
|
796
|
+
self.__default_headers["connection"] = "keep-alive"
|