search
HomeTechnology peripheralsIt IndustryPython Web Applications: The basics of WSGI

Python Web Applications: The basics of WSGI

Key Takeaways

  • WSGI, or Web Server Gateway Interface, underpins all Python web frameworks, providing a common specification for web servers that allows for interaction between different web servers and application frameworks.
  • A WSGI application is a Python callable that must accept two arguments, the environ (a Python dict containing request data) and start_fn (a callable). The application must call start_fn with two arguments: the status code and a list of headers, and return an iterable containing the bytes in the response body.
  • Middleware can be used to extend the functionality of WSGI apps, with middleware and the handler not needing to know or care about each other. This makes it easy to add functionality like logging or error handling.
  • WSGI apps can be served in a variety of ways, with Gunicorn and uWSGI being two popular options. It’s recommended to set up something like nginx in front of these to serve static assets.
Python Web Applications: The basics of WSGI

Beneath Django, Flask, Bottle, and every other Python web framework, lies the Web Server Gateway Interface, or WSGI for short. WSGI is to Python what Servlets are to Java — a common specification for web servers that allows different web servers and application frameworks to interact based on a common API. However, as with most things, the Python version is considerably simpler.

WSGI is defined in PEP 3333, which I encourage you to read as a reference if you want more information after this quick intro.

This article will introduce you to the WSGI spec from an application developer’s perspective, and show you how to work directly with WSGI to create applications (if you so desire).

Your First WSGI App

Here’s the most basic Python web app possible:

<span>def app(environ, start_fn):
</span>    start_fn<span>('200 OK', [('Content-Type', 'text/plain')])
</span>    <span>return ["Hello World!\n"]
</span>

That’s it! The whole file. Call it app.py and run it with any WSGI-compatible server and you’ll get a Hello World response with a 200 status. You can use gunicorn for this; just install it via pip (pip install gunicorn) and run it with gunicorn app:app. This command tells gunicorn to get the WSGI callable from the app variable in the app module.

Right now, you should be pretty excited. Just 3 lines for a running application? That must be some sort of record (barring PHP, because mod_php is cheating). I bet you’re just raring to know more.

So what are the essential parts of a WSGI application?

  • A WSGI application is a Python callable, such as a function, a class, or a class instance with a __call__ method
  • The application callable must accept two arguments: the environ, which is a Python dict containing the request data, and start_fn, itself a callable.
  • The application must call the start_fn with two arguments: the status code (as a string), and a list of headers expressed as 2-tuples.
  • The application returns an iterable containing the bytes in the response body in handy, streamable chunks — in this case, a list of strings containing just "Hello, World!". (If app is a class, this can be accomplished in the __iter__ method.)

By way of example, these next two examples are equivalent to the first:

<span>def app(environ, start_fn):
</span>    start_fn<span>('200 OK', [('Content-Type', 'text/plain')])
</span>    <span>return ["Hello World!\n"]
</span>
<span>class app(object):
</span>
    <span>def __init__(self, environ, start_fn):
</span>        self<span>.environ = environ
</span>        self<span>.start_fn = start_fn
</span>
    <span>def __iter__(self):
</span>        self<span>.start_fn('200 OK', [('Content-Type', 'text/plain')])
</span>        <span>yield "Hello World!\n"
</span>

You might already be thinking of ways that you can use this information, but probably the most relevant one is writing middlewares.

Jazzing It Up

Middlewares are an easy way to extend the functionality of WSGI apps. Since you need only provide a callable, you can wrap it up in other functions however you please.

For example, say we want to examine the contents of environ. We can easily create a middleware to do so, as in this example:

<span>class Application(object):
</span>    <span>def __call__(self, environ, start_fn):
</span>        start_fn<span>('200 OK', [('Content-Type', 'text/plain')])
</span>        <span>yield "Hello World!\n"
</span>
app <span>= Application()
</span>

Here, log_environ is a function that returns a function, which pretty-prints the environ argument before deferring to the original callback.

The advantage of writing middlewares this way is that the middleware and the handler don’t have to know or care about each other. You could easily bolt log_environ onto a Flask application, for example, since Flask apps are WSGI apps.

A few other useful middleware ideas:

<span>import pprint
</span>

<span>def handler(environ, start_fn):
</span>    start_fn<span>('200 OK', [('Content-Type', 'text/plain')])
</span>    <span>return ["Hello World!\n"]
</span>

<span>def log_environ(handler):
</span>    <span>def _inner(environ, start_fn):
</span>        pprint<span>.pprint(environ)
</span>        <span>return handler(environ, start_fn)
</span>    <span>return _inner
</span>

app <span>= log_environ(handler)
</span>

You can use reduce to apply a bunch of middleware at once if you don’t want to make a big pyramid a the bottom of your file:

<span>import pprint
</span>

<span>def handle_error(handler):
</span>    <span>def _inner(environ, start_fn):
</span>        <span>try:
</span>            <span>return handler(environ, start_fn)
</span>        <span>except Exception as e:
</span>            <span>print e  # Log error
</span>            start_fn<span>('500 Server Error', [('Content-Type', 'text/plain')])
</span>            <span>return ['500 Server Error']
</span>    <span>return _inner
</span>

<span>def wrap_query_params(handler):
</span>    <span>def _inner(environ, start_fn):
</span>        qs <span>= environ.get('QUERY_STRING')
</span>        environ<span>['QUERY_PARAMS'] = urlparse.parse_qs(qs)
</span>        <span>return handler(environ, start_fn)
</span>    <span>return _inner
</span>

You can also write middleware that modifies the response, by taking advantage of the start_fn argument. Here’s a middleware that reverses the output if the Content-Type header is text/plain:

<span># Applied from bottom to top on the way in, then top to bottom on the way out
</span>MIDDLEWARES <span>= [wrap_query_params,
</span>               log_environ<span>,
</span>               handle_error<span>]
</span>
app <span>= reduce(lambda h, m: m(h), MIDDLEWARES, handler)
</span>

It’s a little more tangled thanks to the separation of start_fn and response, but still perfectly workable.

Also note that, to be strictly spec-compliant with WSGI, we must check for a close method on the response and call it if present. Legacy WSGI applications may also return a write function instead of an iterable upon calling handler; if you want your middleware to support older applications, you may need to handle this case.

Once you start playing with raw WSGI a little bit, you start to understand why Python has literally dozens of web frameworks. WSGI makes it pretty simple to build something up starting from scratch. For example, you might be considering the problem of routing:

<span>def reverser(handler):
</span>
    <span># A reverse function
</span>    rev <span>= lambda it: it[::-1]
</span>
    <span>def _inner(environ, start_fn):
</span>        do_reverse <span>= []  # Must be a reference type such as a list
</span>
        <span># Override start_fn to check the content type and set a flag
</span>        <span>def start_reverser(status, headers):
</span>            <span>for name, value in headers:
</span>                <span>if (name.lower() == 'content-type'
</span>                        <span>and value.lower() == 'text/plain'):
</span>                    do_reverse<span>.append(True)
</span>                    <span>break
</span>
            <span># Remember to call `start_fn`
</span>            start_fn<span>(status, headers)
</span>
        response <span>= handler(environ, start_reverser)
</span>
        <span>try:
</span>            <span>if do_reverse:
</span>                <span>return list(rev(map(rev, response)))
</span>
            <span>return response
</span>        <span>finally:
</span>            <span>if hasattr(response, 'close'):
</span>                response<span>.close()
</span>    <span>return _inner
</span>

Working with WSGI directly can be nice if you enjoy the flexibility of assembling libraries over

  • Template libraries: just drop in any template library you like (e.g. Jinja2, Pystashe) and return the rendered template from your handler!
  • Help your routing with a library like Routes or perhaps Werkzeug’s routing. Actually, take a look at Werkzeug if you want to use an ever-so-slight abstraction over WSGI.
  • Use any database/migration libraries as you would with Flask or similar.

Of course, for non-specialized applications, you’ll probably still want to use a framework just so that edge cases are properly handled and whatnot.

But What About Servers?

There are a bunch of ways to serve WSGI apps. We already talked about Gunicorn, which is a decent option. uWSGI is another great option. Just make sure you set up something like nginx in front of these to serve static assets and you should have a solid starting point.

And that’s all there is to it!

Frequently Asked Questions (FAQs) about Python Web Applications and WSGI

What is the role of WSGI in Python web applications?

WSGI, or Web Server Gateway Interface, is a standard interface between web servers and web applications. It plays a crucial role in Python web applications as it allows the application and the web server to communicate and send requests to each other. WSGI acts as a bridge, enabling the web server to forward requests from a client (like a web browser) to a web application. The application then processes the request and sends a response back to the client via the web server.

How does WSGI work in a Python web application?

WSGI works by defining a common interface that allows web servers to communicate with web applications. When a client sends a request to a web server, the server uses the WSGI interface to pass that request to the web application. The application processes the request and returns a response, which the server then sends back to the client. This process allows for a consistent and reliable way for web servers and applications to interact, regardless of their specific implementations.

There are several popular WSGI servers available for Python, each with its own strengths and weaknesses. Some of the most commonly used ones include Gunicorn, uWSGI, and mod_wsgi. Gunicorn is known for its simplicity and ease of use, while uWSGI is praised for its speed and efficiency. Mod_wsgi, on the other hand, is a module for Apache servers and is often used in enterprise environments.

How do I deploy a Python web application using WSGI?

Deploying a Python web application using WSGI involves several steps. First, you need to install a WSGI server, such as Gunicorn or uWSGI. Next, you need to configure your web server to use the WSGI server as a proxy for handling requests to your application. This involves modifying your server’s configuration file to include the necessary WSGI settings. Finally, you need to start your WSGI server and point it to your application’s WSGI file.

Can I use WSGI with Django?

Yes, you can use WSGI with Django. In fact, Django comes with a built-in WSGI application that you can use to deploy your Django projects. The Django WSGI application acts as a bridge between your Django project and the web server, allowing them to communicate and exchange requests and responses.

What is the difference between WSGI and ASGI?

WSGI and ASGI are both interfaces for Python web applications, but they serve different purposes. WSGI is a synchronous interface that allows for communication between a web server and a web application. ASGI, or Asynchronous Server Gateway Interface, is an extension of WSGI that supports asynchronous operations. This means that with ASGI, your application can handle multiple requests at the same time without blocking, making it more efficient for real-time applications.

How do I create a WSGI application in Python?

Creating a WSGI application in Python involves defining a function that accepts two arguments: an environment dictionary and a start_response callable. The environment dictionary contains information about the incoming request, while the start_response callable is used to start the response to the request. Your function should return an iterable that produces the body of the response.

What are the benefits of using WSGI in Python web applications?

Using WSGI in Python web applications offers several benefits. First, it provides a standard interface for web servers and applications, making it easier to develop and deploy Python web applications. Second, it allows for greater flexibility, as you can choose from a variety of WSGI-compatible servers and applications. Finally, it promotes code reusability, as you can use the same WSGI application with different servers and middleware.

Can I use WSGI with Flask?

Yes, you can use WSGI with Flask. In fact, Flask applications are WSGI applications by default. When you create a Flask application, you’re actually creating a WSGI application that the Flask framework will use to handle incoming requests and send responses.

What is a WSGI middleware?

A WSGI middleware is a component that sits between a WSGI server and a WSGI application. It can process requests before they reach the application and responses before they’re sent back to the client. Middleware can be used to implement a variety of functionalities, such as session management, URL routing, and authentication.

The above is the detailed content of Python Web Applications: The basics of WSGI. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Behind the first Android access to DeepSeek: Seeing the power of womenBehind the first Android access to DeepSeek: Seeing the power of womenMar 12, 2025 pm 12:27 PM

The rise of Chinese women's tech power in the field of AI: The story behind Honor's collaboration with DeepSeek women's contribution to the field of technology is becoming increasingly significant. Data from the Ministry of Science and Technology of China shows that the number of female science and technology workers is huge and shows unique social value sensitivity in the development of AI algorithms. This article will focus on Honor mobile phones and explore the strength of the female team behind it being the first to connect to the DeepSeek big model, showing how they can promote technological progress and reshape the value coordinate system of technological development. On February 8, 2024, Honor officially launched the DeepSeek-R1 full-blood version big model, becoming the first manufacturer in the Android camp to connect to DeepSeek, arousing enthusiastic response from users. Behind this success, female team members are making product decisions, technical breakthroughs and users

DeepSeek's 'amazing' profit: the theoretical profit margin is as high as 545%!DeepSeek's 'amazing' profit: the theoretical profit margin is as high as 545%!Mar 12, 2025 pm 12:21 PM

DeepSeek released a technical article on Zhihu, introducing its DeepSeek-V3/R1 inference system in detail, and disclosed key financial data for the first time, which attracted industry attention. The article shows that the system's daily cost profit margin is as high as 545%, setting a new high in global AI big model profit. DeepSeek's low-cost strategy gives it an advantage in market competition. The cost of its model training is only 1%-5% of similar products, and the cost of V3 model training is only US$5.576 million, far lower than that of its competitors. Meanwhile, R1's API pricing is only 1/7 to 1/2 of OpenAIo3-mini. These data prove the commercial feasibility of the DeepSeek technology route and also establish the efficient profitability of AI models.

Top 10 Best Free Backlink Checker Tools in 2025Top 10 Best Free Backlink Checker Tools in 2025Mar 21, 2025 am 08:28 AM

Website construction is just the first step: the importance of SEO and backlinks Building a website is just the first step to converting it into a valuable marketing asset. You need to do SEO optimization to improve the visibility of your website in search engines and attract potential customers. Backlinks are the key to improving your website rankings, and it shows Google and other search engines the authority and credibility of your website. Not all backlinks are beneficial: Identify and avoid harmful links Not all backlinks are beneficial. Harmful links can harm your ranking. Excellent free backlink checking tool monitors the source of links to your website and reminds you of harmful links. In addition, you can also analyze your competitors’ link strategies and learn from them. Free backlink checking tool: Your SEO intelligence officer

Midea launches its first DeepSeek air conditioner: AI voice interaction can achieve 400,000 commands!Midea launches its first DeepSeek air conditioner: AI voice interaction can achieve 400,000 commands!Mar 12, 2025 pm 12:18 PM

Midea will soon release its first air conditioner equipped with a DeepSeek big model - Midea fresh and clean air machine T6. The press conference is scheduled to be held at 1:30 pm on March 1. This air conditioner is equipped with an advanced air intelligent driving system, which can intelligently adjust parameters such as temperature, humidity and wind speed according to the environment. More importantly, it integrates the DeepSeek big model and supports more than 400,000 AI voice commands. Midea's move has caused heated discussions in the industry, and is particularly concerned about the significance of combining white goods and large models. Unlike the simple temperature settings of traditional air conditioners, Midea fresh and clean air machine T6 can understand more complex and vague instructions and intelligently adjust humidity according to the home environment, significantly improving the user experience.

Another national product from Baidu is connected to DeepSeek. Is it open or follow the trend?Another national product from Baidu is connected to DeepSeek. Is it open or follow the trend?Mar 12, 2025 pm 01:48 PM

DeepSeek-R1 empowers Baidu Library and Netdisk: The perfect integration of deep thinking and action has quickly integrated into many platforms in just one month. With its bold strategic layout, Baidu integrates DeepSeek as a third-party model partner and integrates it into its ecosystem, which marks a major progress in its "big model search" ecological strategy. Baidu Search and Wenxin Intelligent Intelligent Platform are the first to connect to the deep search functions of DeepSeek and Wenxin big models, providing users with a free AI search experience. At the same time, the classic slogan of "You will know when you go to Baidu", and the new version of Baidu APP also integrates the capabilities of Wenxin's big model and DeepSeek, launching "AI search" and "wide network information refinement"

Prompt Engineering for Web DevelopmentPrompt Engineering for Web DevelopmentMar 09, 2025 am 08:27 AM

AI Prompt Engineering for Code Generation: A Developer's Guide The landscape of code development is poised for a significant shift. Mastering Large Language Models (LLMs) and prompt engineering will be crucial for developers in the coming years. Th

Building a Network Vulnerability Scanner with GoBuilding a Network Vulnerability Scanner with GoApr 01, 2025 am 08:27 AM

This Go-based network vulnerability scanner efficiently identifies potential security weaknesses. It leverages Go's concurrency features for speed and includes service detection and vulnerability matching. Let's explore its capabilities and ethical

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!