From 2d09d5b36c108f7d669c13e87e0958a1833a6422 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 19 Jul 2019 15:15:16 +0100 Subject: [PATCH] Renaming -> httpx (#129) * Renaming -> httpx * Renaming to httpx --- README.md | 48 ++++++------- docs/advanced.md | 10 +-- docs/api.md | 4 +- docs/async.md | 8 +-- docs/compatibility.md | 4 +- docs/img/logo.jpg | Bin 0 -> 15592 bytes docs/index.md | 28 +++++--- docs/parallel.md | 12 ++-- docs/quickstart.md | 72 +++++++++---------- {http3 => httpx}/__init__.py | 0 {http3 => httpx}/__version__.py | 2 +- {http3 => httpx}/api.py | 0 {http3 => httpx}/auth.py | 0 {http3 => httpx}/client.py | 0 {http3 => httpx}/concurrency.py | 0 {http3 => httpx}/config.py | 2 +- {http3 => httpx}/decoders.py | 0 {http3 => httpx}/dispatch/__init__.py | 0 {http3 => httpx}/dispatch/asgi.py | 6 +- {http3 => httpx}/dispatch/connection.py | 0 {http3 => httpx}/dispatch/connection_pool.py | 0 {http3 => httpx}/dispatch/http11.py | 0 {http3 => httpx}/dispatch/http2.py | 0 {http3 => httpx}/dispatch/threaded.py | 0 {http3 => httpx}/dispatch/wsgi.py | 6 +- {http3 => httpx}/exceptions.py | 0 {http3 => httpx}/interfaces.py | 0 {http3 => httpx}/models.py | 0 {http3 => httpx}/multipart.py | 0 {http3 => httpx}/status_codes.py | 0 {http3 => httpx}/utils.py | 0 mkdocs.yml | 8 +-- scripts/clean | 4 +- scripts/lint | 10 +-- scripts/publish | 2 +- scripts/test | 2 +- tests/client/test_async_client.py | 32 ++++----- tests/client/test_auth.py | 2 +- tests/client/test_client.py | 34 ++++----- tests/client/test_cookies.py | 2 +- tests/client/test_redirects.py | 2 +- tests/dispatch/test_connection_pools.py | 20 +++--- tests/dispatch/test_connections.py | 2 +- tests/dispatch/test_http2.py | 2 +- tests/dispatch/test_threaded.py | 2 +- tests/dispatch/utils.py | 2 +- tests/models/test_cookies.py | 2 +- tests/models/test_headers.py | 40 +++++------ tests/models/test_queryparams.py | 2 +- tests/models/test_requests.py | 32 ++++----- tests/models/test_responses.py | 66 ++++++++--------- tests/models/test_url.py | 2 +- tests/test_api.py | 22 +++--- tests/test_asgi.py | 10 +-- tests/test_config.py | 50 ++++++------- tests/test_decoders.py | 20 +++--- tests/test_multipart.py | 2 +- tests/test_status_codes.py | 12 ++-- tests/test_timeouts.py | 2 +- tests/test_utils.py | 2 +- tests/test_wsgi.py | 10 +-- 61 files changed, 307 insertions(+), 295 deletions(-) create mode 100644 docs/img/logo.jpg rename {http3 => httpx}/__init__.py (100%) rename {http3 => httpx}/__version__.py (81%) rename {http3 => httpx}/api.py (100%) rename {http3 => httpx}/auth.py (100%) rename {http3 => httpx}/client.py (100%) rename {http3 => httpx}/concurrency.py (100%) rename {http3 => httpx}/config.py (99%) rename {http3 => httpx}/decoders.py (100%) rename {http3 => httpx}/dispatch/__init__.py (100%) rename {http3 => httpx}/dispatch/asgi.py (98%) rename {http3 => httpx}/dispatch/connection.py (100%) rename {http3 => httpx}/dispatch/connection_pool.py (100%) rename {http3 => httpx}/dispatch/http11.py (100%) rename {http3 => httpx}/dispatch/http2.py (100%) rename {http3 => httpx}/dispatch/threaded.py (100%) rename {http3 => httpx}/dispatch/wsgi.py (97%) rename {http3 => httpx}/exceptions.py (100%) rename {http3 => httpx}/interfaces.py (100%) rename {http3 => httpx}/models.py (100%) rename {http3 => httpx}/multipart.py (100%) rename {http3 => httpx}/status_codes.py (100%) rename {http3 => httpx}/utils.py (100%) diff --git a/README.md b/README.md index dff89d27..89418639 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ -# HTTP3 +# HTTPX - - Build Status + + Build Status - - Coverage + + Coverage - - Package version + + Package version -HTTP3 is a next-generation HTTP client for Python 3. +HTTPX is a next-generation HTTP client for Python 3. **Note**: *This project should be considered as an "alpha" release. It is substantially API complete, but there are still some areas that need more work.* @@ -19,8 +19,8 @@ HTTP3 is a next-generation HTTP client for Python 3. Let's get started... ```python ->>> import http3 ->>> r = http3.get('https://www.example.org/') +>>> import httpx +>>> r = httpx.get('https://www.example.org/') >>> r >>> r.status_code @@ -35,13 +35,13 @@ Let's get started... ## Features -HTTP3 builds on the well-established usability of `requests`, and gives you: +HTTPX builds on the well-established usability of `requests`, and gives you: * A requests-compatible API. * HTTP/2 and HTTP/1.1 support. -* Support for [issuing HTTP requests in parallel](https://www.encode.io/http3/parallel/). *(Coming soon)* -* Standard synchronous interface, but [with `async`/`await` support if you need it](https://www.encode.io/http3/async/). -* Ability to [make requests directly to WSGI or ASGI applications](https://www.encode.io/http3/advanced/#calling-into-python-web-apps). +* Support for [issuing HTTP requests in parallel](https://www.encode.io/httpx/parallel/). *(Coming soon)* +* Standard synchronous interface, but [with `async`/`await` support if you need it](https://www.encode.io/httpx/async/). +* Ability to [make requests directly to WSGI or ASGI applications](https://www.encode.io/httpx/advanced/#calling-into-python-web-apps). * Strict timeouts everywhere. * Fully type annotated. * 100% test coverage. @@ -69,26 +69,26 @@ Plus all the standard features of `requests`... Install with pip: ```shell -$ pip install http3 +$ pip install httpx ``` -HTTP3 requires Python 3.6+ +httpx requires Python 3.6+ ## Documentation -Project documentation is available at [www.encode.io/http3/](https://www.encode.io/http3/). +Project documentation is available at [www.encode.io/httpx/](https://www.encode.io/httpx/). -For a run-through of all the basics, head over to the [QuickStart](https://www.encode.io/http3/quickstart/). +For a run-through of all the basics, head over to the [QuickStart](https://www.encode.io/httpx/quickstart/). -For more advanced topics, see the [Advanced Usage](https://www.encode.io/http3/advanced/) section, or -the specific topics on making [Parallel Requests](https://www.encode.io/http3/parallel/) or using the -[Async Client](https://www.encode.io/http3/async/). +For more advanced topics, see the [Advanced Usage](https://www.encode.io/httpx/advanced/) section, or +the specific topics on making [Parallel Requests](https://www.encode.io/httpx/parallel/) or using the +[Async Client](https://www.encode.io/httpx/async/). -The [Developer Interface](https://www.encode.io/http3/api/) provides a comprehensive API reference. +The [Developer Interface](https://www.encode.io/httpx/api/) provides a comprehensive API reference. ## Dependencies -The HTTP3 project relies on these excellent libraries: +The httpx project relies on these excellent libraries: * `h2` - HTTP/2 support. * `h11` - HTTP/1.1 support. @@ -103,4 +103,4 @@ much of this work follows, as well as to `urllib3` for plenty of design inspiration around the lower level networking details.

— ⭐️ —

-

HTTP3 is BSD licensed code. Designed & built in Brighton, England.

+

httpx is BSD licensed code. Designed & built in Brighton, England.

diff --git a/docs/advanced.md b/docs/advanced.md index e9a54430..3c957ae2 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -7,7 +7,7 @@ will provide cookie persistence, and allows you to apply configuration across all outgoing requests. ```python ->>> client = http3.Client() +>>> client = httpx.Client() >>> r = client.get('https://example.org/') >>> r @@ -15,19 +15,19 @@ all outgoing requests. ## Calling into Python Web Apps -You can configure an `http3` client to call directly into a Python web +You can configure an `httpx` client to call directly into a Python web application, using either the WSGI or ASGI protocol. This is particularly useful for two main use-cases: -* Using `http3` as a client, inside test cases. +* Using `httpx` as a client, inside test cases. * Mocking out external services, during tests or in dev/staging environments. Here's an example of integrating against a Flask application: ```python from flask import Flask -import http3 +import httpx app = Flask(__name__) @@ -36,7 +36,7 @@ app = Flask(__name__) def hello(): return "Hello World!" -client = http3.Client(app=app) +client = httpx.Client(app=app) r = client.get('http://example/') assert r.status_code == 200 assert r.text == "Hello World!" diff --git a/docs/api.md b/docs/api.md index 3b9e4f18..1c6887cb 100644 --- a/docs/api.md +++ b/docs/api.md @@ -16,7 +16,7 @@ *An HTTP client, with connection pooling, redirects, cookie persistence, etc.* ```python ->>> client = http3.Client() +>>> client = httpx.Client() >>> response = client.get('https://example.org') ``` @@ -63,7 +63,7 @@ what gets sent over the wire.* ```python ->>> request = http3.Request("GET", "https://example.org", headers={'host': 'example.org'}) +>>> request = httpx.Request("GET", "https://example.org", headers={'host': 'example.org'}) >>> response = client.send(request) ``` diff --git a/docs/async.md b/docs/async.md index 0303d745..8570c870 100644 --- a/docs/async.md +++ b/docs/async.md @@ -1,6 +1,6 @@ # Async Client -HTTP3 offers a standard synchronous API by default, but also gives you +HTTPX offers a standard synchronous API by default, but also gives you the option of an async client if you need it. Async is a concurrency model that is far more efficient than multi-threading, @@ -15,7 +15,7 @@ async client for sending outgoing HTTP requests. To make asynchronous requests, you'll need an `AsyncClient`. ```python ->>> client = http3.AsyncClient() +>>> client = httpx.AsyncClient() >>> r = await client.get('https://www.example.com/') ``` @@ -25,7 +25,7 @@ If you're using streaming responses then there are a few bits of API that use async methods: ```python ->>> client = http3.AsyncClient() +>>> client = httpx.AsyncClient() >>> r = await client.get('https://www.example.com/', stream=True) >>> try: >>> async for chunk in r.stream(): @@ -44,7 +44,7 @@ The async response methods are: If you're making parallel requests, then you'll also need to use an async API: ```python ->>> client = http3.AsyncClient() +>>> client = httpx.AsyncClient() >>> async with client.parallel() as parallel: >>> pending_one = parallel.get('https://example.com/1') >>> pending_two = parallel.get('https://example.com/2') diff --git a/docs/compatibility.md b/docs/compatibility.md index f712113e..9fdf9cb7 100644 --- a/docs/compatibility.md +++ b/docs/compatibility.md @@ -1,6 +1,6 @@ # Requests Compatibility Guide -HTTP3 aims to be compatible with the `requests` API wherever possible. +HTTPX aims to be compatible with the `requests` API wherever possible. This documentation outlines places where the API differs... @@ -10,7 +10,7 @@ Pretty much all the API mentioned in the `requests` QuickStart should be identic to the API in our own documentation. The following exceptions apply: * `Response.url` - Returns a `URL` instance, rather than a string. Use `str(response.url)` if you need a string instance. -* `http3.codes` - In our documentation we prefer the uppercased versions, such as `codes.NOT_FOUND`, +* `httpx.codes` - In our documentation we prefer the uppercased versions, such as `codes.NOT_FOUND`, but also provide lower-cased versions for API compatibility with `requests`. * `stream=True`. - Streaming responses provide the `.stream()` and `.raw()` byte iterator interfaces, rather than the `.iter_content()` method and the `.raw` socket interface. diff --git a/docs/img/logo.jpg b/docs/img/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9778d17cc33df3d1f9c0c4e0f69654f9f318774d GIT binary patch literal 15592 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 O4gTAB?MFbqFaHk~%dMOM literal 0 HcmV?d00001 diff --git a/docs/index.md b/docs/index.md index f34504b4..444238cf 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,5 +1,15 @@ -

HTTP3

+

+ HTTPX +

+

+HTTPX +

+ +--- + +
+

Build Status @@ -9,8 +19,10 @@ Package version +

-HTTP3 is a next-generation HTTP client for Python 3. +A next-generation HTTP client for Python. +
!!! warning This project should be considered as an "alpha" release. It is substantially @@ -21,8 +33,8 @@ HTTP3 is a next-generation HTTP client for Python 3. Let's get started... ```python ->>> import http3 ->>> r = http3.get('https://www.example.org/') +>>> import httpx +>>> r = httpx.get('https://www.example.org/') >>> r >>> r.status_code @@ -37,7 +49,7 @@ Let's get started... ## Features -HTTP3 builds on the well-established usability of `requests`, and gives you: +HTTPX builds on the well-established usability of `requests`, and gives you: * A requests-compatible API. * HTTP/2 and HTTP/1.1 support. @@ -78,7 +90,7 @@ The [Developer Interface](api.md) provides a comprehensive API reference. ## Dependencies -The HTTP3 project relies on these excellent libraries: +The HTTPX project relies on these excellent libraries: * `h2` - HTTP/2 support. * `h11` - HTTP/1.1 support. @@ -97,7 +109,7 @@ inspiration around the lower level networking details. Install with pip: ```shell -$ pip install http3 +$ pip install httpx ``` -HTTP3 requires Python 3.6+ +HTTPX requires Python 3.6+ diff --git a/docs/parallel.md b/docs/parallel.md index f86fb705..7e40219b 100644 --- a/docs/parallel.md +++ b/docs/parallel.md @@ -2,10 +2,10 @@ !!! warning This page documents some proposed functionality that is not yet released. - See [pull request #52](https://github.com/encode/http3/pull/52) for the + See [pull request #52](https://github.com/encode/httpx/pull/52) for the first-pass of an implementation. -HTTP3 allows you to make HTTP requests in parallel in a highly efficient way, +HTTPX allows you to make HTTP requests in parallel in a highly efficient way, using async under the hood, while still presenting a standard threaded interface. This has the huge benefit of allowing you to efficiently make parallel HTTP @@ -16,7 +16,7 @@ requests without having to switch out to using async all the way through. Let's make two outgoing HTTP requests in parallel: ```python ->>> with http3.parallel() as parallel: +>>> with httpx.parallel() as parallel: >>> pending_one = parallel.get('https://example.com/1') >>> pending_two = parallel.get('https://example.com/2') >>> response_one = pending_one.get_response() @@ -28,7 +28,7 @@ responses sequentially, but rather deal with each response that comes back as soon as it's available: ```python ->>> with http3.parallel() as parallel: +>>> with httpx.parallel() as parallel: >>> for counter in range(1, 10): >>> parallel.get(f'https://example.com/{counter}') >>> while parallel.has_pending_responses: @@ -49,7 +49,7 @@ control the authentication or dispatch behaviour for all requests within the block. ```python ->>> client = http3.Client() +>>> client = httpx.Client() >>> with client.parallel() as parallel: >>> ... ``` @@ -60,7 +60,7 @@ If you're working within an async framework, then you'll want to use a fully async API for making requests. ```python ->>> client = http3.AsyncClient() +>>> client = httpx.AsyncClient() >>> async with client.parallel() as parallel: >>> pending_one = await parallel.get('https://example.com/1') >>> pending_two = await parallel.get('https://example.com/2') diff --git a/docs/quickstart.md b/docs/quickstart.md index 5f5eca2d..6262ee2c 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -2,19 +2,19 @@ !!! note This page closely follows the layout of the `requests` QuickStart documentation. - The `http3` library is designed to be API compatible with `requests` wherever + The `httpx` library is designed to be API compatible with `requests` wherever possible. -First start by importing HTTP3: +First start by importing HTTPX: ``` ->>> import http3 +>>> import httpx ``` Now, let’s try to get a webpage. ```python ->>> r = http3.get('https://httpbin.org/get') +>>> r = httpx.get('https://httpbin.org/get') >>> r ``` @@ -22,16 +22,16 @@ Now, let’s try to get a webpage. Similarly, to make an HTTP POST request: ```python ->>> r = http3.post('https://httpbin.org/post', data={'key': 'value'}) +>>> r = httpx.post('https://httpbin.org/post', data={'key': 'value'}) ``` The PUT, DELETE, HEAD, and OPTIONS requests all follow the same style: ```python ->>> r = http3.put('https://httpbin.org/put', data={'key': 'value'}) ->>> r = http3.delete('https://httpbin.org/delete') ->>> r = http3.head('https://httpbin.org/get') ->>> r = http3.options('https://httpbin.org/get') +>>> r = httpx.put('https://httpbin.org/put', data={'key': 'value'}) +>>> r = httpx.delete('https://httpbin.org/delete') +>>> r = httpx.head('https://httpbin.org/get') +>>> r = httpx.options('https://httpbin.org/get') ``` ## Passing Parameters in URLs @@ -40,7 +40,7 @@ To include URL query parameters in the request, use the `params` keyword: ```python >>> params = {'key1': 'value1', 'key2': 'value2'} ->>> r = http3.get('https://httpbin.org/get', params=params) +>>> r = httpx.get('https://httpbin.org/get', params=params) ``` To see how the values get encoding into the URL string, we can inspect the @@ -55,17 +55,17 @@ You can also pass a list of items as a value: ```python >>> params = {'key1': 'value1', 'key2': ['value2', 'value3']} ->>> r = http3.get('https://httpbin.org/get', params=params) +>>> r = httpx.get('https://httpbin.org/get', params=params) >>> r.url URL('https://httpbin.org/get?key1=value1&key2=value2&key2=value3') ``` ## Response Content -HTTP3 will automatically handle decoding the response content into unicode text. +HTTPX will automatically handle decoding the response content into unicode text. ```python ->>> r = http3.get('https://www.example.org/') +>>> r = httpx.get('https://www.example.org/') >>> r.text '\n\n\nExample Domain...' ``` @@ -110,7 +110,7 @@ For example, to create an image from binary data returned by a request, you can Often Web API responses will be encoded as JSON. ```python ->>> r = http3.get('https://api.github.com/events') +>>> r = httpx.get('https://api.github.com/events') >>> r.json() [{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...' ... }}] ``` @@ -122,7 +122,7 @@ To include additional headers in the outgoing request, use the `headers` keyword ```python >>> url = 'http://httpbin.org/headers' >>> headers = {'user-agent': 'my-app/0.0.1'} ->>> r = http3.get(url, headers=headers) +>>> r = httpx.get(url, headers=headers) ``` ## Sending Form Encoded Data @@ -133,7 +133,7 @@ which is used for HTML forms. ```python >>> data = {'key1': 'value1', 'key2': 'value2'} ->>> r = http3.post("https://httpbin.org/post", data=data) +>>> r = httpx.post("https://httpbin.org/post", data=data) >>> print(r.text) { ... @@ -149,7 +149,7 @@ Form encoded data can also include multiple values form a given key. ```python >>> data = {'key1': ['value1', 'value2']} ->>> r = http3.post("https://httpbin.org/post", data=data) +>>> r = httpx.post("https://httpbin.org/post", data=data) >>> print(r.text) { ... @@ -169,7 +169,7 @@ You can also upload files, using HTTP multipart encoding: ```python >>> files = {'upload-file': open('report.xls', 'rb')} ->>> r = http3.post("https://httpbin.org/post", files=files) +>>> r = httpx.post("https://httpbin.org/post", files=files) >>> print(r.text) { ... @@ -185,7 +185,7 @@ of items for the file value: ```python >>> files = {'upload-file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel')} ->>> r = http3.post("https://httpbin.org/post", files=files) +>>> r = httpx.post("https://httpbin.org/post", files=files) >>> print(r.text) { ... @@ -203,7 +203,7 @@ For more complicated data structures you'll often want to use JSON encoding inst ```python >>> data = {'integer': 123, 'boolean': True, 'list': ['a', 'b', 'c']} ->>> r = http3.post("https://httpbin.org/post", json=data) +>>> r = httpx.post("https://httpbin.org/post", json=data) >>> print(r.text) { ... @@ -233,29 +233,29 @@ binary data. We can inspect the HTTP status code of the response: ```python ->>> r = http3.get('https://httpbin.org/get') +>>> r = httpx.get('https://httpbin.org/get') >>> r.status_code 200 ``` -HTTP3 also includes an easy shortcut for accessing status codes by their text phrase. +HTTPX also includes an easy shortcut for accessing status codes by their text phrase. ```python ->>> r.status_code == http3.codes.OK +>>> r.status_code == httpx.codes.OK True ``` We can raise an exception for any Client or Server error responses (4xx or 5xx status codes): ```python ->>> not_found = http3.get('https://httpbin.org/status/404') +>>> not_found = httpx.get('https://httpbin.org/status/404') >>> not_found.status_code 404 >>> not_found.raise_for_status() Traceback (most recent call last): - File "/Users/tomchristie/GitHub/encode/httpcore/http3/models.py", line 776, in raise_for_status + File "/Users/tomchristie/GitHub/encode/httpcore/httpx/models.py", line 776, in raise_for_status raise HttpError(message) -http3.exceptions.HttpError: 404 Not Found +httpx.exceptions.HttpError: 404 Not Found ``` Any successful response codes will simply return `None` rather than raising an exception. @@ -301,7 +301,7 @@ value, as per [RFC 7230](https://tools.ietf.org/html/rfc7230#section-3.2): Any cookies that are set on the response can be easily accessed: ```python ->>> r = http3.get('http://httpbin.org/cookies/set?chocolate=chip', allow_redirects=False) +>>> r = httpx.get('http://httpbin.org/cookies/set?chocolate=chip', allow_redirects=False) >>> r.cookies['chocolate'] 'chip' ``` @@ -310,7 +310,7 @@ To include cookies in an outgoing request, use the `cookies` parameter: ```python >>> cookies = {"peanut": "butter"} ->>> r = http3.get('http://httpbin.org/cookies', cookies=cookies) +>>> r = httpx.get('http://httpbin.org/cookies', cookies=cookies) >>> r.json() {'cookies': {'peanut': 'butter'}} ``` @@ -319,17 +319,17 @@ Cookies are returned in a `Cookies` instance, which is a dict-like data structur with additional API for accessing cookies by their domain or path. ```python ->>> cookies = http3.Cookies() +>>> cookies = httpx.Cookies() >>> cookies.set('cookie_on_domain', 'hello, there!', domain='httpbin.org') >>> cookies.set('cookie_off_domain', 'nope.', domain='example.org') ->>> r = http3.get('http://httpbin.org/cookies', cookies=cookies) +>>> r = httpx.get('http://httpbin.org/cookies', cookies=cookies) >>> r.json() {'cookies': {'cookie_on_domain': 'hello, there!'}} ``` ## Redirection and History -By default HTTP3 will follow redirects for anything except `HEAD` requests. +By default HTTPX will follow redirects for anything except `HEAD` requests. The `history` property of the response can be used to inspect any followed redirects. It contains a list of all any redirect responses that were followed, in the order @@ -338,7 +338,7 @@ in which they were made. For example, GitHub redirects all HTTP requests to HTTPS. ```python ->>> r = http3.get('http://github.com/') +>>> r = httpx.get('http://github.com/') >>> r.url URL('https://github.com/') >>> r.status_code @@ -350,7 +350,7 @@ URL('https://github.com/') You can modify the default redirection handling with the allow_redirects parameter: ```python ->>> r = http3.get('http://github.com/', allow_redirects=False) +>>> r = httpx.get('http://github.com/', allow_redirects=False) >>> r.status_code 301 >>> r.history @@ -360,7 +360,7 @@ You can modify the default redirection handling with the allow_redirects paramet If you’re making a `HEAD` request, you can use this to enable redirection: ```python ->>> r = http3.head('http://github.com/', allow_redirects=True) +>>> r = httpx.head('http://github.com/', allow_redirects=True) >>> r.url 'https://github.com/' >>> r.history @@ -369,7 +369,7 @@ If you’re making a `HEAD` request, you can use this to enable redirection: ## Timeouts -HTTP3 defaults to including reasonable timeouts for all network operations, +HTTPX defaults to including reasonable timeouts for all network operations, meaning that if a connection is not properly established then it should always raise an error rather than hanging indefinitely. @@ -377,5 +377,5 @@ The default timeout for network inactivity is five seconds. You can modify the value to be more or less strict: ```python ->>> http3.get('https://github.com/', timeout=0.001) +>>> httpx.get('https://github.com/', timeout=0.001) ``` diff --git a/http3/__init__.py b/httpx/__init__.py similarity index 100% rename from http3/__init__.py rename to httpx/__init__.py diff --git a/http3/__version__.py b/httpx/__version__.py similarity index 81% rename from http3/__version__.py rename to httpx/__version__.py index 37bd8f41..c5079f7c 100644 --- a/http3/__version__.py +++ b/httpx/__version__.py @@ -1,3 +1,3 @@ -__title__ = "http3" +__title__ = "httpx" __description__ = "A next generation HTTP client, for Python 3." __version__ = "0.6.7" diff --git a/http3/api.py b/httpx/api.py similarity index 100% rename from http3/api.py rename to httpx/api.py diff --git a/http3/auth.py b/httpx/auth.py similarity index 100% rename from http3/auth.py rename to httpx/auth.py diff --git a/http3/client.py b/httpx/client.py similarity index 100% rename from http3/client.py rename to httpx/client.py diff --git a/http3/concurrency.py b/httpx/concurrency.py similarity index 100% rename from http3/concurrency.py rename to httpx/concurrency.py diff --git a/http3/config.py b/httpx/config.py similarity index 99% rename from http3/config.py rename to httpx/config.py index fba47c93..40e7cdc2 100644 --- a/http3/config.py +++ b/httpx/config.py @@ -12,7 +12,7 @@ VerifyTypes = typing.Union[str, bool] TimeoutTypes = typing.Union[float, typing.Tuple[float, float, float], "TimeoutConfig"] -USER_AGENT = f"python-http3/{__version__}" +USER_AGENT = f"python-httpx/{__version__}" DEFAULT_CIPHERS = ":".join( [ diff --git a/http3/decoders.py b/httpx/decoders.py similarity index 100% rename from http3/decoders.py rename to httpx/decoders.py diff --git a/http3/dispatch/__init__.py b/httpx/dispatch/__init__.py similarity index 100% rename from http3/dispatch/__init__.py rename to httpx/dispatch/__init__.py diff --git a/http3/dispatch/asgi.py b/httpx/dispatch/asgi.py similarity index 98% rename from http3/dispatch/asgi.py rename to httpx/dispatch/asgi.py index 384d6d47..8164b18e 100644 --- a/http3/dispatch/asgi.py +++ b/httpx/dispatch/asgi.py @@ -15,7 +15,7 @@ class ASGIDispatch(AsyncDispatcher): and will setup an appropriate dispatch class: ``` - client = http3.Client(app=app) + client = httpx.Client(app=app) ``` Alternatively, you can setup the dispatch instance explicitly. @@ -23,12 +23,12 @@ class ASGIDispatch(AsyncDispatcher): to the ASGIDispatch class: ``` - dispatch = http3.ASGIDispatch( + dispatch = httpx.ASGIDispatch( app=app, root_path="/submount", client=("1.2.3.4", 123) ) - client = http3.Client(dispatch=dispatch) + client = httpx.Client(dispatch=dispatch) ``` """ diff --git a/http3/dispatch/connection.py b/httpx/dispatch/connection.py similarity index 100% rename from http3/dispatch/connection.py rename to httpx/dispatch/connection.py diff --git a/http3/dispatch/connection_pool.py b/httpx/dispatch/connection_pool.py similarity index 100% rename from http3/dispatch/connection_pool.py rename to httpx/dispatch/connection_pool.py diff --git a/http3/dispatch/http11.py b/httpx/dispatch/http11.py similarity index 100% rename from http3/dispatch/http11.py rename to httpx/dispatch/http11.py diff --git a/http3/dispatch/http2.py b/httpx/dispatch/http2.py similarity index 100% rename from http3/dispatch/http2.py rename to httpx/dispatch/http2.py diff --git a/http3/dispatch/threaded.py b/httpx/dispatch/threaded.py similarity index 100% rename from http3/dispatch/threaded.py rename to httpx/dispatch/threaded.py diff --git a/http3/dispatch/wsgi.py b/httpx/dispatch/wsgi.py similarity index 97% rename from http3/dispatch/wsgi.py rename to httpx/dispatch/wsgi.py index f0bf5311..017eae18 100644 --- a/http3/dispatch/wsgi.py +++ b/httpx/dispatch/wsgi.py @@ -15,7 +15,7 @@ class WSGIDispatch(Dispatcher): and will setup an appropriate dispatch class: ``` - client = http3.Client(app=app) + client = httpx.Client(app=app) ``` Alternatively, you can setup the dispatch instance explicitly. @@ -23,12 +23,12 @@ class WSGIDispatch(Dispatcher): to the WSGIDispatch class: ``` - dispatch = http3.WSGIDispatch( + dispatch = httpx.WSGIDispatch( app=app, script_name="/submount", remote_addr="1.2.3.4" ) - client = http3.Client(dispatch=dispatch) + client = httpx.Client(dispatch=dispatch) ``` """ diff --git a/http3/exceptions.py b/httpx/exceptions.py similarity index 100% rename from http3/exceptions.py rename to httpx/exceptions.py diff --git a/http3/interfaces.py b/httpx/interfaces.py similarity index 100% rename from http3/interfaces.py rename to httpx/interfaces.py diff --git a/http3/models.py b/httpx/models.py similarity index 100% rename from http3/models.py rename to httpx/models.py diff --git a/http3/multipart.py b/httpx/multipart.py similarity index 100% rename from http3/multipart.py rename to httpx/multipart.py diff --git a/http3/status_codes.py b/httpx/status_codes.py similarity index 100% rename from http3/status_codes.py rename to httpx/status_codes.py diff --git a/http3/utils.py b/httpx/utils.py similarity index 100% rename from http3/utils.py rename to httpx/utils.py diff --git a/mkdocs.yml b/mkdocs.yml index d9d3eb3e..360d1360 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,11 +1,11 @@ -site_name: HTTP3 -site_description: The next generation HTTP client. +site_name: HTTPX +site_description: A next-generation HTTP client for Python. theme: name: 'material' -repo_name: encode/http3 -repo_url: https://github.com/encode/http3 +repo_name: encode/httpx +repo_url: https://github.com/encode/httpx edit_uri: "" nav: diff --git a/scripts/clean b/scripts/clean index bd133afe..f08d02c4 100755 --- a/scripts/clean +++ b/scripts/clean @@ -9,6 +9,6 @@ fi if [ -d 'htmlcov' ] ; then rm -r htmlcov fi -if [ -d 'http3.egg-info' ] ; then - rm -r http3.egg-info +if [ -d 'httpx.egg-info' ] ; then + rm -r httpx.egg-info fi diff --git a/scripts/lint b/scripts/lint index 1c02eb6c..fb2e81ab 100755 --- a/scripts/lint +++ b/scripts/lint @@ -7,10 +7,10 @@ fi set -x -${PREFIX}autoflake --in-place --recursive http3 tests setup.py -${PREFIX}isort --multi-line=3 --trailing-comma --force-grid-wrap=0 --combine-as --line-width 88 --recursive --apply http3 tests setup.py -${PREFIX}black http3 tests setup.py -${PREFIX}flake8 --max-line-length=88 --ignore=W503,E203 http3 tests setup.py -${PREFIX}mypy http3 --ignore-missing-imports --disallow-untyped-defs +${PREFIX}autoflake --in-place --recursive httpx tests setup.py +${PREFIX}isort --multi-line=3 --trailing-comma --force-grid-wrap=0 --combine-as --line-width 88 --recursive --apply httpx tests setup.py +${PREFIX}black httpx tests setup.py +${PREFIX}flake8 --max-line-length=88 --ignore=W503,E203 httpx tests setup.py +${PREFIX}mypy httpx --ignore-missing-imports --disallow-untyped-defs scripts/clean diff --git a/scripts/publish b/scripts/publish index cb02ec8f..4fcc734c 100755 --- a/scripts/publish +++ b/scripts/publish @@ -1,6 +1,6 @@ #!/bin/sh -e -export PACKAGE="http3" +export PACKAGE="httpx" export VERSION=`cat ${PACKAGE}/__version__.py | grep __version__ | sed "s/__version__ = //" | sed "s/'//g"` export PREFIX="" if [ -d 'venv' ] ; then diff --git a/scripts/test b/scripts/test index fe000e2f..626d43e9 100755 --- a/scripts/test +++ b/scripts/test @@ -1,6 +1,6 @@ #!/bin/sh -e -export PACKAGE="http3" +export PACKAGE="httpx" export PREFIX="" if [ -d 'venv' ] ; then export PREFIX="venv/bin/" diff --git a/tests/client/test_async_client.py b/tests/client/test_async_client.py index 3f5bf53a..4f79af04 100644 --- a/tests/client/test_async_client.py +++ b/tests/client/test_async_client.py @@ -1,12 +1,12 @@ import pytest -import http3 +import httpx @pytest.mark.asyncio async def test_get(server): url = "http://127.0.0.1:8000/" - async with http3.AsyncClient() as client: + async with httpx.AsyncClient() as client: response = await client.get(url) assert response.status_code == 200 assert response.text == "Hello, world!" @@ -18,7 +18,7 @@ async def test_get(server): @pytest.mark.asyncio async def test_post(server): url = "http://127.0.0.1:8000/" - async with http3.AsyncClient() as client: + async with httpx.AsyncClient() as client: response = await client.post(url, data=b"Hello, world!") assert response.status_code == 200 @@ -26,14 +26,14 @@ async def test_post(server): @pytest.mark.asyncio async def test_post_json(server): url = "http://127.0.0.1:8000/" - async with http3.AsyncClient() as client: + async with httpx.AsyncClient() as client: response = await client.post(url, json={"text": "Hello, world!"}) assert response.status_code == 200 @pytest.mark.asyncio async def test_stream_response(server): - async with http3.AsyncClient() as client: + async with httpx.AsyncClient() as client: response = await client.request("GET", "http://127.0.0.1:8000/", stream=True) assert response.status_code == 200 body = await response.read() @@ -43,10 +43,10 @@ async def test_stream_response(server): @pytest.mark.asyncio async def test_access_content_stream_response(server): - async with http3.AsyncClient() as client: + async with httpx.AsyncClient() as client: response = await client.request("GET", "http://127.0.0.1:8000/", stream=True) assert response.status_code == 200 - with pytest.raises(http3.ResponseNotRead): + with pytest.raises(httpx.ResponseNotRead): response.content @@ -56,7 +56,7 @@ async def test_stream_request(server): yield b"Hello, " yield b"world!" - async with http3.AsyncClient() as client: + async with httpx.AsyncClient() as client: response = await client.request( "POST", "http://127.0.0.1:8000/", data=hello_world() ) @@ -65,14 +65,14 @@ async def test_stream_request(server): @pytest.mark.asyncio async def test_raise_for_status(server): - async with http3.AsyncClient() as client: + async with httpx.AsyncClient() as client: for status_code in (200, 400, 404, 500, 505): response = await client.request( "GET", f"http://127.0.0.1:8000/status/{status_code}" ) if 400 <= status_code < 600: - with pytest.raises(http3.exceptions.HttpError): + with pytest.raises(httpx.exceptions.HttpError): response.raise_for_status() else: assert response.raise_for_status() is None @@ -81,7 +81,7 @@ async def test_raise_for_status(server): @pytest.mark.asyncio async def test_options(server): url = "http://127.0.0.1:8000/" - async with http3.AsyncClient() as client: + async with httpx.AsyncClient() as client: response = await client.options(url) assert response.status_code == 200 assert response.text == "Hello, world!" @@ -90,7 +90,7 @@ async def test_options(server): @pytest.mark.asyncio async def test_head(server): url = "http://127.0.0.1:8000/" - async with http3.AsyncClient() as client: + async with httpx.AsyncClient() as client: response = await client.head(url) assert response.status_code == 200 assert response.text == "" @@ -99,7 +99,7 @@ async def test_head(server): @pytest.mark.asyncio async def test_put(server): url = "http://127.0.0.1:8000/" - async with http3.AsyncClient() as client: + async with httpx.AsyncClient() as client: response = await client.put(url, data=b"Hello, world!") assert response.status_code == 200 @@ -107,7 +107,7 @@ async def test_put(server): @pytest.mark.asyncio async def test_patch(server): url = "http://127.0.0.1:8000/" - async with http3.AsyncClient() as client: + async with httpx.AsyncClient() as client: response = await client.patch(url, data=b"Hello, world!") assert response.status_code == 200 @@ -115,7 +115,7 @@ async def test_patch(server): @pytest.mark.asyncio async def test_delete(server): url = "http://127.0.0.1:8000/" - async with http3.AsyncClient() as client: + async with httpx.AsyncClient() as client: response = await client.delete(url) assert response.status_code == 200 assert response.text == "Hello, world!" @@ -127,7 +127,7 @@ async def test_100_continue(server): headers = {"Expect": "100-continue"} data = b"Echo request body" - async with http3.AsyncClient() as client: + async with httpx.AsyncClient() as client: response = await client.post(url, headers=headers, data=data) assert response.status_code == 200 diff --git a/tests/client/test_auth.py b/tests/client/test_auth.py index 03c3e2dc..44099fba 100644 --- a/tests/client/test_auth.py +++ b/tests/client/test_auth.py @@ -1,6 +1,6 @@ import json -from http3 import ( +from httpx import ( AsyncDispatcher, AsyncRequest, AsyncResponse, diff --git a/tests/client/test_client.py b/tests/client/test_client.py index 19642414..8c402f54 100644 --- a/tests/client/test_client.py +++ b/tests/client/test_client.py @@ -3,7 +3,7 @@ import functools import pytest -import http3 +import httpx def threadpool(func): @@ -26,15 +26,15 @@ def threadpool(func): @threadpool def test_get(server): url = "http://127.0.0.1:8000/" - with http3.Client() as http: + with httpx.Client() as http: response = http.get(url) assert response.status_code == 200 - assert response.url == http3.URL(url) + assert response.url == httpx.URL(url) assert response.content == b"Hello, world!" assert response.text == "Hello, world!" assert response.protocol == "HTTP/1.1" assert response.encoding == "iso-8859-1" - assert response.request.url == http3.URL(url) + assert response.request.url == httpx.URL(url) assert response.headers assert response.is_redirect is False assert repr(response) == "" @@ -42,7 +42,7 @@ def test_get(server): @threadpool def test_post(server): - with http3.Client() as http: + with httpx.Client() as http: response = http.post("http://127.0.0.1:8000/", data=b"Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" @@ -50,7 +50,7 @@ def test_post(server): @threadpool def test_post_json(server): - with http3.Client() as http: + with httpx.Client() as http: response = http.post("http://127.0.0.1:8000/", json={"text": "Hello, world!"}) assert response.status_code == 200 assert response.reason_phrase == "OK" @@ -58,7 +58,7 @@ def test_post_json(server): @threadpool def test_stream_response(server): - with http3.Client() as http: + with httpx.Client() as http: response = http.get("http://127.0.0.1:8000/", stream=True) assert response.status_code == 200 content = response.read() @@ -67,7 +67,7 @@ def test_stream_response(server): @threadpool def test_stream_iterator(server): - with http3.Client() as http: + with httpx.Client() as http: response = http.get("http://127.0.0.1:8000/", stream=True) assert response.status_code == 200 body = b"" @@ -78,7 +78,7 @@ def test_stream_iterator(server): @threadpool def test_raw_iterator(server): - with http3.Client() as http: + with httpx.Client() as http: response = http.get("http://127.0.0.1:8000/", stream=True) assert response.status_code == 200 body = b"" @@ -90,14 +90,14 @@ def test_raw_iterator(server): @threadpool def test_raise_for_status(server): - with http3.Client() as client: + with httpx.Client() as client: for status_code in (200, 400, 404, 500, 505): response = client.request( "GET", "http://127.0.0.1:8000/status/{}".format(status_code) ) if 400 <= status_code < 600: - with pytest.raises(http3.exceptions.HttpError): + with pytest.raises(httpx.exceptions.HttpError): response.raise_for_status() else: assert response.raise_for_status() is None @@ -105,7 +105,7 @@ def test_raise_for_status(server): @threadpool def test_options(server): - with http3.Client() as http: + with httpx.Client() as http: response = http.options("http://127.0.0.1:8000/") assert response.status_code == 200 assert response.reason_phrase == "OK" @@ -113,7 +113,7 @@ def test_options(server): @threadpool def test_head(server): - with http3.Client() as http: + with httpx.Client() as http: response = http.head("http://127.0.0.1:8000/") assert response.status_code == 200 assert response.reason_phrase == "OK" @@ -121,7 +121,7 @@ def test_head(server): @threadpool def test_put(server): - with http3.Client() as http: + with httpx.Client() as http: response = http.put("http://127.0.0.1:8000/", data=b"Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" @@ -129,7 +129,7 @@ def test_put(server): @threadpool def test_patch(server): - with http3.Client() as http: + with httpx.Client() as http: response = http.patch("http://127.0.0.1:8000/", data=b"Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" @@ -137,7 +137,7 @@ def test_patch(server): @threadpool def test_delete(server): - with http3.Client() as http: + with httpx.Client() as http: response = http.delete("http://127.0.0.1:8000/") assert response.status_code == 200 assert response.reason_phrase == "OK" @@ -146,7 +146,7 @@ def test_delete(server): @threadpool def test_base_url(server): base_url = "http://127.0.0.1:8000/" - with http3.Client(base_url=base_url) as http: + with httpx.Client(base_url=base_url) as http: response = http.get("/") assert response.status_code == 200 assert str(response.url) == base_url diff --git a/tests/client/test_cookies.py b/tests/client/test_cookies.py index 77d8095a..280f44bc 100644 --- a/tests/client/test_cookies.py +++ b/tests/client/test_cookies.py @@ -1,7 +1,7 @@ import json from http.cookiejar import Cookie, CookieJar -from http3 import ( +from httpx import ( AsyncDispatcher, AsyncRequest, AsyncResponse, diff --git a/tests/client/test_redirects.py b/tests/client/test_redirects.py index 8484af6e..ff754751 100644 --- a/tests/client/test_redirects.py +++ b/tests/client/test_redirects.py @@ -3,7 +3,7 @@ from urllib.parse import parse_qs import pytest -from http3 import ( +from httpx import ( URL, AsyncClient, AsyncDispatcher, diff --git a/tests/dispatch/test_connection_pools.py b/tests/dispatch/test_connection_pools.py index 00e0a7e4..5ef884ee 100644 --- a/tests/dispatch/test_connection_pools.py +++ b/tests/dispatch/test_connection_pools.py @@ -1,6 +1,6 @@ import pytest -import http3 +import httpx @pytest.mark.asyncio @@ -8,7 +8,7 @@ async def test_keepalive_connections(server): """ Connections should default to staying in a keep-alive state. """ - async with http3.ConnectionPool() as http: + async with httpx.ConnectionPool() as http: response = await http.request("GET", "http://127.0.0.1:8000/") await response.read() assert len(http.active_connections) == 0 @@ -25,7 +25,7 @@ async def test_differing_connection_keys(server): """ Connnections to differing connection keys should result in multiple connections. """ - async with http3.ConnectionPool() as http: + async with httpx.ConnectionPool() as http: response = await http.request("GET", "http://127.0.0.1:8000/") await response.read() assert len(http.active_connections) == 0 @@ -42,9 +42,9 @@ async def test_soft_limit(server): """ The soft_limit config should limit the maximum number of keep-alive connections. """ - pool_limits = http3.PoolLimits(soft_limit=1) + pool_limits = httpx.PoolLimits(soft_limit=1) - async with http3.ConnectionPool(pool_limits=pool_limits) as http: + async with httpx.ConnectionPool(pool_limits=pool_limits) as http: response = await http.request("GET", "http://127.0.0.1:8000/") await response.read() assert len(http.active_connections) == 0 @@ -61,7 +61,7 @@ async def test_streaming_response_holds_connection(server): """ A streaming request should hold the connection open until the response is read. """ - async with http3.ConnectionPool() as http: + async with httpx.ConnectionPool() as http: response = await http.request("GET", "http://127.0.0.1:8000/") assert len(http.active_connections) == 1 assert len(http.keepalive_connections) == 0 @@ -77,7 +77,7 @@ async def test_multiple_concurrent_connections(server): """ Multiple conncurrent requests should open multiple conncurrent connections. """ - async with http3.ConnectionPool() as http: + async with httpx.ConnectionPool() as http: response_a = await http.request("GET", "http://127.0.0.1:8000/") assert len(http.active_connections) == 1 assert len(http.keepalive_connections) == 0 @@ -101,7 +101,7 @@ async def test_close_connections(server): Using a `Connection: close` header should close the connection. """ headers = [(b"connection", b"close")] - async with http3.ConnectionPool() as http: + async with httpx.ConnectionPool() as http: response = await http.request("GET", "http://127.0.0.1:8000/", headers=headers) await response.read() assert len(http.active_connections) == 0 @@ -113,7 +113,7 @@ async def test_standard_response_close(server): """ A standard close should keep the connection open. """ - async with http3.ConnectionPool() as http: + async with httpx.ConnectionPool() as http: response = await http.request("GET", "http://127.0.0.1:8000/") await response.read() await response.close() @@ -126,7 +126,7 @@ async def test_premature_response_close(server): """ A premature close should close the connection. """ - async with http3.ConnectionPool() as http: + async with httpx.ConnectionPool() as http: response = await http.request("GET", "http://127.0.0.1:8000/") await response.close() assert len(http.active_connections) == 0 diff --git a/tests/dispatch/test_connections.py b/tests/dispatch/test_connections.py index f449e859..5273536b 100644 --- a/tests/dispatch/test_connections.py +++ b/tests/dispatch/test_connections.py @@ -1,6 +1,6 @@ import pytest -from http3 import HTTPConnection +from httpx import HTTPConnection @pytest.mark.asyncio diff --git a/tests/dispatch/test_http2.py b/tests/dispatch/test_http2.py index 574a0a10..b1945242 100644 --- a/tests/dispatch/test_http2.py +++ b/tests/dispatch/test_http2.py @@ -1,6 +1,6 @@ import json -from http3 import Client, Response +from httpx import Client, Response from .utils import MockHTTP2Backend diff --git a/tests/dispatch/test_threaded.py b/tests/dispatch/test_threaded.py index a7519004..ac90bdd2 100644 --- a/tests/dispatch/test_threaded.py +++ b/tests/dispatch/test_threaded.py @@ -1,6 +1,6 @@ import json -from http3 import ( +from httpx import ( CertTypes, Client, Dispatcher, diff --git a/tests/dispatch/utils.py b/tests/dispatch/utils.py index 85c2674b..a1e02a4c 100644 --- a/tests/dispatch/utils.py +++ b/tests/dispatch/utils.py @@ -6,7 +6,7 @@ import h2.config import h2.connection import h2.events -from http3 import ( +from httpx import ( AsyncioBackend, BaseReader, BaseWriter, diff --git a/tests/models/test_cookies.py b/tests/models/test_cookies.py index 57b1412c..554681e1 100644 --- a/tests/models/test_cookies.py +++ b/tests/models/test_cookies.py @@ -1,6 +1,6 @@ import pytest -from http3 import CookieConflict, Cookies +from httpx import CookieConflict, Cookies def test_cookies(): diff --git a/tests/models/test_headers.py b/tests/models/test_headers.py index c6b755d1..329fb520 100644 --- a/tests/models/test_headers.py +++ b/tests/models/test_headers.py @@ -1,8 +1,8 @@ -import http3 +import httpx def test_headers(): - h = http3.Headers([("a", "123"), ("a", "456"), ("b", "789")]) + h = httpx.Headers([("a", "123"), ("a", "456"), ("b", "789")]) assert "a" in h assert "A" in h assert "b" in h @@ -18,10 +18,10 @@ def test_headers(): assert list(h) == ["a", "a", "b"] assert dict(h) == {"a": "123, 456", "b": "789"} assert repr(h) == "Headers([('a', '123'), ('a', '456'), ('b', '789')])" - assert h == http3.Headers([("a", "123"), ("b", "789"), ("a", "456")]) + assert h == httpx.Headers([("a", "123"), ("b", "789"), ("a", "456")]) assert h != [("a", "123"), ("A", "456"), ("b", "789")] - h = http3.Headers({"a": "123", "b": "789"}) + h = httpx.Headers({"a": "123", "b": "789"}) assert h["A"] == "123" assert h["B"] == "789" assert h.raw == [(b"a", b"123"), (b"b", b"789")] @@ -29,7 +29,7 @@ def test_headers(): def test_header_mutations(): - h = http3.Headers() + h = httpx.Headers() assert dict(h) == {} h["a"] = "1" assert dict(h) == {"a": "1"} @@ -45,31 +45,31 @@ def test_header_mutations(): def test_copy_headers(): - headers = http3.Headers({"custom": "example"}) - headers_copy = http3.Headers(headers) + headers = httpx.Headers({"custom": "example"}) + headers_copy = httpx.Headers(headers) assert headers == headers_copy def test_headers_insert_retains_ordering(): - headers = http3.Headers({"a": "a", "b": "b", "c": "c"}) + headers = httpx.Headers({"a": "a", "b": "b", "c": "c"}) headers["b"] = "123" assert list(headers.values()) == ["a", "123", "c"] def test_headers_insert_appends_if_new(): - headers = http3.Headers({"a": "a", "b": "b", "c": "c"}) + headers = httpx.Headers({"a": "a", "b": "b", "c": "c"}) headers["d"] = "123" assert list(headers.values()) == ["a", "b", "c", "123"] def test_headers_insert_removes_all_existing(): - headers = http3.Headers([("a", "123"), ("a", "456")]) + headers = httpx.Headers([("a", "123"), ("a", "456")]) headers["a"] = "789" assert dict(headers) == {"a": "789"} def test_headers_delete_removes_all_existing(): - headers = http3.Headers([("a", "123"), ("a", "456")]) + headers = httpx.Headers([("a", "123"), ("a", "456")]) del headers["a"] assert dict(headers) == {} @@ -78,7 +78,7 @@ def test_headers_dict_repr(): """ Headers should display with a dict repr by default. """ - headers = http3.Headers({"custom": "example"}) + headers = httpx.Headers({"custom": "example"}) assert repr(headers) == "Headers({'custom': 'example'})" @@ -86,7 +86,7 @@ def test_headers_encoding_in_repr(): """ Headers should display an encoding in the repr if required. """ - headers = http3.Headers({b"custom": "example ☃".encode("utf-8")}) + headers = httpx.Headers({b"custom": "example ☃".encode("utf-8")}) assert repr(headers) == "Headers({'custom': 'example ☃'}, encoding='utf-8')" @@ -94,7 +94,7 @@ def test_headers_list_repr(): """ Headers should display with a list repr if they include multiple identical keys. """ - headers = http3.Headers([("custom", "example 1"), ("custom", "example 2")]) + headers = httpx.Headers([("custom", "example 1"), ("custom", "example 2")]) assert ( repr(headers) == "Headers([('custom', 'example 1'), ('custom', 'example 2')])" ) @@ -105,7 +105,7 @@ def test_headers_decode_ascii(): Headers should decode as ascii by default. """ raw_headers = [(b"Custom", b"Example")] - headers = http3.Headers(raw_headers) + headers = httpx.Headers(raw_headers) assert dict(headers) == {"custom": "Example"} assert headers.encoding == "ascii" @@ -115,7 +115,7 @@ def test_headers_decode_utf_8(): Headers containing non-ascii codepoints should default to decoding as utf-8. """ raw_headers = [(b"Custom", "Code point: ☃".encode("utf-8"))] - headers = http3.Headers(raw_headers) + headers = httpx.Headers(raw_headers) assert dict(headers) == {"custom": "Code point: ☃"} assert headers.encoding == "utf-8" @@ -125,7 +125,7 @@ def test_headers_decode_iso_8859_1(): Headers containing non-UTF-8 codepoints should default to decoding as iso-8859-1. """ raw_headers = [(b"Custom", "Code point: ÿ".encode("iso-8859-1"))] - headers = http3.Headers(raw_headers) + headers = httpx.Headers(raw_headers) assert dict(headers) == {"custom": "Code point: ÿ"} assert headers.encoding == "iso-8859-1" @@ -136,7 +136,7 @@ def test_headers_decode_explicit_encoding(): particular decoding. """ raw_headers = [(b"Custom", "Code point: ☃".encode("utf-8"))] - headers = http3.Headers(raw_headers) + headers = httpx.Headers(raw_headers) headers.encoding = "iso-8859-1" assert dict(headers) == {"custom": "Code point: â\x98\x83"} assert headers.encoding == "iso-8859-1" @@ -146,8 +146,8 @@ def test_multiple_headers(): """ Most headers should split by commas for `getlist`, except 'Set-Cookie'. """ - h = http3.Headers([("set-cookie", "a, b"), ("set-cookie", "c")]) + h = httpx.Headers([("set-cookie", "a, b"), ("set-cookie", "c")]) h.getlist("Set-Cookie") == ["a, b", "b"] - h = http3.Headers([("vary", "a, b"), ("vary", "c")]) + h = httpx.Headers([("vary", "a, b"), ("vary", "c")]) h.getlist("Vary") == ["a", "b", "c"] diff --git a/tests/models/test_queryparams.py b/tests/models/test_queryparams.py index 369d43ce..983b09fb 100644 --- a/tests/models/test_queryparams.py +++ b/tests/models/test_queryparams.py @@ -1,4 +1,4 @@ -from http3 import QueryParams +from httpx import QueryParams def test_queryparams(): diff --git a/tests/models/test_requests.py b/tests/models/test_requests.py index 66698010..07ff750d 100644 --- a/tests/models/test_requests.py +++ b/tests/models/test_requests.py @@ -1,32 +1,32 @@ import pytest -import http3 +import httpx def test_request_repr(): - request = http3.Request("GET", "http://example.org") + request = httpx.Request("GET", "http://example.org") assert repr(request) == "" def test_no_content(): - request = http3.Request("GET", "http://example.org") + request = httpx.Request("GET", "http://example.org") assert "Content-Length" not in request.headers def test_content_length_header(): - request = http3.Request("POST", "http://example.org", data=b"test 123") + request = httpx.Request("POST", "http://example.org", data=b"test 123") assert request.headers["Content-Length"] == "8" def test_url_encoded_data(): - for RequestClass in (http3.Request, http3.AsyncRequest): + for RequestClass in (httpx.Request, httpx.AsyncRequest): request = RequestClass("POST", "http://example.org", data={"test": "123"}) assert request.headers["Content-Type"] == "application/x-www-form-urlencoded" assert request.content == b"test=123" def test_json_encoded_data(): - for RequestClass in (http3.Request, http3.AsyncRequest): + for RequestClass in (httpx.Request, httpx.AsyncRequest): request = RequestClass("POST", "http://example.org", json={"test": 123}) assert request.headers["Content-Type"] == "application/json" assert request.content == b'{"test": 123}' @@ -38,7 +38,7 @@ def test_transfer_encoding_header(): data = streaming_body(b"test 123") - request = http3.Request("POST", "http://example.org", data=data) + request = httpx.Request("POST", "http://example.org", data=data) assert "Content-Length" not in request.headers assert request.headers["Transfer-Encoding"] == "chunked" @@ -46,14 +46,14 @@ def test_transfer_encoding_header(): def test_override_host_header(): headers = {"host": "1.2.3.4:80"} - request = http3.Request("GET", "http://example.org", headers=headers) + request = httpx.Request("GET", "http://example.org", headers=headers) assert request.headers["Host"] == "1.2.3.4:80" def test_override_accept_encoding_header(): headers = {"Accept-Encoding": "identity"} - request = http3.Request("GET", "http://example.org", headers=headers) + request = httpx.Request("GET", "http://example.org", headers=headers) assert request.headers["Accept-Encoding"] == "identity" @@ -64,27 +64,27 @@ def test_override_content_length_header(): data = streaming_body(b"test 123") headers = {"Content-Length": "8"} - request = http3.Request("POST", "http://example.org", data=data, headers=headers) + request = httpx.Request("POST", "http://example.org", data=data, headers=headers) assert request.headers["Content-Length"] == "8" def test_url(): url = "http://example.org" - request = http3.Request("GET", url) + request = httpx.Request("GET", url) assert request.url.scheme == "http" assert request.url.port == 80 assert request.url.full_path == "/" url = "https://example.org/abc?foo=bar" - request = http3.Request("GET", url) + request = httpx.Request("GET", url) assert request.url.scheme == "https" assert request.url.port == 443 assert request.url.full_path == "/abc?foo=bar" def test_invalid_urls(): - with pytest.raises(http3.InvalidURL): - http3.Request("GET", "example.org") + with pytest.raises(httpx.InvalidURL): + httpx.Request("GET", "example.org") - with pytest.raises(http3.InvalidURL): - http3.Request("GET", "http:///foo") + with pytest.raises(httpx.InvalidURL): + httpx.Request("GET", "http:///foo") diff --git a/tests/models/test_responses.py b/tests/models/test_responses.py index dbdcacab..dddfb4fb 100644 --- a/tests/models/test_responses.py +++ b/tests/models/test_responses.py @@ -3,7 +3,7 @@ from unittest import mock import pytest -import http3 +import httpx def streaming_body(): @@ -17,14 +17,14 @@ async def async_streaming_body(): def test_response(): - response = http3.Response(200, content=b"Hello, world!") + response = httpx.Response(200, content=b"Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" assert response.text == "Hello, world!" def test_response_repr(): - response = http3.Response(200, content=b"Hello, world!") + response = httpx.Response(200, content=b"Hello, world!") assert repr(response) == "" @@ -34,7 +34,7 @@ def test_response_content_type_encoding(): """ headers = {"Content-Type": "text-plain; charset=latin-1"} content = "Latin 1: ÿ".encode("latin-1") - response = http3.Response(200, content=content, headers=headers) + response = httpx.Response(200, content=content, headers=headers) assert response.text == "Latin 1: ÿ" assert response.encoding == "latin-1" @@ -44,7 +44,7 @@ def test_response_autodetect_encoding(): Autodetect encoding if there is no charset info in a Content-Type header. """ content = "おはようございます。".encode("EUC-JP") - response = http3.Response(200, content=content) + response = httpx.Response(200, content=content) assert response.text == "おはようございます。" assert response.encoding == "EUC-JP" @@ -55,7 +55,7 @@ def test_response_fallback_to_autodetect(): """ headers = {"Content-Type": "text-plain; charset=invalid-codec-name"} content = "おはようございます。".encode("EUC-JP") - response = http3.Response(200, content=content, headers=headers) + response = httpx.Response(200, content=content, headers=headers) assert response.text == "おはようございます。" assert response.encoding == "EUC-JP" @@ -67,7 +67,7 @@ def test_response_default_text_encoding(): """ content = b"Hello, world!" headers = {"Content-Type": "text/plain"} - response = http3.Response(200, content=content, headers=headers) + response = httpx.Response(200, content=content, headers=headers) assert response.status_code == 200 assert response.encoding == "iso-8859-1" assert response.text == "Hello, world!" @@ -77,7 +77,7 @@ def test_response_default_encoding(): """ Default to utf-8 if all else fails. """ - response = http3.Response(200, content=b"") + response = httpx.Response(200, content=b"") assert response.text == "" assert response.encoding == "utf-8" @@ -87,7 +87,7 @@ def test_response_non_text_encoding(): Default to apparent encoding for non-text content-type headers. """ headers = {"Content-Type": "image/png"} - response = http3.Response(200, content=b"xyz", headers=headers) + response = httpx.Response(200, content=b"xyz", headers=headers) assert response.text == "xyz" assert response.encoding == "ascii" @@ -96,7 +96,7 @@ def test_response_set_explicit_encoding(): headers = { "Content-Type": "text-plain; charset=utf-8" } # Deliberately incorrect charset - response = http3.Response( + response = httpx.Response( 200, content="Latin 1: ÿ".encode("latin-1"), headers=headers ) response.encoding = "latin-1" @@ -105,7 +105,7 @@ def test_response_set_explicit_encoding(): def test_response_force_encoding(): - response = http3.Response(200, content="Snowman: ☃".encode("utf-8")) + response = httpx.Response(200, content="Snowman: ☃".encode("utf-8")) response.encoding = "iso-8859-1" assert response.status_code == 200 assert response.reason_phrase == "OK" @@ -114,7 +114,7 @@ def test_response_force_encoding(): def test_read_response(): - response = http3.Response(200, content=b"Hello, world!") + response = httpx.Response(200, content=b"Hello, world!") assert response.status_code == 200 assert response.text == "Hello, world!" @@ -129,7 +129,7 @@ def test_read_response(): def test_raw_interface(): - response = http3.Response(200, content=b"Hello, world!") + response = httpx.Response(200, content=b"Hello, world!") raw = b"" for part in response.raw(): @@ -138,7 +138,7 @@ def test_raw_interface(): def test_stream_interface(): - response = http3.Response(200, content=b"Hello, world!") + response = httpx.Response(200, content=b"Hello, world!") content = b"" for part in response.stream(): @@ -148,7 +148,7 @@ def test_stream_interface(): @pytest.mark.asyncio async def test_async_stream_interface(): - response = http3.AsyncResponse(200, content=b"Hello, world!") + response = httpx.AsyncResponse(200, content=b"Hello, world!") content = b"" async for part in response.stream(): @@ -157,7 +157,7 @@ async def test_async_stream_interface(): def test_stream_interface_after_read(): - response = http3.Response(200, content=b"Hello, world!") + response = httpx.Response(200, content=b"Hello, world!") response.read() @@ -169,7 +169,7 @@ def test_stream_interface_after_read(): @pytest.mark.asyncio async def test_async_stream_interface_after_read(): - response = http3.AsyncResponse(200, content=b"Hello, world!") + response = httpx.AsyncResponse(200, content=b"Hello, world!") await response.read() @@ -180,7 +180,7 @@ async def test_async_stream_interface_after_read(): def test_streaming_response(): - response = http3.Response(200, content=streaming_body()) + response = httpx.Response(200, content=streaming_body()) assert response.status_code == 200 assert not response.is_closed @@ -194,7 +194,7 @@ def test_streaming_response(): @pytest.mark.asyncio async def test_async_streaming_response(): - response = http3.AsyncResponse(200, content=async_streaming_body()) + response = httpx.AsyncResponse(200, content=async_streaming_body()) assert response.status_code == 200 assert not response.is_closed @@ -207,49 +207,49 @@ async def test_async_streaming_response(): def test_cannot_read_after_stream_consumed(): - response = http3.Response(200, content=streaming_body()) + response = httpx.Response(200, content=streaming_body()) content = b"" for part in response.stream(): content += part - with pytest.raises(http3.StreamConsumed): + with pytest.raises(httpx.StreamConsumed): response.read() @pytest.mark.asyncio async def test_async_cannot_read_after_stream_consumed(): - response = http3.AsyncResponse(200, content=async_streaming_body()) + response = httpx.AsyncResponse(200, content=async_streaming_body()) content = b"" async for part in response.stream(): content += part - with pytest.raises(http3.StreamConsumed): + with pytest.raises(httpx.StreamConsumed): await response.read() def test_cannot_read_after_response_closed(): - response = http3.Response(200, content=streaming_body()) + response = httpx.Response(200, content=streaming_body()) response.close() - with pytest.raises(http3.ResponseClosed): + with pytest.raises(httpx.ResponseClosed): response.read() @pytest.mark.asyncio async def test_async_cannot_read_after_response_closed(): - response = http3.AsyncResponse(200, content=async_streaming_body()) + response = httpx.AsyncResponse(200, content=async_streaming_body()) await response.close() - with pytest.raises(http3.ResponseClosed): + with pytest.raises(httpx.ResponseClosed): await response.read() def test_unknown_status_code(): - response = http3.Response(600) + response = httpx.Response(600) assert response.status_code == 600 assert response.reason_phrase == "" assert response.text == "" @@ -259,7 +259,7 @@ def test_json_with_specified_encoding(): data = dict(greeting="hello", recipient="world") content = json.dumps(data).encode("utf-16") headers = {"Content-Type": "application/json, charset=utf-16"} - response = http3.Response(200, content=content, headers=headers) + response = httpx.Response(200, content=content, headers=headers) assert response.json() == data @@ -267,7 +267,7 @@ def test_json_with_options(): data = dict(greeting="hello", recipient="world", amount=1) content = json.dumps(data).encode("utf-16") headers = {"Content-Type": "application/json, charset=utf-16"} - response = http3.Response(200, content=content, headers=headers) + response = httpx.Response(200, content=content, headers=headers) assert response.json(parse_int=str)["amount"] == "1" @@ -275,7 +275,7 @@ def test_json_without_specified_encoding(): data = dict(greeting="hello", recipient="world") content = json.dumps(data).encode("utf-32-be") headers = {"Content-Type": "application/json"} - response = http3.Response(200, content=content, headers=headers) + response = httpx.Response(200, content=content, headers=headers) assert response.json() == data @@ -284,7 +284,7 @@ def test_json_without_specified_encoding_decode_error(): content = json.dumps(data).encode("utf-32-be") headers = {"Content-Type": "application/json"} # force incorrect guess from `guess_json_utf` to trigger error - with mock.patch("http3.models.guess_json_utf", return_value="utf-32"): - response = http3.Response(200, content=content, headers=headers) + with mock.patch("httpx.models.guess_json_utf", return_value="utf-32"): + response = httpx.Response(200, content=content, headers=headers) with pytest.raises(json.JSONDecodeError): response.json() diff --git a/tests/models/test_url.py b/tests/models/test_url.py index 365809bd..5f5208ca 100644 --- a/tests/models/test_url.py +++ b/tests/models/test_url.py @@ -1,4 +1,4 @@ -from http3 import URL +from httpx import URL def test_idna_url(): diff --git a/tests/test_api.py b/tests/test_api.py index 0f89e562..62582f0a 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -3,7 +3,7 @@ import functools import pytest -import http3 +import httpx def threadpool(func): @@ -25,7 +25,7 @@ def threadpool(func): @threadpool def test_get(server): - response = http3.get("http://127.0.0.1:8000/") + response = httpx.get("http://127.0.0.1:8000/") assert response.status_code == 200 assert response.reason_phrase == "OK" assert response.text == "Hello, world!" @@ -33,7 +33,7 @@ def test_get(server): @threadpool def test_post(server): - response = http3.post("http://127.0.0.1:8000/", data=b"Hello, world!") + response = httpx.post("http://127.0.0.1:8000/", data=b"Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" @@ -45,47 +45,47 @@ def test_post_byte_iterator(server): yield b", " yield b"world!" - response = http3.post("http://127.0.0.1:8000/", data=data()) + response = httpx.post("http://127.0.0.1:8000/", data=data()) assert response.status_code == 200 assert response.reason_phrase == "OK" @threadpool def test_options(server): - response = http3.options("http://127.0.0.1:8000/") + response = httpx.options("http://127.0.0.1:8000/") assert response.status_code == 200 assert response.reason_phrase == "OK" @threadpool def test_head(server): - response = http3.head("http://127.0.0.1:8000/") + response = httpx.head("http://127.0.0.1:8000/") assert response.status_code == 200 assert response.reason_phrase == "OK" @threadpool def test_put(server): - response = http3.put("http://127.0.0.1:8000/", data=b"Hello, world!") + response = httpx.put("http://127.0.0.1:8000/", data=b"Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" @threadpool def test_patch(server): - response = http3.patch("http://127.0.0.1:8000/", data=b"Hello, world!") + response = httpx.patch("http://127.0.0.1:8000/", data=b"Hello, world!") assert response.status_code == 200 assert response.reason_phrase == "OK" @threadpool def test_delete(server): - response = http3.delete("http://127.0.0.1:8000/") + response = httpx.delete("http://127.0.0.1:8000/") assert response.status_code == 200 assert response.reason_phrase == "OK" @threadpool def test_get_invalid_url(server): - with pytest.raises(http3.InvalidURL): - http3.get("invalid://example.org") + with pytest.raises(httpx.InvalidURL): + httpx.get("invalid://example.org") diff --git a/tests/test_asgi.py b/tests/test_asgi.py index 3b7d1cc0..ca3d02dd 100644 --- a/tests/test_asgi.py +++ b/tests/test_asgi.py @@ -1,6 +1,6 @@ import pytest -import http3 +import httpx async def hello_world(scope, receive, send): @@ -40,26 +40,26 @@ async def raise_exc_after_response(scope, receive, send): def test_asgi(): - client = http3.Client(app=hello_world) + client = httpx.Client(app=hello_world) response = client.get("http://www.example.org/") assert response.status_code == 200 assert response.text == "Hello, World!" def test_asgi_upload(): - client = http3.Client(app=echo_body) + client = httpx.Client(app=echo_body) response = client.post("http://www.example.org/", data=b"example") assert response.status_code == 200 assert response.text == "example" def test_asgi_exc(): - client = http3.Client(app=raise_exc) + client = httpx.Client(app=raise_exc) with pytest.raises(ValueError): client.get("http://www.example.org/") def test_asgi_exc_after_response(): - client = http3.Client(app=raise_exc_after_response) + client = httpx.Client(app=raise_exc_after_response) with pytest.raises(ValueError): client.get("http://www.example.org/") diff --git a/tests/test_config.py b/tests/test_config.py index 7a68b899..a6ef781a 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -3,12 +3,12 @@ import ssl import pytest -import http3 +import httpx @pytest.mark.asyncio async def test_load_ssl_config(): - ssl_config = http3.SSLConfig() + ssl_config = httpx.SSLConfig() context = await ssl_config.load_ssl_context() assert context.verify_mode == ssl.VerifyMode.CERT_REQUIRED assert context.check_hostname is True @@ -16,14 +16,14 @@ async def test_load_ssl_config(): @pytest.mark.asyncio async def test_load_ssl_config_verify_non_existing_path(): - ssl_config = http3.SSLConfig(verify="/path/to/nowhere") + ssl_config = httpx.SSLConfig(verify="/path/to/nowhere") with pytest.raises(IOError): await ssl_config.load_ssl_context() @pytest.mark.asyncio async def test_load_ssl_config_verify_existing_file(): - ssl_config = http3.SSLConfig(verify=http3.config.DEFAULT_CA_BUNDLE_PATH) + ssl_config = httpx.SSLConfig(verify=httpx.config.DEFAULT_CA_BUNDLE_PATH) context = await ssl_config.load_ssl_context() assert context.verify_mode == ssl.VerifyMode.CERT_REQUIRED assert context.check_hostname is True @@ -31,8 +31,8 @@ async def test_load_ssl_config_verify_existing_file(): @pytest.mark.asyncio async def test_load_ssl_config_verify_directory(): - path = os.path.dirname(http3.config.DEFAULT_CA_BUNDLE_PATH) - ssl_config = http3.SSLConfig(verify=path) + path = os.path.dirname(httpx.config.DEFAULT_CA_BUNDLE_PATH) + ssl_config = httpx.SSLConfig(verify=path) context = await ssl_config.load_ssl_context() assert context.verify_mode == ssl.VerifyMode.CERT_REQUIRED assert context.check_hostname is True @@ -40,7 +40,7 @@ async def test_load_ssl_config_verify_directory(): @pytest.mark.asyncio async def test_load_ssl_config_cert_and_key(cert_pem_file, cert_private_key_file): - ssl_config = http3.SSLConfig(cert=(cert_pem_file, cert_private_key_file)) + ssl_config = httpx.SSLConfig(cert=(cert_pem_file, cert_private_key_file)) context = await ssl_config.load_ssl_context() assert context.verify_mode == ssl.VerifyMode.CERT_REQUIRED assert context.check_hostname is True @@ -51,7 +51,7 @@ async def test_load_ssl_config_cert_and_key(cert_pem_file, cert_private_key_file async def test_load_ssl_config_cert_and_encrypted_key( cert_pem_file, cert_encrypted_private_key_file, password ): - ssl_config = http3.SSLConfig( + ssl_config = httpx.SSLConfig( cert=(cert_pem_file, cert_encrypted_private_key_file, password) ) context = await ssl_config.load_ssl_context() @@ -63,7 +63,7 @@ async def test_load_ssl_config_cert_and_encrypted_key( async def test_load_ssl_config_cert_and_key_invalid_password( cert_pem_file, cert_encrypted_private_key_file ): - ssl_config = http3.SSLConfig( + ssl_config = httpx.SSLConfig( cert=(cert_pem_file, cert_encrypted_private_key_file, "password1") ) @@ -73,29 +73,29 @@ async def test_load_ssl_config_cert_and_key_invalid_password( @pytest.mark.asyncio async def test_load_ssl_config_cert_without_key_raises(cert_pem_file): - ssl_config = http3.SSLConfig(cert=cert_pem_file) + ssl_config = httpx.SSLConfig(cert=cert_pem_file) with pytest.raises(ssl.SSLError): await ssl_config.load_ssl_context() @pytest.mark.asyncio async def test_load_ssl_config_no_verify(): - ssl_config = http3.SSLConfig(verify=False) + ssl_config = httpx.SSLConfig(verify=False) context = await ssl_config.load_ssl_context() assert context.verify_mode == ssl.VerifyMode.CERT_NONE assert context.check_hostname is False def test_ssl_repr(): - ssl = http3.SSLConfig(verify=False) + ssl = httpx.SSLConfig(verify=False) assert repr(ssl) == "SSLConfig(cert=None, verify=False)" def test_timeout_repr(): - timeout = http3.TimeoutConfig(timeout=5.0) + timeout = httpx.TimeoutConfig(timeout=5.0) assert repr(timeout) == "TimeoutConfig(timeout=5.0)" - timeout = http3.TimeoutConfig(read_timeout=5.0) + timeout = httpx.TimeoutConfig(read_timeout=5.0) assert ( repr(timeout) == "TimeoutConfig(connect_timeout=None, read_timeout=5.0, write_timeout=None)" @@ -103,32 +103,32 @@ def test_timeout_repr(): def test_limits_repr(): - limits = http3.PoolLimits(hard_limit=100) + limits = httpx.PoolLimits(hard_limit=100) assert ( repr(limits) == "PoolLimits(soft_limit=None, hard_limit=100, pool_timeout=None)" ) def test_ssl_eq(): - ssl = http3.SSLConfig(verify=False) - assert ssl == http3.SSLConfig(verify=False) + ssl = httpx.SSLConfig(verify=False) + assert ssl == httpx.SSLConfig(verify=False) def test_timeout_eq(): - timeout = http3.TimeoutConfig(timeout=5.0) - assert timeout == http3.TimeoutConfig(timeout=5.0) + timeout = httpx.TimeoutConfig(timeout=5.0) + assert timeout == httpx.TimeoutConfig(timeout=5.0) def test_limits_eq(): - limits = http3.PoolLimits(hard_limit=100) - assert limits == http3.PoolLimits(hard_limit=100) + limits = httpx.PoolLimits(hard_limit=100) + assert limits == httpx.PoolLimits(hard_limit=100) def test_timeout_from_tuple(): - timeout = http3.TimeoutConfig(timeout=(5.0, 5.0, 5.0)) - assert timeout == http3.TimeoutConfig(timeout=5.0) + timeout = httpx.TimeoutConfig(timeout=(5.0, 5.0, 5.0)) + assert timeout == httpx.TimeoutConfig(timeout=5.0) def test_timeout_from_config_instance(): - timeout = http3.TimeoutConfig(timeout=5.0) - assert http3.TimeoutConfig(timeout) == http3.TimeoutConfig(timeout=5.0) + timeout = httpx.TimeoutConfig(timeout=5.0) + assert httpx.TimeoutConfig(timeout) == httpx.TimeoutConfig(timeout=5.0) diff --git a/tests/test_decoders.py b/tests/test_decoders.py index 2e217909..49247a9f 100644 --- a/tests/test_decoders.py +++ b/tests/test_decoders.py @@ -3,7 +3,7 @@ import zlib import brotli import pytest -import http3 +import httpx def test_deflate(): @@ -12,7 +12,7 @@ def test_deflate(): compressed_body = compressor.compress(body) + compressor.flush() headers = [(b"Content-Encoding", b"deflate")] - response = http3.Response(200, headers=headers, content=compressed_body) + response = httpx.Response(200, headers=headers, content=compressed_body) assert response.content == body @@ -22,7 +22,7 @@ def test_gzip(): compressed_body = compressor.compress(body) + compressor.flush() headers = [(b"Content-Encoding", b"gzip")] - response = http3.Response(200, headers=headers, content=compressed_body) + response = httpx.Response(200, headers=headers, content=compressed_body) assert response.content == body @@ -31,7 +31,7 @@ def test_brotli(): compressed_body = brotli.compress(body) headers = [(b"Content-Encoding", b"br")] - response = http3.Response(200, headers=headers, content=compressed_body) + response = httpx.Response(200, headers=headers, content=compressed_body) assert response.content == body @@ -47,7 +47,7 @@ def test_multi(): ) headers = [(b"Content-Encoding", b"deflate, gzip")] - response = http3.Response(200, headers=headers, content=compressed_body) + response = httpx.Response(200, headers=headers, content=compressed_body) assert response.content == body @@ -56,11 +56,11 @@ def test_multi_with_identity(): compressed_body = brotli.compress(body) headers = [(b"Content-Encoding", b"br, identity")] - response = http3.Response(200, headers=headers, content=compressed_body) + response = httpx.Response(200, headers=headers, content=compressed_body) assert response.content == body headers = [(b"Content-Encoding", b"identity, br")] - response = http3.Response(200, headers=headers, content=compressed_body) + response = httpx.Response(200, headers=headers, content=compressed_body) assert response.content == body @@ -73,7 +73,7 @@ def test_streaming(): yield compressor.flush() headers = [(b"Content-Encoding", b"gzip")] - response = http3.Response(200, headers=headers, content=compress(body)) + response = httpx.Response(200, headers=headers, content=compress(body)) assert not hasattr(response, "body") assert response.read() == body @@ -83,6 +83,6 @@ def test_decoding_errors(header_value): headers = [(b"Content-Encoding", header_value)] body = b"test 123" compressed_body = brotli.compress(body)[3:] - with pytest.raises(http3.exceptions.DecodingError): - response = http3.Response(200, headers=headers, content=compressed_body) + with pytest.raises(httpx.exceptions.DecodingError): + response = httpx.Response(200, headers=headers, content=compressed_body) response.content diff --git a/tests/test_multipart.py b/tests/test_multipart.py index 4749ffa8..9a8f12c7 100644 --- a/tests/test_multipart.py +++ b/tests/test_multipart.py @@ -6,7 +6,7 @@ from unittest import mock import pytest -from http3 import ( +from httpx import ( CertTypes, Client, Dispatcher, diff --git a/tests/test_status_codes.py b/tests/test_status_codes.py index f7fe2bcd..e62b3e06 100644 --- a/tests/test_status_codes.py +++ b/tests/test_status_codes.py @@ -1,18 +1,18 @@ -import http3 +import httpx def test_status_code_as_int(): - assert http3.codes.NOT_FOUND == 404 - assert str(http3.codes.NOT_FOUND) == "404" + assert httpx.codes.NOT_FOUND == 404 + assert str(httpx.codes.NOT_FOUND) == "404" def test_lowercase_status_code(): - assert http3.codes.not_found == 404 + assert httpx.codes.not_found == 404 def test_reason_phrase_for_status_code(): - assert http3.codes.get_reason_phrase(404) == "Not Found" + assert httpx.codes.get_reason_phrase(404) == "Not Found" def test_reason_phrase_for_unknown_status_code(): - assert http3.codes.get_reason_phrase(499) == "" + assert httpx.codes.get_reason_phrase(499) == "" diff --git a/tests/test_timeouts.py b/tests/test_timeouts.py index bfced702..ab69e690 100644 --- a/tests/test_timeouts.py +++ b/tests/test_timeouts.py @@ -1,6 +1,6 @@ import pytest -from http3 import ( +from httpx import ( AsyncClient, ConnectTimeout, PoolLimits, diff --git a/tests/test_utils.py b/tests/test_utils.py index a27b9067..b2b16711 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,6 +1,6 @@ import pytest -from http3.utils import guess_json_utf +from httpx.utils import guess_json_utf @pytest.mark.parametrize( diff --git a/tests/test_wsgi.py b/tests/test_wsgi.py index 4e2a003c..0dcf9953 100644 --- a/tests/test_wsgi.py +++ b/tests/test_wsgi.py @@ -2,7 +2,7 @@ import sys import pytest -import http3 +import httpx def hello_world(environ, start_response): @@ -69,27 +69,27 @@ def raise_exc(environ, start_response): def test_wsgi(): - client = http3.Client(app=hello_world) + client = httpx.Client(app=hello_world) response = client.get("http://www.example.org/") assert response.status_code == 200 assert response.text == "Hello, World!" def test_wsgi_upload(): - client = http3.Client(app=echo_body) + client = httpx.Client(app=echo_body) response = client.post("http://www.example.org/", data=b"example") assert response.status_code == 200 assert response.text == "example" def test_wsgi_upload_with_response_stream(): - client = http3.Client(app=echo_body_with_response_stream) + client = httpx.Client(app=echo_body_with_response_stream) response = client.post("http://www.example.org/", data=b"example") assert response.status_code == 200 assert response.text == "example" def test_wsgi_exc(): - client = http3.Client(app=raise_exc) + client = httpx.Client(app=raise_exc) with pytest.raises(ValueError): client.get("http://www.example.org/")