commit
0c20fba8a9
@ -1,5 +1,5 @@
|
||||
from .config import PoolLimits, SSLConfig, TimeoutConfig
|
||||
from .connections import Connection
|
||||
from .connectionpool import ConnectionPool
|
||||
from .datastructures import URL, Origin, Request, Response
|
||||
from .exceptions import (
|
||||
BadResponse,
|
||||
@ -10,7 +10,7 @@ from .exceptions import (
|
||||
StreamConsumed,
|
||||
Timeout,
|
||||
)
|
||||
from .pool import ConnectionPool
|
||||
from .http11 import HTTP11Connection
|
||||
from .sync import SyncClient, SyncConnectionPool
|
||||
|
||||
__version__ = "0.2.0"
|
||||
|
||||
@ -2,6 +2,7 @@ import asyncio
|
||||
|
||||
if hasattr(asyncio, "run"):
|
||||
asyncio_run = asyncio.run
|
||||
|
||||
else: # pragma: nocover
|
||||
|
||||
def asyncio_run(main, *, debug=False): # type: ignore
|
||||
|
||||
@ -10,7 +10,7 @@ from .config import (
|
||||
SSLConfig,
|
||||
TimeoutConfig,
|
||||
)
|
||||
from .connections import Connection
|
||||
from .http11 import HTTP11Connection
|
||||
from .datastructures import Client, Origin, Request, Response
|
||||
from .exceptions import PoolTimeout
|
||||
|
||||
@ -31,7 +31,7 @@ class ConnectionPool(Client):
|
||||
self.num_keepalive_connections = 0
|
||||
self._keepalive_connections = (
|
||||
{}
|
||||
) # type: typing.Dict[Origin, typing.List[Connection]]
|
||||
) # type: typing.Dict[Origin, typing.List[HTTP11Connection]]
|
||||
self._max_connections = ConnectionSemaphore(
|
||||
max_connections=self.limits.hard_limit
|
||||
)
|
||||
@ -53,7 +53,7 @@ class ConnectionPool(Client):
|
||||
|
||||
async def acquire_connection(
|
||||
self, origin: Origin, timeout: typing.Optional[TimeoutConfig] = None
|
||||
) -> Connection:
|
||||
) -> HTTP11Connection:
|
||||
try:
|
||||
connection = self._keepalive_connections[origin].pop()
|
||||
if not self._keepalive_connections[origin]:
|
||||
@ -71,7 +71,7 @@ class ConnectionPool(Client):
|
||||
await asyncio.wait_for(self._max_connections.acquire(), pool_timeout)
|
||||
except asyncio.TimeoutError:
|
||||
raise PoolTimeout()
|
||||
connection = Connection(
|
||||
connection = HTTP11Connection(
|
||||
origin,
|
||||
ssl=self.ssl,
|
||||
timeout=self.timeout,
|
||||
@ -81,7 +81,7 @@ class ConnectionPool(Client):
|
||||
|
||||
return connection
|
||||
|
||||
async def release_connection(self, connection: Connection) -> None:
|
||||
async def release_connection(self, connection: HTTP11Connection) -> None:
|
||||
if connection.is_closed:
|
||||
self._max_connections.release()
|
||||
self.num_active_connections -= 1
|
||||
@ -72,24 +72,20 @@ class Origin:
|
||||
def __init__(self, url: typing.Union[str, URL]) -> None:
|
||||
if isinstance(url, str):
|
||||
url = URL(url)
|
||||
self.scheme = url.scheme
|
||||
self.hostname = url.hostname
|
||||
self.is_ssl = url.scheme == "https"
|
||||
self.hostname = url.hostname.lower()
|
||||
self.port = url.port
|
||||
|
||||
@property
|
||||
def is_secure(self) -> bool:
|
||||
return self.scheme == "https"
|
||||
|
||||
def __eq__(self, other: typing.Any) -> bool:
|
||||
return (
|
||||
isinstance(other, self.__class__)
|
||||
and self.scheme == other.scheme
|
||||
and self.is_ssl == other.is_ssl
|
||||
and self.hostname == other.hostname
|
||||
and self.port == other.port
|
||||
)
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash((self.scheme, self.hostname, self.port))
|
||||
return hash((self.is_ssl, self.hostname, self.port))
|
||||
|
||||
|
||||
class Request:
|
||||
|
||||
@ -17,7 +17,7 @@ H11Event = typing.Union[
|
||||
]
|
||||
|
||||
|
||||
class Connection(Client):
|
||||
class HTTP11Connection(Client):
|
||||
def __init__(
|
||||
self,
|
||||
origin: typing.Union[str, Origin],
|
||||
@ -93,13 +93,13 @@ class Connection(Client):
|
||||
)
|
||||
|
||||
async def _connect(self, ssl: SSLConfig, timeout: TimeoutConfig) -> None:
|
||||
ssl_context = await ssl.load_ssl_context() if self.origin.is_secure else None
|
||||
hostname = self.origin.hostname
|
||||
port = self.origin.port
|
||||
ssl_context = await ssl.load_ssl_context() if self.origin.is_ssl else None
|
||||
|
||||
try:
|
||||
self._reader, self._writer = await asyncio.wait_for( # type: ignore
|
||||
asyncio.open_connection(
|
||||
self.origin.hostname, self.origin.port, ssl=ssl_context
|
||||
),
|
||||
asyncio.open_connection(hostname, port, ssl=ssl_context),
|
||||
timeout.connect_timeout,
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
@ -3,8 +3,8 @@ from types import TracebackType
|
||||
|
||||
from .compat import asyncio_run
|
||||
from .config import SSLConfig, TimeoutConfig
|
||||
from .connectionpool import ConnectionPool
|
||||
from .datastructures import URL, Client, Response
|
||||
from .pool import ConnectionPool
|
||||
|
||||
|
||||
class SyncResponse:
|
||||
|
||||
@ -5,7 +5,7 @@ import httpcore
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get(server):
|
||||
http = httpcore.Connection(origin="http://127.0.0.1:8000/")
|
||||
http = httpcore.HTTP11Connection(origin="http://127.0.0.1:8000/")
|
||||
response = await http.request("GET", "http://127.0.0.1:8000/")
|
||||
assert response.status_code == 200
|
||||
assert response.body == b"Hello, world!"
|
||||
@ -13,7 +13,7 @@ async def test_get(server):
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_post(server):
|
||||
http = httpcore.Connection(origin="http://127.0.0.1:8000/")
|
||||
http = httpcore.HTTP11Connection(origin="http://127.0.0.1:8000/")
|
||||
response = await http.request(
|
||||
"POST", "http://127.0.0.1:8000/", body=b"Hello, world!"
|
||||
)
|
||||
|
||||
@ -53,7 +53,7 @@ def test_stream_iterator(server):
|
||||
with httpcore.SyncConnectionPool() as http:
|
||||
response = http.request("GET", "http://127.0.0.1:8000/", stream=True)
|
||||
assert response.status_code == 200
|
||||
body = b''
|
||||
body = b""
|
||||
for chunk in response.stream():
|
||||
body += chunk
|
||||
assert body == b"Hello, world!"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user