python web 框架实现的解析(未完待续)
目录:
web框架
实现一个简单的web服务
对于所有的web应用来讲,都是socket服务端和浏览器等为socket客户端。
#!/usr/bin/env python
#coding:utf-8
import socket
def handle_request(client):
buf = client.recv(1024)
client.send("HTTP/1.1 200 OK\r\n\r\n")
client.send("Hello, why")
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost',8888))
sock.listen(5)
while True:
connection, address = sock.accept()
handle_request(connection)
connection.close()
if __name__ == '__main__':
main()
执行结果
web框架分为两种,一种是内部包含socket和业务逻辑,而还有一种是不包含socket只有业务逻辑的。
tornado就是前者,而后者的代表为jango,flask,bottle。
wsgi是一种规范,定义了python编写的web app和web server之间接口格式,实现了两者之间的解耦,防止不同的框架需要服务器程序提供各种各样的支持。
web框架的本质
通过wsgiref模块构建
示例python代码
from wsgiref.simple_server import make_server
def RunServer(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return '<h1>Hello, web!</h1>'
if __name__ == '__main__':
httpd = make_server('', 8000, RunServer)
print("Serving HTTP on port 8000...")
httpd.serve_forever()
请求到了socket,然后由socket处理,然后交给对应业务逻辑
但是现在我们的所有url请求获取到的都是相同的页面,而正常情况应该根据请求的地址返回不同的业务逻辑。
我们可以打断点也获取一下url,浏览器获取url肯定会传递到socket内部处理然后返回出来参数,只不过我们的RunServer没有用到而已,environ就是请求发送的所有参数都在这封装,start_response封装的是返回client的参数。
通过pycharm进行debug
可以看到PATH_INFO就是url
进行url映射
示例python代码
from wsgiref.simple_server import make_server
def wanghongyu():
return '<h1>Hello, wanghongyu!</h1>'
def why():
return '<h1>Hello, why!</h1>'
def RunServer(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
url = environ['PATH_INFO']
if url == '/wanghongyu':
ret = wanghongyu()
elif url == '/why':
ret = why()
else:
ret = '<h1>Hello, web!</h1>'
return ret
if __name__ == '__main__':
httpd = make_server('', 8000, RunServer)
print("Serving HTTP on port 8000...")
httpd.serve_forever()
不过对于请求url过多就要写很多个if判断,可以通过url字典来实现映射
示例python代码
from wsgiref.simple_server import make_server
def wanghongyu():
f = open('wanghongyu.html','r')
date = f
f.close()
return date
def why():
return '<h1>Hello, why!</h1>'
URLS = {
"/why":why,
"/wanghongyu":wanghongyu
}
def RunServer(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
url = environ['PATH_INFO']
if url in URLS.keys():
function_name = URLS[url]
ret = function_name()
else:
ret = '<h1>Hello, web!</h1>'
return ret
if __name__ == '__main__':
httpd = make_server('', 8000, RunServer)
print("Serving HTTP on port 8000...")
httpd.serve_forever()