Servers API

Network server module.


Abstract Base Classes

Network server interfaces definition module.

class easynetwork.servers.abc.AbstractAsyncNetworkServer

Bases: object

The base class for an asynchronous network server.

async __aenter__() Self

Calls server_activate().

Return type:

Self

async __aexit__(exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None) None

Calls server_close().

abstractmethod is_serving() bool

Checks whether the server is up (is_listening() returns True) and accepting new clients.

Return type:

bool

abstractmethod async serve_forever(*, is_up_event: SupportsEventSet | None = ...) None

Starts the server’s main loop.

Further calls to is_serving() will return True until the loop is stopped.

Parameters:

is_up_event (SupportsEventSet | None) – If given, will be triggered when the server is ready to accept new clients.

Raises:
abstractmethod is_listening() bool

Checks whether the server is up.

Return type:

bool

abstractmethod async server_activate() None

Opens all listeners.

This method MUST be idempotent. Further calls to is_listening() will return True.

Raises:

ServerClosedError – The server is closed.

abstractmethod async server_close() None

Closes the server.

abstractmethod async shutdown() None

Asks for the server to stop.

All active client tasks will be cancelled.

Warning

Do not call this method in the serve_forever() task; it will cause a deadlock.

abstractmethod backend() AsyncBackend
Returns:

The backend implementation linked to this server.

Return type:

AsyncBackend

class easynetwork.servers.abc.AbstractNetworkServer

Bases: object

The base class for a network server.

abstractmethod is_serving() bool

Checks whether the server is up and accepting new clients. Thread-safe.

Return type:

bool

abstractmethod serve_forever(*, is_up_event: SupportsEventSet | None = ...) None

Starts the server’s main loop.

Parameters:

is_up_event (SupportsEventSet | None) – If given, will be triggered when the server is ready to accept new clients.

Raises:
abstractmethod server_close() None

Closes the server. Thread-safe.

abstractmethod shutdown(timeout: float | None = ...) None

Asks for the server to stop. Thread-safe.

All active client tasks will be cancelled.

Warning

Do not call this method in the serve_forever() thread; it will cause a deadlock.

Parameters:

timeout (float | None) – The maximum amount of seconds to wait.

protocol easynetwork.servers.abc.SupportsEventSet

Bases: Protocol

A threading.Event-like object.

Classes that implement this protocol must have the following methods / attributes:

abstractmethod set() None

Notifies that the event has happened.

This method MUST be idempotent.

Asynchronous Server Objects (async def)

TCP Implementation

Asynchronous TCP Network server implementation module.

class easynetwork.servers.async_tcp.AsyncTCPNetworkServer

Bases: AbstractAsyncNetworkServer, Generic[_T_Request, _T_Response]

An asynchronous network server for TCP connections.

__init__(host: str | None | Sequence[str], port: int, protocol: AnyStreamProtocolType[_T_Response, _T_Request], request_handler: AsyncStreamRequestHandler[_T_Request, _T_Response], backend: AsyncBackend | BuiltinAsyncBackendLiteral | None = None, *, ssl: SSLContext | None = None, ssl_handshake_timeout: float | None = None, ssl_shutdown_timeout: float | None = None, ssl_standard_compatible: bool | None = None, backlog: int | None = None, reuse_port: bool = False, max_recv_size: int | None = None, log_client_connection: bool | None = None, logger: logging.Logger | None = None) None
Parameters:
  • host (str | None | Sequence[str]) –

    Can be set to several types which determine where the server would be listening:

    • If host is a string, the TCP server is bound to a single network interface specified by host.

    • If host is a sequence of strings, the TCP server is bound to all network interfaces specified by the sequence.

    • If host is None, all interfaces are assumed and a list of multiple sockets will be returned (most likely one for IPv4 and another one for IPv6).

  • port (int) – specify which port the server should listen on. If the value is 0, a random unused port will be selected (note that if host resolves to multiple network interfaces, a different random port will be selected for each interface).

  • protocol (AnyStreamProtocolType[_T_Response, _T_Request]) – The protocol object to use.

  • request_handler (AsyncStreamRequestHandler[_T_Request, _T_Response]) – The request handler to use.

  • backend (AsyncBackend | BuiltinAsyncBackendLiteral | None) – The asynchronous backend interface to use.

Keyword Arguments:
  • ssl – can be set to an ssl.SSLContext instance to enable TLS over the accepted connections.

  • ssl_handshake_timeout – (for a TLS connection) the time in seconds to wait for the TLS handshake to complete before aborting the connection. 60.0 seconds if None (default).

  • ssl_shutdown_timeout – the time in seconds to wait for the SSL shutdown to complete before aborting the connection. 30.0 seconds if None (default).

  • ssl_standard_compatible – if False, skip the closing handshake when closing the connection, and don’t raise an exception if the peer does the same.

  • backlog – is the maximum number of queued connections passed to listen (defaults to 100).

  • reuse_port – Tells the kernel to allow this endpoint to be bound to the same port as other existing endpoints are bound to, so long as they all set this flag when being created. This option is not supported on Windows and some Unixes. If the SO_REUSEPORT constant is not defined then this capability is unsupported.

  • max_recv_size – Read buffer size. If not given, a default reasonable value is used.

  • log_client_connection – If True, log clients connection/disconnection in logging.INFO level. (This log will always be available in logging.DEBUG level.)

  • logger – If given, the logger instance to use.

get_addresses() Sequence[IPv4SocketAddress | IPv6SocketAddress]

Returns all interfaces to which the server is bound.

Returns:

A sequence of socket address. If the server is not serving (is_serving() returns False), an empty sequence is returned.

Return type:

Sequence[IPv4SocketAddress | IPv6SocketAddress]

get_sockets() Sequence[SocketProxy]

Gets the listeners sockets.

Returns:

a read-only sequence of SocketProxy objects.

If the server is not running, an empty sequence is returned.

Return type:

Sequence[SocketProxy]

backend() AsyncBackend
Returns:

The backend implementation linked to this server.

Return type:

AsyncBackend

is_listening() bool

Checks whether the server is up.

Return type:

bool

is_serving() bool

Checks whether the server is up (is_listening() returns True) and accepting new clients.

Return type:

bool

async serve_forever(*, is_up_event: SupportsEventSet | None = None) None

Starts the server’s main loop.

Further calls to is_serving() will return True until the loop is stopped.

Parameters:

is_up_event (SupportsEventSet | None) – If given, will be triggered when the server is ready to accept new clients.

Raises:
async server_activate() None

Opens all listeners.

This method is idempotent. Further calls to is_listening() will return True.

Raises:

ServerClosedError – The server is closed.

async server_close() None

Closes the server.

async shutdown() None

Asks for the server to stop.

All active client tasks will be cancelled.

Warning

Do not call this method in the serve_forever() task; it will cause a deadlock.

UDP Implementation

Asynchronous UDP Network server implementation module.

class easynetwork.servers.async_udp.AsyncUDPNetworkServer

Bases: AbstractAsyncNetworkServer, Generic[_T_Request, _T_Response]

An asynchronous network server for UDP communication.

__init__(host: str | None | Sequence[str], port: int, protocol: DatagramProtocol[_T_Response, _T_Request], request_handler: AsyncDatagramRequestHandler[_T_Request, _T_Response], backend: AsyncBackend | Literal['asyncio', 'trio'] | None = None, *, reuse_port: bool = False, logger: Logger | None = None) None
Parameters:
  • host (str | None | Sequence[str]) – specify which network interface to which the server should bind.

  • port (int) – specify which port the server should listen on. If the value is 0, a random unused port will be selected (note that if host resolves to multiple network interfaces, a different random port will be selected for each interface).

  • protocol (DatagramProtocol[_T_Response, _T_Request]) – The protocol object to use.

  • request_handler (AsyncDatagramRequestHandler[_T_Request, _T_Response]) – The request handler to use.

  • backend (AsyncBackend | Literal['asyncio', 'trio'] | None) – The asynchronous backend interface to use.

Keyword Arguments:
  • reuse_port – Tells the kernel to allow this endpoint to be bound to the same port as other existing endpoints are bound to, so long as they all set this flag when being created. This option is not supported on Windows and some Unixes. If the SO_REUSEPORT constant is not defined then this capability is unsupported.

  • logger – If given, the logger instance to use.

get_addresses() Sequence[IPv4SocketAddress | IPv6SocketAddress]

Returns all interfaces to which the server is bound.

Returns:

A sequence of socket address. If the server is not serving (is_serving() returns False), an empty sequence is returned.

Return type:

Sequence[IPv4SocketAddress | IPv6SocketAddress]

get_sockets() Sequence[SocketProxy]

Gets the listeners sockets.

Returns:

a read-only sequence of SocketProxy objects.

If the server is not running, an empty sequence is returned.

Return type:

Sequence[SocketProxy]

backend() AsyncBackend
Returns:

The backend implementation linked to this server.

Return type:

AsyncBackend

is_listening() bool

Checks whether the server is up.

Return type:

bool

is_serving() bool

Checks whether the server is up (is_listening() returns True) and accepting new clients.

Return type:

bool

async serve_forever(*, is_up_event: SupportsEventSet | None = None) None

Starts the server’s main loop.

Further calls to is_serving() will return True until the loop is stopped.

Parameters:

is_up_event (SupportsEventSet | None) – If given, will be triggered when the server is ready to accept new clients.

Raises:
async server_activate() None

Opens all listeners.

This method is idempotent. Further calls to is_listening() will return True.

Raises:

ServerClosedError – The server is closed.

async server_close() None

Closes the server.

async shutdown() None

Asks for the server to stop.

All active client tasks will be cancelled.

Warning

Do not call this method in the serve_forever() task; it will cause a deadlock.

UNIX Stream Implementation

Asynchronous Unix stream server implementation module.

Added in version 1.1.

class easynetwork.servers.async_unix_stream.AsyncUnixStreamServer

Bases: AbstractAsyncNetworkServer, Generic[_T_Request, _T_Response]

An asynchronous Unix stream server.

Added in version 1.1.

__init__(path: str | PathLike[str] | bytes | UnixSocketAddress, protocol: StreamProtocol[_T_Response, _T_Request] | BufferedStreamProtocol[_T_Response, _T_Request, Any], request_handler: AsyncStreamRequestHandler[_T_Request, _T_Response], backend: AsyncBackend | Literal['asyncio', 'trio'] | None = None, *, backlog: int | None = None, mode: int | None = None, max_recv_size: int | None = None, log_client_connection: bool | None = None, logger: Logger | None = None) None
Parameters:
Keyword Arguments:
  • backlog – is the maximum number of queued connections passed to listen (defaults to 100).

  • mode – Permissions to set on the socket.

  • max_recv_size – Read buffer size. If not given, a default reasonable value is used.

  • log_client_connection – If True, log clients connection/disconnection in logging.INFO level. (This log will always be available in logging.DEBUG level.)

  • logger – If given, the logger instance to use.

get_addresses() Sequence[UnixSocketAddress]

Returns all interfaces to which the server is bound.

Returns:

A sequence of socket address. If the server is not serving (is_serving() returns False), an empty sequence is returned.

Return type:

Sequence[UnixSocketAddress]

get_sockets() Sequence[SocketProxy]

Gets the listeners sockets.

Returns:

a read-only sequence of SocketProxy objects.

If the server is not running, an empty sequence is returned.

Return type:

Sequence[SocketProxy]

backend() AsyncBackend
Returns:

The backend implementation linked to this server.

Return type:

AsyncBackend

is_listening() bool

Checks whether the server is up.

Return type:

bool

is_serving() bool

Checks whether the server is up (is_listening() returns True) and accepting new clients.

Return type:

bool

async serve_forever(*, is_up_event: SupportsEventSet | None = None) None

Starts the server’s main loop.

Further calls to is_serving() will return True until the loop is stopped.

Parameters:

is_up_event (SupportsEventSet | None) – If given, will be triggered when the server is ready to accept new clients.

Raises:
async server_activate() None

Opens all listeners.

This method is idempotent. Further calls to is_listening() will return True.

Raises:

ServerClosedError – The server is closed.

async shutdown() None

Asks for the server to stop.

All active client tasks will be cancelled.

Warning

Do not call this method in the serve_forever() task; it will cause a deadlock.

UNIX Datagram Implementation

Asynchronous Unix datagram server implementation module.

Added in version 1.1.

class easynetwork.servers.async_unix_datagram.AsyncUnixDatagramServer

Bases: AbstractAsyncNetworkServer, Generic[_T_Request, _T_Response]

An asynchronous Unix datagram server.

Added in version 1.1.

__init__(path: str | PathLike[str] | bytes | UnixSocketAddress, protocol: DatagramProtocol[_T_Response, _T_Request], request_handler: AsyncDatagramRequestHandler[_T_Request, _T_Response], backend: AsyncBackend | Literal['asyncio', 'trio'] | None = None, *, mode: int | None = None, unnamed_addresses_behavior: Literal['ignore', 'handle', 'warn'] | None = None, logger: Logger | None = None) None
Parameters:
Keyword Arguments:
  • mode – Permissions to set on the socket.

  • unnamed_addresses_behavior

    Defines what to do when receiving datagrams sent from unbound datagram sockets:

    • "ignore" (the default): Silently drop the datagram.

    • "handle": Act as a normal reception.

    • "warn": Drop the datagram and issue a WARNING log.

  • logger – If given, the logger instance to use.

get_addresses() Sequence[UnixSocketAddress]

Returns all interfaces to which the server is bound.

Returns:

A sequence of socket address. If the server is not serving (is_serving() returns False), an empty sequence is returned.

Return type:

Sequence[UnixSocketAddress]

get_sockets() Sequence[SocketProxy]

Gets the listeners sockets.

Returns:

a read-only sequence of SocketProxy objects.

If the server is not running, an empty sequence is returned.

Return type:

Sequence[SocketProxy]

backend() AsyncBackend
Returns:

The backend implementation linked to this server.

Return type:

AsyncBackend

is_listening() bool

Checks whether the server is up.

Return type:

bool

is_serving() bool

Checks whether the server is up (is_listening() returns True) and accepting new clients.

Return type:

bool

async serve_forever(*, is_up_event: SupportsEventSet | None = None) None

Starts the server’s main loop.

Further calls to is_serving() will return True until the loop is stopped.

Parameters:

is_up_event (SupportsEventSet | None) – If given, will be triggered when the server is ready to accept new clients.

Raises:
async server_activate() None

Opens all listeners.

This method is idempotent. Further calls to is_listening() will return True.

Raises:

ServerClosedError – The server is closed.

async shutdown() None

Asks for the server to stop.

All active client tasks will be cancelled.

Warning

Do not call this method in the serve_forever() task; it will cause a deadlock.

Synchronous Server Objects

TCP Implementation

TCP Network server implementation module.

class easynetwork.servers.standalone_tcp.StandaloneTCPNetworkServer

Bases: AbstractNetworkServer, Generic[_T_Request, _T_Response]

A network server for TCP connections.

It embeds an AsyncTCPNetworkServer instance.

__init__(host: str | None | Sequence[str], port: int, protocol: AnyStreamProtocolType[_T_Response, _T_Request], request_handler: AsyncStreamRequestHandler[_T_Request, _T_Response], backend: AsyncBackend | BuiltinAsyncBackendLiteral | None = None, *, runner_options: Mapping[str, Any] | None = None, ssl: _SSLContext | None = None, ssl_handshake_timeout: float | None = None, ssl_shutdown_timeout: float | None = None, ssl_standard_compatible: bool | None = None, backlog: int | None = None, reuse_port: bool = False, max_recv_size: int | None = None, log_client_connection: bool | None = None, logger: logging.Logger | None = None) None

For the other arguments, see AsyncTCPNetworkServer documentation.

Parameters:
get_addresses() Sequence[IPv4SocketAddress | IPv6SocketAddress]

Returns all interfaces to which the server is bound. Thread-safe.

Returns:

A sequence of socket address. If the server is not serving (is_serving() returns False), an empty sequence is returned.

Return type:

Sequence[IPv4SocketAddress | IPv6SocketAddress]

get_sockets() Sequence[SocketProxy]

Gets the listeners sockets. Thread-safe.

Returns:

a read-only sequence of SocketProxy objects.

If the server is not running, an empty sequence is returned.

Return type:

Sequence[SocketProxy]

is_serving() bool

Checks whether the server is up and accepting new clients. Thread-safe.

Return type:

bool

serve_forever(*, is_up_event: SupportsEventSet | None = None, runner_options: Mapping[str, Any] | None = None) None

Starts the server’s main loop.

Parameters:
  • is_up_event (SupportsEventSet | None) – If given, will be triggered when the server is ready to accept new clients.

  • runner_options (Mapping[str, Any] | None) – Options to pass to the AsyncBackend.bootstrap() method. The specified keys override the keys passed at initialization.

Raises:
server_close() None

Closes the server. Thread-safe.

shutdown(timeout: float | None = None) None

Asks for the server to stop. Thread-safe.

All active client tasks will be cancelled.

Warning

Do not call this method in the serve_forever() thread; it will cause a deadlock.

Parameters:

timeout (float | None) – The maximum amount of seconds to wait.

UDP Implementation

UDP Network server implementation module.

class easynetwork.servers.standalone_udp.StandaloneUDPNetworkServer

Bases: AbstractNetworkServer, Generic[_T_Request, _T_Response]

A network server for UDP communication.

It embeds an AsyncUDPNetworkServer instance.

__init__(host: str | None | Sequence[str], port: int, protocol: DatagramProtocol[_T_Response, _T_Request], request_handler: AsyncDatagramRequestHandler[_T_Request, _T_Response], backend: AsyncBackend | Literal['asyncio', 'trio'] | None = None, *, runner_options: Mapping[str, Any] | None = None, reuse_port: bool = False, logger: Logger | None = None) None

For the other arguments, see AsyncUDPNetworkServer documentation.

Parameters:
get_addresses() Sequence[IPv4SocketAddress | IPv6SocketAddress]

Returns all interfaces to which the server is bound. Thread-safe.

Returns:

A sequence of socket address. If the server is not serving (is_serving() returns False), an empty sequence is returned.

Return type:

Sequence[IPv4SocketAddress | IPv6SocketAddress]

get_sockets() Sequence[SocketProxy]

Gets the listeners sockets. Thread-safe.

Returns:

a read-only sequence of SocketProxy objects.

If the server is not running, an empty sequence is returned.

Return type:

Sequence[SocketProxy]

is_serving() bool

Checks whether the server is up and accepting new clients. Thread-safe.

Return type:

bool

serve_forever(*, is_up_event: SupportsEventSet | None = None, runner_options: Mapping[str, Any] | None = None) None

Starts the server’s main loop.

Parameters:
  • is_up_event (SupportsEventSet | None) – If given, will be triggered when the server is ready to accept new clients.

  • runner_options (Mapping[str, Any] | None) – Options to pass to the AsyncBackend.bootstrap() method. The specified keys override the keys passed at initialization.

Raises:
server_close() None

Closes the server. Thread-safe.

shutdown(timeout: float | None = None) None

Asks for the server to stop. Thread-safe.

All active client tasks will be cancelled.

Warning

Do not call this method in the serve_forever() thread; it will cause a deadlock.

Parameters:

timeout (float | None) – The maximum amount of seconds to wait.

UNIX Stream Implementation

Unix stream server implementation module.

Added in version 1.1.

class easynetwork.servers.standalone_unix_stream.StandaloneUnixStreamServer

Bases: AbstractNetworkServer, Generic[_T_Request, _T_Response]

A Unix stream server.

It embeds an AsyncUnixStreamServer instance.

Added in version 1.1.

__init__(path: str | PathLike[str] | bytes | UnixSocketAddress, protocol: StreamProtocol[_T_Response, _T_Request] | BufferedStreamProtocol[_T_Response, _T_Request, Any], request_handler: AsyncStreamRequestHandler[_T_Request, _T_Response], backend: AsyncBackend | Literal['asyncio', 'trio'] | None = None, *, runner_options: Mapping[str, Any] | None = None, backlog: int | None = None, mode: int | None = None, max_recv_size: int | None = None, log_client_connection: bool | None = None, logger: Logger | None = None) None

For the other arguments, see AsyncUnixStreamServer documentation.

Parameters:
get_addresses() Sequence[UnixSocketAddress]

Returns all interfaces to which the server is bound. Thread-safe.

Returns:

A sequence of socket address. If the server is not serving (is_serving() returns False), an empty sequence is returned.

Return type:

Sequence[UnixSocketAddress]

get_sockets() Sequence[SocketProxy]

Gets the listeners sockets. Thread-safe.

Returns:

a read-only sequence of SocketProxy objects.

If the server is not running, an empty sequence is returned.

Return type:

Sequence[SocketProxy]

is_serving() bool

Checks whether the server is up and accepting new clients. Thread-safe.

Return type:

bool

serve_forever(*, is_up_event: SupportsEventSet | None = None, runner_options: Mapping[str, Any] | None = None) None

Starts the server’s main loop.

Parameters:
  • is_up_event (SupportsEventSet | None) – If given, will be triggered when the server is ready to accept new clients.

  • runner_options (Mapping[str, Any] | None) – Options to pass to the AsyncBackend.bootstrap() method. The specified keys override the keys passed at initialization.

Raises:
server_close() None

Closes the server. Thread-safe.

shutdown(timeout: float | None = None) None

Asks for the server to stop. Thread-safe.

All active client tasks will be cancelled.

Warning

Do not call this method in the serve_forever() thread; it will cause a deadlock.

Parameters:

timeout (float | None) – The maximum amount of seconds to wait.

UNIX Datagram Implementation

Unix datagram server implementation module.

Added in version 1.1.

class easynetwork.servers.standalone_unix_datagram.StandaloneUnixDatagramServer

Bases: AbstractNetworkServer, Generic[_T_Request, _T_Response]

A Unix datagram server.

It embeds an AsyncUnixDatagramServer instance.

Added in version 1.1.

__init__(path: str | PathLike[str] | bytes | UnixSocketAddress, protocol: DatagramProtocol[_T_Response, _T_Request], request_handler: AsyncDatagramRequestHandler[_T_Request, _T_Response], backend: AsyncBackend | Literal['asyncio', 'trio'] | None = None, *, runner_options: Mapping[str, Any] | None = None, mode: int | None = None, unnamed_addresses_behavior: Literal['ignore', 'handle', 'warn'] | None = None, logger: Logger | None = None) None

For the other arguments, see AsyncUnixDatagramServer documentation.

Parameters:
get_addresses() Sequence[UnixSocketAddress]

Returns all interfaces to which the server is bound. Thread-safe.

Returns:

A sequence of socket address. If the server is not serving (is_serving() returns False), an empty sequence is returned.

Return type:

Sequence[UnixSocketAddress]

get_sockets() Sequence[SocketProxy]

Gets the listeners sockets. Thread-safe.

Returns:

a read-only sequence of SocketProxy objects.

If the server is not running, an empty sequence is returned.

Return type:

Sequence[SocketProxy]

is_serving() bool

Checks whether the server is up and accepting new clients. Thread-safe.

Return type:

bool

serve_forever(*, is_up_event: SupportsEventSet | None = None, runner_options: Mapping[str, Any] | None = None) None

Starts the server’s main loop.

Parameters:
  • is_up_event (SupportsEventSet | None) – If given, will be triggered when the server is ready to accept new clients.

  • runner_options (Mapping[str, Any] | None) – Options to pass to the AsyncBackend.bootstrap() method. The specified keys override the keys passed at initialization.

Raises:
server_close() None

Closes the server. Thread-safe.

shutdown(timeout: float | None = None) None

Asks for the server to stop. Thread-safe.

All active client tasks will be cancelled.

Warning

Do not call this method in the serve_forever() thread; it will cause a deadlock.

Parameters:

timeout (float | None) – The maximum amount of seconds to wait.

Request Handler Interface

Asynchronous network servers’ request handler base classes module.

class easynetwork.servers.handlers.AsyncStreamRequestHandler

Bases: Generic[_T_Request, _T_Response]

The base class for a stream request handler, used by TCP network servers.

async service_init(exit_stack: AsyncExitStack, server: Any, /) None

Called at server startup. The default implementation does nothing.

Parameters:
abstractmethod handle(client: AsyncStreamClient[_T_Response], /) AsyncGenerator[float | None, _T_Request]

This function must do all the work required to service a request.

It is an asynchronous generator function:

async def handle(self, client):
    request = yield

    # Do some stuff
    ...

    await client.send_packet(response)

handle() can yield whenever a request from the client is needed.

The generator is started immediately after on_connection(). When the generator returns, a new generator is created and started immediately after.

The generator does not represent the client life time, await client.aclose() must be called explicitly.

Note

There is one exception: if the generator returns before the first yield statement, the connection is forcibly closed.

Parameters:

client (AsyncStreamClient[_T_Response]) – An interface to communicate with the remote endpoint.

Yields:

None or a number interpreted as the timeout delay.

Return type:

AsyncGenerator[float | None, _T_Request]

on_connection(client: AsyncStreamClient[_T_Response], /) Coroutine[Any, Any, None] | AsyncGenerator[float | None, _T_Request]

Called once the client is connected to perform any initialization actions required. The default implementation does nothing.

It can be either a coroutine function:

async def on_connection(self, client):
    # Do some stuff
    ...

or an asynchronous generator function:

async def on_connection(self, client):
    # Do some stuff
    ...

    initial_info = yield

    # Finish initialization
    ...

In the latter case, as for handle(), on_connection() can yield whenever a request from the client is needed.

Parameters:

client (AsyncStreamClient[_T_Response]) – An interface to communicate with the remote endpoint.

Yields:

If it is an asynchronous generator, None or a number interpreted as the timeout delay.

Return type:

Coroutine[Any, Any, None] | AsyncGenerator[float | None, _T_Request]

async on_disconnection(client: AsyncStreamClient[_T_Response], /) None

Called once the client is disconnected to perform any clean-up actions required. The default implementation does nothing.

This function will not be called in the following conditions:

Important

AsyncStreamClient.is_closing() should return True when this function is called. However, if handle() raises an exception, the client task is shut down and the connection is forcibly closed after on_disconnection() is called.

This behavior allows you to notify the client that something unusual has occurred.

Parameters:

client (AsyncStreamClient[_T_Response]) – An interface to communicate with the remote endpoint.

class easynetwork.servers.handlers.AsyncDatagramRequestHandler

Bases: Generic[_T_Request, _T_Response]

The base class for a datagram request handler, used by UDP network servers.

async service_init(exit_stack: AsyncExitStack, server: Any, /) None

Called at server startup. The default implementation does nothing.

Parameters:
abstractmethod handle(client: AsyncDatagramClient[_T_Response], /) AsyncGenerator[float | None, _T_Request]

This function must do all the work required to service a request.

It is an asynchronous generator function:

async def handle(self, client):
    request = yield

    # Do some stuff
    ...

    await client.send_packet(response)

handle() can yield whenever a request from the client is needed.

Warning

UDP does not guarantee ordered delivery. Packets are typically “sent” in order, but they may be received out of order. In large networks, it is reasonably common for some packets to arrive out of sequence (or not at all).

Since there is no connection management, the generator is started when the datagram is received. When the generator returns, a new generator is created and started when a new datagram is received.

Important

There will always be only one active generator per client. All the pending datagrams received while the generator is running are queued.

This behavior is designed to act like a stream request handler.

Note

If the generator returns before the first yield statement, the received datagram is discarded.

This is useful when a client that you do not expect to see sends something; the datagrams are parsed only when the generator hits a yield statement.

Parameters:

client (AsyncDatagramClient[_T_Response]) – An interface to communicate with the remote endpoint.

Yields:

None or a number interpreted as the timeout delay.

Return type:

AsyncGenerator[float | None, _T_Request]

Client API

class easynetwork.servers.handlers.AsyncBaseClientInterface

Bases: TypedAttributeProvider, Generic[_T_Response]

The base class for a client interface, used by request handlers.

abstractmethod async send_packet(packet: _T_Response, /) None

Sends packet to the remote endpoint. Does not require task synchronization.

Warning

In the case of a cancellation, it is impossible to know if all the packet data has been sent. This would leave the connection in an inconsistent state.

Parameters:

packet (_T_Response) – the Python object to send.

Raises:
  • ClientClosedError – the client object is closed.

  • ConnectionError – connection unexpectedly closed during operation. You should not attempt any further operation and close the client object.

  • OSError – unrelated OS error occurred. You should check OSError.errno.

abstractmethod is_closing() bool

Checks if the client is closed or in the process of being closed.

If True, all future operations on the client object will raise a ClientClosedError.

Returns:

the client state.

Return type:

bool

abstractmethod backend() AsyncBackend
Returns:

The backend implementation linked to the server.

Return type:

AsyncBackend

class easynetwork.servers.handlers.AsyncStreamClient

Bases: AsyncBaseClientInterface[_T_Response]

A client interface for stream oriented connection, used by stream request handlers.

abstractmethod async aclose() None

Close the client. Does not require task synchronization.

Once that happens, all future operations on the client object will raise a ClientClosedError. The remote end will receive no more data (after queued data is flushed).

Can be safely called multiple times.

Warning

aclose() performs a graceful close, waiting for the connection to close.

If aclose() is cancelled, the client is closed abruptly.

class easynetwork.servers.handlers.AsyncDatagramClient

Bases: AsyncBaseClientInterface[_T_Response]

A client interface for datagram oriented connection, used by datagram request handlers.

Unlike AsyncStreamClient, the client object can be recreated on each handle() call, but implements __hash__() and __eq__() for uniqueness checking, so it can be used in a set for example.

Client Attributes

class easynetwork.servers.handlers.INETClientAttribute

Bases: TypedAttributeSet

Typed attributes which can be used on an AsyncBaseClientInterface.

socket: ISocket = <object object>

socket.socket instance.

local_address: IPv4SocketAddress | IPv6SocketAddress = <object object>

the socket’s own address, result of socket.socket.getsockname().

remote_address: IPv4SocketAddress | IPv6SocketAddress = <object object>

the remote address to which the socket is connected, result of socket.socket.getpeername().

class easynetwork.servers.handlers.UNIXClientAttribute

Bases: TypedAttributeSet

Typed attributes which can be used on an AsyncBaseClientInterface.

Added in version 1.1.

socket: ISocket = <object object>

socket.socket instance.

local_name: UnixSocketAddress = <object object>

the socket’s own address, result of socket.socket.getsockname().

peer_name: UnixSocketAddress = <object object>

the remote address to which the socket is connected, result of socket.socket.getpeername().

peer_credentials: UnixCredentials = <object object>

the credentials of the peer process connected to this socket.


Server implementation tools


See also

How-to — Standalone Servers

Explains the case of stand-alone servers.

How-to — TCP Servers

Describes what can be done with the servers.

How-to — UDP Servers

Describes what can be done with the servers.

Alternative — Unix Stream Servers

Describes what can be done with the servers.

Alternative — Unix Datagram Servers

Describes what can be done with the servers.