WSGI學習系列WebOb

1. WSGI Server <-----> WSGI Middleware<-----> WSGI Application html

 

1.1 WSGI Serverweb

  wsgi server能夠理解爲一個符合wsgi規範的web server,接收request請求,封裝一系列環境變量,按照wsgi規範調用註冊的wsgi app,最後將response返回給客戶端。服務器

 

1.2 WSGI Applicationapp

      wsgi application就是一個普通的callable對象,當有請求到來時,wsgi server會調用這個wsgi application。函數

   這個對象接收兩個參數,一般爲environ,start_response。ui

   environ能夠理解爲環境變量,跟一次請求相關的全部信息都保存在了這個環境變量中,包括服務器信息,客戶端信息,請求信息。url

   start_response是一個callback函數,wsgi application經過調用start_response,將response headers/status 返回給wsgi server。spa

   此外這個wsgi application會return一個iterator對象 ,這個iterator就是response body。code

 

1.3 WSGI Middlewareorm

  中間件是爲了使應用程序擁有額外的行爲而存在的。若是你不能隨意決定是否將它放到程序的前面,它就再也不是中間件了。而是程序的一部分。

  好比:URL dispatch功能,權限判斷。

 

1.4 WSGI模型示例
 
from wsgiref.simple_server import make_server

URL_PATTERNS= (
    ('hi/','say_hi'),
    ('hello/','say_hello'),
    )

class Dispatcher(object):

    def _match(self,path):
        path = path.split('/')[1]
        for url,app in URL_PATTERNS:
            if path in url:
                return app

    def __call__(self,environ, start_response):
        path = environ.get('PATH_INFO','/')
        app = self._match(path)
        if app :
            app = globals()[app]
            return app(environ, start_response)
        else:
            start_response("404 NOT FOUND",[('Content-type', 'text/plain')])
            return ["Page dose not exists!"]

def say_hi(environ, start_response):
    start_response("200 OK",[('Content-type', 'text/html')])
    return ["kenshin say hi to you!"]

def say_hello(environ, start_response):
    start_response("200 OK",[('Content-type', 'text/html')])
    return ["kenshin say hello to you!"]

app = Dispatcher()

httpd = make_server('', 8000, app)
print "Serving on port 8000..."
httpd.serve_forever()

 

2.WebOb

  WebOb是一個用於對WSGI Request環境進行包裝,以及用於建立WSGI Response的一個包。

  WebOb把WSGI的幾個參數、返回的方法都封裝成了Reqeust、Response這兩個對象,同時還提供了一個使用方便的Exception對象。

  Related API Link: http://docs.webob.org/en/latest/reference.html

2.1 Request

from webob import Request
 
req = Request.blank('/')
 
def wsgi_app(environ, start_response):
    start_response('200 OK', [('Content-type', 'text/plain')])
    return ['Hi!']
 
print req.call_application(wsgi_app)

2.2 Response

from webob import Response
from pprint import pprint
res = Response(content_type='text/plain', charset=None) f = res.body_file f.write('hey') f.write('test') # pprint(res.status) # pprint(res.headerlist) # pprint(res.body)

2.3 Full Sample about Request and Response

from webob import Request
from webob import Response
from webob.dec import wsgify

# @wsgify
def my_app(environ, start_response):
    req = Request(environ)
    res = Response()
    res.content_type = 'text/plain'
    parts = []
    for name, value in sorted(req.environ.items()):
        parts.append('%s: %r' % (name, value))
    res.body = 'n'.join(parts)
    return res(environ, start_response)

req = Request.blank('/')
res = req.get_response(my_app)
print res

2.4 Exception

  下述總結了WebOb對於HTTP返回碼的類定義。

Exception
  HTTPException
    HTTPOk
      * 200 - :class:`HTTPOk`
      * 201 - :class:`HTTPCreated`
      * 202 - :class:`HTTPAccepted`
      * 203 - :class:`HTTPNonAuthoritativeInformation`
      * 204 - :class:`HTTPNoContent`
      * 205 - :class:`HTTPResetContent`
      * 206 - :class:`HTTPPartialContent`
    HTTPRedirection
      * 300 - :class:`HTTPMultipleChoices`
      * 301 - :class:`HTTPMovedPermanently`
      * 302 - :class:`HTTPFound`
      * 303 - :class:`HTTPSeeOther`
      * 304 - :class:`HTTPNotModified`
      * 305 - :class:`HTTPUseProxy`
      * 307 - :class:`HTTPTemporaryRedirect`
    HTTPError
      HTTPClientError
        * 400 - :class:`HTTPBadRequest`
        * 401 - :class:`HTTPUnauthorized`
        * 402 - :class:`HTTPPaymentRequired`
        * 403 - :class:`HTTPForbidden`
        * 404 - :class:`HTTPNotFound`
        * 405 - :class:`HTTPMethodNotAllowed`
        * 406 - :class:`HTTPNotAcceptable`
        * 407 - :class:`HTTPProxyAuthenticationRequired`
        * 408 - :class:`HTTPRequestTimeout`
        * 409 - :class:`HTTPConflict`
        * 410 - :class:`HTTPGone`
        * 411 - :class:`HTTPLengthRequired`
        * 412 - :class:`HTTPPreconditionFailed`
        * 413 - :class:`HTTPRequestEntityTooLarge`
        * 414 - :class:`HTTPRequestURITooLong`
        * 415 - :class:`HTTPUnsupportedMediaType`
        * 416 - :class:`HTTPRequestRangeNotSatisfiable`
        * 417 - :class:`HTTPExpectationFailed`
        * 422 - :class:`HTTPUnprocessableEntity`
        * 423 - :class:`HTTPLocked`
        * 424 - :class:`HTTPFailedDependency`
        * 428 - :class:`HTTPPreconditionRequired`
        * 429 - :class:`HTTPTooManyRequests`
        * 431 - :class:`HTTPRequestHeaderFieldsTooLarge`
        * 451 - :class:`HTTPUnavailableForLegalReasons`
      HTTPServerError
        * 500 - :class:`HTTPInternalServerError`
        * 501 - :class:`HTTPNotImplemented`
        * 502 - :class:`HTTPBadGateway`
        * 503 - :class:`HTTPServiceUnavailable`
        * 504 - :class:`HTTPGatewayTimeout`
        * 505 - :class:`HTTPVersionNotSupported`
        * 511 - :class:`HTTPNetworkAuthenticationRequired`
相關文章
相關標籤/搜索