美文网首页
Python入门教程: 一个基本的WSGI接口

Python入门教程: 一个基本的WSGI接口

作者: 破旧的大卡车 | 来源:发表于2017-12-20 14:37 被阅读75次

主要参考: Let’s Build A Web Serve

服务器

#/usr/bin/env python
# -*- coding: utf-8 -*-

'''
    A module for WSGI: As a demostration
    Usage:
        python wsgiserver.py wsgiapp:app
'''

__author__ = 'Van Abel'

import socket
import StringIO
import sys


class WSGIServer(object):

    socket_family = socket.AF_INET
    socket_type = socket.SOCK_STREAM
    max_queue = 10

    def __init__(self, s_addr):
        # Create a listening socket
        self.s = s = socket.socket(
            self.socket_family,
                    self.socket_type
        )
        # Allow to reuse the same address
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        try:
            # Bind to addr, port
            s.bind(s_addr)
            # Listen on port
            s.listen(self.max_queue)
        except socket.error as e:
            print 'Server error >> %s ' % e
            sys.exit(1)
        # Get server host,port
        shost, self.s_port = self.s.getsockname()[:2]
        self.s_host = socket.getfqdn(shost)
        # Return headers set by web framework/app
        self.headers = []

    def set_app(self, app):
        self.app = app

    def server_forever(self):
        s = self.s
        while True:
            # New client conn
            self.c_conn, c_addr = s.accept()
            # Handle request and close
            #   Then loop over to wait for another client conn
            self.handle()

    def handle(self):
        # Read request from client
        self.r_data = r_data = self.c_conn.recv(1024)
        # Print formatted request data as 'curl -v'
        print(''.join(
            '< {line}\n'.format(line=line)
                for line in r_data.splitlines()
        ))
        # Parse the request
        self.parse(r_data)

        # Construct environment dict useing r_data
        env = self.get_env()

        # Call app(defined in wsgiapp.py and pass in by set_app())
        #   and get result as HTTP response body
        b_data = self.app(env, self.start)

        # Construct a response and send to client
        self.send(b_data)

    def parse(self, data):
        headers = data.splitlines()[0].rstrip('\r\n')
        # Break down the headers
        (
            self.method,
            self.path,
            self.protcl
        ) = headers.split()

    def get_env(self):
        env = {}

        # Required WSGI variables
        env['wsgi.version'] = (1, 0)
        env['wsgi.url_scheme'] = 'http'
        env['wsgi.input'] = StringIO.StringIO(self.r_data)
        env['wsgi.errors'] = sys.stderr
        env['wsgi.multithread'] = False
        env['wsgi.multiprocess'] = False
        env['wsgi.run_once'] = False

        # Required CGI variables
        env['REQUEST_METHOD'] = self.method
        env['PATH_INFO'] = self.path
        env['SERVER_NAME'] = self.protcl
        env['SERVER_PORT'] = str(self.s_port)

        return env

    def start(self, status, r_headers, exc_info=None):
        # Add necessary server header
        s_headers = [
            ('Data', 'Tue, 19 Dec 2017 15:23:41 CST'),
                ('Server', 'WSGI Server 0.1')
        ]
        self.headers = [status, r_headers + s_headers]

    def send(self, body):
        try:
            status, r_headers = self.headers
            r = 'HTTP/1.x {status}\r\n'.format(status=status)
            for header in r_headers:
                r += '{0}: {1}\r\n'.format(*header)
            r += '\r\n'
            for data in body:
                r += data
            # Print formatted response data as 'curl -v'
            print(''.join(
                '> {line}\n'.format(line=line)
                for line in r.splitlines()
            ))
            self.c_conn.sendall(r)
        finally:
            self.c_conn.close()

SERVER_ADDRESS = (HOST, PORT) = '', 8000


def make_server(s_addr, app):
    server = WSGIServer(s_addr)
    server.set_app(app)
    return server

if __name__ == '__main__':
    if len(sys.argv) < 2:
        sys.exit('Usage:\n\tProvide a WSGI app object as module:callable')

    app_path = sys.argv[1]
    module, app = app_path.split(':')
    module = __import__(module)
    app = getattr(module, app)
    httpd = make_server(SERVER_ADDRESS, app)
    print('WSGIServer: Serving HTTP on port {port} ...\n'.format(port=PORT))
    httpd.server_forever()

客户端

#/usr/bin/env python
# -*- coding: utf-8 -*-
'''
    wsgiapp.py
    A demo client for server_wsgi.py
'''
__author__ = 'Van Abel'

def app(environ, start):
    # A barebones WSGI app
    # you can take it as a start point of your webframework
    status = '200 OK'
    resp_h = [('Content-Type', 'text/plain')]
    start(status, resp_h)
    return 'Hello world from a simple WSGI app!\n'

相关文章

  • Python入门教程: 一个基本的WSGI接口

    主要参考: Let’s Build A Web Serve 服务器 客户端

  • WSGI规范

    1.WSGI协议 什么是WSGI(1)、WSGI(Web 服务器网关接口)是python中所定义的Web Serv...

  • Python || WSGI接口

    总结: 无论多复杂的Web应用,入口都是一个WSGI处理函数; HTTP请求的所有信息都从environ参数获取;...

  • python wsgi+Odoo 的启动

    参考:WSGI初探Odoo web 机制浅析python的 WSGI 简介python wsgi 简介 wsgi的...

  • wsgi 与 asgi

    什么是wsgi Web服务器网关接口(Python Web Server Gateway Interface,缩写...

  • 1. Flask基础知识

    1. Flask的web服务器 1)WSGI Python Web服务器网关接口(Python Web Serve...

  • Apache Python WSGI服务

    一、什么是WSGI? WSGI是指web服务器和python web应用或web框架之间的标准接口。以提高web...

  • Python-WSGI接口

    Python WSGI规定了Web服务器和Python Web应用程序或Web框架之间的标准接口,主要是为了促进W...

  • wsgi简介

    wsgi是什么? WSGI:Web Server Gateway Interface。WSGI接口定义非常简单,它...

  • 南大慕课《用Python玩转数据》-01走近Python

    Python的应用 WEB开发,定了WSGI标准应用接口来协调http服务器与基于python的web程序之间的沟...

网友评论

      本文标题:Python入门教程: 一个基本的WSGI接口

      本文链接:https://www.haomeiwen.com/subject/rbsgwxtx.html