diff --git a/docs/connections.md b/docs/connections.md
index a442439..5698bb7 100644
--- a/docs/connections.md
+++ b/docs/connections.md
@@ -4,7 +4,9 @@ The mechanics of sending HTTP requests is dealt with by the `ConnectionPool` and
We can introspect a `Client` instance to get some visibility onto the state of the connection pool.
-```python
+
+
+```{ .python .httpx }
>>> with httpx.Client() as cli
>>> urls = [
... "https://www.wikipedia.org/",
@@ -23,6 +25,25 @@ We can introspect a `Client` instance to get some visibility onto the state of t
... # ]
```
+```{ .python .ahttpx .hidden }
+>>> async with ahttpx.Client() as cli
+>>> urls = [
+... "https://www.wikipedia.org/",
+... "https://www.theguardian.com/",
+... "https://news.ycombinator.com/",
+... ]
+... for url in urls:
+... await cli.get(url)
+... print(cli.transport)
+... #
+... print(cli.transport.connections)
+... # [
+... # ,
+... # ,
+... # ,
+... # ]
+```
+
---
## Understanding the stack
@@ -31,25 +52,46 @@ The `Client` class is responsible for handling redirects and cookies.
It also ensures that outgoing requests include a default set of headers such as `User-Agent` and `Accept-Encoding`.
-```python
-with httpx.Client() as cli:
- r = cli.request("GET", "https://www.example.com/")
+
+
+```{ .python .httpx }
+>>> with httpx.Client() as cli:
+>>> r = cli.request("GET", "https://www.example.com/")
+```
+
+```{ .python .ahttpx .hidden }
+>>> async with ahttpx.Client() as cli:
+>>> r = await cli.request("GET", "https://www.example.com/")
```
The `Client` class sends requests using a `ConnectionPool`, which is responsible for managing a pool of HTTP connections. This ensures quicker and more efficient use of resources than opening and closing a TCP connection with each request. The connection pool also handles HTTP proxying if required.
A single connection pool is able to handle multiple concurrent requests, with locking in place to ensure that the pool does not become over-saturated.
-```python
-with httpx.ConnectionPool() as pool:
- r = pool.request("GET", "https://www.example.com/")
+
+
+```{ .python .httpx }
+>>> with httpx.ConnectionPool() as pool:
+>>> r = pool.request("GET", "https://www.example.com/")
+```
+
+```{ .python .ahttpx .hidden }
+>>> async with ahttpx.ConnectionPool() as pool:
+>>> r = await pool.request("GET", "https://www.example.com/")
```
Individual HTTP connections can be managed directly with the `Connection` class. A single connection can only handle requests sequentially. Locking is provided to ensure that requests are strictly queued sequentially.
-```python
-with httpx.open_connection("https://www.example.com/") as conn:
- r = conn.request("GET", "/")
+
+
+```{ .python .httpx }
+>>> with httpx.open_connection("https://www.example.com/") as conn:
+>>> r = conn.request("GET", "/")
+```
+
+```{ .python .ahttpx .hidden }
+>>> async with ahttpx.open_connection("https://www.example.com/") as conn:
+>>> r = await conn.request("GET", "/")
```
Protocol handling is dealt with using [the `h11` package](https://h11.readthedocs.io/en/latest/), a rigorously designed HTTP/1.1 implementation which follows [the Sans-IO design pattern](https://sans-io.readthedocs.io/).
@@ -60,33 +102,61 @@ The `NetworkBackend` is responsible for managing the TCP stream, providing a raw
## ConnectionPool
-```python
+
+
+```{ .python .httpx }
>>> pool = httpx.ConnectionPool()
>>> pool
```
+```{ .python .ahttpx .hidden }
+>>> pool = ahttpx.ConnectionPool()
+>>> pool
+
+```
+
### `.request(method, url, headers=None, content=None)`
-```python
+
+
+```{ .python .httpx }
>>> with httpx.ConnectionPool() as pool:
>>> res = pool.request("GET", "https://www.example.com")
>>> res, pool
,
```
+```{ .python .ahttpx .hidden }
+>>> async with ahttpx.ConnectionPool() as pool:
+>>> res = await pool.request("GET", "https://www.example.com")
+>>> res, pool
+,
+```
+
### `.stream(method, url, headers=None, content=None)`
-```python
+
+
+```{ .python .httpx }
>>> with httpx.ConnectionPool() as pool:
>>> with pool.stream("GET", "https://www.example.com") as res:
>>> res, pool
,
```
+```{ .python .ahttpx .hidden }
+>>> with ahttpx.ConnectionPool() as pool:
+>>> with await pool.stream("GET", "https://www.example.com") as res:
+>>> res, pool
+,
+```
+
### `.send(request)`
-```python
+
+
+```{ .python .httpx }
>>> with httpx.ConnectionPool() as pool:
>>> req = httpx.Request("GET", "https://www.example.com")
>>> with pool.send(req) as res:
@@ -95,14 +165,31 @@ The `NetworkBackend` is responsible for managing the TCP stream, providing a raw
,
```
+```{ .python .ahttpx .hidden }
+>>> with ahttpx.ConnectionPool() as pool:
+>>> req = ahttpx.Request("GET", "https://www.example.com")
+>>> async with await pool.send(req) as res:
+>>> await res.read()
+>>> res, pool
+,
+```
+
### `.close()`
-```python
+
+
+```{ .python .httpx }
>>> with httpx.ConnectionPool() as pool:
>>> pool.close()
```
+```{ .python .ahttpx .hidden }
+>>> with ahttpx.ConnectionPool() as pool:
+>>> await pool.close()
+
+```
+
---
## Connection
@@ -113,23 +200,40 @@ The `NetworkBackend` is responsible for managing the TCP stream, providing a raw
## Protocol upgrades
-```python
+
+
+```{ .python .httpx }
with httpx.open_connection("https://www.example.com/") as conn:
with conn.upgrade("GET", "/feed", {"Upgrade": "WebSocket"}) as stream:
...
```
+```{ .python .ahttpx .hidden }
+async with await ahttpx.open_connection("https://www.example.com/") as conn:
+ async with await conn.upgrade("GET", "/feed", {"Upgrade": "WebSocket"}) as stream:
+ ...
+```
+
``
## Proxy `CONNECT` requests
-```python
+
+
+```{ .python .httpx }
with httpx.open_connection("http://127.0.0.1:8080") as conn:
with conn.upgrade("CONNECT", "www.encode.io:443") as stream:
stream.start_tls(ctx, hostname="www.encode.io")
...
```
+```{ .python .ahttpx .hidden }
+async with await ahttpx.open_connection("http://127.0.0.1:8080") as conn:
+ async with await conn.upgrade("CONNECT", "www.encode.io:443") as stream:
+ await stream.start_tls(ctx, hostname="www.encode.io")
+ ...
+```
+
``
---
diff --git a/docs/content-types.md b/docs/content-types.md
index 3c529dd..557ed63 100644
--- a/docs/content-types.md
+++ b/docs/content-types.md
@@ -10,12 +10,20 @@ The most common content types for upload data are...
Content can be included directly in a request by using bytes or a byte iterator and setting the appropriate `Content-Type` header.
-```python
+
+
+```{ .python .httpx }
>>> headers = {'Content-Type': 'application/json'}
->>> content = json.dumps({{"number": 123.5, "bool": [True, False], "text": "hello"})
+>>> content = json.dumps({"number": 123.5, "bool": [True, False], "text": "hello"})
>>> response = cli.put(url, headers=headers, content=content)
```
+```{ .python .ahttpx .hidden }
+>>> headers = {'Content-Type': 'application/json'}
+>>> content = json.dumps({"number": 123.5, "bool": [True, False], "text": "hello"})
+>>> response = await cli.put(url, headers=headers, content=content)
+```
+
There are also several classes provided for setting the request content. These implement either the `Content` or `StreamingContent` API, and handle constructing the content and setting the relevant headers.
* `