±¾»ÃµÆƬÊʺÏ
- ¶ÔÏÖÓÐWeb¿ò¼Ü¸Ðµ½²»ÂúµÄÈË
- ΪPythonic¿ñÈȵÄÈË
- Á¢Ö¾×Ô¼º¿ª·¢Web¿ò¼ÜµÄÈË
- ÎÞËùÊÂʵÄÈË
- ¼á³Ö¼òµ¥ÔÔò, ¶ÔWeb¿ª·¢Ã»ÓÐÌرðÒªÇóµÄÈË, ÏñÎÒ
ʲôÊÇWSGI
- WSGI:Python Web Server Gateway Interface v1.0
- ËüÊÇ
PEP333
Öж¨ÒåµÄ
- WSGIÊÇPythonÓ¦ÓóÌÐò»ò¿ò¼ÜºÍWeb·þÎñÆ÷Ö®¼äµÄÒ»ÖÖ½Ó¿Ú
- WSGI±»¹ã·º½ÓÊÜ, ÒÑ»ù±¾´ï³ÉËüÁË¿ÉÒÆÖ²ÐÔ·½ÃæµÄÄ¿±ê
- ÔÚGuidoµÄ
Blog
Öз´¸´Ìá¼°, ¸öÈËÈÏΪWSGIÊÇPython Web·½Ãæ×îPythonicµÄ
- ÀàËÆÓÚJavaÖеÄ"servlet" API
WSGIµÄÄ¿±ê¼°Ìصã
Ä¿±ê
- PEP333µÄÄ¿±ê½¨Á¢Ò»¸ö¼òµ¥µÄÆÕ±éÊÊÓõķþÎñÆ÷ÓëWeb¿ò¼ÜÖ®¼äµÄ½Ó¿Ú:
Python Web Server Gateway Interface
Ìصã
- ¼òµ¥(ÀàËÆCGI)
- ¿ÉÒÆÖ²
- µ×²ã(Öмä¼þ?)
WSGIµÄʵÏÖ(1)
- WSGI ûÓйٷ½µÄʵÏÖ, ÒòΪWSGI¸üÏñÒ»¸öÐÒé.
Ö»Òª×ñÕÕÕâЩÐÒé,WSGIÓ¦ÓÃ(Application)¶¼¿ÉÒÔÔÚÈκÎʵÏÖ(Server)ÉÏÔËÐÐ, ·´Ö®ÒàÈ»
- wsgiref - PEP333µÄ×÷ÕßдµÄWSGI»ù´¡¿â, ʵÏÖÁË´ó¶àÊýWSGIʵÏÖÖеÄÄѵã.
- Python Paste
- WSGIµ×²ã¹¤¾ß¼¯. °üÀ¨¶àÏß³Ì, SSLºÍ
»ùÓÚCookies, sessionsµÈµÄÑéÖ¤(authentication)¿â.
¿ÉÒÔÓÃPasts·½±ãµÃ´î½¨×Ô¼ºµÄWeb¿ò¼Ü
- PEAK - Python Enterprise Application Kit
- WSGIUtils
WSGIµÄʵÏÖ(2)
-
py-lib - °üÀ¨ÁËÒ»¶ÑWSGIµÄʵÏÖ¼°¹¤¾ß
- Python Web
- WSGIarea
- Twisted Web2 ʵÑéÐÔHTTP·þÎñÆ÷ , ÓÐWSGIʵÏÖ
- modjy - JythonµÄWSGIʵÏÖ
- isapi_wsgi - IISµÄWSGIʵÏÖ
Ö§³ÖWSGIµÄWeb¿ò¼Ü
- Colubrid Ò»¸öÇáÁ¿¼¶µÄWSGI¹¤¾ß¼¯(²»ÄÜ˵ÍêÈ«ÊÇ¿ò¼Ü), WSGIareaÏÂÊô
- CherryPy
- Django
- Zope 3
- QWIP -
Quixote µÄWSGI½Ó¿Ú.
Middleware
WSGIµÄÀ©Õ¹¾ÍÔÚÓÚÖмä¼þ, ÔÔòÉÏÖмä¼þ¿É¸÷ÖÖWSGIʵÏÖÖÐͨÓÃ, ÏÂÃæÌṩ¿ÉÒÔÕÒµ½¸÷ÖÖÖмä¼þµÄµØ·½:
- flup Öмä¼þ°üÀ¨error, gzip, sessionµÈ
- WSGIarea
- ÆäËü¸÷ÖÖWSGIʵÏÖ, ÉõÖÁÊÇijЩFrameworkµÄʵÏÖÖÐ
WSGIµÄ½á¹¹
- WSGI·ÖΪÁ½¸ö·½Ãæ: Server/Gateway·½ÃæºÍApplication/Framework·½Ãæ
- WSGIµÄ½á¹¹¿ÉÒÔÐÎÏóµÃ±íʾΪÈçϼ¸ÖÖÐÎʽ:
WSGI/Server -- Application
WSGI/Server -- Framework -- Framework Application
httpd -- WSGI/Gateway -- Application
httpd -- WSGI/Gateway -- Framework -- Framework Application
Ò»¸ö¼òµ¥µÄÀý×Ó(1)
Application/function
def simple_app(environ, start_response):
"""Simplest possible application object"""
status = '200 OK'
response_headers = [('Content-type','text/plain')]
start_response(status, response_headers)
return ['Hello world!\n']
Ò»¸ö¼òµ¥µÄÀý×Ó(2)
Application/class
class AppClass:
def __init__(self, environ, start_response):
self.environ = environ
self.start = start_response
def __iter__(self):
status = '200 OK'
response_headers = [('Content-type','text/plain')]
self.start(status, response_headers)
yield "Hello world!\n"
MiddlewareµÄÀý×Ó(1)
class UpperIter:
def __init__(self,result,transform_ok):
if hasattr(result,'close'):
self.close = result.close
self._next = iter(result).next
self.transform_ok = transform_ok
def __iter__(self):
return self
def next(self):
if self.transform_ok:
return self._next().upper()
else:
return self._next()
MiddlewareµÄÀý×Ó(2)
class Upperator:
transform = False
def __init__(self, application):
self.application = application
def __call__(self, environ, start_response):
transform_ok = []
def start_upper(status,response_headers,exc_info=None):
# Reset ok flag, in case this is a repeat call
transform_ok[:]=[]
for name,value in response_headers:
if name.lower()=='content-type' and value=='text/plain':
transform_ok.append(True)
# Strip content-length if present, else it'll be wrong
response_headers = [(name,value)
for name,value in response_headers
if name.lower()<>'content-length'
]
break
MiddlewareµÄÀý×Ó(3)
write = start_response(status,
response_headers,exc_info)
if exc_info:
try:
write('Errortype:%s\nValue:%s\nTraceback:%s'%
(exc_info[0], exc_info[1],
traceback.format_tb(exc_info[2]))
)
finally:
exec_info = None
if transform_ok:
def write_upper(data):
write(data.upper())
return write_upper
else:
return write
return UpperIter(self.application(environ,start_upper),
transform_ok)
MiddlewareµÄÀý×Ó(4)(´íÎó´¦Àí)
def e_app(environ, start_response):
try:
# regular application code here
status = "200 Froody"
response_headers = [("content-type","text/plain")]
start_response(status, response_headers)
a = 1/0
return ["normal body goes here"]
except:
# XXX should trap runtime issues like MemoryError, KeyboardInterrupt
# in a separate handler before this bare 'except:'...
status = "500 Oops"
response_headers = [("content-type","text/plain")]
start_response(status, response_headers, sys.exc_info())
return ["\nerror body goes here"]
MiddlewareµÄÀý×Ó(5)
uapp = Upperator(simple_app)
eapp = Upperator(e_app)
´¦Àí»·¾³±äÁ¿(±íµ¥)
def form_app(environ, start_response):
status = "200 Froody"
response_headers = [("content-type","text/html")]
form = cgi.FieldStorage(fp=environ['wsgi.input'],
environ= environ, keep_blank_values=0)
start_response(status, response_headers)
if form.has_key('username'):
name = form['username'].value
if form.has_key('passwd'):
passwd = form['passwd'].value
return [formstr%(name, passwd)]
pyblosxom
ÎÒ¶ÔWSGIµÄÁ˽âÔ´×Ôpyblosxom, ËûÊǸö±ê×¼µÄWSGIÓ¦ÓÃ, ͨ¹ýmiddlewareÀ©Õ¹»ñµÃsessionºó,
ÎÒдÁËһЩ²å¼þ,
¿É¼ûmdxxµÄ
´úÂë¿â.
±¾»ÃµÆƬʹÓÃÈí¼þ
S5 Woodpecker Ä£°å
python2html.1.py
Apache + mod_python + mp_wsgi_handler/wsgiref
лл!