Skip to content

pygase.client

Connect to PyGaSe servers.

Contents

  • Client: main API class for PyGaSe clients

Client

Client(self)

Exchange events with a PyGaSe server and access a synchronized game state.

Attributes

  • connection (pygase.connection.ClientConnection): object that contains all networking information

Example

from time import sleep
# Connect a client to the server from the Backend code example
client = Client()
client.connect_in_thread(hostname="localhost", port=8080)
# Increase `bar` five times, then reset `foo`
for i in range(5):
    client.dispatch_event("SET_BAR", new_bar=i)
    sleep(1)
client.dispatch_event("RESET_FOO")

connect

Client.connect(self, port:int, hostname:str='localhost') -> None

Open a connection to a PyGaSe server.

This is a blocking function but can also be spawned as a coroutine or in a thread via Client.connect_in_thread().

Arguments

  • port (int): port number of the server to which to connect
  • hostname (str): hostname or IPv4 address of the server to which to connect

connect_in_thread

Client.connect_in_thread(self, port:int, hostname:str='localhost') -> threading.Thread

Open a connection in a seperate thread.

See Client.connect().

Returns

threading.Thread: the thread the client loop runs in

disconnect

Client.disconnect(self, shutdown_server:bool=False) -> None

Close the client connection.

This method can also be spawned as a coroutine. shutdown_server (bool): wether or not the server should be shut down (only has an effect if the client has host permissions)

access_game_state

Client.access_game_state(self)

Return a context manager to access the shared game state.

Can be used in a with block to lock the synchronized game_state while working with it.

Example

with client.access_game_state() as game_state:
    do_stuff(game_state)

wait_until

Client.wait_until(self, game_state_condition, timeout:float=1.0) -> None

Block until a condition on the game state is satisfied.

Arguments

  • game_state_condition (callable): function that takes a pygase.GameState instance and returns a bool
  • timeout (float): time in seconds after which to raise a TimeoutError

Raises

  • TimeoutError: if the condition is not met after timeout seconds

try_to

Client.try_to(self, function, timeout:float=1.0)

Execute a function using game state attributes that might not yet exist.

This method repeatedly tries to execute function(game_state), ignoring KeyError exceptions, until it either worksor times out.

Arguments

  • function (callable): function that takes a pygase.GameState instance and returns anything
  • timeout (float): time in seconds after which to raise a TimeoutError

Returns

any: whatever function(game_state) returns

Raises

  • TimeoutError: if the function doesn't run through after timeout seconds

dispatch_event

Client.dispatch_event(self, event_type:str, *args, retries:int=0, ack_callback=None, **kwargs) -> None

Send an event to the server.

Arguments

  • event_type (str): event type identifier that links to a handler
  • retries (int): number of times the event is to be resent in case it times out
  • ack_callback (callable, coroutine): will be invoked after the event was received Additional positional and keyword arguments will be sent as event data and passed to the handler function.

ack_callback should not perform any long-running blocking operations (say a while True loop), as that will block the connections asynchronous event loop. Use a coroutine instead, with appropriately placed awaits.

register_event_handler

Client.register_event_handler(self, event_type:str, event_handler_function) -> None

Register an event handler for a specific event type.

Arguments

  • event_type (str): event type to link the handler function to
  • handler_func (callable, coroutine): will be called for events of the given type

pygase.backend

Serve PyGaSe clients.

Provides the Server class and all PyGaSe components that deal with progression and syncing of game states.

Contents

  • GameStateStore: main API class for game state repositories
  • Server: main API class for PyGaSe servers
  • GameStateMachine: main API class for game logic components
  • Backend: main API class for a fully integrated PyGaSe backend

GameStateStore

GameStateStore(self, initial_game_state:pygase.gamestate.GameState=None)

Provide access to a game state and manage state updates.

Arguments

  • inital_game_state (GameState): state of the game before the simulation begins

get_update_cache

GameStateStore.get_update_cache(self) -> list

Return the latest state updates.

get_game_state

GameStateStore.get_game_state(self) -> pygase.gamestate.GameState

Return the current game state.

push_update

GameStateStore.push_update(self, update:pygase.gamestate.GameStateUpdate) -> None

Push a new state update to the update cache.

This method will usually be called by whatever is progressing the game state, usually a GameStateMachine.

Server

Server(self, game_state_store:pygase.backend.GameStateStore)

Listen to clients and orchestrate the flow of events and state updates.

The Server instance does not contain game logic or state, it is only responsible for connections to clients. The state is provided by a GameStateStore and game logic by a GameStateMachine.

Arguments

  • game_state_store (GameStateStore): part of the backend that provides an interface to the pygase.GameState

Attributes

  • connections (list): contains each clients address as a key leading to the corresponding pygase.connection.ServerConnection instance
  • host_client (tuple): address of the host client (who has permission to shutdown the server), if there is any
  • game_state_store (GameStateStore): game state repository

Members

  • hostname (str): read-only access to the servers hostname
  • port (int): read-only access to the servers port number

hostname

Get the hostname or IP address on which the server listens.

Returns None when the server is not running.

port

Get the port number on which the server listens.

Returns None when the server is not running.

run

Server.run(self, port:int=0, hostname:str='localhost', event_wire=None) -> None

Start the server under a specified address.

This is a blocking function but can also be spawned as a coroutine or in a thread via Server.run_in_thread().

Arguments

  • port (int): port number the server will be bound to, default will be an available port chosen by the computers network controller
  • hostname (str): hostname or IP address the server will be bound to. Defaults to 'localhost'.
  • event_wire (GameStateMachine): object to which events are to be repeated (has to implement a _push_event(event) method and is typically a GameStateMachine)

run_in_thread

Server.run_in_thread(self, port:int=0, hostname:str='localhost', event_wire=None, daemon=True) -> threading.Thread

Start the server in a seperate thread.

See Server.run().

Returns

threading.Thread: the thread the server loop runs in

shutdown

Server.shutdown(self) -> None

Shut down the server.

The server can be restarted via Server.run() in which case it will remember previous connections. This method can also be spawned as a coroutine.

dispatch_event

Server.dispatch_event(self, event_type:str, *args, target_client='all', retries:int=0, ack_callback=None, **kwargs) -> None

Send an event to one or all clients.

Arguments

  • event_type (str): identifies the event and links it to a handler
  • target_client (tuple, str): either 'all' for an event broadcast, or a clients address as a tuple
  • retries (int): number of times the event is to be resent in case it times out
  • ack_callback (callable, coroutine): will be executed after the event was received and be passed a reference to the corresponding pygase.connection.ServerConnection instance Additional positional and keyword arguments will be sent as event data and passed to the clients handler function.

register_event_handler

Server.register_event_handler(self, event_type:str, event_handler_function) -> None

Register an event handler for a specific event type.

Arguments

  • event_type (str): event type to link the handler function to
  • handler_func (callable, coroutine): will be called for received events of the given type

GameStateMachine

GameStateMachine(self, game_state_store:pygase.backend.GameStateStore)

Run a simulation that propagates the game state.

A GameStateMachine progresses a game state through time, applying all game simulation logic. This class is meant either as a base class from which you inherit and implement the GameStateMachine.time_step() method, or you assign an implementation after instantiation.

Arguments

  • game_state_store (GameStateStore): part of the PyGaSe backend that provides the state

Attributes

  • game_time (float): duration the game has been running in seconds

register_event_handler

GameStateMachine.register_event_handler(self, event_type:str, event_handler_function) -> None

Register an event handler for a specific event type.

For event handlers to have any effect, the events have to be wired from a Server to the GameStateMachine via the event_wire argument of the Server.run() method.

Arguments

  • event_type (str): which type of event to link the handler function to
  • handler_func (callable, coroutine): function or coroutine to be invoked for events of the given type, gets passed the keyword argument game_state (along with those attached to the event) and is expected to return an update dict

run_game_loop

GameStateMachine.run_game_loop(self, interval:float=0.02) -> None

Simulate the game world.

This function blocks as it continously progresses the game state through time but it can also be spawned as a coroutine or in a thread via Server.run_game_loop_in_thread(). As long as the simulation is running, the game_state.status will be GameStatus.get('Active').

Arguments

  • interval (float): (minimum) duration in seconds between consecutive time steps

run_game_loop_in_thread

GameStateMachine.run_game_loop_in_thread(self, interval:float=0.02) -> threading.Thread

Simulate the game in a seperate thread.

See GameStateMachine.run_game_loop().

Returns

threading.Thread: the thread the game loop runs in

stop

GameStateMachine.stop(self, timeout:float=1.0) -> bool

Pause the game simulation.

This sets self.status to Gamestatus.get('Paused'). This method can also be spawned as a coroutine. A subsequent call of GameStateMachine.run_game_loop() will resume the simulation at the point where it was stopped.

Arguments

  • timeout (float): time in seconds to wait for the simulation to stop

Returns

bool: wether or not the simulation was successfully stopped

time_step

GameStateMachine.time_step(self, game_state:pygase.gamestate.GameState, dt:float) -> dict

Calculate a game state update.

This method should be implemented to return a dict with all the updated state attributes.

Arguments

  • game_state (GameState): the state of the game prior to the time step
  • dt (float): time in seconds since the last time step, use it to simulate at a consistent speed

Returns

dict: updated game state attributes

Backend

Backend(self, initial_game_state:pygase.gamestate.GameState, time_step_function, event_handlers:dict=None)

Easily create a fully integrated PyGaSe backend.

Arguments

  • initial_game_state (GameState): state of the game before the simulation begins
  • time_step_function (callable): function that takes a game state and a time difference and returns a dict of updated game state attributes (see GameStateMachine.time_step())
  • event_handlers (dict): a dict with event types as keys and event handler functions as values

Attributes

  • game_state_store (GameStateStore): the backends game state repository
  • game_state_machine (GameStateMachine): logic component that runs the game loop
  • server (Server): handles connections to PyGaSe clients

Example

# Run a game loop that continuously increments `foo` with velocity `bar`.
Backend(
    initial_gamestate=GameState(foo=0.0, bar=0.5),
    time_step_function=lambda game_state, dt: {foo: game_state.foo + game_state.bar*dt},
    # Handle client events to reset `foo` and set a new `bar` value.
    event_handlers={
        "RESET_FOO": lambda game_state, dt: {foo: 0.0},
        "SET_BAR": lambda new_bar, game_state, dt: {bar: new_bar}
    }
).run(hostname="localhost", port=8080)

run

Backend.run(self, hostname:str, port:int)

Run state machine and server and bind the server to a given address.

Arguments

  • hostname (str): hostname or IPv4 address the server will be bound to
  • port (int): port number the server will be bound to

pygase.gamestate

Customize a game state model and apply state updates.

Contents

  • TO_DELETE: 4 byte update marker for game state attributes that are to be deleted
  • GameStatus: enum for the status of the game simulation
  • GameState: class for serializable custom state data objects
  • GameStateUpdate: class for serializable objects that express changes to a GameState object

GameStatus

GameStatus(self, /, *args, **kwargs)

Enum for the game simulation status.

  • 'Paused'
  • 'Active'

GameState

GameState(self, time_order:int=0, game_status:int=0, **kwargs)

Customize a serializable game state model.

Contains game state information that will be synchronized between the server and the clients. Via pygase.utils.Sendable its instances will be serialized using the msgpack protocol and must only contain attributes of type str, bytes, Sqn, int, float, bool as well as lists or tuples of such.

Arguments

  • time_order (): current time order number of the game state, higher means more recent
  • game_status (): GameStatus enum value that describes whether or not the game loop is running Provide custom game state attributes via keyword arguments or assign them later.

Attributes

game_status () time_order () GameState instances mainly consist of custom attributes that make up the game state.

is_paused

GameState.is_paused(self) -> bool

Return True if game is paused.

GameStateUpdate

GameStateUpdate(self, time_order:int, **kwargs)

Update a GameState object.

Contains a set of changes to carry out on a GameState. The server keeps a time_order counter and labels all updates in ascending order.

Attributes of a GameStateUpdate object represent new values of GameState attributes. To remove game state attributes just assign TO_DELETE to it in the update.

Use the + operator to add updates to one another and combine them or to add them to a game state in order to update it.

Arguments

  • time_order (): the time order up to which the update reaches game state attributes to be updated

Attributes

time_order () GameStateUpdate instances mainly consist of custom game state attributes to update.

from_bytes

GameStateUpdate.from_bytes(bytepack:bytes) -> 'GameStateUpdate'

Extend Sendable.from_bytes to make sure time_order is of type Sqn.

pygase.connection

Provide low-level networking logic.

This module is not supposed to be required by users of this library.

Contents

  • PROTOCOL_ID: 4 byte identifier for the PyGaSe package protocol
  • ProtocolIDMismatchError: exception for receiving non-PyGaSe packages
  • DuplicateSequenceError: exception for duplicate packages
  • Header: class for PyGaSe package headers
  • Package: class for PyGaSe UDP packages
  • ClientPackage: subclass of Package for packages sent by clients
  • ServerPackage: subclass of Package for packages sent by servers
  • ConnectionStatus: enum for the status of a client-server connection
  • Connection: class for the core network logic of client-server connections
  • ClientConnection: subclass of Connection for the client side
  • ServerConnection: subclass of Connectoin for the server side

ProtocolIDMismatchError

ProtocolIDMismatchError(self, /, *args, **kwargs)

Bytestring could not be identified as a valid PyGaSe package.

DuplicateSequenceError

DuplicateSequenceError(self, /, *args, **kwargs)

Received a package with a sequence number that was already received before.

Header(self, sequence:int, ack:int, ack_bitfield:str)

Create a PyGaSe package header.

Arguments

  • sequence (int): package sequence number
  • ack (int): sequence number of the last received package
  • ack_bitfield (str): A 32 character string representing the 32 sequence numbers prior to the last one received, with the first character corresponding the packge directly preceding it and so forth. '1' means that package has been received, '0' means it hasn't.

Attributes

  • sequence (int): see corresponding constructor argument
  • ack (int): see corresponding constructor argument
  • ack_bitfield (str): see corresponding constructor argument

  • Sequence numbers: A sequence of 0 means no packages have been sent or received. After 65535 sequence numbers wrap around to 1, so they can be stored in 2 bytes.

to_bytearray

Header.to_bytearray(self) -> bytearray

Return 12 bytes representing the header.

destructure

Header.destructure(self) -> tuple

Return the tuple (sequence, ack, ack_bitfield).

deconstruct_datagram

Header.deconstruct_datagram(datagram:bytes) -> tuple

Return a tuple containing the header and the rest of the datagram.

Arguments

  • datagram (bytes): serialized PyGaSe package to deconstruct

Returns

tuple: (header, payload) with payload being a bytestring of the rest of the datagram

Package

Package(self, header:pygase.connection.Header, events:list=None)

Create a UDP package implementing the PyGaSe protocol.

Arguments

  • header (Header): package header

Arguments

  • events (pygase.event.Event): list events to attach to this package

Attributes

  • header (Header):

Members

  • events (pygase.event.Event): see corresponding constructor argument

PyGaSe servers and clients use the subclasses ServerPackage and ClientPackage respectively. The Package class would also work on its own (it's not an 'abstract' class), in which case you would have all features of PyGaSe except for a synchronized game state.

events

Get a list of the events in the package.

add_event

Package.add_event(self, event:pygase.event.Event) -> None

Add a PyGaSe event to the package.

Arguments

  • event (pygase.event.Event): the event to be attached to this package

Raises

  • OverflowError: if the package has previously been converted to a datagram and and its size with the added event would exceed Package._max_size (2048 bytex)

get_bytesize

Package.get_bytesize(self) -> int

Return the size in bytes the package has as a datagram.

to_datagram

Package.to_datagram(self) -> bytes

Return package compactly serialized to bytes.

Raises

  • OverflowError: if the resulting datagram would exceed Package._max_size

from_datagram

Package.from_datagram(datagram:bytes) -> 'Package'

Deserialize datagram to Package.

Arguments

  • datagram (bytes): bytestring to deserialize, typically received via network

Returns

Package: the deserialized package

Raises

  • ProtocolIDMismatchError: if the first four bytes don't match the PyGaSe protocol ID

ClientPackage

ClientPackage(self, header:pygase.connection.Header, time_order:int, events:list=None)

Subclass of Package for packages sent by PyGaSe clients.

Arguments

  • time_order (int): the clients last known time order of the game state

Attributes

  • time_order (int): see corresponding constructor argument

to_datagram

ClientPackage.to_datagram(self) -> bytes

Override Package.to_datagram to include time_order.

from_datagram

ClientPackage.from_datagram(datagram:bytes) -> 'ClientPackage'

Override Package.from_datagram to include time_order.

ServerPackage

ServerPackage(self, header:pygase.connection.Header, game_state_update:pygase.gamestate.GameStateUpdate, events:list=None)

Subclass of Package for packages sent by PyGaSe servers.

Arguments

  • game_state_update (pygase.gamestate.GameStateUpdate): the servers most recent minimal update for the client

to_datagram

ServerPackage.to_datagram(self) -> bytes

Override Package.to_datagram to include game_state_update.

from_datagram

ServerPackage.from_datagram(datagram:bytes) -> 'ServerPackage'

Override Package.from_datagram to include game_state_update.

ConnectionStatus

ConnectionStatus(self, /, *args, **kwargs)

Enum for the state of a connection.

  • 'Disconnected'
  • 'Connecting'
  • 'Connected'

Connection

Connection(self, remote_address:tuple, event_handler, event_wire=None)

Exchange packages between PyGaSe clients and servers.

PyGaSe connections exchange events with their other side which are handled using custom handler functions. They also keep each other informed about which packages have been sent and received and automatically avoid network congestion.

Arguments

  • remote_address (tuple): ('hostname', port) for the connection partner's address
  • event_handler (pygase.event.UniversalEventHandler): object that has a callable handle attribute that takes a pygase.event.Event as argument
  • event_wire (pygase.GameStateMachine): object to which events are to be repeated (has to implement a _push_event method)

Attributes

  • remote_address (tuple): see corresponding constructor argument
  • event_handler (pygase.event.UniversalEventHandler): see corresponding constructor argument
  • event_wire (pygase.GameStateMachine): see corresponding constructor argument
  • local_sequence (pygase.utils.Sqn): sequence number of the last sent package
  • remote_sequence (pygase.utils.Sqn): sequence number of the last received package
  • ack_bitfield (str): acks for the 32 packages prior to self.remote_sequence
  • latency (float): the last registered RTT (round trip time)
  • status (ConnectionStatus): an integer value that informs about the state of the connections
  • quality (str): either 'good' or 'bad' depending on latency, used internally for congestion avoidance

PyGaSe servers and clients use the subclasses ServerConnection and ClientConnection respectively. The Connection class would also work on its own (it's not an 'abstract' class), in which case you would have all features of PyGaSe except for a synchronized game state.

dispatch_event

Connection.dispatch_event(self, event:pygase.event.Event, ack_callback=None, timeout_callback=None)

Send an event to the connection partner.

Arguments

  • event (pygase.event.Event): the event to dispatch
  • ack_callback (callable, coroutine): will be executed after the event was received
  • timeout_callback (callable, coroutine): will be executed if the event was not received

Using long-running blocking operations in any of the callback functions can disturb the connection.

ClientConnection

ClientConnection(self, remote_address:tuple, event_handler)

Subclass of Connection to describe the client side of a PyGaSe connection.

Client connections hold a copy of the game state which is continously being updated according to state updates received from the server.

Attributes

  • game_state_context (pygase.utils.LockedRessource): provides thread-safe access to a pygase.GameState

shutdown

ClientConnection.shutdown(self, shutdown_server:bool=False)

Shut down the client connection.

This method can also be spawned as a coroutine.

Arguments

  • shutdown_server (bool): wether or not the server should be shut down too (only has an effect if the client has host permissions)

loop

ClientConnection.loop(self)

Continously operate the connection.

This method will keep sending and receiving packages and handling events until it is cancelled or the connection receives a shutdown command. It can also be spawned as a coroutine.

ServerConnection

ServerConnection(self, remote_address:tuple, event_handler, game_state_store, last_client_time_order:pygase.utils.Sqn, event_wire=None)

Subclass of Connection that describes the server side of a PyGaSe connection.

Arguments

  • game_state_store (pygase.GameStateStore): object that serves as an interface to the game state repository (has to provide the methods get_gamestate, get_update_cache and push_update)
  • last_client_time_order (pygase.utils.Sqn): the last time order number known to the client

Attributes

  • game_state_store (pygase.GameStateStore): see corresponding constructor argument
  • last_client_time_order (pygase.utils.Sqn): see corresponding constructor argument

loop

ServerConnection.loop(hostname:str, port:int, server, event_wire) -> None

Continously orchestrate and operate connections to clients.

This coroutine will keep listening for client packages, create new ServerConnection objects when necessary and make sure all packages are handled by and sent via the right connection.

It will return as soon as the server receives a shutdown message.

Arguments

  • hostname (str): the hostname or IPv4 address to which to bind the server socket
  • port (int): the port number to which to bind the server socket
  • server (pygase.Server): the server for which this loop is run
  • event_wire (pygase.GameStateMachine): object to which events are to be repeated (has to implement a _push_event method)

pygase.event

Handle events in PyGaSe clients, servers and state machines.

Contains the basic components of the PyGaSe event framework.

Contents

  • Event: class for serializable event objects with event type and data
  • UniversalEventHandler: class for components that can handle various event types

Event

Event(self, event_type:str, *args, **kwargs)

Send PyGaSe events and attached data via UDP packages.

Arguments

  • event_type (): string that identifies the event and links it to a handler

Arguments

Additional positional arguments represent event data and will be passed to the handler function on the other side of the connection. keyword arguments to be passed to the handler function on the other side of the connection

Attributes

  • type ():
  • handler_args ():
  • handler_kwargs ():

UniversalEventHandler

UniversalEventHandler(self)

Handle PyGaSe events with callback functions.

register_event_handler

UniversalEventHandler.register_event_handler(self, event_type:str, event_handler_function) -> None

Register an event handler for a specific event type.

Arguments

  • event_type (): string that identifies the events to be handled by this function
  • event_handler_function (): callback function or coroutine that will be invoked with the handler args and kwargs with which the incoming event has been dispatched

handle

UniversalEventHandler.handle(self, event:pygase.event.Event, **kwargs)

Invoke the appropriate handler function.

Arguments

  • event (): the event to be handled keyword arguments to be passed to the handler function (in addition to those already attached to the event)

has_event_type

UniversalEventHandler.has_event_type(self, event_type:str) -> bool

Check if a handler was registered for event_type.

pygase.utils

Use helpful classes and functions.

Provides utilities used in PyGaSe code or helpful to users of this library.

Contents

  • Comparable: mixin that makes object compare as equal if their type and attributes match
  • Sendable: mixin that allows to serialize objects to small bytestrings
  • NamedEnum: base class for lists of strings to be mapped to integer values
  • Sqn: subclass of int for sequence numbers that always fit in 2 bytes
  • LockedRessource: class that attaches a threading.Lock to a ressource
  • get_available_ip_addresses: function that returns a list of local network interfaces

Comparable

Comparable(self, /, *args, **kwargs)

Compare objects by equality of attributes.

Sendable

Sendable(self, /, *args, **kwargs)

Send objects via UDP packages.

This mixin for classes that are supposed to be sendable as part of a PyGaSe package makes objects serializable with the msgpack protocol. Sendables can only have attributes of type str, bytes, Sqn, int, float, bool as well as lists or tuples of such.

to_bytes

Sendable.to_bytes(self) -> bytes

Serialize the object to a compact bytestring.

from_bytes

Sendable.from_bytes(bytepack:bytes)

Deserialize a bytestring into an instance of this class.

Arguments

  • bytepack (): the bytestring to be parsed to a subclass of Sendable

Returns

a copy of an object that was serialized via Sendable.to_bytes

NamedEnum

NamedEnum(self, /, *args, **kwargs)

Map string labels to integer values.

This is a base class meant to be subclassed to produce a dynamic enum mapping type.

Example

class MyEnum(NamedEnum):

    '''Encode labels in integers.
     - "foo"
     - "bar"

    '''


    MyEnum.register("foo")
    MyEnum.register("bar")

    assert MyEnum.get("foo") == 1
    assert MyEnum.get("bar") == 2
    assert MyEnum.get(1) == "foo"
    assert MyEnum.get(2) == "bar"

get

NamedEnum.get(name_or_value)

Get the value for a label or vice versa.

Arguments

  • name_or_value (): label or value to de- or encode

Returns

int value for given string label or vice versa

Raises

  • TypeError: if argument is neither int nor str

register

NamedEnum.register(name:str) -> None

Add a new label to the mapping.

Arguments

  • name (): string label to register as new enum value

Sqn

Sqn(self, /, *args, **kwargs)

Use finite periodic integers that fit in 2 bytes.

Subclass of int that provides a residue-class-like behaviour of wrapping back to 1 after a maximum value. Use it to represent sequence numbers with a fixed number of bytes when you only need well-defined ordering within a specific finite scale. 0 represents the state before the sequence has started.

For the default bytesize of 2 the maximum sequence number is 65535.

set_bytesize

Sqn.set_bytesize(bytesize:int) -> None

Redefine the bytesize and wrap-over behaviour for all Sqn instances.

Arguments

  • bytesize (): new size for the bytes representation of Sqn instances

get_max_sequence

Sqn.get_max_sequence() -> int

Return the maximum sequence number after which Sqns wrap back to 1.

to_sqn_bytes

Sqn.to_sqn_bytes(self) -> bytes

Return representation of the number in exactly the currenly set bytesize.

The default bytesize is 2.

from_sqn_bytes

Sqn.from_sqn_bytes(bytestring:bytes) -> 'Sqn'

Return Sqn object that was encoded in given bytestring.

LockedRessource

LockedRessource(self, ressource)

Access a ressource thread-safely.

This class makes an object available via a context manager that essentialy attaches a threading.Lock to it, that threads writing to this object should abide.

Usage example:

myRessource = { 'foo': 'bar' }
myLockedRessource = LockedRessource(myRessource)
with myLockedRessource() as ressource:
    # do stuff without any other threads meddling with the ressource

Arguments

  • ressource (): object to be wrapped

Attributes

  • lock (): threading.Lock that threads writing to ressource should abide. ressource ()

get_available_ip_addresses

get_available_ip_addresses() -> list

Return a list of all locally available IPv4 addresses.