pyreqwest 0.6.0__cp314-cp314-macosx_10_12_x86_64.whl → 0.10.1__cp314-cp314-macosx_10_12_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.
- pyreqwest/_pyreqwest.cpython-314-darwin.so +0 -0
- pyreqwest/client/__init__.py +4 -6
- pyreqwest/client/__init__.pyi +32 -22
- pyreqwest/exceptions/__init__.py +18 -15
- pyreqwest/http/__init__.py +1 -1
- pyreqwest/logging/__init__.py +7 -0
- pyreqwest/logging/__init__.pyi +4 -0
- pyreqwest/pytest_plugin/mock.py +20 -1
- pyreqwest/request/__init__.py +9 -5
- pyreqwest/request/__init__.pyi +21 -3
- pyreqwest/response/__init__.py +2 -2
- pyreqwest/response/__init__.pyi +3 -3
- pyreqwest/runtime/__init__.py +15 -0
- pyreqwest/runtime/__init__.pyi +25 -0
- pyreqwest/simple/__init__.py +1 -0
- pyreqwest/simple/request/__init__.py +21 -0
- pyreqwest/simple/request/__init__.pyi +29 -0
- pyreqwest/simple/sync_request/__init__.py +21 -0
- pyreqwest/simple/sync_request/__init__.pyi +29 -0
- {pyreqwest-0.6.0.dist-info → pyreqwest-0.10.1.dist-info}/METADATA +37 -1
- {pyreqwest-0.6.0.dist-info → pyreqwest-0.10.1.dist-info}/RECORD +24 -15
- {pyreqwest-0.6.0.dist-info → pyreqwest-0.10.1.dist-info}/WHEEL +1 -1
- {pyreqwest-0.6.0.dist-info → pyreqwest-0.10.1.dist-info}/entry_points.txt +0 -0
- {pyreqwest-0.6.0.dist-info → pyreqwest-0.10.1.dist-info}/licenses/LICENSE +0 -0
|
Binary file
|
pyreqwest/client/__init__.py
CHANGED
|
@@ -5,17 +5,15 @@ from pyreqwest._pyreqwest.client import (
|
|
|
5
5
|
BaseClientBuilder,
|
|
6
6
|
Client,
|
|
7
7
|
ClientBuilder,
|
|
8
|
-
Runtime,
|
|
9
8
|
SyncClient,
|
|
10
9
|
SyncClientBuilder,
|
|
11
10
|
)
|
|
12
11
|
|
|
13
|
-
__all__ = [
|
|
14
|
-
"
|
|
12
|
+
__all__ = [
|
|
13
|
+
"BaseClientBuilder",
|
|
15
14
|
"ClientBuilder",
|
|
16
|
-
"SyncClient",
|
|
17
15
|
"SyncClientBuilder",
|
|
18
16
|
"BaseClient",
|
|
19
|
-
"
|
|
20
|
-
"
|
|
17
|
+
"Client",
|
|
18
|
+
"SyncClient",
|
|
21
19
|
]
|
pyreqwest/client/__init__.pyi
CHANGED
|
@@ -103,13 +103,18 @@ class BaseClientBuilder:
|
|
|
103
103
|
def base_url(self, url: Url | str) -> Self:
|
|
104
104
|
"""Set a base URL automatically prepended to relative request URLs."""
|
|
105
105
|
|
|
106
|
-
def
|
|
107
|
-
"""Use
|
|
106
|
+
def runtime_multithreaded(self, enable: bool) -> Self:
|
|
107
|
+
"""Use multithreaded Tokio runtime for client. Default is single-threaded or as configured globally via
|
|
108
|
+
`pyreqwest.runtime` module.
|
|
109
|
+
|
|
110
|
+
Multithreaded runtime may improve performance for high concurrency workloads with complex requests.
|
|
111
|
+
See also `pyreqwest.runtime` module for configuring global multithreaded runtime behavior.
|
|
112
|
+
"""
|
|
108
113
|
|
|
109
114
|
def max_connections(self, max_connections: int | None) -> Self:
|
|
110
115
|
"""Maximum number of inflight requests. None means no limit. Default is None."""
|
|
111
116
|
|
|
112
|
-
def error_for_status(self, enable: bool) -> Self:
|
|
117
|
+
def error_for_status(self, enable: bool = True) -> Self:
|
|
113
118
|
"""Enable automatic HTTP error raising (4xx/5xx)."""
|
|
114
119
|
|
|
115
120
|
def user_agent(self, value: str) -> Self:
|
|
@@ -176,6 +181,14 @@ class BaseClientBuilder:
|
|
|
176
181
|
def pool_max_idle_per_host(self, max_idle: int) -> Self:
|
|
177
182
|
"""Sets the maximum idle connection per host allowed in the pool."""
|
|
178
183
|
|
|
184
|
+
def connection_verbose(self, enable: bool) -> Self:
|
|
185
|
+
"""Set whether connections should emit verbose logs. This should be used for debugging only.
|
|
186
|
+
|
|
187
|
+
Enabling this option will emit log messages at the Debug level for read and write operations on connections.
|
|
188
|
+
Note that logs are flushed to Python logging handling when request finishes or client closes. Logs can be
|
|
189
|
+
manually flushed by calling `pyreqwest.logging.flush_logs`.
|
|
190
|
+
"""
|
|
191
|
+
|
|
179
192
|
def http1_lower_case_headers(self) -> Self:
|
|
180
193
|
"""Send headers as lowercase instead of title case. Default is false.
|
|
181
194
|
|
|
@@ -198,13 +211,22 @@ class BaseClientBuilder:
|
|
|
198
211
|
"""
|
|
199
212
|
|
|
200
213
|
def http1_only(self) -> Self:
|
|
201
|
-
"""Only use HTTP/1.
|
|
214
|
+
"""Only use HTTP/1. This is the default. This is consistent with reqwest opt-in http2 feature.
|
|
202
215
|
|
|
203
|
-
|
|
204
|
-
"""
|
|
216
|
+
Same as `.http2(False)`
|
|
217
|
+
"""
|
|
218
|
+
|
|
219
|
+
def http2(self, enabled: bool) -> Self:
|
|
220
|
+
"""Enable or disable HTTP/2 support. Default is false. This is consistent with reqwest opt-in http2 feature.
|
|
221
|
+
|
|
222
|
+
When enabling, it is recommended to tune "http2_" settings for production usage based on expected workloads.
|
|
223
|
+
"""
|
|
205
224
|
|
|
206
225
|
def http2_prior_knowledge(self) -> Self:
|
|
207
|
-
"""Only use HTTP/2.
|
|
226
|
+
"""Only use HTTP/2.
|
|
227
|
+
|
|
228
|
+
When enabling, it is recommended to tune "http2_" settings for production usage based on expected workloads.
|
|
229
|
+
"""
|
|
208
230
|
|
|
209
231
|
def http2_initial_stream_window_size(self, value: int | None) -> Self:
|
|
210
232
|
"""Sets the SETTINGS_INITIAL_WINDOW_SIZE option for HTTP2 stream-level flow control. Default is 65K."""
|
|
@@ -230,6 +252,9 @@ class BaseClientBuilder:
|
|
|
230
252
|
def http2_keep_alive_while_idle(self, enabled: bool) -> Self:
|
|
231
253
|
"""Sets whether HTTP2 keep-alive should apply while the connection is idle. Default is false."""
|
|
232
254
|
|
|
255
|
+
def http09_responses(self) -> Self:
|
|
256
|
+
"""Allow HTTP/0.9 responses (very old / uncommon)."""
|
|
257
|
+
|
|
233
258
|
def tcp_nodelay(self, enabled: bool) -> Self:
|
|
234
259
|
"""Set TCP_NODELAY (disable Nagle). Default is true."""
|
|
235
260
|
|
|
@@ -260,15 +285,9 @@ class BaseClientBuilder:
|
|
|
260
285
|
def add_crl_pem(self, cert: bytes) -> Self:
|
|
261
286
|
"""Add a certificate revocation list from PEM data."""
|
|
262
287
|
|
|
263
|
-
def tls_built_in_root_certs(self, enable: bool) -> Self:
|
|
264
|
-
"""Toggle built-in root cert usage. Defaults to true - built-in system certs will be used."""
|
|
265
|
-
|
|
266
288
|
def identity_pem(self, buf: bytes) -> Self:
|
|
267
289
|
"""Sets the identity to be used for client certificate authentication."""
|
|
268
290
|
|
|
269
|
-
def danger_accept_invalid_hostnames(self, enable: bool) -> Self:
|
|
270
|
-
"""Disable hostname verification (INSECURE). Defaults to false."""
|
|
271
|
-
|
|
272
291
|
def danger_accept_invalid_certs(self, enable: bool) -> Self:
|
|
273
292
|
"""Disable certificate validation (INSECURE). Defaults to false."""
|
|
274
293
|
|
|
@@ -330,12 +349,3 @@ class SyncClientBuilder(BaseClientBuilder):
|
|
|
330
349
|
|
|
331
350
|
def json_handler(self, *, loads: SyncJsonLoads | None = ..., dumps: JsonDumps | None = ...) -> Self:
|
|
332
351
|
"""Override JSON loads / dumps callables for this sync client."""
|
|
333
|
-
|
|
334
|
-
class Runtime:
|
|
335
|
-
"""Tokio runtime instance. Usually not needed, as library global runtime is used by default."""
|
|
336
|
-
|
|
337
|
-
def __init__(self) -> None:
|
|
338
|
-
"""Create a tokio runtime instance. This is an advanced feature."""
|
|
339
|
-
|
|
340
|
-
async def close(self) -> None:
|
|
341
|
-
"""Shutdown runtime resources. Clients using this runtime won't work anymore after closing."""
|
pyreqwest/exceptions/__init__.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Exception classes."""
|
|
2
2
|
|
|
3
3
|
from json import JSONDecodeError as JSONDecodeError_
|
|
4
|
-
from typing import Any,
|
|
4
|
+
from typing import Any, TypedDict
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class Cause(TypedDict):
|
|
@@ -19,12 +19,10 @@ class CauseErrorDetails(TypedDict):
|
|
|
19
19
|
class StatusErrorDetails(TypedDict):
|
|
20
20
|
"""Details for errors that have an associated HTTP status code."""
|
|
21
21
|
|
|
22
|
+
causes: list[Cause] | None
|
|
22
23
|
status: int
|
|
23
24
|
|
|
24
25
|
|
|
25
|
-
T = TypeVar("T", bound=CauseErrorDetails | StatusErrorDetails)
|
|
26
|
-
|
|
27
|
-
|
|
28
26
|
class PyreqwestError(Exception):
|
|
29
27
|
"""Base class for all pyreqwest errors."""
|
|
30
28
|
|
|
@@ -35,41 +33,46 @@ class PyreqwestError(Exception):
|
|
|
35
33
|
self.message = message
|
|
36
34
|
|
|
37
35
|
|
|
38
|
-
class DetailedPyreqwestError(PyreqwestError
|
|
36
|
+
class DetailedPyreqwestError(PyreqwestError):
|
|
39
37
|
"""Base class for all pyreqwest errors with details.
|
|
40
38
|
|
|
41
39
|
Details may be available in `details`.
|
|
42
40
|
"""
|
|
43
41
|
|
|
44
|
-
def __init__(self, message: str, details:
|
|
42
|
+
def __init__(self, message: str, details: CauseErrorDetails) -> None:
|
|
45
43
|
"""Internally initialized."""
|
|
46
44
|
assert isinstance(details, dict)
|
|
47
45
|
PyreqwestError.__init__(self, message, details)
|
|
48
|
-
self.details = details
|
|
46
|
+
self.details: CauseErrorDetails = details
|
|
49
47
|
|
|
50
48
|
|
|
51
|
-
class RequestError(DetailedPyreqwestError
|
|
49
|
+
class RequestError(DetailedPyreqwestError):
|
|
52
50
|
"""Error while processing a request.
|
|
53
51
|
|
|
54
52
|
Details may be available in `details`.
|
|
55
53
|
"""
|
|
56
54
|
|
|
57
55
|
|
|
58
|
-
class StatusError(RequestError
|
|
56
|
+
class StatusError(RequestError):
|
|
59
57
|
"""Error due to HTTP 4xx or 5xx status code. Raised when `error_for_status` is enabled.
|
|
60
58
|
|
|
61
59
|
The status code is available in `details["status"]`.
|
|
62
60
|
"""
|
|
63
61
|
|
|
62
|
+
def __init__(self, message: str, details: StatusErrorDetails) -> None:
|
|
63
|
+
"""Internally initialized."""
|
|
64
|
+
RequestError.__init__(self, message, details)
|
|
65
|
+
self.details: StatusErrorDetails = details
|
|
66
|
+
|
|
64
67
|
|
|
65
|
-
class RedirectError(RequestError
|
|
68
|
+
class RedirectError(RequestError):
|
|
66
69
|
"""Error due to too many redirects. Raised when `max_redirects` is exceeded.
|
|
67
70
|
|
|
68
71
|
Cause details may be available in `details["causes"]`.
|
|
69
72
|
"""
|
|
70
73
|
|
|
71
74
|
|
|
72
|
-
class DecodeError(RequestError
|
|
75
|
+
class DecodeError(RequestError):
|
|
73
76
|
"""Error while decoding the response.
|
|
74
77
|
|
|
75
78
|
Cause details may be available in `details["causes"]`.
|
|
@@ -98,7 +101,7 @@ class JSONDecodeError(BodyDecodeError, JSONDecodeError_):
|
|
|
98
101
|
BodyDecodeError.__init__(self, message, {"causes": details["causes"]})
|
|
99
102
|
|
|
100
103
|
|
|
101
|
-
class TransportError(RequestError
|
|
104
|
+
class TransportError(RequestError):
|
|
102
105
|
"""Error while processing the transport layer.
|
|
103
106
|
|
|
104
107
|
Cause details may be available in `details["causes"]`.
|
|
@@ -170,21 +173,21 @@ class WriteError(NetworkError):
|
|
|
170
173
|
"""
|
|
171
174
|
|
|
172
175
|
|
|
173
|
-
class ClientClosedError(RequestError
|
|
176
|
+
class ClientClosedError(RequestError):
|
|
174
177
|
"""Error due to user closing the client while request was being processed.
|
|
175
178
|
|
|
176
179
|
Cause details may be available in `details["causes"]`.
|
|
177
180
|
"""
|
|
178
181
|
|
|
179
182
|
|
|
180
|
-
class BuilderError(DetailedPyreqwestError
|
|
183
|
+
class BuilderError(DetailedPyreqwestError, ValueError):
|
|
181
184
|
"""Error while building a request.
|
|
182
185
|
|
|
183
186
|
Cause details may be available in `details["causes"]`.
|
|
184
187
|
"""
|
|
185
188
|
|
|
186
189
|
|
|
187
|
-
class RequestPanicError(RequestError
|
|
190
|
+
class RequestPanicError(RequestError):
|
|
188
191
|
"""Error due to a panic in the request processing.
|
|
189
192
|
|
|
190
193
|
This indicates a bug in pyreqwest or one of its dependencies.
|
pyreqwest/http/__init__.py
CHANGED
pyreqwest/pytest_plugin/mock.py
CHANGED
|
@@ -20,7 +20,15 @@ from pyreqwest.pytest_plugin.types import (
|
|
|
20
20
|
QueryMatcher,
|
|
21
21
|
UrlMatcher,
|
|
22
22
|
)
|
|
23
|
-
from pyreqwest.request import
|
|
23
|
+
from pyreqwest.request import (
|
|
24
|
+
BaseRequestBuilder,
|
|
25
|
+
OneOffRequestBuilder,
|
|
26
|
+
Request,
|
|
27
|
+
RequestBody,
|
|
28
|
+
RequestBuilder,
|
|
29
|
+
SyncOneOffRequestBuilder,
|
|
30
|
+
SyncRequestBuilder,
|
|
31
|
+
)
|
|
24
32
|
from pyreqwest.response import BaseResponse, Response, ResponseBuilder, SyncResponse
|
|
25
33
|
from pyreqwest.types import HeadersType
|
|
26
34
|
|
|
@@ -383,8 +391,19 @@ class ClientMocker:
|
|
|
383
391
|
monkeypatch.setattr(klass, "build", lambda slf: build_patch(slf, orig_build_consumed))
|
|
384
392
|
monkeypatch.setattr(klass, "build_streamed", lambda slf: build_patch(slf, orig_build_streamed))
|
|
385
393
|
|
|
394
|
+
def setup_oneoff(klass: type[BaseRequestBuilder], *, is_async: bool) -> None:
|
|
395
|
+
orig_send = klass.send # type: ignore[attr-defined]
|
|
396
|
+
|
|
397
|
+
def send_patch(self: BaseRequestBuilder) -> Any:
|
|
398
|
+
middleware = mocker._create_middleware() if is_async else mocker._create_sync_middleware()
|
|
399
|
+
return orig_send(self.with_middleware(middleware)) # type: ignore[attr-defined]
|
|
400
|
+
|
|
401
|
+
monkeypatch.setattr(klass, "send", send_patch)
|
|
402
|
+
|
|
386
403
|
setup(RequestBuilder, is_async=True)
|
|
387
404
|
setup(SyncRequestBuilder, is_async=False)
|
|
405
|
+
setup_oneoff(OneOffRequestBuilder, is_async=True)
|
|
406
|
+
setup_oneoff(SyncOneOffRequestBuilder, is_async=False)
|
|
388
407
|
|
|
389
408
|
return mocker
|
|
390
409
|
|
pyreqwest/request/__init__.py
CHANGED
|
@@ -3,23 +3,27 @@
|
|
|
3
3
|
from pyreqwest._pyreqwest.request import (
|
|
4
4
|
BaseRequestBuilder,
|
|
5
5
|
ConsumedRequest,
|
|
6
|
+
OneOffRequestBuilder,
|
|
6
7
|
Request,
|
|
7
8
|
RequestBody,
|
|
8
9
|
RequestBuilder,
|
|
9
10
|
StreamRequest,
|
|
10
11
|
SyncConsumedRequest,
|
|
12
|
+
SyncOneOffRequestBuilder,
|
|
11
13
|
SyncRequestBuilder,
|
|
12
14
|
SyncStreamRequest,
|
|
13
15
|
)
|
|
14
16
|
|
|
15
|
-
__all__ = [
|
|
17
|
+
__all__ = [
|
|
18
|
+
"BaseRequestBuilder",
|
|
19
|
+
"RequestBuilder",
|
|
20
|
+
"SyncRequestBuilder",
|
|
21
|
+
"Request",
|
|
16
22
|
"ConsumedRequest",
|
|
17
23
|
"StreamRequest",
|
|
18
24
|
"SyncConsumedRequest",
|
|
19
25
|
"SyncStreamRequest",
|
|
20
|
-
"Request",
|
|
21
|
-
"RequestBuilder",
|
|
22
|
-
"SyncRequestBuilder",
|
|
23
|
-
"BaseRequestBuilder",
|
|
24
26
|
"RequestBody",
|
|
27
|
+
"OneOffRequestBuilder",
|
|
28
|
+
"SyncOneOffRequestBuilder",
|
|
25
29
|
]
|
pyreqwest/request/__init__.pyi
CHANGED
|
@@ -123,7 +123,7 @@ class RequestBody:
|
|
|
123
123
|
"""Copy body (Zero-copied bytes. Stream supplies its own copy)."""
|
|
124
124
|
|
|
125
125
|
class BaseRequestBuilder:
|
|
126
|
-
def error_for_status(self, enable: bool) -> Self:
|
|
126
|
+
def error_for_status(self, enable: bool = True) -> Self:
|
|
127
127
|
"""Enable automatic HTTP error raising (4xx/5xx)."""
|
|
128
128
|
|
|
129
129
|
def header(self, name: str, value: str) -> Self:
|
|
@@ -182,7 +182,7 @@ class RequestBuilder(BaseRequestBuilder):
|
|
|
182
182
|
"""Set streaming request body."""
|
|
183
183
|
|
|
184
184
|
def with_middleware(self, middleware: Middleware) -> Self:
|
|
185
|
-
"""
|
|
185
|
+
"""Use a middleware component (added after client level middlewares, executed in chain order)."""
|
|
186
186
|
|
|
187
187
|
class SyncRequestBuilder(BaseRequestBuilder):
|
|
188
188
|
"""Synchronous request builder. Use `build()` or `build_streamed()` to create the request to send."""
|
|
@@ -197,4 +197,22 @@ class SyncRequestBuilder(BaseRequestBuilder):
|
|
|
197
197
|
"""Set streaming request body."""
|
|
198
198
|
|
|
199
199
|
def with_middleware(self, middleware: SyncMiddleware) -> Self:
|
|
200
|
-
"""
|
|
200
|
+
"""Use a middleware component (added after client level middlewares, executed in chain order)."""
|
|
201
|
+
|
|
202
|
+
class OneOffRequestBuilder(BaseRequestBuilder):
|
|
203
|
+
"""One-off request builder. Use `send()` to execute the request."""
|
|
204
|
+
|
|
205
|
+
async def send(self) -> Response:
|
|
206
|
+
"""Execute the request returning a Response with fully read response body."""
|
|
207
|
+
|
|
208
|
+
def with_middleware(self, middleware: Middleware) -> Self:
|
|
209
|
+
"""Use a middleware component."""
|
|
210
|
+
|
|
211
|
+
class SyncOneOffRequestBuilder(BaseRequestBuilder):
|
|
212
|
+
"""Synchronous one-off request builder. Use `send()` to execute the request."""
|
|
213
|
+
|
|
214
|
+
def send(self) -> SyncResponse:
|
|
215
|
+
"""Execute the request returning a Response with fully read response body."""
|
|
216
|
+
|
|
217
|
+
def with_middleware(self, middleware: SyncMiddleware) -> Self:
|
|
218
|
+
"""Use a middleware component."""
|
pyreqwest/response/__init__.py
CHANGED
|
@@ -9,10 +9,10 @@ from pyreqwest._pyreqwest.response import (
|
|
|
9
9
|
SyncResponseBodyReader,
|
|
10
10
|
)
|
|
11
11
|
|
|
12
|
-
__all__ = [
|
|
12
|
+
__all__ = [
|
|
13
|
+
"BaseResponse",
|
|
13
14
|
"Response",
|
|
14
15
|
"SyncResponse",
|
|
15
|
-
"BaseResponse",
|
|
16
16
|
"ResponseBuilder",
|
|
17
17
|
"ResponseBodyReader",
|
|
18
18
|
"SyncResponseBodyReader",
|
pyreqwest/response/__init__.pyi
CHANGED
|
@@ -101,13 +101,13 @@ class ResponseBuilder:
|
|
|
101
101
|
def build_sync(self) -> SyncResponse:
|
|
102
102
|
"""Build synchronous response (disallows async streams)."""
|
|
103
103
|
|
|
104
|
-
def status(self,
|
|
104
|
+
def status(self, status: int) -> Self:
|
|
105
105
|
"""Set status code."""
|
|
106
106
|
|
|
107
|
-
def version(self,
|
|
107
|
+
def version(self, version: str) -> Self:
|
|
108
108
|
"""Set HTTP version string."""
|
|
109
109
|
|
|
110
|
-
def header(self,
|
|
110
|
+
def header(self, key: str, value: str) -> Self:
|
|
111
111
|
"""Append single header value (multiple allowed)."""
|
|
112
112
|
|
|
113
113
|
def headers(self, headers: HeadersType) -> Self:
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Runtime configuration. See Tokio runtime documentation for details about config parameters."""
|
|
2
|
+
|
|
3
|
+
from pyreqwest._pyreqwest.runtime import (
|
|
4
|
+
runtime_blocking_thread_keep_alive,
|
|
5
|
+
runtime_max_blocking_threads,
|
|
6
|
+
runtime_multithreaded_default,
|
|
7
|
+
runtime_worker_threads,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"runtime_multithreaded_default",
|
|
12
|
+
"runtime_worker_threads",
|
|
13
|
+
"runtime_max_blocking_threads",
|
|
14
|
+
"runtime_blocking_thread_keep_alive",
|
|
15
|
+
]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from datetime import timedelta
|
|
2
|
+
|
|
3
|
+
def runtime_multithreaded_default(enable: bool | None) -> None:
|
|
4
|
+
"""Enable to use multithreaded runtime by default. None uses default behavior which is to use single-threaded
|
|
5
|
+
runtime.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
def runtime_worker_threads(threads: int | None) -> None:
|
|
9
|
+
"""Set the number of worker threads for the multithreaded runtime. None uses default Tokio behavior which is the
|
|
10
|
+
number of cores available to the system.
|
|
11
|
+
|
|
12
|
+
Should be configured at startup. Can not be changed after multithreaded runtime has been initialized.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def runtime_max_blocking_threads(threads: int | None) -> None:
|
|
16
|
+
"""Set the maximum number of blocking threads for the multithreaded runtime. None uses default Tokio behavior.
|
|
17
|
+
|
|
18
|
+
Should be configured at startup. Can not be changed after multithreaded runtime has been initialized.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def runtime_blocking_thread_keep_alive(duration: timedelta | None) -> None:
|
|
22
|
+
"""Set the keep-alive time for blocking threads in the multithreaded runtime. None uses default Tokio behavior.
|
|
23
|
+
|
|
24
|
+
Should be configured at startup. Can not be changed after multithreaded runtime has been initialized.
|
|
25
|
+
"""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Simple interfaces for doing one-off requests."""
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Simple async interfaces for doing one-off requests."""
|
|
2
|
+
|
|
3
|
+
from pyreqwest._pyreqwest.simple.request import (
|
|
4
|
+
pyreqwest_delete,
|
|
5
|
+
pyreqwest_get,
|
|
6
|
+
pyreqwest_head,
|
|
7
|
+
pyreqwest_patch,
|
|
8
|
+
pyreqwest_post,
|
|
9
|
+
pyreqwest_put,
|
|
10
|
+
pyreqwest_request,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"pyreqwest_request",
|
|
15
|
+
"pyreqwest_get",
|
|
16
|
+
"pyreqwest_post",
|
|
17
|
+
"pyreqwest_put",
|
|
18
|
+
"pyreqwest_patch",
|
|
19
|
+
"pyreqwest_delete",
|
|
20
|
+
"pyreqwest_head",
|
|
21
|
+
]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from pyreqwest.http import Url
|
|
2
|
+
from pyreqwest.request import OneOffRequestBuilder
|
|
3
|
+
|
|
4
|
+
def pyreqwest_request(method: str, url: Url | str) -> OneOffRequestBuilder:
|
|
5
|
+
"""Create a simple request with the given HTTP method and URL.
|
|
6
|
+
|
|
7
|
+
Returns a request builder, which will allow setting headers and the request body before sending.
|
|
8
|
+
|
|
9
|
+
NOTE: This is only recommended for simple scripting use-cases. Usually, the client should be reused for multiple
|
|
10
|
+
requests to benefit from connection pooling and other optimizations (via ClientBuilder).
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def pyreqwest_get(url: Url | str) -> OneOffRequestBuilder:
|
|
14
|
+
"""Same as `pyreqwest_request("GET", url)`."""
|
|
15
|
+
|
|
16
|
+
def pyreqwest_post(url: Url | str) -> OneOffRequestBuilder:
|
|
17
|
+
"""Same as `pyreqwest_request("POST", url)`."""
|
|
18
|
+
|
|
19
|
+
def pyreqwest_put(url: Url | str) -> OneOffRequestBuilder:
|
|
20
|
+
"""Same as `pyreqwest_request("PUT", url)`."""
|
|
21
|
+
|
|
22
|
+
def pyreqwest_patch(url: Url | str) -> OneOffRequestBuilder:
|
|
23
|
+
"""Same as `pyreqwest_request("PATCH", url)`."""
|
|
24
|
+
|
|
25
|
+
def pyreqwest_delete(url: Url | str) -> OneOffRequestBuilder:
|
|
26
|
+
"""Same as `pyreqwest_request("DELETE", url)`."""
|
|
27
|
+
|
|
28
|
+
def pyreqwest_head(url: Url | str) -> OneOffRequestBuilder:
|
|
29
|
+
"""Same as `pyreqwest_request("HEAD", url)`."""
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Simple sync interfaces for doing one-off requests."""
|
|
2
|
+
|
|
3
|
+
from pyreqwest._pyreqwest.simple.sync_request import (
|
|
4
|
+
pyreqwest_delete,
|
|
5
|
+
pyreqwest_get,
|
|
6
|
+
pyreqwest_head,
|
|
7
|
+
pyreqwest_patch,
|
|
8
|
+
pyreqwest_post,
|
|
9
|
+
pyreqwest_put,
|
|
10
|
+
pyreqwest_request,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"pyreqwest_request",
|
|
15
|
+
"pyreqwest_get",
|
|
16
|
+
"pyreqwest_post",
|
|
17
|
+
"pyreqwest_put",
|
|
18
|
+
"pyreqwest_patch",
|
|
19
|
+
"pyreqwest_delete",
|
|
20
|
+
"pyreqwest_head",
|
|
21
|
+
]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from pyreqwest.http import Url
|
|
2
|
+
from pyreqwest.request import SyncOneOffRequestBuilder
|
|
3
|
+
|
|
4
|
+
def pyreqwest_request(method: str, url: Url | str) -> SyncOneOffRequestBuilder:
|
|
5
|
+
"""Create a simple request with the given HTTP method and URL.
|
|
6
|
+
|
|
7
|
+
Returns a request builder, which will allow setting headers and the request body before sending.
|
|
8
|
+
|
|
9
|
+
NOTE: This is only recommended for simple scripting use-cases. Usually, the client should be reused for multiple
|
|
10
|
+
requests to benefit from connection pooling and other optimizations (via ClientBuilder).
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def pyreqwest_get(url: Url | str) -> SyncOneOffRequestBuilder:
|
|
14
|
+
"""Same as `pyreqwest_request("GET", url)`."""
|
|
15
|
+
|
|
16
|
+
def pyreqwest_post(url: Url | str) -> SyncOneOffRequestBuilder:
|
|
17
|
+
"""Same as `pyreqwest_request("POST", url)`."""
|
|
18
|
+
|
|
19
|
+
def pyreqwest_put(url: Url | str) -> SyncOneOffRequestBuilder:
|
|
20
|
+
"""Same as `pyreqwest_request("PUT", url)`."""
|
|
21
|
+
|
|
22
|
+
def pyreqwest_patch(url: Url | str) -> SyncOneOffRequestBuilder:
|
|
23
|
+
"""Same as `pyreqwest_request("PATCH", url)`."""
|
|
24
|
+
|
|
25
|
+
def pyreqwest_delete(url: Url | str) -> SyncOneOffRequestBuilder:
|
|
26
|
+
"""Same as `pyreqwest_request("DELETE", url)`."""
|
|
27
|
+
|
|
28
|
+
def pyreqwest_head(url: Url | str) -> SyncOneOffRequestBuilder:
|
|
29
|
+
"""Same as `pyreqwest_request("HEAD", url)`."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyreqwest
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.10.1
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Programming Language :: Python
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -100,6 +100,42 @@ def example_sync():
|
|
|
100
100
|
|
|
101
101
|
Context manager usage is optional, but recommended. Also `close()` methods are available.
|
|
102
102
|
|
|
103
|
+
#### Mocking in pytest
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from pyreqwest.client import ClientBuilder
|
|
107
|
+
from pyreqwest.pytest_plugin import ClientMocker
|
|
108
|
+
|
|
109
|
+
async def test_client(client_mocker: ClientMocker) -> None:
|
|
110
|
+
client_mocker.get(path="/api").with_body_text("Hello Mock")
|
|
111
|
+
|
|
112
|
+
async with ClientBuilder().build() as client:
|
|
113
|
+
response = await client.get("http://example.invalid/api").build().send()
|
|
114
|
+
assert response.status == 200 and await response.text() == "Hello Mock"
|
|
115
|
+
assert client_mocker.get_call_count() == 1
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Manual mocking is available via `ClientMocker.create_mocker(MonkeyPatch)`.
|
|
119
|
+
|
|
120
|
+
#### Simple request interface
|
|
121
|
+
|
|
122
|
+
This is only recommended for simple use-cases such as scripts. Usually, the full client API should be used which reuses
|
|
123
|
+
connections and has other optimizations.
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
# Sync example
|
|
127
|
+
from pyreqwest.simple.sync_request import pyreqwest_get
|
|
128
|
+
response = pyreqwest_get("https://httpbun.com/get").query({"q": "val"}).send()
|
|
129
|
+
print(response.json())
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
# Async example
|
|
134
|
+
from pyreqwest.simple.request import pyreqwest_get
|
|
135
|
+
response = await pyreqwest_get("https://httpbun.com/get").query({"q": "val"}).send()
|
|
136
|
+
print(await response.json())
|
|
137
|
+
```
|
|
138
|
+
|
|
103
139
|
## Documentation
|
|
104
140
|
|
|
105
141
|
See [docs](https://markussintonen.github.io/pyreqwest/pyreqwest.html)
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
pyreqwest-0.6.0.dist-info/METADATA,sha256=vWepMhQitXcL4ksYIzjgOpIp9OoL-HN8KGiqtIuMxB8,4678
|
|
2
|
-
pyreqwest-0.6.0.dist-info/WHEEL,sha256=0p9RWqZ1tTIS4XVGVX-OqQSPs2Wp470cV_pQ0zUt98A,107
|
|
3
|
-
pyreqwest-0.6.0.dist-info/entry_points.txt,sha256=x6BM9g8m805tw6VqKvSe_Kgd2qp4Eq3moyIoFnETeoE,61
|
|
4
|
-
pyreqwest-0.6.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
5
1
|
pyreqwest/__init__.py,sha256=AqtJmAtOEQ6kYGY2_Qzw2f_q5K3Q5PN-TpOmIKaeiEM,86
|
|
6
2
|
pyreqwest/__init__.pyi,sha256=Y25n44pyE3vp92MiABKrcK3IWRyQ1JG1rZ4Ufqy2nC0,17
|
|
7
|
-
pyreqwest/_pyreqwest.cpython-314-darwin.so,sha256=
|
|
3
|
+
pyreqwest/_pyreqwest.cpython-314-darwin.so,sha256=uda6d-wGz24qisls7vVJWgIkBpZBMjDhF6hoYo-uFss,9218600
|
|
8
4
|
pyreqwest/bytes/__init__.py,sha256=uzB8cxWbBizu0kyrdXhmnwWKWdwBcVIv4mgEhCR1LMs,465
|
|
9
5
|
pyreqwest/bytes/__init__.pyi,sha256=bttN8uCg7K3gW90FBgPP4vbtNrBCOwqX4v7LAK-T1pU,4569
|
|
10
|
-
pyreqwest/client/__init__.py,sha256=
|
|
11
|
-
pyreqwest/client/__init__.pyi,sha256=
|
|
6
|
+
pyreqwest/client/__init__.py,sha256=37hK94Tz4MKvCJiYl9H_ZYVXF0CExX4Om-grcPIC9oY,325
|
|
7
|
+
pyreqwest/client/__init__.pyi,sha256=9QjOlirKKXAPqi49JpL8X0HOcumFXfchabUKlI9Jx5k,14832
|
|
12
8
|
pyreqwest/client/types.py,sha256=CpfplqBGOyvpZNpwbOqal89dBztZlZTYuX-nM1Qrwrg,1475
|
|
13
9
|
pyreqwest/compatibility/__init__.py,sha256=yJ4VD9iMzvSpYDjM6kEM-F2A_avMFCkOo1g5bgD2AGU,102
|
|
14
10
|
pyreqwest/compatibility/httpx/__init__.py,sha256=Gc0jMCgmpSHkqQha_zAzxXjrbRSvS6KUOnHp4Z0UMDc,334
|
|
@@ -16,9 +12,11 @@ pyreqwest/compatibility/httpx/_internal.py,sha256=olu1ES7bV8AHUqtEMEmGHlejQCxAS3
|
|
|
16
12
|
pyreqwest/compatibility/httpx/transport.py,sha256=2wuhREEvpWvcrCZcNv0mH_7MbuqwCO0_b9j7TMxkee8,6672
|
|
17
13
|
pyreqwest/cookie/__init__.py,sha256=whcJaTtVHgqH2n_lvGYXYHP7D9BolDU6SvKjuKpewAs,128
|
|
18
14
|
pyreqwest/cookie/__init__.pyi,sha256=YCOI79evRpc7xmSpY6q1MsQMCHSucGDpLmsk0ZqfXN4,6401
|
|
19
|
-
pyreqwest/exceptions/__init__.py,sha256=
|
|
20
|
-
pyreqwest/http/__init__.py,sha256=
|
|
15
|
+
pyreqwest/exceptions/__init__.py,sha256=BiKq0hwV7nqu6f2K0Am_BXC9vvuD8snvWbkRLRFZm4Q,5360
|
|
16
|
+
pyreqwest/http/__init__.py,sha256=hyzkUQ8bj_xrPfOPYwUx0NpahQFFMWzpm2wKCmBe3ug,318
|
|
21
17
|
pyreqwest/http/__init__.pyi,sha256=xmG6eD1Uz0Y1nRgPb_zxUMKc57rgxWq58W5nsCRg9V0,13798
|
|
18
|
+
pyreqwest/logging/__init__.py,sha256=KCmYt3ssr69rMe5u3ywFv2cbMOkj4Nz7qxdaBlu_CNc,125
|
|
19
|
+
pyreqwest/logging/__init__.pyi,sha256=b4Pl_LkY7jLUqidazrNFIrLB4kAAgUTdjT1Tr6_-2RQ,190
|
|
22
20
|
pyreqwest/middleware/__init__.py,sha256=0i12zyrey3OmmKLtYRLTK4goC7QHWi0Di5erhe4VYHw,118
|
|
23
21
|
pyreqwest/middleware/__init__.pyi,sha256=dkrwXkePVkvQNa4xe0l0-L-4WL3VsrNdJOO1-zNGApo,476
|
|
24
22
|
pyreqwest/middleware/asgi/__init__.py,sha256=jLj4n6F4O2SKOl6HyufmSEvldDOQ1seWtcZPLOxZCyw,95
|
|
@@ -35,11 +33,22 @@ pyreqwest/pytest_plugin/internal/assert_eq.py,sha256=j4bEJPHWZvLAvSKqS3eCFViI0X8
|
|
|
35
33
|
pyreqwest/pytest_plugin/internal/assert_message.py,sha256=oRkvzpIFw69rOaGTYBFGd8gP1Piut_RpG8G51OhYbes,4853
|
|
36
34
|
pyreqwest/pytest_plugin/internal/matcher.py,sha256=aB08rUdI3rLQL2pMxerYAD-S8p1TeFUl36i0G2-tdgs,1221
|
|
37
35
|
pyreqwest/pytest_plugin/internal/plugin.py,sha256=NkneUC5Ui-1ATlrG0q-R4_xdkA_Ou3UEF3t6qAlhS_M,448
|
|
38
|
-
pyreqwest/pytest_plugin/mock.py,sha256=
|
|
36
|
+
pyreqwest/pytest_plugin/mock.py,sha256=0eFdaXQB4BsfBg3R5ctOShg5yCEgyLlm1mdI44Rynpo,20995
|
|
39
37
|
pyreqwest/pytest_plugin/types.py,sha256=QyFxjkth7favATSwt3d8EtUBcVjqcUYQ5BxA617T54g,895
|
|
40
|
-
pyreqwest/request/__init__.py,sha256=
|
|
41
|
-
pyreqwest/request/__init__.pyi,sha256=
|
|
42
|
-
pyreqwest/response/__init__.py,sha256=
|
|
43
|
-
pyreqwest/response/__init__.pyi,sha256=
|
|
38
|
+
pyreqwest/request/__init__.py,sha256=zr4G_-kES2pN2HZ5nhbRbpwtEWooLJDX01KXrlUMET4,604
|
|
39
|
+
pyreqwest/request/__init__.pyi,sha256=eLbFMU9_dSMtfMhaWf79lr1TlFmXl8vRfUOq_v-LejU,7868
|
|
40
|
+
pyreqwest/response/__init__.py,sha256=40wLYwCOzIALl8qZecVLT-qj14Jf5EYTnW7CPVjIvzQ,357
|
|
41
|
+
pyreqwest/response/__init__.pyi,sha256=gfgXNg4q7GZfYgUesw_zyY4slwvso0bzNY-E8__iFZY,5739
|
|
42
|
+
pyreqwest/runtime/__init__.py,sha256=wdw_AyBkN9a98l3nmzoUhp5Wcfa1BIKB3PpGhAWY_eI,441
|
|
43
|
+
pyreqwest/runtime/__init__.pyi,sha256=ndUeESCWse43tDdg3yQa_7utPzEW4EImCvb5tyUXqs8,1168
|
|
44
|
+
pyreqwest/simple/__init__.py,sha256=kNB7FA92J7OlFnPMColUkUQjEQq_3GTiNWbE2BmHG7k,52
|
|
45
|
+
pyreqwest/simple/request/__init__.py,sha256=INoWzPcGE_O15wzfJ1tZwy5j0ua0GUAiPDcqwj1qI7Q,428
|
|
46
|
+
pyreqwest/simple/request/__init__.pyi,sha256=p9BSuuQh1rJk44xwdJhGV8apGPvdB0qAo2HWwqQYj8E,1227
|
|
47
|
+
pyreqwest/simple/sync_request/__init__.py,sha256=8Jv0wYehivbmscZvpOPkwHpIqNGEIY4x4hZPB5zv2rU,432
|
|
48
|
+
pyreqwest/simple/sync_request/__init__.pyi,sha256=heyLHDzLPuePzTeX7DLpc9IyTEEHeZKOSjXis0j6BF8,1259
|
|
44
49
|
pyreqwest/types.py,sha256=10lGx5uugbo5awMz6nNOcuIsyeG3NIB7DqQHiPbOHLk,643
|
|
45
|
-
pyreqwest-0.
|
|
50
|
+
pyreqwest-0.10.1.dist-info/METADATA,sha256=0gUNNuHUolKXcl0-t3d5UoA3ZIjiDy4_pmUF9CgFq6o,5851
|
|
51
|
+
pyreqwest-0.10.1.dist-info/WHEEL,sha256=jyP0hJCe-fSX_gEscesIqqW7KerDJw7iyldGx-__w10,107
|
|
52
|
+
pyreqwest-0.10.1.dist-info/entry_points.txt,sha256=x6BM9g8m805tw6VqKvSe_Kgd2qp4Eq3moyIoFnETeoE,61
|
|
53
|
+
pyreqwest-0.10.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
54
|
+
pyreqwest-0.10.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|