Are a Wsgi Server and Http Server Required to Serve a Flask App

Are a WSGI server and HTTP server required to serve a Flask app?

When you "run Flask" you are actually running Werkzeug's development WSGI server, and passing your Flask app as the WSGI callable.

The development server is not intended for use in production. It is not designed to be particularly efficient, stable, or secure. It does not support all the possible features of a HTTP server.

Replace the Werkzeug dev server with a production-ready WSGI server such as Gunicorn or uWSGI when moving to production, no matter where the app will be available.


The answer is similar for "should I use a web server". WSGI servers happen to have HTTP servers but they will not be as good as a dedicated production HTTP server (Nginx, Apache, etc.).


Flask documents how to deploy in various ways. Many hosting providers also have documentation about deploying Python or Flask.

What is the use of a web server in flask deployments?

With Flask, you build your web application. WSGI is the interface the application follows to be hosted by WSGI servers. gevent is a WSGI server that can host your application.

Usually, you would then put a full fledged web server (e.g. nginx or apache) as a reverse proxy in front of it to get the full features modern web servers usually offer, without the intermediate WSGI server having to offer those features themselves. That makes everything simpler and easier to reason about, since every component can focus on what it does best (the WSGI server’s job being to only host your application).

The dev server that comes with Flask is a very simple server that runs in a single process. It uses werkzeug for this, which also explictly mentions that it should not be used for production:

The development server is not intended to be used on production systems. It was designed especially for development purposes and performs poorly under high load. For deployment setups have a look at the Application Deployment pages.

So instead, you use a “real” WSGI server to host your application; it will then do whatever necessary to run your application properly. A WSGI server is still rather simple though; you put another web server as a reverse proxy in front to get access to the features that make webservers really powerful (e.g. load balancing, caching, SSL termination, …).

Running Flask application without nginx

For running flask, you do not need nginx, just a webserver of your choice, but life with nginx is just easier. If you are using Apache, you want to consider to use a WSGI.

I remember reading somewhere in the Flask documentation what is stated by an answer to "Are a WSGI server and HTTP server required to serve a Flask app?" as

The answer is similar for "should I use a web server". WSGI servers happen to have HTTP servers but they will not be as good as a dedicated production HTTP server (Nginx, Apache, etc.).

The main idea behind is the architectural principle of splitting layers to ease debugging and increase security, similarly to the concept that you split content and structure (HTML & CSS, UI vs. API):

  • For the lower layers, see e.g. https://en.wikipedia.org/wiki/Transport_layer
    Having a dedicated HTTP server allows you to do package-filtering etc. on that level.
  • The WSGI is the interface layer between the webserver and the webframework.

Update

I have seen clients only running a WSGI server alone, with integrated HTTP support. Using an additional webserver and/ or proxy is just good practice, but IMHO not strictly necessary.

References

  • https://flask.palletsprojects.com/en/1.1.x/deploying/mod_wsgi/ describes the Apache way for flask
  • https://flask.palletsprojects.com/en/1.1.x/tutorial/deploy/ elaborates on how a production environment should look like
  • Deploying Python web app (Flask) in Windows Server (IIS) using FastCGI
  • Debugging a Flask app running in Gunicorn
  • Flask at first run: Do not use the development server in a production environment

How to serve Flask With Http Server

Can I not start each server with the following code?

Yes, there are many other ways.

WSGI

wsgi, which stands for Web Server Gateway Interface is defined in PEP 333:

This document specifies a proposed standard interface between web
servers and Python web applications or frameworks, to promote web
application portability across a variety of web servers.

framework side

flask, django and many other frameworks all implement this interface. So when you write an app in flask, app implements wsgi so any web server that knows how to serve a wsgi app can serve it.

web server side

There are many choices and you can find more at wsgi.org:

  • gunicorn
  • uWSGI
  • ...

Basically, you can choose any of these to start your server and use httpd to proxy requests to it. Or you can use mod_wsgi:

mod_wsgi is an Apache module that embeds a Python application within
the server and allow them to communicate through the Python WSGI
interface as defined in the Python PEP 333.

Note

The bundled server in flask is not suitable for production use, you can see this question for more details.


For Updated Question

I want to run Flask's built-in web server and HTTPServer
simultaneously from a script.

Just Run Shell Command

You can start another process and call shell command using Popen:

if __name__ == '__main__':
p = Popen(['python -m http.server'], shell=True)
app.run(host='localhost', port=5000)

Use whatever command you like, you can even start a node http server here.

Use Thread/Process

You can start http server in another thread or process, here I use threading for example:

if __name__ == '__main__':
from threading import Thread
Thread(target=run, daemon=True).start()
app.run(host='localhost', port=5000)

Use Flask To Serve File

Instead of starting two servers binding to two ports, you can actually use flask to serve file as well. In this way, you only start one server binding to one port:

@app.route('/videos/<path:filename>')
def download_file(filename):
return send_from_directory(r'C:\Users\User\Videos',
filename, as_attachment=True)

You can see documentation for more details.

Why does running Flask with Nginx require a WSGI wrapper?

Nginx is a web server and is concerned with web server stuff, not with how to run Python programs. uWSGI is an application server and knows how to speak WSGI with Python (and other languages now). Both Nginx and uWSGI speak the uWSGI protocol, which is an efficient protocol over UNIX sockets.

Nginx deals with http requests from/responses to the outside world (possibly load balancing, caching, etc.). Your Flask application deals with WSGI requests/responses. uWSGI knows how to start your application (possibly with multiprocessing and/or threading) and bridge the gap between HTTP and WSGI.

There are other HTTP servers besides Nginx, and other WSGI servers besides uWSGI, but they all use the same workflow: the HTTP server passes to the WSGI server, which manages your application process and passes back to the HTTP server.

This setup is known as a reverse proxy. It allows each tool to do what it's good at and not be concerned about the other parts of the process. There is nothing particularly inefficient about it, until you get to truly massive scales.

Can we connect our Flask app directly with Nginx server?

You need to understand what is Web Server Gateway Interface (WSGI) to understand the difference between Gunicorn, uWSGI and Nginx.

What does it mean?

[WSGI is] a proposed standard interface between web servers and Python web applications or frameworks, to promote web application portability across a variety of web servers. Source: PEP 333

As explained above, it is a standardization that simplifies the implementation of a Web application in python within a server. WSGI describes how the interactions between a server and a python application must be. No matter what your application is, if you follow the rules defined in PEP 333, then any WSGI-compatible HTTP server will be able to communicate with your application.

But there is no point in reinventing the wheel, developers have already created WSGI applications so that you can create applications more easily. Flask is one of them, but there are others.

Why do I need WSGI HTTP server? I can run my Flask application in the cmd, isn't it?

You always need a WSGI HTTP server. Flask is a very good tool and it directly includes a Werkzeug development server but you must not use Werkzeug server in production.

The [Werkzeug] development server is not intended to be used on production systems. It was designed especially for development purposes and performs poorly under high load. Source: Werkzeug Documentation

That is why you always have this message when you try to run your flask application with the command run().

WARNING: Do not use the development server in a production environment.

Then you will need a server for production.

Gunicorn, uWSGI, Twisted Web etc?

There are many WSGI-compatible servers available. The choice is purely arbitrary and depends exclusively on your needs. The installation and configuration can be different. More or fewer options will be available. It's up to you to find out which one suits you best. There is a part of the Flask documentation that is reserved for this: Standalone WSGI Container.

This link could be useful too : Flask Deploying

What is Nginx's role?

Nginx can be used as a reverse proxy.

A reverse proxy is an intermediary proxy service which takes a client request, passes it on to one or more servers, and subsequently delivers the server's response to the client. Source: Setting up an Nginx Reverse Proxy

To Go Further

What is the advantage of using Nginx + WSGI server? CI/CD.

It is really easy to dockerize an Nginx server and your application within a WSGI server. Then you can manage your dockers with Kubernetes and manage the continuous integration with Jenkins. DevOps Culture.

However, this is absolutely not mandatory. A solution that is also very nice to use is Nginx Unit, it allows you to have the power of Nginx and to part with Gunicorn or uWSGI. The flaw that could be found in this solution is that it is not compatible with the Docker + Kubernetes + Jenkins fashion that you can find easily on Google. It is quite possible to do continuous integration on it, but it is less common. This will require more knowledge: blue/green environment, etc....

Flask at first run: Do not use the development server in a production environment

As of Flask 2.2, the development server always shows this warning. The development server is not intended for use in production. It is not designed to be particularly efficient, stable, or secure. Use a production WSGI server instead. See the deployment docs from Flask for more information.

That warning is just a warning though, it's not an error preventing your app from running. If your app isn't working, there's something else wrong with your code.



Related Topics



Leave a reply



Submit