From: Tom Christie Date: Wed, 1 May 2019 14:17:58 +0000 (+0100) Subject: Still truckin' on X-Git-Tag: 0.3.0~48 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6cb5c0de0e93bc0fa9c5cb3e220c48112f05083b;p=thirdparty%2Fhttpx.git Still truckin' on --- diff --git a/README.md b/README.md index 571f2467..0c8817a7 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,11 @@ Making a request: ```python >>> import httpcore >>> client = httpcore.Client() ->>> response = await client.get('http://example.com') +>>> response = await client.get('https://example.com') >>> response.status_code +>>> response.protocol +'HTTP/2' >>> response.text '\n\n\nExample Domain\n...' ``` @@ -48,9 +50,11 @@ Alternatively, thread-synchronous requests: ```python >>> import httpcore >>> client = httpcore.SyncClient() ->>> response = client.get('http://example.com') +>>> response = client.get('https://example.com') >>> response.status_code +>>> response.protocol +'HTTP/2' >>> response.text '\n\n\nExample Domain\n...' ``` @@ -61,22 +65,24 @@ Alternatively, thread-synchronous requests: #### `Client([ssl], [timeout], [pool_limits], [max_redirects])` -* `.request(method, url, ...)` -* `.get(url, ...)` -* `.options(url, ...)` -* `.head(url, ...)` -* `.post(url, ...)` -* `.put(url, ...)` -* `.patch(url, ...)` -* `.delete(url, ...)` -* `.prepare_request(request)` -* `.send(request, ...)` -* `.close()` +* `async def .request(method, url, ...)` +* `async def .get(url, ...)` +* `async def .options(url, ...)` +* `async def .head(url, ...)` +* `async def .post(url, ...)` +* `async def .put(url, ...)` +* `async def .patch(url, ...)` +* `async def .delete(url, ...)` +* `def .prepare_request(request)` +* `async def .send(request, ...)` +* `async def .close()` ### Models #### `Response(...)` +*An HTTP response.** + * `.status_code` - **int** * `.reason_phrase` - **str** * `.protocol` - `"HTTP/2"` or `"HTTP/1.1"` @@ -89,9 +95,6 @@ Alternatively, thread-synchronous requests: * `.request` - **Request** * `.cookies` - **Cookies** *TODO* * `.history` - **List[Response]** - -Methods: - * `def .raise_for_status()` - **Response** *TODO* * `def .json()` - **Any** *TODO* * `async def .read()` - **bytes** @@ -102,6 +105,14 @@ Methods: #### `Request(method, url, content, headers)` +*An HTTP request. Can be constructed explicitly for more control over exactly +what gets sent over the wire.* + +```python +>>> request = Request("GET", "http://example.org", headers={'host': 'example.org'}) +>>> response = await client.send(request) +``` + * `.method` - **str** (Uppercased) * `.url` - **URL** * `.content` - **byte** or **byte async iterator** @@ -123,9 +134,6 @@ Methods: * `.origin` - **Origin** * `.is_absolute_url` - **bool** * `.is_relative_url` - **bool** - -Methods: - * `def .copy_with([scheme], [authority], [path], [query], [fragment])` - **URL** * `def .resolve_with(url)` - **URL** diff --git a/httpcore/models.py b/httpcore/models.py index 72a52e27..267c1ce3 100644 --- a/httpcore/models.py +++ b/httpcore/models.py @@ -421,6 +421,11 @@ class Request: for item in reversed(auto_headers): self.headers.raw.insert(0, item) + def __repr__(self) -> str: + class_name = self.__class__.__name__ + url = str(self.url) + return f"<{class_name}({self.method}, {url})>" + class Response: def __init__( @@ -437,7 +442,7 @@ class Response: ): try: # Use a StatusCode IntEnum if possible, for a nicer representation. - self.status_code = codes(status_code) + self.status_code = codes(status_code) # type: int except ValueError: self.status_code = status_code self.reason_phrase = reason_phrase or get_reason_phrase(status_code) @@ -619,3 +624,7 @@ class Response: ) and "location" in self.headers ) + + def __repr__(self) -> str: + class_name = self.__class__.__name__ + return f"<{class_name}(status_code={self.status_code})>" diff --git a/httpcore/sync.py b/httpcore/sync.py index 63fdf9ff..300c276b 100644 --- a/httpcore/sync.py +++ b/httpcore/sync.py @@ -36,6 +36,10 @@ class SyncResponse: def reason_phrase(self) -> str: return self._response.reason_phrase + @property + def protocol(self) -> typing.Optional[str]: + return self._response.protocol + @property def headers(self) -> Headers: return self._response.headers @@ -70,6 +74,10 @@ class SyncResponse: def close(self) -> None: return self._loop.run_until_complete(self._response.close()) + def __repr__(self) -> str: + class_name = self.__class__.__name__ + return f"<{class_name}(status_code={self.status_code})>" + class SyncClient: def __init__( @@ -99,19 +107,16 @@ class SyncClient: ssl: SSLConfig = None, timeout: TimeoutConfig = None, ) -> SyncResponse: - response = self._loop.run_until_complete( - self._client.request( - method, - url, - content=content, - headers=headers, - stream=stream, - allow_redirects=allow_redirects, - ssl=ssl, - timeout=timeout, - ) + request = Request(method, url, headers=headers, content=content) + self.prepare_request(request) + response = self.send( + request, + stream=stream, + allow_redirects=allow_redirects, + ssl=ssl, + timeout=timeout, ) - return SyncResponse(response, self._loop) + return response def get( self, @@ -261,6 +266,29 @@ class SyncClient: timeout=timeout, ) + def prepare_request(self, request: Request) -> None: + self._client.prepare_request(request) + + def send( + self, + request: Request, + *, + stream: bool = False, + allow_redirects: bool = True, + ssl: SSLConfig = None, + timeout: TimeoutConfig = None, + ) -> SyncResponse: + response = self._loop.run_until_complete( + self._client.send( + request, + stream=stream, + allow_redirects=allow_redirects, + ssl=ssl, + timeout=timeout, + ) + ) + return SyncResponse(response, self._loop) + def close(self) -> None: self._loop.run_until_complete(self._client.close())