uWSGI and Flask Server Sent Events - nginx

I want to run a Flask application on my Raspberry Pi 3. I already developed the Flask app and it works fine, but this is on Flask's development server.
I want to use a production server so i'm using nginx as the webserver and uWSGI as the application server on the Pi. Now, the Flask app uses server sent events (SSE) to to get live data from the server. When I run the app using uWSGI, it stalls. I believe its because i'm using SSE because I had a similar problem on the Flask server but all I did was enable threading and the problem was solved. Enabling threading on uWSGI (when running the uWSGI script) doesn't solve the issue though. HELP!
This is my uWSGI .ini file.
[uwsgi]
base = /home/pi/heap
app = app
module = %(app)
home = %(base)/venv
pythonpath = %(base)
socket = /home/pi/heap/%n.sock
chmod-socket = 666
callable = app
Thank you!

Try running it in port instead of socket mode with defined processes and threads.
[uwsgi]
base = project_path
chdir = project_path
module = your_module_name
callable = your_app_name
enable-threads = true
master = true
processes = 5
threads = 2
http = :5000

Related

How do I deploy Apache-Airflow via uWSGI and nginx?

I'm trying to deploy airflow in a production environment on a server running nginx and uWSGI.
I've searched the web and found instructions on installing airflow behind a reverse proxy, but those instructions only have nginx config examples. However, due to the permissions, I can't change the nginx.conf itself and have to solve it via uswsgi.
My folder structure is:
project_folder
|_airflow
|_airflow.cfg
|_webserver_config.py
|_wsgi.py
|_env
|_start
|_stop
|_uwsgi.ini
My path/to/myproject/uwsgi.ini file is configured as follows:
[uwsgi]
master = True
http-socket = 127.0.0.1:9999
virtualenv = /path/to/myproject/env/
daemonize = /path/to/myproject/uwsgi.log
pidfile = /path/to/myproject/tmp/myapp.pid
workers = 2
threads = 2
# adjust the following to point to your project
wsgi-file = /path/to/myproject/airflow/wsgi.py
touch-reload = /path/to/myproject/airflow/wsgi.py
and currently the /path/to/myproject/airflow/wsgi.py looks as follows:
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b'Hello World!']
I'm assuming I have to somehow call the airflow flask app from the wsgi.py file (perhaps by also changing some reverse proxy fix configs, since I'm behind SSL), but I'm stuck; what do I have to configure?
Will this procedure then be identical for the workers and scheduler?

request.client.host is working in one server but not in other server?

We are using same gunicorn and nginx configuration in both servers. one server it is giving client ip but not in other server. Both are ubuntu servers.
we are developing rest API services by using fastAPI framework. we are running gunicorn behind the nginx.
below are the gunicorn.py file
import os
errorlog = '/var/log/gunicorn/gunicorn.log'
loglevel = 'debug'
bind = 'unix:/tmp/gunicorn.sock'
daemon = True
workers = os.cpu_count() * 2
timeout = 600
graceful_timeout = 600
keepalive = 60
worker_class = "uvicorn.workers.UvicornWorker"
max_requests = 2048
preload_app = True
max_requests_jitter = 1024
worker_connections = 1000
proxy_protocol = True
forwarded_allow_ips = "*"
proxy_allow_ips = "*"
we are running above gunicorn.py file using gunicorn -c gunicorn.py base.main:app
we are getting client ip by using request.client.host
Issue got resolved by recreating my virtual environment again. Removed existing environment and created again in the serve. it's working now.

Uvicorn not processing some requests randomly

We are running a Fastapi + Uvicorn web application using gunicorn as a process manager and Nginx as the reverse proxy server. The application is running in async mode for most of the i/o operations (DB call, Rest apis). The whole setup is running inside a Docker container on Ubuntu 16.04.
The setup works most of the times but sometimes it does not process a request at all & it gets timed out at Nginx end. We also tried taking Nginx out of the setup and observed that few requests get processed after really long time (like after 15 mins). This is very random but usually happens 2-3 times in an hour.
Below is the gunicorn config that we are using –
host = os.getenv("HOST", "0.0.0.0")
port = os.getenv("PORT", "80")
# Gunicorn config variables
workers = web_concurrency
bind = f"{host}:{port}"
keepalive = 2
timeout = 60
graceful_timeout = 30
threads = 2
worker_tmp_dir = "/dev/shm"
# Logging mechanism
capture_output = True
loglevel = os.getenv("LOG_LEVEL", "debug")
And gunicorn is invoked with command exec gunicorn -k uvicorn.workers.UvicornWorker -c "$GUNICORN_CONF" "$APP_MODULE"
We have tried several config changes like –
Changing the number of workers, worker timeout
Changing the process manager from gunicorn to supervisord
Offloading the CPU intensive task to Celery instead of threading
Binding uvicorn app to unix socket instead of proxy server

Pytorch model prediction in production with uwsgi

I have a problem deploying a pytorch model in production. For a demonstration, I build a simple model and a flask app. I put everything in a docker container (pytorch+flask+uwsgi) plus another container for nginx. Everything is running well, my app is rendered and I can navigate inside. However, well I navigate into the URL that launches a prediction of the model, the server hangs and does not seem to compute anything.
The uWSGI is run like this:
/opt/conda/bin/uwsgi --ini /usr/src/web/uwsgi.ini
with uwsgi.ini
[uwsgi]
#application's base folder
chdir = /usr/src/web/
#python module to import
wsgi-file = /usr/src/web/wsgi.py
callable = app
#socket file's location
socket = /usr/src/web/uwsgi.sock
#permissions for the socket file
chmod-socket = 666
# Port to expose
http = :5000
# Cleanup the socket when process stops
vacuum = true
#Log directory
logto = /usr/src/web/app.log
# minimum number of workers to keep at all times
cheaper = 2
processes = 16
As said, the server hangs and I finally got a timeout. What is strange is when I run the flask application directly (also in the container) with
python /usr/src/web/manage.py runserver --host 0.0.0.0
I get my prediction in no time
I think this is related to
https://discuss.pytorch.org/t/basic-operations-do-not-work-in-1-1-0-with-uwsgi-flask/50257
Maybe try as mentioned there:
app = flask.Flask(__name__)
segmentator = None
#app.before_first_request
def load_segmentator():
global segmentator
segmentator = Segmentator()
where Segmentator is a class with pytorch’s nn.Module, which loads weights in __init__
FYI this solution worked for me with one app but not the other

How to deploy a python WSGI Flask Application using nginx without manually running uwsgi?

So, I am right now at this point. The webpage can be accessed without any errors and without using any specific port. Example: www.my-example.com.
But, this works only when I run the command "uwsgi --socket 0.0.0.0:4567 --protocol=http -w wsgi" in my server.
How to automate this app deployment through nginx?
You can use something like Supervisor to automatically start uWSGI, restart it if it fails, and log stderr/stdout:
[program:app]
# emulates a virtualenv
directory = /srv/app/
environment = PATH="/srv/app/virtualenv/bin"
command = /srv/app/virtualenv/bin/uwsgi --ini /srv/app/config/uwsgi.ini
autostart = true
autorestart = true
user = app-user

Resources