python 内置库wsgiref的使用(WSGI基础入门)

WSGI基本原理

1. WSGI处理过程

  1. 浏览器到WSGI Server:浏览器发送的请求会先到WSGI Server。
  2. environ:WSGI Server会将HTTP请求中的参数等信息封装到environ(一个字典)中。
  3. WSGI Server到WSGI App:App就是我们自己编写的后台程序,每个URL会映射到对应的入口处理函数(或其他可调用对象),WSGI Server调用后台App时,会将environ和WSGI Server中自己的一个start_response函数注入到后台App中。
  4. 逻辑处理:后台函数(或其他可调用对象)需要接收environ和start_response,进行逻辑处理后返回一个可迭代对象,可迭代对象中的元素为HTTP正文。
  5. WSGI App到WSGI Server:后台函数处理完后,会先调用start_response函数将HTTP状态码、报文头等信息(响应头)返回给WSGI Server,然后再将函数的返回值作为HTTP正文(响应body)返回给WSGI Server。
  6. WSGI Server到浏览器:WSGI Server将从App中得到的所有信息封装为一个response返回给浏览器。

2. WSGI示例

wsgiref简单示例

运行以下示例程序后,在浏览器中输入以http://127.0.0.1:9999/开头的随意一个url都可以看到返回结果。实例程序中所有url都会以同一个App进行处理,实际生产环境中不同的url肯定是需要映射到不同的App上的,但这部分本文不作讲解。

# wsgiref是Python自带的内置库,它用来开发者对wsgi进行测试用的,不可以用在生产环境中
from wsgiref.simple_server import make_server, demo_app

# wsgi也是基于socket server编写
# 默认情况下会将所有url都传入demo_app进行处理,具体可参考demo_app源码
# app参数可以是任何可调用对象,但是内部处理需要参考demo_app源码,即environ处理、start_response调用、返回值类型
ws = make_server('127.0.0.1', 9999, demo_app)
# 启动服务
ws.serve_forever()

demo_app源码

def demo_app(environ,start_response):
    from io import StringIO
    stdout = StringIO()
    print("Hello world!", file=stdout)
    print(file=stdout)
    # environ是一个字典,包含了所有请求信息
    h = sorted(environ.items())
    for k,v in h:
        print(k,'=',repr(v), file=stdout)
    # return之前需要调用start_response设置响应头信息
    start_response("200 OK", [('Content-Type','text/plain; charset=utf-8')])
    return [stdout.getvalue().encode("utf-8")]  # 一个可迭代对象,元素为byte类型,元素内容依据start_response中指定的Content-Type来指定

demo_app类定义的两种方式

# 第一种方式:定义类的__init__和__iter__方法,前者用来接收和处理environ和start_response,后者生成一个可迭代对象
# make_server中app参数只需传入类名即可
class ApplicationClass:
    def __init__(self, environ, start_response):
        self.e = environ
        self.sr = start_response

    def __iter__(self):
        from io import StringIO
        stdout = StringIO()
        print("Hello world!", file=stdout)
        print(file=stdout)
        h = sorted(self.e.items())
        for k, v in h:
            print(k, '=', repr(v), file=stdout)
        self.sr("200 OK", [('Content-Type', 'text/plain; charset=utf-8')])
        yield from [stdout.getvalue().encode("utf-8")]

# 第二种方式:定义__call__方法,接收和处理environ和start_response,并返回一个可迭代对象
# make_server中app参数需要传入类的实例
class ApplicationInstance:
    def __call__(self, environ, start_response):
        from io import StringIO
        stdout = StringIO()
        print("Hello world!", file=stdout)
        print(file=stdout)
        h = sorted(environ.items())
        for k, v in h:
            print(k, '=', repr(v), file=stdout)
        start_response("200 OK", [('Content-Type', 'text/plain; charset=utf-8')])
        return [stdout.getvalue().encode("utf-8")]

3. WSGI web服务器和应用程序

WSGI web服务器

  • 本质上是一个TCP服务器,监听在特定的端口上。
  • 支持HTTP协议,能够解析HTTP请求报文,能够按HTTP协议将响应数据封装为报文并返回给浏览器。
  • 实现了WSGI协议,该协议约定了和应用程序之间的接口,即url到app之间的映射。

WSGI应用程序

  • 遵从WSGI协议。
  • 本身是一个可调用对象。
  • 调用start_response,返回响应头部。
  • 返回包含正文的可迭代对象。

以上就是python 内置库wsgiref的使用(WSGI基础入门)的详细内容,更多关于python wsgiref的使用的资料请关注我们其它相关文章!

(0)

相关推荐

  • python web框架 django wsgi原理解析

    前言 django wsgi python有个自带的wsgi模块 可以写自定义web框架 用wsgi在内部创建socket对象就可以了 自己只写处理函数就可以了 django只是web框架 他也不负责写socket django 依赖wsgi接口创建socket wsgi是一套规则 是一套接口 按照wsgi规则写 以后想封装socket 在内部封装socket就可以了 我只要遵循规则 把wsgi模块一导入 我就可以使用wsgi写的socket了 遵循wsg socketi接口有哪些 这些模块已经

  • VPS CENTOS 上配置python,mysql,nginx,uwsgi,django的方法详解

    本文实例讲述了VPS CENTOS 上配置python,mysql,nginx,uwsgi,django的方法.分享给大家供大家参考,具体如下: 昨天试用了VPS,花了一天部署了一个简单应用.在下面的过程中省去了用django 创建project的一步,忘记了你自己一用startporject 创建. 下面是原来边操作,边记录的东西,我习惯文本编辑.可能格式不好看.现在搬到博客中来. 首先安装GCC. yum -y install gcc automake autoconf libtool ma

  • Python WSGI 规范简介

    作为 Python Web 开发者来说,在开发程序阶段一般是不会接触到 WSGI 这个名词的,但当程序开发完成,考虑上线部署的时候,WSGI 规范是一个绕不开的话题,本文将介绍何为 WSGI. WSGI 全拼 Web Server Gateway Interface,是为 Python 语言定义的 Web 服务器和 Web 应用程序(或框架)之间的一种通用编程接口.翻译成白话就是说 WSGI 是一个协议,就像 HTTP 协议定义了客户端和服务端数据传输的规范,WSGI 协议定义了 Web 服务器

  • CentOS7部署Flask(Apache、mod_wsgi、Python36、venv)

    一.安装Apache # yum install -y httpd httpd-devel # systemctl start httpd.service # 启动 # systemctl stop httpd.service # 关闭 # systemctl restart httpd.service # 重启 # systemctl enable httpd.service # 开机自启 防火墙开放80端口 # firewall-cmd --zone=public --add-port=80

  • python 解决flask uwsgi 获取不到全局变量的问题

    问题 在写flask,使用uwsgi启动的时候,涉及到多request线程访问同一个全局变量,发现不能获取到全局变量的值的修改,这在flask独立启动的时候是没有问题的. 伪代码 全局变量 @app.route('/request1/') def 函数1 修改全局变量 @app.route('/request2/') def 函数2 获取全局变量 严重怀疑是uwsgi的线程机制的问题,因为uwsgi是可以指定子进程的数目的,然而我设置子进程数目为1,之后,在处理函数1的时候是不能同时处理函数2的

  • Python开发之Nginx+uWSGI+virtualenv多项目部署教程

    1.新建独立运行环境,命名为env [root@vultr ~]# mkdir projects # 测试的项目总目录 [root@vultr ~]# pip3 install virtualenv [root@vultr ~]# cd projects [root@vultr projects]# virtualenv env --python=python3 --no-site-packages --python:指定Python版本 --no-site-packages:不复制系统已安装P

  • Docker构建python Flask+ nginx+uwsgi容器

    安装Nginx 首先拉下centos镜像docker pull centos 我们安装最新的nginx1.19版本:下载地址 将centos镜像运行起来并进入: docker run --name ver -d -p 8051:80 -it nginx_start 将nginx-1.19.0.tar.gz这个包放入容器里面: docker cp nginx-1.19.0.tar.gz 10e87af84c05:/root(10e87af84c05为centos容器id) 安装nginx前先装一些

  • 详解如何在Apache中运行Python WSGI应用

    在生产环境上,一般会使用比较健壮的Web服务器,如Apache来运行我们的应用.如果我们的Web应用是采用Python开发,而且符合WSGI规范,比如基于Django,Flask等框架,那如何将其部署在Apache中呢?本文中,我们就会介绍如何使用Apache模块mod_wsgi来运行Python WSGI应用. 安装mod_wsgi 我们假设你已经有了Apache和Python环境,在Linux或者Mac上,那第一步自然是安装.在Ubuntu或Debian环境中,你可以使用apt-get命令来

  • 浅析Python 中的 WSGI 接口和 WSGI 服务的运行

    HTTP格式 HTTP GET请求的格式: GET /path HTTP/1.1 Header1: Value1 Header2: Value2 Header3: Value3 每个Header一行一个,换行符是\r\n. HTTP POST请求的格式: POST /path HTTP/1.1 Header1: Value1 Header2: Value2 Header3: Value3 body data goes here... 当遇到连续两个\r\n时,Header部分结束,后面的数据全部

  • python wsgiref源码解析

    python web开发中http请求的处理流程通常是: web-browser , web-server , wsgi 和 web-application四个环节, 我们学习过基于bottle实现的web-application,也学习了http.server.再完成python3源码中自带的wsgiref的库,就可以拼接最后一个环节wsgi.本文会分下面几个部分: wsgi相关概念 cgi示例 wsgiref源码 wsgi小结 小技巧 wsgi 相关概念 CGI CGI(Common Gat

随机推荐