Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename PoolLimits to Limits #1113

Merged
merged 4 commits into from
Aug 1, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,8 @@ response = client.get('http://example.com/')

## Pool limit configuration

You can control the connection pool size using the `pool_limits` keyword
argument on the client. It takes instances of `httpx.PoolLimits` which define:
You can control the connection pool size using the `limits` keyword
argument on the client. It takes instances of `httpx.Limits` which define:

- `max_keepalive`, number of allowable keep-alive connections, or `None` to always
allow. (Defaults 10)
Expand All @@ -411,8 +411,8 @@ allow. (Defaults 10)


```python
limits = httpx.PoolLimits(max_keepalive=5, max_connections=10)
client = httpx.Client(pool_limits=limits)
limits = httpx.Limits(max_keepalive=5, max_connections=10)
client = httpx.Client(limits=limits)
```

## Multipart file encoding
Expand Down
3 changes: 2 additions & 1 deletion httpx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from ._api import delete, get, head, options, patch, post, put, request, stream
from ._auth import Auth, BasicAuth, DigestAuth
from ._client import AsyncClient, Client
from ._config import PoolLimits, Proxy, Timeout, create_ssl_context
from ._config import Limits, PoolLimits, Proxy, Timeout, create_ssl_context
from ._exceptions import (
CloseError,
ConnectError,
Expand Down Expand Up @@ -59,6 +59,7 @@
"BasicAuth",
"Client",
"DigestAuth",
"Limits",
"PoolLimits",
"Proxy",
"Timeout",
Expand Down
63 changes: 39 additions & 24 deletions httpx/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
from ._auth import Auth, BasicAuth, FunctionAuth
from ._config import (
DEFAULT_MAX_REDIRECTS,
DEFAULT_POOL_LIMITS,
DEFAULT_LIMITS,
DEFAULT_TIMEOUT_CONFIG,
UNSET,
PoolLimits,
Limits,
Proxy,
Timeout,
UnsetType,
Expand Down Expand Up @@ -50,6 +50,7 @@
get_logger,
same_origin,
should_not_be_proxied,
warn_deprecated,
)

logger = get_logger(__name__)
Expand Down Expand Up @@ -418,8 +419,7 @@ class Client(BaseClient):
URLs.
* **timeout** - *(optional)* The timeout configuration to use when sending
requests.
* **pool_limits** - *(optional)* The connection pool configuration to use
when determining the maximum number of concurrently open HTTP connections.
* **limits** - *(optional)* The limits configuration to use.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haven't found a better description of the parameter that's not redundant with the info in the Limits docstring. I don't think it's included in the Developer Interface yet so that could be a nice follow-up, and then cross-link it here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we could say something like... "Allows for configuration options, such as the maximum number of open connections to allow." Just to give a bit of an indication what we mean by "limits" here(?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's pull this in for now as it is. Welcome to follow up with docstring improvements later.

* **max_redirects** - *(optional)* The maximum number of redirect responses
that should be followed.
* **base_url** - *(optional)* A URL to use as the base when building
Expand All @@ -444,7 +444,8 @@ def __init__(
http2: bool = False,
proxies: ProxiesTypes = None,
timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG,
pool_limits: PoolLimits = DEFAULT_POOL_LIMITS,
limits: Limits = DEFAULT_LIMITS,
pool_limits: Limits = None,
max_redirects: int = DEFAULT_MAX_REDIRECTS,
base_url: URLTypes = None,
transport: httpcore.SyncHTTPTransport = None,
Expand All @@ -462,13 +463,20 @@ def __init__(
trust_env=trust_env,
)

if pool_limits is not None:
warn_deprecated(
"Client(..., pool_limits=...) is deprecated and will raise "
"errors in the future. Use Client(..., limits=...) instead."
)
limits = pool_limits

proxy_map = self._get_proxy_map(proxies, trust_env)

self._transport = self._init_transport(
verify=verify,
cert=cert,
http2=http2,
pool_limits=pool_limits,
limits=limits,
transport=transport,
app=app,
trust_env=trust_env,
Expand All @@ -483,7 +491,7 @@ def __init__(
verify=verify,
cert=cert,
http2=http2,
pool_limits=pool_limits,
limits=limits,
trust_env=trust_env,
)
for key, proxy in proxy_map.items()
Expand All @@ -495,7 +503,7 @@ def _init_transport(
verify: VerifyTypes = True,
cert: CertTypes = None,
http2: bool = False,
pool_limits: PoolLimits = DEFAULT_POOL_LIMITS,
limits: Limits = DEFAULT_LIMITS,
transport: httpcore.SyncHTTPTransport = None,
app: typing.Callable = None,
trust_env: bool = True,
Expand All @@ -510,8 +518,8 @@ def _init_transport(

return httpcore.SyncConnectionPool(
ssl_context=ssl_context,
max_keepalive=pool_limits.max_keepalive,
max_connections=pool_limits.max_connections,
max_keepalive=limits.max_keepalive,
max_connections=limits.max_connections,
keepalive_expiry=KEEPALIVE_EXPIRY,
http2=http2,
)
Expand All @@ -522,7 +530,7 @@ def _init_proxy_transport(
verify: VerifyTypes = True,
cert: CertTypes = None,
http2: bool = False,
pool_limits: PoolLimits = DEFAULT_POOL_LIMITS,
limits: Limits = DEFAULT_LIMITS,
trust_env: bool = True,
) -> httpcore.SyncHTTPTransport:
ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env)
Expand All @@ -532,8 +540,8 @@ def _init_proxy_transport(
proxy_headers=proxy.headers.raw,
proxy_mode=proxy.mode,
ssl_context=ssl_context,
max_keepalive=pool_limits.max_keepalive,
max_connections=pool_limits.max_connections,
max_keepalive=limits.max_keepalive,
max_connections=limits.max_connections,
keepalive_expiry=KEEPALIVE_EXPIRY,
http2=http2,
)
Expand Down Expand Up @@ -942,8 +950,7 @@ class AsyncClient(BaseClient):
URLs.
* **timeout** - *(optional)* The timeout configuration to use when sending
requests.
* **pool_limits** - *(optional)* The connection pool configuration to use
when determining the maximum number of concurrently open HTTP connections.
* **limits** - *(optional)* The limits configuration to use.
* **max_redirects** - *(optional)* The maximum number of redirect responses
that should be followed.
* **base_url** - *(optional)* A URL to use as the base when building
Expand All @@ -968,7 +975,8 @@ def __init__(
http2: bool = False,
proxies: ProxiesTypes = None,
timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG,
pool_limits: PoolLimits = DEFAULT_POOL_LIMITS,
limits: Limits = DEFAULT_LIMITS,
pool_limits: Limits = None,
max_redirects: int = DEFAULT_MAX_REDIRECTS,
base_url: URLTypes = None,
transport: httpcore.AsyncHTTPTransport = None,
Expand All @@ -986,13 +994,20 @@ def __init__(
trust_env=trust_env,
)

if pool_limits is not None:
warn_deprecated(
"AsyncClient(..., pool_limits=...) is deprecated and will raise "
"errors in the future. Use AsyncClient(..., limits=...) instead."
)
limits = pool_limits

proxy_map = self._get_proxy_map(proxies, trust_env)

self._transport = self._init_transport(
verify=verify,
cert=cert,
http2=http2,
pool_limits=pool_limits,
limits=limits,
transport=transport,
app=app,
trust_env=trust_env,
Expand All @@ -1007,7 +1022,7 @@ def __init__(
verify=verify,
cert=cert,
http2=http2,
pool_limits=pool_limits,
limits=limits,
trust_env=trust_env,
)
for key, proxy in proxy_map.items()
Expand All @@ -1019,7 +1034,7 @@ def _init_transport(
verify: VerifyTypes = True,
cert: CertTypes = None,
http2: bool = False,
pool_limits: PoolLimits = DEFAULT_POOL_LIMITS,
limits: Limits = DEFAULT_LIMITS,
transport: httpcore.AsyncHTTPTransport = None,
app: typing.Callable = None,
trust_env: bool = True,
Expand All @@ -1034,8 +1049,8 @@ def _init_transport(

return httpcore.AsyncConnectionPool(
ssl_context=ssl_context,
max_keepalive=pool_limits.max_keepalive,
max_connections=pool_limits.max_connections,
max_keepalive=limits.max_keepalive,
max_connections=limits.max_connections,
keepalive_expiry=KEEPALIVE_EXPIRY,
http2=http2,
)
Expand All @@ -1046,7 +1061,7 @@ def _init_proxy_transport(
verify: VerifyTypes = True,
cert: CertTypes = None,
http2: bool = False,
pool_limits: PoolLimits = DEFAULT_POOL_LIMITS,
limits: Limits = DEFAULT_LIMITS,
trust_env: bool = True,
) -> httpcore.AsyncHTTPTransport:
ssl_context = create_ssl_context(verify=verify, cert=cert, trust_env=trust_env)
Expand All @@ -1056,8 +1071,8 @@ def _init_proxy_transport(
proxy_headers=proxy.headers.raw,
proxy_mode=proxy.mode,
ssl_context=ssl_context,
max_keepalive=pool_limits.max_keepalive,
max_connections=pool_limits.max_connections,
max_keepalive=limits.max_keepalive,
max_connections=limits.max_connections,
keepalive_expiry=KEEPALIVE_EXPIRY,
http2=http2,
)
Expand Down
19 changes: 15 additions & 4 deletions httpx/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from ._models import URL, Headers
from ._types import CertTypes, HeaderTypes, TimeoutTypes, URLTypes, VerifyTypes
from ._utils import get_ca_bundle_from_env, get_logger
from ._utils import get_ca_bundle_from_env, get_logger, warn_deprecated

DEFAULT_CIPHERS = ":".join(
[
Expand Down Expand Up @@ -301,9 +301,9 @@ def __repr__(self) -> str:
)


class PoolLimits:
class Limits:
"""
Limits on the number of connections in a connection pool.
Configuration for limits to various client behaviors.

**Parameters:**

Expand Down Expand Up @@ -334,6 +334,17 @@ def __repr__(self) -> str:
)


class PoolLimits(Limits):
def __init__(
self, *, max_keepalive: int = None, max_connections: int = None,
) -> None:
warn_deprecated(
"httpx.PoolLimits(...) is deprecated and will raise errors in the future. "
"Use httpx.Limits(...) instead."
)
super().__init__(max_keepalive=max_keepalive, max_connections=max_connections)


class Proxy:
def __init__(
self, url: URLTypes, *, headers: HeaderTypes = None, mode: str = "DEFAULT",
Expand Down Expand Up @@ -373,5 +384,5 @@ def __repr__(self) -> str:


DEFAULT_TIMEOUT_CONFIG = Timeout(timeout=5.0)
DEFAULT_POOL_LIMITS = PoolLimits(max_keepalive=10, max_connections=100)
DEFAULT_LIMITS = Limits(max_keepalive=10, max_connections=100)
DEFAULT_MAX_REDIRECTS = 20
10 changes: 10 additions & 0 deletions tests/client/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,13 @@ def test_merge_url_hsts(url: str, scheme: str, is_ssl: bool):
request = client.build_request("GET", url)
assert request.url.scheme == scheme
assert request.url.is_ssl == is_ssl


def test_pool_limits_deprecated():
limits = httpx.Limits()

with pytest.warns(DeprecationWarning):
httpx.Client(pool_limits=limits)

with pytest.warns(DeprecationWarning):
httpx.AsyncClient(pool_limits=limits)
13 changes: 9 additions & 4 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,18 @@ def test_create_ssl_context_with_get_request(server, cert_pem_file):


def test_limits_repr():
limits = httpx.PoolLimits(max_connections=100)
assert repr(limits) == "PoolLimits(max_keepalive=None, max_connections=100)"
limits = httpx.Limits(max_connections=100)
assert repr(limits) == "Limits(max_keepalive=None, max_connections=100)"


def test_limits_eq():
limits = httpx.PoolLimits(max_connections=100)
assert limits == httpx.PoolLimits(max_connections=100)
limits = httpx.Limits(max_connections=100)
assert limits == httpx.Limits(max_connections=100)


def test_pool_limits_deprecated():
with pytest.warns(DeprecationWarning):
httpx.PoolLimits()


def test_timeout_eq():
Expand Down
4 changes: 2 additions & 2 deletions tests/test_timeouts.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ async def test_connect_timeout(server):

@pytest.mark.usefixtures("async_environment")
async def test_pool_timeout(server):
pool_limits = httpx.PoolLimits(max_connections=1)
limits = httpx.Limits(max_connections=1)
timeout = httpx.Timeout(None, pool_timeout=1e-4)

async with httpx.AsyncClient(pool_limits=pool_limits, timeout=timeout) as client:
async with httpx.AsyncClient(limits=limits, timeout=timeout) as client:
async with client.stream("GET", server.url):
with pytest.raises(httpx.PoolTimeout):
await client.get("http://localhost:8000/")