punkreq 0.2.4__tar.gz → 0.3.0__tar.gz
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.
- {punkreq-0.2.4 → punkreq-0.3.0}/PKG-INFO +3 -4
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_connect.py +11 -23
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_pool.py +5 -5
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_proxies.py +5 -3
- punkreq-0.3.0/punkreq/_version.py +1 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/pyproject.toml +3 -4
- punkreq-0.2.4/punkreq/_version.py +0 -1
- {punkreq-0.2.4 → punkreq-0.3.0}/.gitignore +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/LICENSE +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/README.md +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/__init__.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_auth.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_client.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_config.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_content.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_cookies.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_decoders.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_exceptions.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_headers.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_models.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_multipart.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_redirects.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_transport.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/_urls.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/asyncio.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/py.typed +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/punkreq/tonio.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/__init__.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/conftest.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/e2e.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/fakes.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/servers.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/servers_tonio.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_client.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_config.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_connect.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_content.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_cookies.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_decoders.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_e2e_asyncio.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_e2e_tonio.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_exceptions.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_headers.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_models.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_multipart.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_pool.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_redirects.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_transport.py +0 -0
- {punkreq-0.2.4 → punkreq-0.3.0}/tests/test_urls.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: punkreq
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: An async HTTP client built on httpunk
|
|
5
5
|
Project-URL: Homepage, https://github.com/gi0baro/punkreq
|
|
6
6
|
Project-URL: Funding, https://github.com/sponsors/gi0baro
|
|
@@ -15,7 +15,6 @@ Classifier: Intended Audience :: Developers
|
|
|
15
15
|
Classifier: License :: OSI Approved :: BSD License
|
|
16
16
|
Classifier: Operating System :: OS Independent
|
|
17
17
|
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.13
|
|
@@ -23,8 +22,8 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.15
|
|
24
23
|
Classifier: Programming Language :: Python :: Free Threading :: 3 - Stable
|
|
25
24
|
Classifier: Topic :: Internet :: WWW/HTTP
|
|
26
|
-
Requires-Python: >=3.
|
|
27
|
-
Requires-Dist: httpunk~=0.
|
|
25
|
+
Requires-Python: >=3.11
|
|
26
|
+
Requires-Dist: httpunk~=0.5.0
|
|
28
27
|
Provides-Extra: brotli
|
|
29
28
|
Requires-Dist: brotli~=1.2.0; extra == 'brotli'
|
|
30
29
|
Provides-Extra: tonio
|
|
@@ -11,7 +11,7 @@ from httpunk.h2.client import H2Connection
|
|
|
11
11
|
from ._exceptions import ConnectError, UnsupportedProtocol
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
__all__ = ["Connector", "Origin", "connect_errors", "create_ssl_context", "
|
|
14
|
+
__all__ = ["Connector", "Origin", "connect_errors", "create_ssl_context", "origin_for_url"]
|
|
15
15
|
|
|
16
16
|
DEFAULT_PORTS = {"http": 80, "https": 443}
|
|
17
17
|
|
|
@@ -94,19 +94,6 @@ def connect_errors(backend: typing.Any) -> tuple[type[BaseException], ...]:
|
|
|
94
94
|
return (OSError, ssl.SSLError, HTTPunkError, *backend.broken_transport_errors)
|
|
95
95
|
|
|
96
96
|
|
|
97
|
-
async def enter_connection(conn: typing.Any, transport: typing.Any, backend: typing.Any) -> typing.Any:
|
|
98
|
-
"""Run `conn`'s HTTP handshake (`__aenter__`) and return it. Until that
|
|
99
|
-
completes the transport we dialed is still ours to close: httpunk closes
|
|
100
|
-
it on `__aexit__`, which a failed or interrupted `__aenter__` never
|
|
101
|
-
reaches (h2 waits there for the peer's SETTINGS, pumps already running)."""
|
|
102
|
-
try:
|
|
103
|
-
await conn.__aenter__()
|
|
104
|
-
except BaseException:
|
|
105
|
-
backend.close_transport(transport)
|
|
106
|
-
raise
|
|
107
|
-
return conn
|
|
108
|
-
|
|
109
|
-
|
|
110
97
|
class Connector:
|
|
111
98
|
"""The default connector: dial `origin` and return the protocol-matching
|
|
112
99
|
httpunk connection, entered."""
|
|
@@ -142,14 +129,15 @@ class Connector:
|
|
|
142
129
|
async def __call__(self, origin: Origin) -> H1Connection | H2Connection:
|
|
143
130
|
try:
|
|
144
131
|
if origin.scheme == "https":
|
|
145
|
-
conn
|
|
132
|
+
conn = await self._connect_tls(origin)
|
|
146
133
|
else:
|
|
147
|
-
conn
|
|
148
|
-
|
|
134
|
+
conn = await self._connect_tcp(origin)
|
|
135
|
+
await conn.__aenter__()
|
|
136
|
+
return conn
|
|
149
137
|
except connect_errors(self._backend) as exc:
|
|
150
138
|
raise ConnectError(f"Failed to connect to {origin}: {exc}")
|
|
151
139
|
|
|
152
|
-
async def _connect_tls(self, origin: Origin) ->
|
|
140
|
+
async def _connect_tls(self, origin: Origin) -> H1Connection | H2Connection:
|
|
153
141
|
# our context already carries the offer; a backend-created default one
|
|
154
142
|
# (no context given) is configured per dial
|
|
155
143
|
alpn = None if self._ssl_context is not None else self.alpn
|
|
@@ -157,12 +145,12 @@ class Connector:
|
|
|
157
145
|
origin.host, origin.port, alpn=alpn, ssl_context=self._ssl_context
|
|
158
146
|
)
|
|
159
147
|
if selected == "h2" or not self._http1:
|
|
160
|
-
return H2Connection(stream, authority=origin.authority, scheme="https", backend=self._backend)
|
|
161
|
-
return H1Connection(stream, authority=origin.authority, backend=self._backend)
|
|
148
|
+
return H2Connection(stream, authority=origin.authority, scheme="https", backend=self._backend)
|
|
149
|
+
return H1Connection(stream, authority=origin.authority, backend=self._backend)
|
|
162
150
|
|
|
163
|
-
async def _connect_tcp(self, origin: Origin) ->
|
|
151
|
+
async def _connect_tcp(self, origin: Origin) -> H1Connection | H2Connection:
|
|
164
152
|
stream = await self._backend.connect_tcp(origin.host, origin.port)
|
|
165
153
|
if not self._http1:
|
|
166
154
|
# h2 prior knowledge over cleartext (reqwest's http2_prior_knowledge)
|
|
167
|
-
return H2Connection(stream, authority=origin.authority, scheme="http", backend=self._backend)
|
|
168
|
-
return H1Connection(stream, authority=origin.authority, backend=self._backend)
|
|
155
|
+
return H2Connection(stream, authority=origin.authority, scheme="http", backend=self._backend)
|
|
156
|
+
return H1Connection(stream, authority=origin.authority, backend=self._backend)
|
|
@@ -11,14 +11,14 @@ Concept mapping (hyper-util `client/pool/*.rs` ≡ `httpunk.util.pool` ≡ here)
|
|
|
11
11
|
≡ `_HostState.shared` + `.dialing` + `.mode`. Waiters re-attempt internally
|
|
12
12
|
instead of surfacing `Canceled` — the same retry-by-calling-again
|
|
13
13
|
semantics. A closed shared conn is ditched and redialed at checkout
|
|
14
|
-
(`Singled::poll_ready` reset
|
|
14
|
+
(`Singled::poll_ready` reset, as httpunk's `Singleton` does).
|
|
15
15
|
* `Cache` (idle set, drop-returns-to-cache) ≡ `_HostState.idle` + `release()`.
|
|
16
16
|
The park check (`discard or closed or busy`) matches httpunk's `_Lease`:
|
|
17
17
|
`closed` mirrors `Cached::poll_ready`-sets-`is_closed` + `Drop` skipping
|
|
18
|
-
the put; `busy` is the runtime-forced extra
|
|
19
|
-
failed exchange instead of re-parking is httpunk's
|
|
20
|
-
httpunk's `Cache
|
|
21
|
-
|
|
18
|
+
the put; `busy` is the runtime-forced extra httpunk also adds; closing on
|
|
19
|
+
a failed exchange instead of re-parking is httpunk's choice too. Like
|
|
20
|
+
httpunk's `Cache`, there is no checkout-vs-connect race: an empty idle
|
|
21
|
+
set dials directly.
|
|
22
22
|
|
|
23
23
|
Policy layered on top (owner-owned, per the modern pool's design — its only
|
|
24
24
|
culling surface is `Cache::retain(predicate)`, everything else is the
|
|
@@ -10,7 +10,7 @@ from httpunk.h2.client import H2Connection
|
|
|
10
10
|
from httpunk.util.proxy import Matcher
|
|
11
11
|
|
|
12
12
|
from ._config import Proxy
|
|
13
|
-
from ._connect import Connector, Origin, connect_errors
|
|
13
|
+
from ._connect import Connector, Origin, connect_errors
|
|
14
14
|
from ._exceptions import ConnectError, ProxyError
|
|
15
15
|
from ._headers import Headers
|
|
16
16
|
from ._urls import URL
|
|
@@ -112,7 +112,8 @@ class ProxyConnector:
|
|
|
112
112
|
transport = await self._dial_proxy(intercept)
|
|
113
113
|
conn = H1Connection(transport, authority=origin.authority, backend=self._backend)
|
|
114
114
|
setattr(conn, PROXY_ATTR, ProxyInfo(auth=intercept.basic_auth(), headers=self._config.headers))
|
|
115
|
-
|
|
115
|
+
await conn.__aenter__()
|
|
116
|
+
return conn
|
|
116
117
|
|
|
117
118
|
async def _tunnel(self, origin: Origin, intercept: typing.Any) -> typing.Any:
|
|
118
119
|
transport = await self._dial_proxy(intercept)
|
|
@@ -152,4 +153,5 @@ class ProxyConnector:
|
|
|
152
153
|
conn = H2Connection(tls, authority=origin.authority, scheme="https", backend=self._backend)
|
|
153
154
|
else:
|
|
154
155
|
conn = H1Connection(tls, authority=origin.authority, backend=self._backend)
|
|
155
|
-
|
|
156
|
+
await conn.__aenter__()
|
|
157
|
+
return conn
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.0"
|
|
@@ -4,11 +4,11 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "punkreq"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "An async HTTP client built on httpunk"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "BSD-3-Clause"
|
|
11
|
-
requires-python = ">=3.
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
12
|
|
|
13
13
|
authors = [
|
|
14
14
|
{ name = "Giovanni Barillari", email = "g@baro.dev" }
|
|
@@ -22,7 +22,6 @@ classifiers = [
|
|
|
22
22
|
"Operating System :: OS Independent",
|
|
23
23
|
"Programming Language :: Python :: Free Threading :: 3 - Stable",
|
|
24
24
|
"Programming Language :: Python :: 3",
|
|
25
|
-
"Programming Language :: Python :: 3.10",
|
|
26
25
|
"Programming Language :: Python :: 3.11",
|
|
27
26
|
"Programming Language :: Python :: 3.12",
|
|
28
27
|
"Programming Language :: Python :: 3.13",
|
|
@@ -32,7 +31,7 @@ classifiers = [
|
|
|
32
31
|
]
|
|
33
32
|
|
|
34
33
|
dependencies = [
|
|
35
|
-
"httpunk~=0.
|
|
34
|
+
"httpunk~=0.5.0",
|
|
36
35
|
]
|
|
37
36
|
|
|
38
37
|
[project.optional-dependencies]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.2.4"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|