antarctica / PolarRoute-server

Backend server for serving PolarRoute and MeshiPhi assets and managing their calcuation using Django & Celery.
MIT License
0 stars 0 forks source link

PolarRoute Server

Dev Status GitHub Tag GitHub License

A web server to manage requests for meshes and routes generated using the PolarRoute and MeshiPhi libraries, implemented using Django, Celery and Django REST framework.

It currently takes vessel meshes created using MeshiPhi and serves requests for routes, which are calculated using PolarRoute.

Setup/installation

PolarRouteServer can be installed from GitHub using pip.

Alternatively, clone this repository and install from source with pip install -e .

For development

Depends on:

  1. Clone this repository and create and activate a python virtual environment of your choice.
  2. Inside a virtual environment or machine: pip install -e .[dev]
  3. Before first use, create the database by running make migrate
  4. To start all of the services needed for the dev deployment run: make serve-dev (which sets the DJANGO_SETTINGS_MODULE environment variable and spins up celery, rabbitmq in a docker container, and the Django development server)

For development, also install and use the development tools:

  1. pre-commit install

A number of helpful development tools are made available through the Makefile, to see a description of each of these commands, run make (with no arguments) from the top-level of this directory.

Using docker compose

Optionally, use docker compose for development deployment to orchestrate celery and rabbitmq alongside the django development server.

Clone this repository and run docker compose up to build and start the services.

Note: In development, meshes are not automatically ingested into the database. Follow these steps to add a mesh to the database.

  1. Make a local directory structure with mkdir -p data/mesh and copy a vessel mesh file from MeshiPhi into ./data/mesh, which is bind-mounted into the app container.
  2. Run docker compose exec app /bin/bash to open a shell inside the running app container.
  3. Run django-admin insert_mesh /usr/src/app/data/mesh/<MESH FILENAME> to insert the mesh into the database manually.

Test that the app is working using the demo tool as described below. The URL of the service should be localhost:8000.

The django development server supports hot reloading and the source code is bind-mounted into the container, so changes should be reflected in the running app. Any changes to polarrouteserver.route_api.models.py will necessitate a migration to the database. To create and run migrations, run:

docker compose exec app django-admin makemigrations
docker compose exec app django-admin migrate

Optionally, Swagger can be used to serve an API schema. This is not started by default, but can be enabled by started docker compose with the --profile swagger option, e.g. docker compose --profile swagger up -d - the swagger UI will be served at localhost:80/swagger.

Configuration

Configuration of PolarRouteServer works with environment variables. You can either set these directly or from a .env file. An example .env file is included here as env.example.

Environment variables used directly by the Django site are prefixed wit POLARROUTE_ and those which configure Celery are prefixed with CELERY_.

The following are inherited from Django and more information can be found on their effects via the Django docs.

Production Deployment

For production, the following are required:

For serving with Gunicorn, run make start-django-server to serve with WSGI and production settings.

Management of a deployment

All of the commands used for administration of a Django project are available post-installation via the django-admin command.

Of particular interest in production are:

$ django-admin makemigrations # create new migrations files based on changes to models
$ django-admin migrate # apply new migrations files to alter the database
$ django-admin dbshell # open the database's command line interface

To see more commands, run django-admin --help.

In addition a custom command is available to manually insert new meshes into the database from file:

$ django-admin insert_mesh <Mesh file or list of files>

insert_mesh takes a filename or list of filepaths containing meshes either as .vessel.json format or gzipped vessel mesh files.

Only meshes which are not present in the database will be inserted. Uniqueness is based on the md5 hash of the unzipped vessel mesh file.

Making requests using the demo tool

A demo script is available in this repo (polarrouteserver/demo.py) to be used as a utility for making route requests.

To obtain, either:

This can be done with wget by running:

wget https://raw.githubusercontent.com/antarctica/PolarRoute-server/refs/heads/main/polarrouteserver/demo.py

To run, you'll just need python ~3.11 installed. Earlier versions of python may work, but are untested.

Usage

Help for the utility can be printed out by running python demo.py --help.

Alternatively, if you have the package installed, a command named request_route is made available.

$ request_route --help
# OR
$ python demo.py --help

usage: demo.py [-h] [-u URL] -s [START] -e [END] [-d [DELAY]] [-f] [-o [OUTPUT]]

Requests a route from polarRouteServer, repeating the request for status until the route is available. Specify start and end points by coordinates or from one of the standard locations: ['bird', 'falklands',
'halley', 'rothera', 'kep', 'signy', 'nyalesund', 'harwich', 'rosyth']

options:
  -h, --help            show this help message and exit
  -u URL, --url URL     Base URL to send request to.
  -s [START], --start [START]
                        Start location either as the name of a standard location or latitude,longitude separated by a comma, e.g. -56.7,-65.01
  -e [END], --end [END]
                        End location either as the name of a standard location or latitude,longitude separated by a comma, e.g. -56.7,-65.01
  -d [DELAY], --delay [DELAY]
                        (integer) number of seconds to delay between status calls.
  -f, --force           Force polarRouteServer to recalculate the route even if it is already available.
  -o [OUTPUT], --output [OUTPUT]
                        File path to write out route to. (Default: None and print to stdout)

So to request a route from Falklands to Rothera, for example:

python demo.py --url example-polar-route-server.com -s falklands -e rothera --delay 120 --output demo_output.json

This will request the route from the server running at example-polar-route-server.com, and initiate a route calculation if one is not already available.

The utility will then request the route's status every 120 seconds.

The HTTP response from each request will be printed to stdout.

Once the route is available it will be returned, or if 10 attempts to get the route have passed, the utility will stop.