base.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. from __future__ import annotations
  2. import typing
  3. from types import TracebackType
  4. from .._models import Request, Response
  5. T = typing.TypeVar("T", bound="BaseTransport")
  6. A = typing.TypeVar("A", bound="AsyncBaseTransport")
  7. __all__ = ["AsyncBaseTransport", "BaseTransport"]
  8. class BaseTransport:
  9. def __enter__(self: T) -> T:
  10. return self
  11. def __exit__(
  12. self,
  13. exc_type: type[BaseException] | None = None,
  14. exc_value: BaseException | None = None,
  15. traceback: TracebackType | None = None,
  16. ) -> None:
  17. self.close()
  18. def handle_request(self, request: Request) -> Response:
  19. """
  20. Send a single HTTP request and return a response.
  21. Developers shouldn't typically ever need to call into this API directly,
  22. since the Client class provides all the higher level user-facing API
  23. niceties.
  24. In order to properly release any network resources, the response
  25. stream should *either* be consumed immediately, with a call to
  26. `response.stream.read()`, or else the `handle_request` call should
  27. be followed with a try/finally block to ensuring the stream is
  28. always closed.
  29. Example usage:
  30. with httpx.HTTPTransport() as transport:
  31. req = httpx.Request(
  32. method=b"GET",
  33. url=(b"https", b"www.example.com", 443, b"/"),
  34. headers=[(b"Host", b"www.example.com")],
  35. )
  36. resp = transport.handle_request(req)
  37. body = resp.stream.read()
  38. print(resp.status_code, resp.headers, body)
  39. Takes a `Request` instance as the only argument.
  40. Returns a `Response` instance.
  41. """
  42. raise NotImplementedError(
  43. "The 'handle_request' method must be implemented."
  44. ) # pragma: no cover
  45. def close(self) -> None:
  46. pass
  47. class AsyncBaseTransport:
  48. async def __aenter__(self: A) -> A:
  49. return self
  50. async def __aexit__(
  51. self,
  52. exc_type: type[BaseException] | None = None,
  53. exc_value: BaseException | None = None,
  54. traceback: TracebackType | None = None,
  55. ) -> None:
  56. await self.aclose()
  57. async def handle_async_request(
  58. self,
  59. request: Request,
  60. ) -> Response:
  61. raise NotImplementedError(
  62. "The 'handle_async_request' method must be implemented."
  63. ) # pragma: no cover
  64. async def aclose(self) -> None:
  65. pass