• python之web框架(3):WSGI之web应用完善


    python之web框架(3):WSGI之web应用完善

    1.上篇的web框架太low,只能实现回应固定页面。现在将它进行完善。首先将wsgi和web服务器进行分离,并给予它回复静态页面的能力。

    • web_server.py
    #!/usr/bin/env python3
    # coding:utf-8
    
    from test_frame import app
    from socket import *
    from multiprocessing import Process
    
    
    class MyWebServer(object):
        def start_response(self, status, head_list):
            self.response_head = 'HTTP/1.1 ' + status + ' 
    '
            self.response_head = self.response_head.encode()
            # print(self.response_head)
    
        def deal(self, conn):
            recv_data = conn.recv(1024).decode('utf-8')
            recv_data_head = recv_data.splitlines()[0]
            # print('------recv_data_head: ', recv_data_head)
            request_method, request_path, http_version = recv_data_head.split()
            request_path = request_path.split('?')[0]  # 去掉url中的?和之后的参数
    
            env = {'request_method': request_method, 'request_path': request_path}
    
            # 这里是wsgi接口调用的地方
            response_body = app(env, self.start_response)
    
            response_data = self.response_head + b'
    ' + response_body
            conn.send(response_data)
            # print('response_data = ', response_data)
    
        def __init__(self):
            self.s = socket(AF_INET, SOCK_STREAM)
            self.s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
            self.s.bind(('', 8000))
            self.s.listen(1023)
            self.response_head = ''
    
        def start(self):
            while 1:
                conn, user_info = self.s.accept()
                print(user_info, '接入')
                p = Process(target=self.deal, args=(conn,))
                p.start()
                conn.close()  # 进程会复制出一个新的conn,所以这里的conn需要关闭
    
    
    s = MyWebServer()
    s.start()
    
    
    • test_frame.py
    def app(env, start_response):
        file_name = env['request_path']
        if file_name == '/':
            file_name = '/index.html'
        try:
            f = open('.' + file_name, 'rb')
        except IOError:
            status = '404 error'
            head_list = [("name", "wanghui")]
            start_response(status, head_list)
            return b'<h1>File not found</h1>'
    
        status = '200 OK'
        head_list = [("name", "wanghui")]
        start_response(status, head_list)
        read_data = f.read()
        f.close()
        return read_data
    
    

    2.框架已经提供了静态页面的能力。下面对框架进一步完善。

    • web_server.py
    #!/usr/bin/env python3
    # coding:utf-8
    
    from testframe import app
    from socket import *
    from multiprocessing import Process
    
    
    class MyWebServer(object):
        def start_response(self, status, head_list):
            self.response_head = 'HTTP/1.1 ' + status + ' 
    '
            self.response_head = self.response_head.encode()
    
        def deal(self, conn):
            recv_data = conn.recv(1024).decode('utf-8')
            recv_data_head = recv_data.splitlines()[0]
            request_method, request_path, http_version = recv_data_head.split()
            request_path = request_path.split('?')[0]  # 去掉url中的?和之后的参数
    
            env = {'request_method': request_method, 'request_path': request_path}
    
            # 这里是wsgi接口调用的地方
            response_body = self.app(env, self.start_response)
    
            response_data = self.response_head + b'
    ' + response_body
            conn.send(response_data)
            conn.close()
    
        def __init__(self, app, port=8000):
            self.s = socket(AF_INET, SOCK_STREAM)
            self.s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
            self.s.bind(('', port))
            self.s.listen(1023)
            self.response_head = ''
            self.app = app
    
        def start(self):
            while 1:
                conn, user_info = self.s.accept()
                print(user_info, '接入')
                p = Process(target=self.deal, args=(conn,))
                p.start()
                conn.close()  # 进程会复制出一个新的conn,所以这里的conn需要关闭
    
    
    s = MyWebServer(app)
    s.start()
    
    
    • test_frame.py
    import time
    
    
    class Application(object):
        def __init__(self, url_list):
            self.url_list = url_list
    
        def __call__(self, env, start_response):
            file_name = env['request_path']
            if file_name == '/':
                file_name = '/index.html'
    
            try:
                f = open('.' + file_name, 'rb')
            except IOError:
                get_name = url_list.get(file_name, 'say_error')
                return eval(get_name)(start_response)
    
            status = '200 OK'
            head_list = [("name", "wanghui")]
            start_response(status, head_list)
            read_data = f.read()
            f.close()
            return read_data
    
    
    def say_error(start_response):
        status = '404 error'
        head_list = [("name", "wanghui")]
        start_response(status, head_list)
        return b'<h1>File not found</h1>'
    
    
    def say_time(start_response):
        status = '200 OK'
        head_list = [("name", "wanghui")]
        start_response(status, head_list)
        return time.ctime().encode()
    
    
    def say_hello(start_response):
        status = '200 OK'
        head_list = [("name", "wanghui")]
        start_response(status, head_list)
        return b'<h1>hello world</b>'
    
    
    url_list = {'/time.py': 'say_time',
                '/error.py': 'say_error',
                '/hello.py': 'say_hello',
                }
    app = Application(url_list)
    
    
    • 此时如果访问http://localhost/time.py,则会动态的将当前时间返回给客户。
    • 不过功能还不够完善,像不支持长连接,还不能支持外部py文件动态解析。

  • 相关阅读:
    第06组 Alpha冲刺(3/4)
    第06组 Alpha冲刺(2/4)
    第06组 Alpha冲刺(1/4)
    第06组 团队Git现场编程实战
    第二次结对编程作业
    2019 SDN大作业
    2019 SDN上机第7次作业
    第08组 Beta版本演示
    第08组 Beta冲刺(5/5)
    第08组 Beta冲刺(4/5)
  • 原文地址:https://www.cnblogs.com/PrettyTom/p/6759969.html
Copyright © 2020-2023  润新知