WSGI+pastedeploy+webob

本文深入探讨了WSGI标准,PasteDeploy配置方法,以及WebOb库的应用,展示了如何通过这些技术实现灵活的Web应用程序部署与请求处理。

web server接收HTTP请求,封装环境变量,按照WSGI接口标准调用注册的WSGI Application,返回响应给客户端。

paste.deploy

openstack使用pastedeploy组件来完成WSGI服务器和应用的构建
  • section:[type: name]
    • type = composite
      •  把URL请求分发给对应的app
    • type = app
      • app是具体的WSGI Application
    • type = filter-app
      • 过滤并转发给app
    • type = filter
      • 类似于filter-app,但没有next
    • type = pipeline
      • 由filter+...+filter+app组成
# config.ini 

[composite:main]
# use表明具体的分发方式
# egg:Paste#urlmap表示使用paste包中的urlmap模块
use = egg:Paste#urlmap     
# key=value表示使用urlmap进行分发的参数
/ = home
/wiki = wiki
/blog = blog
/cms = config:cms.ini

[app:home]
# use指定app
# python egg
use = egg:Paste#static

[app:app2]
# config.ini
use = config:myconfig.ini#app_name

[app:app3]
# 直接调用另外一个模块中的app
use = call:myproject:application

[app:app4]
# 另外一个section
use = myotherapp

[app:app5]
# myapp.modulename
paste.app_factory = myapp.modulename:app_factory

[filter-app:blog]
# use指定过滤条件
use = egg:Authentication#auth
# next表示过滤后的app
next = blogapp
roles = admin
htpasswd = /home/me/users.htpasswd

[pipeline:main]
pipeline = filter1 egg:FilterEgg#filter2 filter3 app

[filter:filter1]
...
  • app_factory
def app_factory(loader, global_config, **local_conf)
    return wsgi_app
  • 调用paste.deploy
from paste.deploy import loadapp
wsgi_app = loadapp('config:/path/to/config.ini')

webob

webob对WSGI请求与响应进行封装

  • webob.Request

    • 对WSGI请求的environ参数进行封装

  • webob.Response

    • 包含所有标准WSGI响应要素

  • webob.exc

    • 封装HTTP错误代码

  • webob.dec.wsgify

    • 封装WSGI参数和返回格式

 

  • 标准WSGI格式

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return '<h1>Hello</h1>'
  • webob.dec.wsgify封装格式

@webob.dec.wsgify
def application(req):
    return webob.Response('OK')
# RequestClass过滤
@webob.dec.wsgify(RequestClass=MyRequest)

WSGI

  • 标准WSGI格式

def application(environ, start_response):
    # HTTP请求:environ
    # HTTP响应:start_response(HTTP响应码,HTTP Header, 错误信息)
    start_response('200 OK', [('Content-Type', 'text/html')], exc_info=None)
    # 返回Body
    return '<h1>Hello</h1>'

WSGI+pastedeploy+webob

 

# tsroutes.ini

[composite:main]
use=egg:Paste#urlmap
/=show

[pipeline:show]
pipeline = root

[app:root]
paste.app_factory = tsroutes:Router.app_factory

 

# tsroutes.py

import logging
import os

import webob.dec
import webob.exc

from paste.deploy import loadapp
from wsgiref.simple_server import make_server

import routes.middleware


LOG = logging.getLogger(__name__)


class Controller(object):
    @webob.dec.wsgify
    def __call__(self, req):
        arg_dict = req.environ['wsgiorg.routing_args'][1]
        action = arg_dict.pop('action')

        return webob.Response('OK')

    def getMessage(self, context, user_id):
        return {'Message': 'TestMessage'}


class Router(object):
    def __init__(self):
        self._mapper = routes.Mapper()
        self._mapper.connect('/test/{user_id}',
                             controller=Controller(),
                             action='getMessage',
                             conditions={'method': ['GET']})
        self._router = routes.middleware.RoutesMiddleware(self._dispatch, self._mapper)


    @webob.dec.wsgify
    def __call__(self, req):
        return self._router

    @staticmethod
    @webob.dec.wsgify
    def _dispatch(req):
        match = req.environ['wsgiorg.routing_args'][1]

        if not match:
            return webob.exc.HTTPNotFound()

        app = match['controller']
        return app

    @classmethod
    def app_factory(cls, global_config, **local_config):
        return cls()


if __name__ == '__main__':
    configfile = 'tsroutes.ini'
    appname = "main"
    wsgi_app = loadapp("config:%s" % os.path.abspath(configfile), appname)
    httpd = make_server('localhost', 8282, wsgi_app)
    httpd.serve_forever()

测试:localhost:8282/test/1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值