Beemon Server

class server.Server(host_address: str | None = '127.0.0.1', listening_port: int | None = 8080, socket_timeout_seconds: int | None = 3, receive_size_bytes: int | None = 1024)[source]
__init__(host_address: str | None = '127.0.0.1', listening_port: int | None = 8080, socket_timeout_seconds: int | None = 3, receive_size_bytes: int | None = 1024)[source]

Represents a bare-bones/basic Server in Python. The Server class (when instantiated) will enter into an infinite loop awaiting incoming client connections. In order to stay available for inbound client requests, the Server class leverages a single instance of the Orchestrator multiprocessing.Process to execute the received commands. All commands received by the server are pushed onto a multiprocessing.Queue where they are then ingested by the orchestrator.Orchestrator.

Parameters:
  • host_address (Optional[str]) – The public IP address of this Server which incoming clients will connect to.

  • listening_port (Optional[int]) – The network port which is open on this Server for incoming requests.

  • socket_timeout_seconds (Optional[int]) – The number of seconds which will be allowed to elapse without a response from the client, before the opened socket is declared to be in a timeout state.

  • receive_size_bytes (Optional[int]) – The size of the Server’s buffer for incoming client packets (in bytes).

_accept_loop()[source]

Private helper method that accepts incoming clients in an infinite loop. This method ignores socket timeouts as they are quite common for our use case. When a new connection is established, the server.Server.on_accept() method is invoked.

on_accept(socket_connection: socket, ip_address: Tuple[str, int]) None[source]

Handles what happens when a new connection is accepted by the Server. Generally this involves waiting for an incoming connection and then reading from the buffer the specified amount of bytes. The raw (encoded in binary) message which is read from the socket is sent to the server’s on_receive() method.

Parameters:
  • socket_connection (socket.socket) – A socket.socket object which encapsulates the connection between the server process and the client.

  • ip_address (IPAddress) – A size-two tuple containing the server’s host address and port to which the current client is connected to.

Returns:

A size-2 tuple containing:

  • socket (socket):

  • IPAddress (IPAddress):

Return type:

(Tuple[socket.socket, IPAddress])

on_receive(message: bytes, socket_connection: socket, ip_address: Tuple[str, int]) None[source]

Handles the receipt of an encoded/binary message from a client of the server. Upon receiving a message from a client, the server will decode the message into UTF-8 and then parse the received command. If the command is a known command for the server, an affirmative response will be issued back to the client process. Otherwise an error message will be dispatched in response to the client. All recognized commands are sent decoded (verbatim) to the orchestrator.Orchestrator process via an IPC channel (multiprocessing.Queue).

Notes

The orchestrator.Orchestrator performs all operations associated with the received command. The server.Server class performs no executing of commands.

Parameters:
  • message (bytes) – The raw/binary encoded message received from the client.

  • socket_connection (socket.socket) – An instantiated socket.socket object which sent the received message.

  • ip_address (IPAddress) – A size-two tuple containing both: the IP address (and port number for the IP address) which dispatched the received message.

start() None[source]

Starts the server process by opening a socket for incoming client requests, binding to the specified IP address and listening port.

Raises:

OSError – This method raises an OSError in the event that the specified host address and listening port cannot be bound to.

stop()[source]

Shuts down the server’s infinite loop which listens for incoming client connection requests.