Web服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。自从WSGI被开发出来以后,许多其它语言中也出现了类似接口。
def app(environ, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) yield "Hello world!\n" time.sleep(5) yield "END\n"
入口处提供一个start_response,用于回流(回调,callback),入口会连接到出口的一个函数,并传递environ字典和start_response作为参数;
而出口处的函数先是调用start_response并传递status和header,然后return返回完整content。或者使用yiled分部分返回content,实现长链接。
from wsgiref.simple_server import make_server def hello_world_app(environ, start_response): status = '200 OK' # HTTP Status headers = [('Content-type', 'text/plain')] # HTTP Headers start_response(status, headers) # The returned object is going to be printed return ["Hello World"] httpd = make_server('', 8000, hello_world_app) print "Serving on port 8000..." # Serve until process is killed httpd.serve_forever() 来自 https://blog.weizhe.net/?p=46
ubuntu下用uwsgi+nginx布署python WEB项目
1.安装nginx,uwsgi以及uwsgi-plugin-python
比如:apt-get install nginx,uwsgi,uwsgi-plugin-python
2.写一个测试文件叫wsgi_httpsvr.py,保存到/home/test_wsgi目录下,内容如下:
from wsgiref.simple_server import make_server def application(environ, start_response): status = '200 OK' # HTTP Status headers = [('Content-type', 'text/plain')] # HTTP Headers start_response(status, headers) # The returned object is going to be printed yield "Hello World" if __name__=='__main__': httpd = make_server('', 8000, application) print "Serving on port 8000..." # Serve until process is killed httpd.serve_forever()
3.在/etc/uwsgi/apps-available下创建一个名叫test_wsgi.xml的配置文件(名称随便),内容如下:
<uwsgi> <socket>127.0.0.1:9006</socket> <plugins>python</plugins> <chdir>/home/test_wsgi</chdir> <module>wsgi_httpsvr</module> </uwsgi>
然后在/etc/uwsgi/apps-enabled下创建一下这个配置文件的link,比如:
ln -s /etc/uwsgi/apps-available/test_wsgi.xml /etc/uwsgi/apps-enabled/test_wsgi.xml
4.在/etc/nginx/sites-available下创建nginx配置文件(名称随便,这里叫test_wsgi),内容如下:
server { listen 80; ## listen for ipv4 server_name wzw.th360.cn; #charset koi8-r; access_log /var/log/nginx/test-wsgi.access.log access; # root html location / { # First attempt to serve request as file, then # as directory, then fall back to index.html #try_files $uri =404; #try_files $uri $uri/ /index.html; include uwsgi_params; uwsgi_pass 127.0.0.1:9006; #uwsgi_pass unix:///tmp/test_wsgi.socket; } }5.执行如下指令:
service uwsgi restart
service nginx reload
======================================================
很奇怪,配置uwsgi的socket为/tmp/test_wsgi.socket方式时,死活不成功,虽然tmp目录下也生成socket文件了,而且服务也正常启动,但是访问nginx时报502 back gateway错误,暂不知道什么原因
=======================================================
以下是两个真实布署django的uwsgi配置文件和nginx的配置文件例子:
<uwsgi> <socket>127.0.0.1:9009</socket> <master/> <uid>www-data</uid> <gid>www-data</gid> <plugins>python</plugins> <chdir>/mnt/data/home/websearch/wwwroot/new_cntsyy/th_payment/payment</chdir> <pythonpath>..</pythonpath> <module>wsgi</module> </uwsgi>
server { listen 80; server_name test.th010.com test.th360.cn; root /mnt/data/home/websearch/wwwroot/new_cntsyy/th_payment; access_log /var/log/nginx/test.th360.cn.access.log access; #error_log /var/log/nginx/test.th360.cn.error.log access; #配置django admin需要的文件 location ~* ^/media/(css|img|js)/.*$ { root /usr/local/lib/python2.7/dist-packages/django/contrib/admin; expires 30d; break; } location ^~ /static { autoindex on; alias /home/websearch/wwwroot/new_cntsyy/th_payment/payment/static; } location / { ###uwsgi config### include uwsgi_params; uwsgi_pass 127.0.0.1:9009; uwsgi_param UWSGI_SCHEME $scheme; uwsgi_param SERVER_SOFTWARE nginx/$nginx_version; } }
uwsgi官方文档:
http://uwsgi-docs.readthedocs.org/en/latest/WSGIquickstart.html#installing-uwsgi-with-python-support
来自 http://mysrc.sinaapp.com/view_note/?id=142
Wsgiref Error: AttributeError: 'NoneType' object has no attribute 'split'
wsgiref错误:意思:“nonetype的对象没有属性“分裂”
问题 (Question)
I am trying to implement my own version of wsgiref for learning purpose and i ended up here.
from wsgiref.simple_server import make_server
class DemoApp():
def __init__(self, environ, start_response):
self.environ = environ
self.start = start_response
def __iter__(self, status):
self.status = '200 OK'
response_headers = [('Content-type','text/plain')]
self.start(status, response_headers)
return ["Hello World"]
if __name__ == '__main__':
httpd = make_server('', 1000, DemoApp)
print("Serving on port 1000")
httpd.serve_forever()
When i go to port 1000, i am getting the attribute error.
AttributeError: 'NoneType' object has no attribute 'split'
Where i am leaving mistakes ?
Stacktrace
Serving on port 1000
Traceback (most recent call last):
File "C:\Python27\lib\wsgiref\handlers.py", line 86, in run
self.finish_response()
File "C:\Python27\lib\wsgiref\handlers.py", line 131, in finish_response
self.close()
File "C:\Python27\lib\wsgiref\simple_server.py", line 33, in close
self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'
127.0.0.1 - - [11/Jan/2014 12:40:09] "GET / HTTP/1.1" 500 59
Traceback (most recent call last):
File "C:\Python27\lib\SocketServer.py", line 295, in _handle_request_noblock
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 54469)
self.process_request(request, client_address)
File "C:\Python27\lib\SocketServer.py", line 321, in process_request
self.finish_request(request, client_address)
File "C:\Python27\lib\SocketServer.py", line 334, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "C:\Python27\lib\SocketServer.py", line 649, in __init__
self.handle()
File "C:\Python27\lib\wsgiref\simple_server.py", line 124, in handle
handler.run(self.server.get_app())
File "C:\Python27\lib\wsgiref\handlers.py", line 92, in run
self.close()
File "C:\Python27\lib\wsgiref\simple_server.py", line 33, in close
self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'
我想学习的目的,我自己版本的wsgiref实施和我结束这里。
from wsgiref.simple_server import make_server
class DemoApp():
def __init__(self, environ, start_response):
self.environ = environ
self.start = start_response
def __iter__(self, status):
self.status = '200 OK'
response_headers = [('Content-type','text/plain')]
self.start(status, response_headers)
return ["Hello World"]
if __name__ == '__main__':
httpd = make_server('', 1000, DemoApp)
print("Serving on port 1000")
httpd.serve_forever()
当我去到端口1000,我得到的属性错误。
AttributeError: 'NoneType' object has no attribute 'split'
在我离开的错误?
堆栈跟踪
Serving on port 1000
Traceback (most recent call last):
File "C:\Python27\lib\wsgiref\handlers.py", line 86, in run
self.finish_response()
File "C:\Python27\lib\wsgiref\handlers.py", line 131, in finish_response
self.close()
File "C:\Python27\lib\wsgiref\simple_server.py", line 33, in close
self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'
127.0.0.1 - - [11/Jan/2014 12:40:09] "GET / HTTP/1.1" 500 59
Traceback (most recent call last):
File "C:\Python27\lib\SocketServer.py", line 295, in _handle_request_noblock
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 54469)
self.process_request(request, client_address)
File "C:\Python27\lib\SocketServer.py", line 321, in process_request
self.finish_request(request, client_address)
File "C:\Python27\lib\SocketServer.py", line 334, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "C:\Python27\lib\SocketServer.py", line 649, in __init__
self.handle()
File "C:\Python27\lib\wsgiref\simple_server.py", line 124, in handle
handler.run(self.server.get_app())
File "C:\Python27\lib\wsgiref\handlers.py", line 92, in run
self.close()
File "C:\Python27\lib\wsgiref\simple_server.py", line 33, in close
self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'
最佳答案 (Best Answer)
How about this, you need to yield
the output than returning it.
from wsgiref.simple_server import make_server
class DemoApp:
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!'
if __name__ == '__main__':
httpd = make_server('', 1000, DemoApp)
print("Serving HTTP on port 1000...")
httpd.serve_forever()
这个怎么样,你需要yield
产量比返回。
from wsgiref.simple_server import make_server
class DemoApp:
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!'
if __name__ == '__main__':
httpd = make_server('', 1000, DemoApp)
print("Serving HTTP on port 1000...")
httpd.serve_forever()
答案 (Answer) 2
DemoApp
is called; The return value of DemoApp.__init__
is used.
DemoApp.__init__
returns nothing (You can't return anything in constructor).
Try following instead of DemoApp
class:
def DemoApp(environ, start_response):
response_headers = [('Content-type','text/plain')]
start_response('200 OK', response_headers)
return ["Hello World"]
Using class (Use __call__
instead of __iter__
):
from wsgiref.simple_server import make_server
class DemoApp:
def __call__(self, environ, start_response):
response_headers = [('Content-type','text/plain')]
start_response('200 OK', response_headers)
return ["Hello World"]
if __name__ == '__main__':
httpd = make_server('', 1000, DemoApp()) # Don't forget instantiate a class.
# ^^
print("Serving on port 1000")
httpd.serve_forever()
DemoApp
调用的返回值;DemoApp.__init__
使用。
DemoApp.__init__
(你不能返回不返回任何构造函数)。
尝试下面而不是DemoApp
类
def DemoApp(environ, start_response):
response_headers = [('Content-type','text/plain')]
start_response('200 OK', response_headers)
return ["Hello World"]
使用类(使用__call__
而不是__iter__
):
from wsgiref.simple_server import make_server
class DemoApp:
def __call__(self, environ, start_response):
response_headers = [('Content-type','text/plain')]
start_response('200 OK', response_headers)
return ["Hello World"]
if __name__ == '__main__':
httpd = make_server('', 1000, DemoApp()) # Don't forget instantiate a class.
# ^^
print("Serving on port 1000")
httpd.serve_forever()
- Print a two dimension list with format in Python [打印一二维列表格式在Python]
- Python - how to print amount of numbers, periods, and commas in file [Python——如何打印数字,时间,和逗号分隔文件]
- How to chose python executable if several exist? [如何选择python可执行如果几个存在吗?]
- Guessing Game python binary search [猜谜游戏python二进制搜索]
- Python: Testing Serial Ports for Answer [Python测试串口的回答:]
- Python single statement dictionary generator [Python语句字典生成器]
- Node.js + Python Child Process: Print returns data, but return doesn't [Node.js + Python子进程:打印数据返回,但还没有]
- Why doesn't Python allow to put a for followed by an if on the same line? [为什么不Python允许将紧随其后的是一种如果在同一行?]
- Python: MySQLdb LOAD DATA INFILE silently fails [Python:MySQLdb INFILE默默地加载数据失败]
- python gzip "unexpected end of file" when writing a data stream [Python gzip”遇到意外的文件结尾”写的一个数据流时