From: Tom Christie Date: Wed, 30 Oct 2019 15:21:39 +0000 (+0000) Subject: First pass at autodoc support (#464) X-Git-Tag: 0.7.6~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1ce3cc3269eb73d28a8371906baa80a70cdc8aba;p=thirdparty%2Fhttpx.git 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 --- diff --git a/docs/api.md b/docs/api.md index 6d2897c5..12b790af 100644 --- a/docs/api.md +++ b/docs/api.md @@ -8,40 +8,35 @@ enable HTTP/2 and connection pooling for more efficient and long-lived connections. -* `get(url, [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])` -* `options(url, [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])` -* `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])` -* `put(url, [data], [files], [json], [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])` -* `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])` -* `request(method, url, [data], [files], [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout], [proxies])` -* `build_request(method, url, [data], [files], [json], [params], [headers], [cookies])` +::: httpx.request + :docstring: -## `Client` +::: httpx.get + :docstring: -*An HTTP client, with connection pooling, HTTP/2, redirects, cookie persistence, etc.* +::: httpx.options + :docstring: -```python ->>> with httpx.Client() as client: -... response = client.get('https://example.org') -``` +::: httpx.head + :docstring: -* `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()` +::: httpx.post + :docstring: + +::: httpx.put + :docstring: + +::: httpx.patch + :docstring: + +::: httpx.delete + :docstring: + +## `Client` + +::: httpx.Client + :docstring: + :members: headers cookies params request get head options post put patch delete build_request send close ## `Response` diff --git a/docs/css/custom.css b/docs/css/custom.css new file mode 100644 index 00000000..6e5d9191 --- /dev/null +++ b/docs/css/custom.css @@ -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; +} diff --git a/httpx/api.py b/httpx/api.py index 5d134b0c..82fc48dc 100644 --- a/httpx/api.py +++ b/httpx/api.py @@ -32,6 +32,51 @@ def request( stream: bool = False, trust_env: bool = None, ) -> 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 + + ``` + """ with Client(http_versions=["HTTP/1.1"]) as client: return client.request( method=method, @@ -66,6 +111,14 @@ def get( timeout: TimeoutTypes = None, trust_env: bool = None, ) -> 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( "GET", url, @@ -96,6 +149,14 @@ def options( timeout: TimeoutTypes = None, trust_env: bool = None, ) -> 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( "OPTIONS", url, @@ -126,6 +187,16 @@ def head( timeout: TimeoutTypes = None, trust_env: bool = None, ) -> 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( "HEAD", url, @@ -159,6 +230,11 @@ def post( timeout: TimeoutTypes = None, trust_env: bool = None, ) -> Response: + """ + Sends a `POST` request. + + **Parameters**: See `httpx.request`. + """ return request( "POST", url, @@ -195,6 +271,11 @@ def put( timeout: TimeoutTypes = None, trust_env: bool = None, ) -> Response: + """ + Sends a `PUT` request. + + **Parameters**: See `httpx.request`. + """ return request( "PUT", url, @@ -231,6 +312,11 @@ def patch( timeout: TimeoutTypes = None, trust_env: bool = None, ) -> Response: + """ + Sends a `PATCH` request. + + **Parameters**: See `httpx.request`. + """ return request( "PATCH", url, @@ -264,6 +350,14 @@ def delete( timeout: TimeoutTypes = None, trust_env: bool = None, ) -> 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( "DELETE", url, diff --git a/httpx/client.py b/httpx/client.py index bdf00d4a..060dad0a 100644 --- a/httpx/client.py +++ b/httpx/client.py @@ -135,6 +135,9 @@ class BaseClient: @property def headers(self) -> Headers: + """ + HTTP headers to include when sending requests. + """ return self._headers @headers.setter @@ -143,6 +146,9 @@ class BaseClient: @property def cookies(self) -> Cookies: + """ + Cookie values to include when sending requests. + """ return self._cookies @cookies.setter @@ -151,6 +157,9 @@ class BaseClient: @property def params(self) -> QueryParams: + """ + Query parameters to include in the URL when sending requests. + """ return self._params @params.setter @@ -329,6 +338,9 @@ class BaseClient: headers: HeaderTypes = None, cookies: CookieTypes = None, ) -> AsyncRequest: + """ + Build and return a request instance. + """ url = self.merge_url(url) headers = self.merge_headers(headers) cookies = self.merge_cookies(cookies) @@ -654,6 +666,52 @@ class AsyncClient(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: # Iterating over response content allocates an async environment on each step. # This is relatively cheap on asyncio, but cannot be guaranteed for all @@ -715,6 +773,51 @@ class Client(BaseClient): timeout: TimeoutTypes = None, trust_env: bool = None, ) -> 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 + + ``` + """ request = self.build_request( method=method, url=url, @@ -748,6 +851,9 @@ class Client(BaseClient): timeout: TimeoutTypes = None, trust_env: bool = None, ) -> Response: + """ + Sends a request over the network, returning a response. + """ concurrency_backend = self.concurrency_backend coroutine = self._get_response @@ -805,6 +911,14 @@ class Client(BaseClient): timeout: TimeoutTypes = None, trust_env: bool = None, ) -> 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( "GET", url, @@ -835,6 +949,14 @@ class Client(BaseClient): timeout: TimeoutTypes = None, trust_env: bool = None, ) -> 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( "OPTIONS", url, @@ -865,6 +987,16 @@ class Client(BaseClient): timeout: TimeoutTypes = None, trust_env: bool = None, ) -> 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( "HEAD", url, @@ -898,6 +1030,11 @@ class Client(BaseClient): timeout: TimeoutTypes = None, trust_env: bool = None, ) -> Response: + """ + Sends a `POST` request. + + **Parameters**: See `Client.request`. + """ return self.request( "POST", url, @@ -934,6 +1071,11 @@ class Client(BaseClient): timeout: TimeoutTypes = None, trust_env: bool = None, ) -> Response: + """ + Sends a `PUT` request. + + **Parameters**: See `Client.request`. + """ return self.request( "PUT", url, @@ -970,6 +1112,11 @@ class Client(BaseClient): timeout: TimeoutTypes = None, trust_env: bool = None, ) -> Response: + """ + Sends a `PATCH` request. + + **Parameters**: See `Client.request`. + """ return self.request( "PATCH", url, @@ -1003,6 +1150,11 @@ class Client(BaseClient): timeout: TimeoutTypes = None, trust_env: bool = None, ) -> Response: + """ + Sends a `DELETE` request. + + **Parameters**: See `Client.request`. + """ return self.request( "DELETE", url, @@ -1019,6 +1171,9 @@ class Client(BaseClient): ) def close(self) -> None: + """ + Close any open connections in the connection pool. + """ coroutine = self.dispatch.close self.concurrency_backend.run(coroutine) diff --git a/mkdocs.yml b/mkdocs.yml index f7773d3a..1e16651a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -22,4 +22,7 @@ nav: markdown_extensions: - admonition - codehilite - - pymdownx.superfences + - mkautodoc + +extra_css: + - css/custom.css diff --git a/noxfile.py b/noxfile.py index acd8fce5..ef524ebb 100644 --- a/noxfile.py +++ b/noxfile.py @@ -44,8 +44,8 @@ def check(session): @nox.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")