一个UWSGI的例子 *************************************

2024-04-30 14:32
文章标签 uwsgi 例子

本文主要是介绍一个UWSGI的例子 *************************************,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://blog.csdn.net/crazyhacking/article/details/18617873

 

 

摘要:uwsgi执行顺序:启动master进程,执行python脚本的公共代码(import同一层)。然后生成worker进程,uwsgi.post_fork_hook=init_functions,初始化生成work子进程。然后请求来临时,每个子进程执行application代码

什么是WSGI
wsgi是一个在web服务器和应用程序app之间统一的接口,这样来规范app和web server,说的简单一点就是规范的接受web请求(request),但是不仅如此
1 你在类似CGI环境里分发传递,意味着数据可以在登录用户安全传递
2 在类似CGI环境里传递更多的上下文信息,脚本名称和路径
3 你可以扩展自身的wsgi环境,并允许回调,扩展信息并插入python对象,任何你想添加的却不能在http头里添加的
wsgi不仅仅是在web和应用之间,可以用在交互的每个层面 ,这使得应用app变成lib库,可以很好的扩展和重用

写一个wsgi应用

我们来简单的写一个wsgi的应用
简短的一个摘要
1 一个简单的wsgi应用就是一个可调用的对象比如一个function,有两个参数environ 和 start_response
2 环境environment是一个字典,python的标准字典有一些传统的http参数比如REQUEST_METHOD和HTTP_POST
3 environment可以包含一些特别的键wsgi.input 像post请求里的输入流
4 start_response是一个返回客户端结果的方法,需要提供http的状态和headers
start_response 是一个接受两个必需的固定参数和一个可选参数的 callable 对象. 为便于说明, 我们把这三个参数分别命名为: status, response_headers, 和 exc_info, 当然你也可以给他们起其他名字. 应用程序必需使用固定参数调用 start_response (比如:
start_response(status,response_headers)) , 参数 status 是一个形如 “999 Message here” 的表示状态的字符串。而 response_headers 参数是一个描述 http 响应头的列表, 其中每一个元素都是像 (header_name,header_value) 这样的元组。可选的 exc_info 参数会在后面的 start_response() callable 和 错误处理 两节中进行描述,该参数只有在应用程序产生了错误并希望在浏览器上显示错误信息的时候才用得上。

5 最后应用返回一个含有迭代器的response(通常是一个字符串列表)
例子

 

1
2
3
def app(environ, start_response):
    start_response('200 OK', [('content-type', 'text/html')])
    return ['Hello world!']

 

然后更简单的一个server来运行这个app

 

1
2
3
if __name__ == '__main__':
    from paste import httpserver
    httpserver.serve(app, host='127.0.0.1', port='8080')

 

这样就可以在本机用8080端口来请求他了

一个带有互动的例子

 

1
2
3
4
5
6
7
8
9
10
from paste.request import parse_formvars
def app(environ, start_response):
    fields = parse_formvars(environ)
    if environ['REQUEST_METHOD'] == 'POST':
        start_response('200 OK', [('content-type', 'text/html')])
        return ['Hello, ', fields['name'], '!']
    else:
        start_response('200 OK', [('content-type', 'text/html')])
        return ['<form method="POST">Name: <input type="text" '
                'name="name"><input type="submit"></form>']

 

这些都很简单,我们需要更多的页面,测试还有运行环境

对象发布 Object publishing
一个典型的对象发布 转换 ‘/’ 为 ‘..’
/articles/view?id=5 转换为 root.articles.view(id=5)
我们必须启动相应的对象

1
2
3
4
5
6
class ObjectPublisher(object):
def __init__(self, root):
        self.root = root
def __call__(self, environ, start_response):
        ...
app = ObjectPublisher(my_root_object)

 

我们重写__call__方法来实现一个callable ObjectPublisher ,就像一个wsgi的方法,现在我们要做的事情就是传递environ进去,调用它,然后返回结果response

路径
WSGI会把请求的路径放到两个变量SCRIPT_NAME和PATH_INFO里
SCRIPT_NAME就是我们将要到达的地方脚本名称,PATH_INFO
就是请求的路径,这是框架寻找对象的方式

我们来实现__call__方法

class ObjectPublisher(object):
def __init__(self, root):
        self.root = root
def __call__(self, environ, start_response):
        ...
app = ObjectPublisher(my_root_object)

我们重写__call__方法来实现一个callable ObjectPublisher ,就像一个wsgi的方法,现在我们要做的事情就是传递environ进去,调用它,然后返回结果response

路径
WSGI会把请求的路径放到两个变量SCRIPT_NAME和PATH_INFO里
SCRIPT_NAME就是我们将要到达的地方脚本名称,PATH_INFO就是请求的路径,这是框架寻找对象的方式

我们来实现__call__方法

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def __call__(self, environ, start_response):
    fields = parse_formvars(environ)
    obj = self.find_object(self.root, environ)
    response_body = obj(**fields.mixed())
    start_response('200 OK', [('content-type', 'text/html')])
    return [response_body]
def find_object(self, obj, environ):
    path_info = environ.get('PATH_INFO', '')
    if not path_info or path_info == '/':
        # We've arrived!
        return obj
    # PATH_INFO always starts with a /, so we'll get rid of it:
    path_info = path_info.lstrip('/')
    # Then split the path into the "next" chunk, and everything
    # after it ("rest"):
    parts = path_info.split('/', 1)
    next = parts[0]
    if len(parts) == 1:
        rest = ''
    else:
        rest = '/' + parts[1]
    # Hide private methods/attributes:
    assert not next.startswith('_')
    # Now we get the attribute; getattr(a, 'b') is equivalent
    # to a.b...
    next_obj = getattr(obj, next)
    # Now fix up SCRIPT_NAME and PATH_INFO...
    environ['SCRIPT_NAME'] += '/' + next
    environ['PATH_INFO'] = rest
    # and now parse the remaining part of the URL...
    return self.find_object(next_obj, environ)

 

现在用ObjectPublisher来包装应用,并放到一个包中去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from objectpub import ObjectPublisher
class Root(object):
# The "index" method:
    def __call__(self):
        return 
'''
        <form action="welcome">
        Name: <input type="text" name="name">
        <input type="submit">
        </form>
        '''

def welcome(self, name):
        return 'Hello %s!' % name
app = ObjectPublisher(Root())
if __name__ == '__main__':
    from paste import httpserver
    httpserver.serve(app, host='127.0.0.1', port='8080')

 

需要注意的是,本来WSGI是要传入一个app的方法的,于是这里用了对象,并实现了__call__方法,结果是一样的

我们会发现缺少很多东西,比较特殊的我们没有地方去设置输出的headers,还有request里的信息是很少的

 

1
2
3
4
5
6
7
8
9
10
11
# This is just a dictionary-like object that has case-
# insensitive keys:
from paste.response import HeaderDict
class Request(object):
    def __init__(self, environ):
        self.environ = environ
        self.fields = parse_formvars(environ)
class Response(object):
    def __init__(self):
        self.headers = HeaderDict(
            {'content-type''text/html'})

 

我们不想改变方法,但是不能让request对象和response对象在全局的变量里,因为我们想要线程安全
修改__call__方法为

 

1
2
3
4
5
6
7
8
9
10
11
import threading
webinfo = threading.local()
class ObjectPublisher(object):
    ...
def __call__(self, environ, start_response):
        webinfo.request = Request(environ)
        webinfo.response = Response()
        obj = self.find_object(self.root, environ)
        response_body = obj(**dict(webinfo.request.fields))
        start_response('200 OK', webinfo.response.headers.items())
        return [response_body]

 

现在在我们的方法里可以这么做

 

1
2
3
class Root:
    def rss(self):
        webinfo.response.headers['content-type'] = 'text/xml'

 

 

这篇关于一个UWSGI的例子 *************************************的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/949119

相关文章

JavaFX环境的搭建和一个简单的例子

之前在网上搜了很多与javaFX相关的资料,都说要在Eclepse上要安装sdk插件什么的,反正就是乱七八糟的一大片,最后还是没搞成功,所以我在这里写下我搭建javaFX成功的环境给大家做一个参考吧。希望能帮助到你们! 1.首先要保证你的jdk版本能够支持JavaFX的开发,jdk-7u25版本以上的都能支持,最好安装jdk8吧,因为jdk8对支持JavaFX有新的特性了,比如:3D等;

javaScript日期相加减例子

当前时间加上2天 var d = new Date(“2015-7-31”); d.setDate(d.getDate()+2); var addTwo=d.getFullYear()+”年”+(d.getMonth()+1)+”月”+d.getDate()+”日”; “控制台输出===============”+”当前日期加2天:”+addTwo; 使用这种方法,月份也会给你计算.

设计模式大全和详解,含Python代码例子

若有不理解,可以问一下这几个免费的AI网站 https://ai-to.cn/chathttp://m6z.cn/6arKdNhttp://m6z.cn/6b1quhhttp://m6z.cn/6wVAQGhttp://m6z.cn/63vlPw 下面是设计模式的简要介绍和 Python 代码示例,涵盖主要的创建型、结构型和行为型模式。 一、创建型模式 1. 单例模式 (Singleton

JSP 简单表单显示例子

<html><!--http://localhost:8080/test_jsp/input.html --><head><meta http-equiv="Content-Type" content="text/HTML; charset=utf-8"><title>input页面</title></head><body><form action="input.jsp" method

shell循环sleep while例子 条件判断

i=1# 小于5等于时候才执行while [ ${i} -le 5 ]doecho ${i}i=`expr ${i} + 1`# 休眠3秒sleep 3doneecho done 参考 http://c.biancheng.net/cpp/view/2736.html

【ReactJS】通过一个例子学习React组件的生命周期

源代码 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Reac

简单的android Listview使用例子

为了熟悉Listview的使用,做了一个小例子联系一下, 主要步骤: 1. 在MainActivity中,创建一个adapter对象(可以是android自带的ArrayAdapter,也可以是自定义的如SongAdapter) 2. 如果自定义,就要创建ListView的子项,如song_listview_item.xml 3. 创建ListView对象,并用setAdapter方法把a

【 python pymongo】使用pymongo的例子

MongoDB优点 MongoDB是一个为当代web应用而生的noSQL数据库,它有如下优点: 1、文档型存储。可以把关系型数据库的表理解为一个电子表格,列表示字段,每行的记录其实是按照列的字段顺序排列的值得元组。而存储在MongoDB中的文档被存储为键-值对的形式,值却可以是任意类型且可以嵌套。之前在用关系型数据库的时候,我们把产品信息打散到不同的表中,要通过关系表或者使用join拼接成复杂

c:if test=/c:if如何判断空(使用例子)

userName是登录的时候放到session中了 <c:if test="${ not empty userName }">这表示userName判断不为null `<c:if test="${empty userName }"> ` 这表示userName判断为null 使用案例 <c:if test="${ not empty userName }"><ul><li><a

CSS学习6--背景图片、颜色、位置、附着、简写、透明、缩放、多背景、凹凸文字、导航栏例子

CSS背景 一、背景颜色和图片二、背景位置三、背景附着四、背景简写五、背景透明六、背景缩放七、多背景八、凹凸文字九、导航栏例子 一、背景颜色和图片 background-color: pink; 背景颜色backgroundoimage: url(##.jpg); 背景图片background-repeat: 平铺 repeat-x横向平铺,repeat-y纵向平铺; 平铺不到