python web 框架实现的解析(未完待续)

时间:Aug. 29, 2017 分类:

目录:

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()