Skip to content

Expose network backends as part of the public API. #695

Description

@lovelydinosaur

We should add a Network Backends section to our documentation, which documents our supported network backends.

The sort of functionality that this would allow for includes...

  • Network recording / replay.
  • In-depth debug tooling.
  • Network mocking.
  • Custom network behaviour such as handling non-standard SSL or DNS requirements.

For example...

importhttpcorefromhttpcore.backends.baseimportNetworkBackend, NetworkStreamfromhttpcore.backends.syncimportSyncBackendclassRecordingNetworkStream(NetworkStream):
def__init__(self, record_file, stream):
self.record_file=record_fileself.stream=streamdefread(self, max_bytes, timeout=None):
data=self.stream.read(max_bytes, timeout=timeout)
self.record_file.write(data)
returndatadefwrite(self, buffer, timeout=None):
self.stream.write(buffer, timeout=timeout)
defclose(self) ->None:
self.stream.close()
defstart_tls(
self,
ssl_context,
server_hostname=None,
timeout=None,
):
self.stream=self.stream.start_tls(
ssl_context, server_hostname=server_hostname, timeout=timeout
)
returnselfdefget_extra_info(self, info):
returnself.stream.get_extra_info(info)
classRecordingNetworkBackend(NetworkBackend):
def__init__(self, record_file):
self.record_file=record_fileself.backend=SyncBackend()
defconnect_tcp(
self,
host,
port,
timeout=None,
local_address=None,
) ->NetworkStream:
stream=self.backend.connect_tcp(
host, port, timeout=timeout, local_address=local_address
)
returnRecordingNetworkStream(self.record_file, stream)
defconnect_unix_socket(self, path, timeout=None) ->NetworkStream:
stream=self.backend.connect_unix_socket(path, timeout=timeout)
returnRecordingNetworkStream(self.record_file, stream)
defsleep(self, seconds: float) ->None:
self.backend.sleep(seconds)
withopen("network-recording", "wb") asrecord_file:
network_backend=RecordingNetworkBackend(record_file)
withhttpcore.ConnectionPool(network_backend=network_backend) ashttp:
http.request("GET", "https://www.example.com/")

My expectation is that documenting the network backends as public API would also push us towards a few minor naming/API changes.

Other potential benefits of exposing this API publicly...

  • Helping developers understand how httpcore is designed.
  • Exposes a set of sync/asyncio/trio network primitives, available to other packages that want to support sync+async network operations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions