Apologies Server Python Library

Release v0.2.2+10.0d2f7dd

https://img.shields.io/pypi/v/apologiesserver.svg https://img.shields.io/pypi/l/apologiesserver.svg https://img.shields.io/pypi/wheel/apologiesserver.svg https://img.shields.io/pypi/pyversions/apologiesserver.svg https://readthedocs.org/projects/apologies-server/badge/?version=stable&style=flat https://coveralls.io/repos/github/pronovic/apologies-server/badge.svg?branch=master

ApologiesServer is a Websocket server interface used to interactively play a multi-player game using the Apologies library. The Apologies library implements a game similar to the Sorry board game.

I originally developed this code in mid-2020 during COVID-enforced downtime, as part of an effort to write a UI to play the Apologies board game in a web browser. However, Javascript moves really fast, and by mid-2021, my UI implementation was already partially obsolete, and I abandoned work on it.

This code is still a reasonable example of how to build a Websocket server including a state machine to manage board game state. However, its main purpose was to support the process of building that web UI, so it’s not designed or architected for production use. It doesn’t really look like something I would today, given the benefit of more experience with async design patterns in Python. But, it works.

Installation

Install the package with pip:

$ pip install apologiesserver

Design Documentation

As a technology demonstration effort, the Apologies Server is fairly simplistic. It runs as a single stateful process that maintains game state in memory. It cannot be horizontally scaled, and there is no option for an external data store. There is also only limited support for authentication and authorization - any player can register any handle that is not currently being used. We do enforce resource limits (open connections, registered users, in-progress games) to limit the amount of damage abusive clients can do.

Running the Server

The PyPI package includes a script called apologies-server:

$ apologies-server --help
usage: apologies-server [-h] [--quiet] [--verbose] [--debug] [--config CONFIG]
                        [--logfile LOGFILE] [--override OVERRIDE]

Start the apologies server and let it run forever.

optional arguments:
  -h, --help           show this help message and exit
  --quiet              decrease log verbosity from INFO to ERROR
  --verbose            increase log verbosity from INFO to DEBUG
  --debug              like --verbose but also include websockets logs
  --config CONFIG      path to configuration on disk
  --logfile LOGFILE    path to logfile on disk (default is stdout)
  --override OVERRIDE  override a config parameter as "param:value"

By default, the server writes logs to stdout. If you prefer, you can specify
the path to a logfile, and logs will be written there instead. The default
configuration file is "/Users/kpronovici/.apologiesrc". If the default
configuration file is not found, default values will be set. If you override
the default config file, it must exist. You may override any individual config
parameter with "--override param:value".

The simplest way to start the server is with no arguments:

$ apologies-server
2020-06-10 14:31:39,831Z --> [INFO   ] Apologies server started
2020-06-10 14:31:39,832Z --> [INFO   ] Configuration: {
  "logfile_path": null,
  "server_host": "localhost",
  "server_port": 8080,
  "close_timeout_sec": 10,
  "websocket_limit": 1000,
  "total_game_limit": 1000,
  "in_progress_game_limit": 25,
  "registered_player_limit": 100,
  "websocket_idle_thresh_min": 2,
  "websocket_inactive_thresh_min": 5,
  "player_idle_thresh_min": 15,
  "player_inactive_thresh_min": 30,
  "game_idle_thresh_min": 10,
  "game_inactive_thresh_min": 20,
  "game_retention_thresh_min": 2880,
  "idle_websocket_check_period_sec": 120,
  "idle_websocket_check_delay_sec": 300,
  "idle_player_check_period_sec": 120,
  "idle_player_check_delay_sec": 300,
  "idle_game_check_period_sec": 120,
  "idle_game_check_delay_sec": 300,
  "obsolete_game_check_period_sec": 300,
  "obsolete_game_check_delay_sec": 300
}
2020-06-10 14:31:39,832Z --> [INFO   ] Adding signal handlers...
2020-06-10 14:31:39,832Z --> [INFO   ] Scheduling tasks...
2020-06-10 14:31:39,832Z --> [INFO   ] Completed starting websocket server

The server displays its configuration when it boots. You can override any of this configuration using the switches described in the help output above.