First pass at autodoc support (#464)

* First pass at autodoc support

* Add mkautodoc requirement for docs builds

* Linting

* pip install httpx when building docs, to make it available to mkautodoc

* Fix code example in docstring slightly

* Use latest mkautodoc to resolve rendering of code snippets in docstrings

* Fill in 'Helper functions' API docs

* First pass at documenting Client

* Add autodoc for Client

* Update to mkautodoc 0.1

* Fix typos
This commit is contained in:
Tom Christie 2019-10-30 15:21:39 +00:00 committed by Florimond Manca
parent e3140a0803
commit 1ce3cc3269
6 changed files with 291 additions and 34 deletions

View File

@ -8,40 +8,35 @@
enable HTTP/2 and connection pooling for more efficient and enable HTTP/2 and connection pooling for more efficient and
long-lived connections. long-lived connections.
* `get(url, [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])` ::: httpx.request
* `options(url, [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])` :docstring:
* `head(url, [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])`
* `post(url, [data], [files], [json], [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])` ::: httpx.get
* `put(url, [data], [files], [json], [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])` :docstring:
* `patch(url, [data], [files], [json], [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])`
* `delete(url, [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])` ::: httpx.options
* `request(method, url, [data], [files], [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])` :docstring:
* `build_request(method, url, [data], [files], [json], [params], [headers], [cookies])`
::: httpx.head
:docstring:
::: httpx.post
:docstring:
::: httpx.put
:docstring:
::: httpx.patch
:docstring:
::: httpx.delete
:docstring:
## `Client` ## `Client`
*An HTTP client, with connection pooling, HTTP/2, redirects, cookie persistence, etc.* ::: httpx.Client
:docstring:
```python :members: headers cookies params request get head options post put patch delete build_request send close
>>> with httpx.Client() as client:
... response = client.get('https://example.org')
```
* `def __init__([auth], [params], [headers], [cookies], [verify], [cert], [timeout], [pool_limits], [max_redirects], [app], [dispatch])`
* `.params` - **QueryParams**
* `.headers` - **Headers**
* `.cookies` - **Cookies**
* `def .get(url, [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])`
* `def .options(url, [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])`
* `def .head(url, [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])`
* `def .post(url, [data], [files], [json], [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])`
* `def .put(url, [data], [files], [json], [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])`
* `def .patch(url, [data], [files], [json], [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])`
* `def .delete(url, [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])`
* `def .request(method, url, [data], [files], [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])`
* `def .build_request(method, url, [data], [files], [json], [params], [headers], [cookies])`
* `def .send(request, [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])`
* `def .close()`
## `Response` ## `Response`

10
docs/css/custom.css Normal file
View File

@ -0,0 +1,10 @@
div.autodoc-docstring {
padding-left: 20px;
margin-bottom: 30px;
border-left: 5px solid rgba(230, 230, 230);
}
div.autodoc-members {
padding-left: 20px;
margin-bottom: 15px;
}

View File

@ -32,6 +32,51 @@ def request(
stream: bool = False, stream: bool = False,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends an HTTP request.
**Parameters:**
* **method** - HTTP method for the new `Request` object: `GET`, `OPTIONS`,
`HEAD`, `POST`, `PUT`, `PATCH`, or `DELETE`.
* **url** - URL for the new `Request` object.
* **params** - *(optional)* Query parameters to include in the URL, as a
string, dictionary, or list of two-tuples.
* **data** - *(optional)* Data to include in the body of the request, as a
dictionary
* **files** - *(optional)* A dictionary of upload files to include in the
body of the request.
* **json** - *(optional)* A JSON serializable object to include in the body
of the request.
* **headers** - *(optional)* Dictionary of HTTP headers to include in the
request.
* **cookies** - *(optional)* Dictionary of Cookie items to include in the
request.
* **auth** - *(optional)* An authentication class to use when sending the
request.
* **timeout** - *(optional)* The timeout configuration to use when sending
the request.
* **allow_redirects** - *(optional)* Enables or disables HTTP redirects.
* **cert** - *(optional)* Either a path to an SSL certificate file, or
two-tuple of (certificate file, key file), or a three-tuple of (certificate
file, key file, password).
* **verify** - *(optional)* Enables or disables SSL verification.
* **trust_env** - *(optional)* Enables or disables usage of environment
variables for configuration.
* **proxies** - *(optional)* A dictionary mapping HTTP protocols to proxy
URLs.
**Returns:** `Response`
Usage:
```
>>> import httpx
>>> response = httpx.request('GET', 'https://httpbin.org/get')
>>> response
<Response [200 OK]>
```
"""
with Client(http_versions=["HTTP/1.1"]) as client: with Client(http_versions=["HTTP/1.1"]) as client:
return client.request( return client.request(
method=method, method=method,
@ -66,6 +111,14 @@ def get(
timeout: TimeoutTypes = None, timeout: TimeoutTypes = None,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends a `GET` request.
**Parameters**: See `httpx.request`.
Note that the `data`, `files`, and `json` parameters are not available on
this function, as `GET` requests should not include a request body.
"""
return request( return request(
"GET", "GET",
url, url,
@ -96,6 +149,14 @@ def options(
timeout: TimeoutTypes = None, timeout: TimeoutTypes = None,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends an `OPTIONS` request.
**Parameters**: See `httpx.request`.
Note that the `data`, `files`, and `json` parameters are not available on
this function, as `OPTIONS` requests should not include a request body.
"""
return request( return request(
"OPTIONS", "OPTIONS",
url, url,
@ -126,6 +187,16 @@ def head(
timeout: TimeoutTypes = None, timeout: TimeoutTypes = None,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends a `HEAD` request.
**Parameters**: See `httpx.request`.
Note that the `data`, `files`, and `json` parameters are not available on
this function, as `HEAD` requests should not include a request body. The
`HEAD` method also differs from the other cases in that `allow_redirects`
defaults to `False`.
"""
return request( return request(
"HEAD", "HEAD",
url, url,
@ -159,6 +230,11 @@ def post(
timeout: TimeoutTypes = None, timeout: TimeoutTypes = None,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends a `POST` request.
**Parameters**: See `httpx.request`.
"""
return request( return request(
"POST", "POST",
url, url,
@ -195,6 +271,11 @@ def put(
timeout: TimeoutTypes = None, timeout: TimeoutTypes = None,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends a `PUT` request.
**Parameters**: See `httpx.request`.
"""
return request( return request(
"PUT", "PUT",
url, url,
@ -231,6 +312,11 @@ def patch(
timeout: TimeoutTypes = None, timeout: TimeoutTypes = None,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends a `PATCH` request.
**Parameters**: See `httpx.request`.
"""
return request( return request(
"PATCH", "PATCH",
url, url,
@ -264,6 +350,14 @@ def delete(
timeout: TimeoutTypes = None, timeout: TimeoutTypes = None,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends a `DELETE` request.
**Parameters**: See `httpx.request`.
Note that the `data`, `files`, and `json` parameters are not available on
this function, as `DELETE` requests should not include a request body.
"""
return request( return request(
"DELETE", "DELETE",
url, url,

View File

@ -135,6 +135,9 @@ class BaseClient:
@property @property
def headers(self) -> Headers: def headers(self) -> Headers:
"""
HTTP headers to include when sending requests.
"""
return self._headers return self._headers
@headers.setter @headers.setter
@ -143,6 +146,9 @@ class BaseClient:
@property @property
def cookies(self) -> Cookies: def cookies(self) -> Cookies:
"""
Cookie values to include when sending requests.
"""
return self._cookies return self._cookies
@cookies.setter @cookies.setter
@ -151,6 +157,9 @@ class BaseClient:
@property @property
def params(self) -> QueryParams: def params(self) -> QueryParams:
"""
Query parameters to include in the URL when sending requests.
"""
return self._params return self._params
@params.setter @params.setter
@ -329,6 +338,9 @@ class BaseClient:
headers: HeaderTypes = None, headers: HeaderTypes = None,
cookies: CookieTypes = None, cookies: CookieTypes = None,
) -> AsyncRequest: ) -> AsyncRequest:
"""
Build and return a request instance.
"""
url = self.merge_url(url) url = self.merge_url(url)
headers = self.merge_headers(headers) headers = self.merge_headers(headers)
cookies = self.merge_cookies(cookies) cookies = self.merge_cookies(cookies)
@ -654,6 +666,52 @@ class AsyncClient(BaseClient):
class Client(BaseClient): class Client(BaseClient):
"""
An HTTP client, with connection pooling, HTTP/2, redirects, cookie persistence, etc.
Usage:
```
>>> client = httpx.Client()
>>> response = client.get('https://example.org')
```
**Parameters:**
* **auth** - *(optional)* An authentication class to use when sending
requests.
* **params** - *(optional)* Query parameters to include in request URLs, as
a string, dictionary, or list of two-tuples.
* **headers** - *(optional)* Dictionary of HTTP headers to include when
sending requests.
* **cookies** - *(optional)* Dictionary of Cookie items to include when
sending requests.
* **verify** - *(optional)* Enables or disables SSL verification.
* **cert** - *(optional)* Either a path to an SSL certificate file, or
two-tuple of (certificate file, key file), or a three-tuple of (certificate
file, key file, password).
* **http_versions** - *(optional)* A list of strings of HTTP protocol
versions to use when sending requests. eg. `http_versions=["HTTP/1.1"]`
* **proxies** - *(optional)* A dictionary mapping HTTP protocols to proxy
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.
* **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
request URLs.
* **dispatch** - *(optional)* A dispatch class to use for sending requests
over the network.
* **app** - *(optional)* A WSGI or ASGI application to send requests to,
rather than sending actual network requests.
* **backend** - *(optional)* A concurrency backend to use when issuing
async requests.
* **trust_env** - *(optional)* Enables or disables usage of environment
variables for configuration.
"""
def check_concurrency_backend(self, backend: ConcurrencyBackend) -> None: def check_concurrency_backend(self, backend: ConcurrencyBackend) -> None:
# Iterating over response content allocates an async environment on each step. # Iterating over response content allocates an async environment on each step.
# This is relatively cheap on asyncio, but cannot be guaranteed for all # This is relatively cheap on asyncio, but cannot be guaranteed for all
@ -715,6 +773,51 @@ class Client(BaseClient):
timeout: TimeoutTypes = None, timeout: TimeoutTypes = None,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends an HTTP request.
**Parameters:**
* **method** - HTTP method for the new `Request` object: `GET`, `OPTIONS`,
`HEAD`, `POST`, `PUT`, `PATCH`, or `DELETE`.
* **url** - URL for the new `Request` object.
* **data** - *(optional)* Data to include in the body of the request, as a
dictionary
* **files** - *(optional)* A dictionary of upload files to include in the
body of the request.
* **json** - *(optional)* A JSON serializable object to include in the body
of the request.
* **params** - *(optional)* Query parameters to include in the URL, as a
string, dictionary, or list of two-tuples.
* **headers** - *(optional)* Dictionary of HTTP headers to include on the
request.
* **cookies** - *(optional)* Dictionary of Cookie items to include in the
request.
* **stream** - *(optional)* Enable/disable streaming responses.
* **auth** - *(optional)* An authentication class to use when sending the
request.
* **allow_redirects** - *(optional)* Enables or disables HTTP redirects.
* **cert** - *(optional)* Either a path to an SSL certificate file, or
two-tuple of (certificate file, key file), or a three-tuple of (certificate
file, key file, password).
* **verify** - *(optional)* Enables or disables SSL verification.
* **timeout** - *(optional)* The timeout configuration to use when sending
the request.
* **trust_env** - *(optional)* Enables or disables usage of environment
variables for configuration.
**Returns:** `Response`
Usage:
```
>>> import httpx
>>> client = httpx.Client()
>>> response = client.request('GET', 'https://httpbin.org/get')
>>> response
<Response [200 OK]>
```
"""
request = self.build_request( request = self.build_request(
method=method, method=method,
url=url, url=url,
@ -748,6 +851,9 @@ class Client(BaseClient):
timeout: TimeoutTypes = None, timeout: TimeoutTypes = None,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends a request over the network, returning a response.
"""
concurrency_backend = self.concurrency_backend concurrency_backend = self.concurrency_backend
coroutine = self._get_response coroutine = self._get_response
@ -805,6 +911,14 @@ class Client(BaseClient):
timeout: TimeoutTypes = None, timeout: TimeoutTypes = None,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends a `GET` request.
**Parameters**: See `Client.request`.
Note that the `data`, `files`, and `json` parameters are not available on
this function, as `GET` requests should not include a request body.
"""
return self.request( return self.request(
"GET", "GET",
url, url,
@ -835,6 +949,14 @@ class Client(BaseClient):
timeout: TimeoutTypes = None, timeout: TimeoutTypes = None,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends an `OPTIONS` request.
**Parameters**: See `Client.request`.
Note that the `data`, `files`, and `json` parameters are not available on
this function, as `OPTIONS` requests should not include a request body.
"""
return self.request( return self.request(
"OPTIONS", "OPTIONS",
url, url,
@ -865,6 +987,16 @@ class Client(BaseClient):
timeout: TimeoutTypes = None, timeout: TimeoutTypes = None,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends a `HEAD` request.
**Parameters**: See `Client.request`.
Note that the `data`, `files`, and `json` parameters are not available on
this function, as `HEAD` requests should not include a request body. The
`HEAD` method also differs from the other cases in that `allow_redirects`
defaults to `False`.
"""
return self.request( return self.request(
"HEAD", "HEAD",
url, url,
@ -898,6 +1030,11 @@ class Client(BaseClient):
timeout: TimeoutTypes = None, timeout: TimeoutTypes = None,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends a `POST` request.
**Parameters**: See `Client.request`.
"""
return self.request( return self.request(
"POST", "POST",
url, url,
@ -934,6 +1071,11 @@ class Client(BaseClient):
timeout: TimeoutTypes = None, timeout: TimeoutTypes = None,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends a `PUT` request.
**Parameters**: See `Client.request`.
"""
return self.request( return self.request(
"PUT", "PUT",
url, url,
@ -970,6 +1112,11 @@ class Client(BaseClient):
timeout: TimeoutTypes = None, timeout: TimeoutTypes = None,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends a `PATCH` request.
**Parameters**: See `Client.request`.
"""
return self.request( return self.request(
"PATCH", "PATCH",
url, url,
@ -1003,6 +1150,11 @@ class Client(BaseClient):
timeout: TimeoutTypes = None, timeout: TimeoutTypes = None,
trust_env: bool = None, trust_env: bool = None,
) -> Response: ) -> Response:
"""
Sends a `DELETE` request.
**Parameters**: See `Client.request`.
"""
return self.request( return self.request(
"DELETE", "DELETE",
url, url,
@ -1019,6 +1171,9 @@ class Client(BaseClient):
) )
def close(self) -> None: def close(self) -> None:
"""
Close any open connections in the connection pool.
"""
coroutine = self.dispatch.close coroutine = self.dispatch.close
self.concurrency_backend.run(coroutine) self.concurrency_backend.run(coroutine)

View File

@ -22,4 +22,7 @@ nav:
markdown_extensions: markdown_extensions:
- admonition - admonition
- codehilite - codehilite
- pymdownx.superfences - mkautodoc
extra_css:
- css/custom.css

View File

@ -44,8 +44,8 @@ def check(session):
@nox.session @nox.session
def docs(session): def docs(session):
session.install("--upgrade", "mkdocs", "mkdocs-material", "pymdown-extensions") session.install("--upgrade", "mkdocs", "mkdocs-material", "mkautodoc>=0.1.0")
session.install("-e", ".")
session.run("mkdocs", "build") session.run("mkdocs", "build")