AlexKressner / OptiDeploy

Template for deploying an optimization model accessible via a web service based on FastAPI, mongodb and celery

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

About The Project

Serving mathematical optimization models as a web service made easy! powered by FastAPI, mongodb and Celery.

This repository contains a template for building a containerized web services which serves an optimization model build with SCIP as an example. SCIP is currently one of the fastest non-commercial solvers for mixed integer programming (MIP) and mixed integer nonlinear programming (MINLP). Please note that the template is flexible enough to integrate other solvers and customized algorithms with minor adjustments and is not limited to SCIP. Using FastAPI, optimization models are served as a RESTful API. The backend is powered by mongoDB and stores problem instances and solutions. Optimizations run as background tasks via Celery using RabbitMQ as broker and redis as (intermediate) result backend. Professional log-management is realized with Papertrail. A simple facility location problem is used as an example optimization model.

Hopefully, this template helps people to be faster going from an optimization model on a local machine to a simple optimization web service that can be plugged in existing or new applications.

Architectural Overview

Gunicorn is used for managing Uvicorn workers (ASGI servers), i.e. monitor process aliveness, managing process restarts/ shutdowns and scaling the number of processes. Have a look at this nice video explaining Gunicorn.

A full optimization loop looks like this:

  1. Send problem data via a post request. The data will be validated against the defined problem instance model and stored in mongoDB with a unique problem instance ID.
  2. Send a post request including a reference to the problem instance to be solved and appropriate parameters to configure the solver.
  3. The optimization task (problem instance & solver settings) is enqueued until a woker process picks up the task. To build a model instance, the worker process fetches the problem data from mongoDB and starts the optimization with defined solver settings.
  4. The worker constantly stores the current status of the optimization task in redis, which can be polled.
  5. A successfull optimiation run terminates with task status "SUCCESS" returning a unique solution ID which can be used to fetch the optimition results from monogDB.

Getting Started

Make sure Docker and Docker Compose is installed.

  1. Clone repo
  git clone https://github.com/AlexKressner/OptiDeploy
  1. Change directory
  cd OptiDeploy
  1. Build and launch with docker-compose
  docker-compose up -d --build
  1. Visit http://localhost:8004/docs to see spec of RESTful API via OpenAPI

  2. Visit http://localhost:5556 to see flower for monitoring and administrating celery cluster

  3. Visit http://localhost:15672 and login (user=admin, password=admin) to see the RabbitMQ dashboard

Deployment to DigitalOcean with docker swarm

  1. Create an account on Docker Hub, if you don't already have one, and then log in:
  docker login
  1. Add your Docker Hub namespace:
  export DOCKERHUB_NAMESPACE=[your_dockerhub_namespace]
  1. Run the init script to build and push the images to Docker Hub:
  source init_images.sh
  1. Sign up for a DigitalOcean account (if you don’t already have one), and then generate an access token so you can access the DigitalOcean API.

  2. Add your token:

  export DIGITAL_OCEAN_ACCESS_TOKEN=[your_digital_ocean_token]
  1. Sign up for Papertrail with a free plan and add the service "app log files" (LINUX/UNIX) for professional Log-management. You will get a host and port (HOST.papertrailapp.com:PORT) which you should (permanently) add as an environment variable on your machine.
  export PAPERTRAIL_URL=HOST.papertrailapp.com:PORT
  1. Configure deployment setting (number of nodes, node size, etc., for details see https://slugs.do-api.dev) in deploy.sh and docker-compose-swarm.yml (e.g. replicas). Afterwards run deploy script:
  sh deploy.sh
  1. Fetch IP adress from terminal and test the endpoints. It might take a minute until everything is setup and running on the server side.
  1. Bring down the stack and remove the nodes:
  sh remove.sh

Continuous Integraion and Delivery with Github Actions

CI/CD workflows are implemented via Github Actions. The branching workflow follows the so called "Git Flow" model. There are two branches with infinite lifetime: master which contains production code and develop which contains pre-production code and is merged to master when finished. CI runs for develop and master. CD runs for master only. Feel free to use additional supporting branches (feature,hotfix, etc.). Deployments are done with zero downtime by using docker swarm's internal update mechanisms.

Setting up CI/CD

  1. ssh in the remote machine ("node-1") which is your swarm manager node:
  docker-machine ssh node-1
  1. Generate private and public ssh keys - do not enter a passphrase:
  ssh-keygen
  1. Copy public key to authorized keys:
  cat .ssh/id_rsa.pub >> .ssh/authorized_keys
  1. Copy private key
  cat .ssh/id_rsa
  1. Add secrets on github
  • PRIVATE_KEY: your private ssh key copied from the manager node
  • SERVER_IPV4: ip address of the manager node
  • PAPERTRAIL_URL: your papertrail url
  • DOCKERHUB_NAMESPACE: your dockerhub namespace
  • DOCKERHUB_ACCESS_TOKEN: your dockerhub access token to push and pull images
  • DIGITAL_OCEAN_ACCESS_TOKEN: your digitalocean access token to access the droplets

Load testing

Loucst is used for load testing and runs in a docker container. To test you application cd load_testing and run docker run -p 8089:8089 -v $PWD:/mnt/locust locustio/locust -f /mnt/locust/locustfile.py. Afterwards, the Locust user interface is available at http://localhost:8089.

Serving your own model

Easy, just do the following:

  1. Define all the relevant sets and parameters of your problem as a pydantic model in data.py. This model will also serve to validate data send when placing a problem instance.
  2. To control the behavior of your solver define another model in the solver_parameters.py. This model will also be used to check solver settings sent via the API.
  3. Finally, implement your solver in solver.py.

About

Template for deploying an optimization model accessible via a web service based on FastAPI, mongodb and celery


Languages

Language:Python 89.4%Language:Shell 7.2%Language:Dockerfile 3.4%