What is WSGI (Web Server Gateway Interface)?
What is WSGI (Web Server Gateway Interface)?
https://medium.com/analytics-vidhya/what-is-wsgi-web-server-gateway-interface-ed2d290449e
PYTHON领域的 Web服务器网关接口 协议。
用于解耦 web服务器(apache gunicorn uwsgi) 和 web应用(包括web框架 django or flask)
Overview on Web Server Gateway Interface
WSGI refers to Web Server Gateway Interface. WSGI plays a vital role at the time when you deploy your Django or Flask application. Here, in this blog, I will be discussing what WSGI is, when should you dive deeper into the concept of WSGI and how does WSGI works.
WSGI is a specification that describes the communication between web servers and Python web applications or frameworks. It explains how a web server communicates with python web applications/frameworks and how web applications/frameworks can be chained for processing a request.
Python standard WSGI has been explained in detail with PEP 3333. Therefore, if you are willing to learn more about PEP 3333 you can have a look into the official documentation of Python which has been provided in the link below.
PEP 3333 -- Python Web Server Gateway Interface v1.0.1
WSGI协议。
https://www.python.org/dev/peps/pep-3333/
How does WSGI work?
实现了 WSGI 协议的Web服务器,都可以执行python开发的web应用。
如下图
(1)第一个框是标准的web服务器,或者代理服务器,
(2)后两个框实际上是一个程序, 前一个框是弱化的web server(WSGI server),实现了 WSGI 协议服务器API, 后一个框是应用代码,实现了WSGI应用API.
Now, web server is able to send requests or communicate with WSGI containers. Likewise, Python application provides a ‘callable’ object which contains certain functionalities that are invoked by WSGI application which are defined as per the PEP 3333 standard. Hence, there are multiple WSGI containers available such as Gunicorn, uWSGI, etc.
The figure below represents the communication that is carried out between web server, WSGI, and Python application.
Communication between user, web server, WSGI, and Python application.
There are multiple WSGI containers that are available today. Hence, a WSGI container is required to be installed in the project so that a web server can communicate to a WSGI container which further communicates to the Python application and provides the response back accordingly. Finally, when the web server obtains the response, it is sent back to the web browser/users.
Why use the WSGI rather than directly pointing the web server to the Django or Flask application?
为什么要使用WSGI, 而不是直接将webserver指向Django应用?
(1)为了灵活性考虑。
解耦 web服务器 和 web应用,可以随意切换其中任意一方。
刚开始使用gunicorn部署应用, 后面决定切换到apache上,只需要借助apache的mod_wsgi模块,就能实现。
刚开始使用django开发,后来决定使用flask代替,服务器不用做任何改变。
(2)为了伸缩性考虑。
WSGI server只负责处理来自web server的请求, 并把前通过求转发到 应用集成处理。
当访问量变大时候, 我们可以启动多个 WSGI server,增加web流量。
当流量变小的时候,进行相反操作。
If you directly point your web server to your application, it reduces the flexibility of your application. Since your web server now directly points to your web application, you are unable to swap out web stack components. Now, let’s have a look at an example to make you clear about the applicability of WSGI. For instance, today you have decided to deploy your application using Gunicorn but after some years you decide to switch from Gunicorn to mod_wsgi. Now, in this case, you can easily switch to mod_wsgi without making any changes in the application or framework that implements WSGI. Hence, WSGI provides flexibility to your application.
Another reason for using WSGI is due to its scalability. Once your application is live, up and running there can be thousands of requests in your application. Hence, WSGI is capable of serving thousands of requests at a time. As we know, the WSGI server is responsible for handling the requests from the web server and takes decision for carrying out the communication of those requests to an application framework’s process. Here, we can divide the responsibilities among the servers for scaling web traffic.
Implementation of WSGI server
There are various servers that support WSGI. If you are willing to have a look at all the servers that support WSGI, you can visit the link provided below.
Gunicorn (Green Unicorn)
Gunicorn is a pre-fork worker model based server which is compatible with various web frameworks. Additionally, it is simple to implement. Gunicorn
Note: You can have a look at the official documentation of Gunicorn from the link provided below.
uWSGI
uWSGI is well known for being a highly-performant WSGI server implementation. uWSGI can be used for the development and deployment of Python application. In uWSGI, application servers, proxies, process managers, and monitors are all implemented through a common API and a common configuration style which makes UWSGI a developer-friendly WSGI server.
Note: You can have a look at the official documentation of uWSGI from the link provided below.
mod_wsgi
mod_wsgi is a python package that provides an Apache module which implements a WSGI compliant interface for hosting Python-based web applications on top of the Apache web server.
Note: You can have a look at the official documentation of mod_wsgi from the link provided below.
完整列表:
https://wsgi.readthedocs.io/en/latest/servers.html
Frameworks that run on WSGI
例如如下著名
完整列表:
https://wsgi.readthedocs.io/en/latest/frameworks.html
- CherryPy
- CherryPy is a pythonic, object-oriented web development framework. Includes support for WSGI servers. CherryPy 3 includes better support for living alongside other WSGI frameworks, applications, and middleware.
- Django
- Includes support for WSGI servers
- Flask
Flask is a microframework for Python based on Werkzeug, Jinja 2 and good intentions.
It inherits its high WSGI usage and compliance from Werkzeug.
Gunicorn
https://gunicorn.org/#quickstart
预先启动多个worker的服务器。类似 fastCGI的主从模式。
Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It's a pre-fork worker model. The Gunicorn server is broadly compatible with various web frameworks, simply implemented, light on server resources, and fairly speedy.
Installation
Here's a quick rundown on how to get started with Gunicorn. For more details read the documentation.
$ pip install gunicorn $ cat myapp.py def app(environ, start_response): data = b"Hello, World!\n" start_response("200 OK", [ ("Content-Type", "text/plain"), ("Content-Length", str(len(data))) ]) return iter([data]) $ gunicorn -w 4 myapp:app [2014-09-10 10:22:28 +0000] [30869] [INFO] Listening at: http://127.0.0.1:8000 (30869) [2014-09-10 10:22:28 +0000] [30869] [INFO] Using worker: sync [2014-09-10 10:22:28 +0000] [30874] [INFO] Booting worker with pid: 30874 [2014-09-10 10:22:28 +0000] [30875] [INFO] Booting worker with pid: 30875 [2014-09-10 10:22:28 +0000] [30876] [INFO] Booting worker with pid: 30876 [2014-09-10 10:22:28 +0000] [30877] [INFO] Booting worker with pid: 30877
https://villoro.com/post/nginx_gunicorn
uWSGI
https://en.wikipedia.org/wiki/UWSGI
uWSGI is a software application that "aims at developing a full stack for building hosting services".[3] It is named after the Web Server Gateway Interface (WSGI), which was the first plugin supported by the project.[3]
uwsgi (all lowercase) is the native binary protocol that uWSGI uses to communicate with other servers.[4]
uWSGI is often used for serving Python web applications in conjunction with web servers such as Cherokee and Nginx, which offer direct support for uWSGI's native uwsgi protocol.[5] For example, data may flow like this: HTTP client ↔ Nginx ↔ uWSGI ↔ Python app.[6]
uWSGI是一个综合的项目,不仅仅包含 WSGI server
目标是开发全栈应用,为构建宿主服务。
包括以下组件:
Application servers (for various programming languages and protocols),
proxies,
process managers and monitors
https://uwsgi-docs.readthedocs.io/en/latest/
The uWSGI project
The uWSGI project aims at developing a full stack for building hosting services.
Application servers (for various programming languages and protocols), proxies, process managers and monitors are all implemented using a common api and a common configuration style.
Thanks to its pluggable architecture it can be extended to support more platforms and languages.
Currently, you can write plugins in C, C++ and Objective-C.
The “WSGI” part in the name is a tribute to the namesake Python standard, as it has been the first developed plugin for the project.
Versatility, performance, low-resource usage and reliability are the strengths of the project (and the only rules followed).
Included components (updated to latest stable release)
The Core (implements configuration, processes management, sockets creation, monitoring, logging, shared memory areas, ipc, cluster membership and the uWSGI Subscription Server)
Request plugins (implement application server interfaces for various languages and platforms: WSGI, PSGI, Rack, Lua WSAPI, CGI, PHP, Go …)
Gateways (implement load balancers, proxies and routers)
The Emperor (implements massive instances management and monitoring)
Loop engines (implement events and concurrency, components can be run in preforking, threaded, asynchronous/evented and green thread/coroutine modes. Various technologies are supported, including uGreen, Greenlet, Stackless, Gevent, Coro::AnyEvent, Tornado, Goroutines and Fibers)
部署WSGI应用
https://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html
Quickstart for Python/WSGI applications
This quickstart will show you how to deploy simple WSGI applications and common web frameworks.
flask部署在uwsgi上
https://flask.palletsprojects.com/en/1.1.x/deploying/uwsgi/
uWSGI支持 uWSGI、 FastCGI 和 HTTP协议。
uWSGI is a deployment option on servers like nginx, lighttpd, and cherokee; see FastCGI and Standalone WSGI Containers for other options. To use your WSGI application with uWSGI protocol you will need a uWSGI server first. uWSGI is both a protocol and an application server; the application server can serve uWSGI, FastCGI, and HTTP protocols.
The most popular uWSGI server is uwsgi, which we will use for this guide. Make sure to have it installed to follow along.
ngx_http_uwsgi_module
nginx的对应uwsgi协议实现, 用于将请求转发到 WSGI server
http://nginx.org/en/docs/http/ngx_http_uwsgi_module.html
This directive appeared in version 1.7.7.
Limits the speed of reading the response from the uwsgi server. The
rate
is specified in bytes per second. The zero value disables rate limiting. The limit is set per a request, and so if nginx simultaneously opens two connections to the uwsgi server, the overall rate will be twice as much as the specified limit. The limitation works only if buffering of responses from the uwsgi server is enabled.
Syntax: uwsgi_limit_rate
rate
;
Default: uwsgi_limit_rate 0;Context: http
,server
,location
Sets a
parameter
that should be passed to the uwsgi server. Thevalue
can contain text, variables, and their combination. These directives are inherited from the previous configuration level if and only if there are nouwsgi_param
directives defined on the current level.Standard CGI environment variables should be provided as uwsgi headers, see the
uwsgi_params
file provided in the distribution:location / { include uwsgi_params; ... }
If the directive is specified with
if_not_empty
(1.1.11) then such a parameter will be passed to the server only if its value is not empty:uwsgi_param HTTPS $https if_not_empty;
Syntax: uwsgi_pass [
protocol
://]address
;
Default: — Context: location
,if in location
Sets the protocol and address of a uwsgi server. As a
protocol
, “uwsgi
” or “suwsgi
” (secured uwsgi, uwsgi over SSL) can be specified. The address can be specified as a domain name or IP address, and a port:uwsgi_pass localhost:9000; uwsgi_pass uwsgi://localhost:9000; uwsgi_pass suwsgi://[2001:db8::1]:9090;or as a UNIX-domain socket path:
uwsgi_pass unix:/tmp/uwsgi.socket;
If a domain name resolves to several addresses, all of them will be used in a round-robin fashion. In addition, an address can be specified as a server group.
Parameter value can contain variables. In this case, if an address is specified as a domain name, the name is searched among the described server groups, and, if not found, is determined using a resolver.
Secured uwsgi protocol is supported since version 1.5.8.
Syntax: uwsgi_param
parameter
value
[if_not_empty
];
Default: — Context: http
,server
,location
The uwsgi Protocol
https://uwsgi-docs.readthedocs.io/en/latest/Protocol.html
The uwsgi (lowercase!) protocol is the native protocol used by the uWSGI server.
It is a binary protocol that can carry any type of data. The first 4 bytes of a uwsgi packet describe the type of the data contained by the packet.
Every uwsgi request generates a response in the uwsgi format.
Wire protocol
上面的协议,实际上是一种 wire 协议, 这是用通用的方法, 来表示应用层的信息,
用于多应用进程之间交换信息。
https://en.wikipedia.org/wiki/Wire_protocol
In computer networking, a wire protocol refers to a way of getting data from point to point: A wire protocol is needed if more than one application has to interoperate. It generally refers to protocols higher than the physical layer.[1] In contrast to transport protocols at the transport level (like TCP or UDP), the term "wire protocol" is used to describe a common way to represent information at the application level. It refers only to a common application layer protocol and not to a common object semantic[clarification needed] of the applications. Such a representation at application level needs a common infoset (e.g. XML) and a data binding (using e.g. a common encoding scheme like XSD).
The wire protocol may be either text-based or a binary protocol. Although an important architectural decision, this is a separate matter from the distinction between wire protocols and programmatic APIs.
In electronics, a wire protocol is the mechanism used to transmit data from one point to another.[1]
Nginx+uWSGI
How To Set Up uWSGI and Nginx to Serve Python Apps on Ubuntu 14.04
https://www.digitalocean.com/community/tutorials/how-to-set-up-uwsgi-and-nginx-to-serve-python-apps-on-ubuntu-14-04
Introduction
In this guide, we will be setting up a simple WSGI application served by uWSGI. We will use the Nginx web server as a reverse proxy to the application server to provide more robust connection handling. We will be installing and configuring these components on an Ubuntu 14.04 server.
Definitions and Concepts
Clarifying Some Terms
Before we jump in, we should address some confusing terminology associated with the interrelated concepts we will be dealing with. These three separate terms that appear interchangeable, but actually have distinct meanings:
- WSGI: A Python spec that defines a standard interface for communication between an application or framework and an application/web server. This was created in order to simplify and standardize communication between these components for consistency and interchangeability. This basically defines an API interface that can be used over other protocols.
- uWSGI: An application server container that aims to provide a full stack for developing and deploying web applications and services. The main component is an application server that can handle apps of different languages. It communicates with the application using the methods defined by the WSGI spec, and with other web servers over a variety of other protocols. This is the piece that translates requests from a conventional web server into a format that the application can process.
- uwsgi: A fast, binary protocol implemented by the uWSGI server to communicate with a more full-featured web server. This is a wire protocol, not a transport protocol. It is the preferred way to speak to web servers that are proxying requests to uWSGI.
How to do rapid prototyping with Flask, uWSGI, NGINX, and Docker on OpenShift
https://towardsdatascience.com/how-to-do-rapid-prototyping-with-flask-uwsgi-nginx-and-docker-on-openshift-f0ef144033cb
WSGI evolution
http://cewing.github.io/training.python_web/html/presentations/session03.html#wsgi
The Web Server Gateway Interface
CGI Problems
CGI is great, but there are problems:
- Code is executed in a new process
- Every call to a CGI script starts a new process on the server
- Starting a new process is expensive in terms of server resources
- Especially for interpreted languages like Python
How do we overcome this problem?
The most popular approach is to have a long-running process inside the server that handles CGI scripts.
FastCGI and SCGI are existing implementations of CGI in this fashion.
The PHP scripting language works in much the same way.
The Apache module mod_python offers a similar capability for Python code.
- Each of these options has a specific API
- None are compatible with each-other
- Code written for one is not portable to another
This makes it much more difficult to share resources
A Solution
Enter WSGI, the Web Server Gateway Interface.
Other alternatives are specific implementations of the CGI standard.
WSGI is itself a new standard, not an implementation.
WSGI is generalized to describe a set of interactions.
Developers can write WSGI-capable apps and deploy them on any WSGI server.
Read the original WSGI spec: http://www.python.org/dev/peps/pep-0333
There is also an update for Python 3:
https://www.python.org/dev/peps/pep-3333Apps and Servers
WSGI consists of two parts, a server and an application.
A WSGI Server must:
- set up an environment, much like the one in CGI
- provide a method
start_response(status, headers, exc_info=None)
- build a response body by calling an application, passing
environment
andstart_response
as args- return a response with the status, headers and body
A WSGI Appliction must:
- Be a callable (function, method, class)
- Take an environment and a
start_response
callable as arguments- Call the
start_response
method.- Return an iterable of 0 or more strings, which are treated as the body of the response.
A third part of the puzzle is something called WSGI middleware
- Middleware implements both the server and application interfaces
- Middleware acts as a server when viewed from an application
- Middleware acts as an application when viewed from a server
WSGI Servers:
HTTP <—> WSGI
WSGI Applications:
WSGI <—> app code
The WSGI Stack can thus be expressed like so:
HTTP <—> WSGI <—> app code
The Python standard lib provides a reference implementation of WSGI:
You can also deploy with Apache as your HTTP server, using mod_wsgi:
Finally, it is also common to see WSGI apps deployed via a proxied WSGI server:
wsgiref
https://docs.python.org/3/library/wsgiref.html
单一程序 实现 webserver功能, 和 WSGI 协议。
用于开发调试。
The Web Server Gateway Interface (WSGI) is a standard interface between web server software and web applications written in Python. Having a standard interface makes it easy to use an application that supports WSGI with a number of different web servers.
Only authors of web servers and programming frameworks need to know every detail and corner case of the WSGI design. You don’t need to understand every detail of WSGI just to install a WSGI application or to write a web application using an existing framework.
wsgiref
is a reference implementation of the WSGI specification that can be used to add WSGI support to a web server or framework. It provides utilities for manipulating WSGI environment variables and response headers, base classes for implementing WSGI servers, a demo HTTP server that serves WSGI applications, and a validation tool that checks WSGI servers and applications for conformance to the WSGI specification (PEP 3333).See wsgi.readthedocs.io for more information about WSGI, and links to tutorials and other resources.
mod_wsgi
https://modwsgi.readthedocs.io/en/master/
apache上添加此插件, 改造为 WSGI server, 可以直接运行 WSGI 应用。
The mod_wsgi package implements a simple to use Apache module which can host any Python web application which supports the Python WSGI specification. The package can be installed in two different ways depending on your requirements.
The first is as a traditional Apache module installed into an existing Apache installation. Following this path you will need to manually configure Apache to load mod_wsgi and pass through web requests to your WSGI application.