Search code examples
pythondeploymentnginxproduction-environmenteve

Running Python Eve Rest API in Production


It is no time to move my Python Eve Api into a production environment. There are several ways to do this and the most common requirements are:

  • Error Logging
  • Automatic Respawn
  • Multiple Processes (if possible)

The best solution I found is to have a nginx server as frontend server. With python eve running on the uWSGI middleware.

The problem: I have a custom __main__ which is not called by uwsgi.

Does anyone have this configuration running or another proposal? As soon as it works, I will share a running configuration.

thank you.

Solution (Update):

Based on the proposial below I moved the Eve() Method to the init.py and run the app with a sperate wsgi.py.

Folder structure:

webservice/ init.py webservice/modules/... settings.py wsgi.py

Where init.py contains

app = Eve(auth=globalauth.TokenAuth)
Bootstrap(app)
app.config['X_DOMAINS'] = '*'
...

and wsgi.py contains

from webservice import app
if __name__ == "__main__":
  app.run()

wsgi.ini

[uwsgi]
chdir=/var/www/api/prod
module=wsgi:app
socket=/tmp/api.sock
processes=1
master=True
pidfile=/tmp/api.v1.pid
max-requests=5000
daemonize=/var/www/api/logs/prod.api.log
logto=/var/www/api/logs/uwsgi.log

nginx.conf

location = /v1 { rewrite ^ /v1/; }
    location /v1 { try_files $uri @apiWSGIv1; }
    location @apiWSGIv1 {
              include uwsgi_params;
              uwsgi_modifier1 30;
              uwsgi_pass unix:/tmp/digdisapi.sock;
    }

start command:

uwsgi --ini uwsgi.ini

Solution

  • WSGI containers expect a callable/function to run, they do not execute your 'main' entry. With run:Eve you are asking uWSGI to execute (at every request) the "Eve" function in the "run" module (that is obviously wrong)

    Move

    app = Eve(auth=globalauth.TokenAuth)
    

    out of the __main__ check and tell uWSGI to use the 'app' callable in the "run" module with

    module = run:app