专栏首页python3python:记一次简单的模拟flas

python:记一次简单的模拟flas

最近web服务器知识,中间懒癌犯了,断了一两天后思路有点接不上来,手头上也有其他事情要做,先简单的总结下学习进度,很多重要的功能都没跑通,目前flask只是简单实现路由分显示不同的结果,cgi可以根据不同的静态资源或者py脚本文件路径显示不同的结果。目前来说文章亮点就是解耦做的还行,有一定的可扩展性

简单的仿flask实现路由分发

from wsgiref.simple_server import make_server


''''
WSGI规定:
1. 应用程序需要是一个可调用的对象
2. 可调用对象接收两个参数
3.可调用对象要返回一个值,这个值是可迭代的。
具体参考附录一,pep-0333标准
'''
class SimServer(object):
    def __init__(self):
        self.url_map = {}
    
    def __call__(self, environ, start_response):
        status = u'200 OK'
        response_headers = [('Content-type', 'text/plain')]
        start_response(status, response_headers)
        data=self.dispatch_request(environ)
        return [data.encode('utf-8'),]
    
    def run(self, ip=None, host=None):
        if not ip:
            ip = ''
        if not host:
            host = 8080
        httpd = make_server(ip, host, self)
        httpd.serve_forever()
    
    #路由装饰器
    def route(self, rule):  
        def decorator(f):  
            self.url_map[rule.lstrip('/')] = f
            return f
        
        return decorator
    
    #路由的分发
    def dispatch_request(self, request):
        print(request)
        path = request.get('PATH_INFO', '').lstrip('/')
        print(path)
        return self.url_map[path]()  # 从url_map中找到对应的处理函数,并调用



#创建一个app
app=SimServer()

@app.route('/index')
def index():
    return  'hello world'


@app.route('/login')
def login():
    return 'please login'

if __name__=="__main__":
    app.run()


if __name__=="__main__":
    app.run()

CGI web服务器,静态资源的转发

handler.py

import os
import subprocess

class BaseHandler(object):
    '''Parent for case handlers.'''
    
    def handle_file(self, handler, full_path):
        try :
            with open(full_path, 'rb') as reader:
                content = reader.read()
            handler.send_content(content)
        except IOError as msg:
            msg = "'{0}' cannot be read: {1}".format(full_path, msg)
            handler.handle_error(msg)
    
    def index_path(self, handler):
        return os.path.join(handler.full_path, 'index.html')
    
    def test(self, handler):
        assert False, 'Not implemented.'
    
    def act(self, handler):
        assert False, 'Not implemented.'

#处理首页
class Case_directory_idnex_file(BaseHandler):
    def test(self, handler):
        return (os.path.isdir(handler.full_path) and
                os.path.isfile(self.index_path(handler)))
    
    def act(self, handler):
        self.handle_file(handler, self.index_path(handler))
    

#处理普通html文件
class Case_existing_file(BaseHandler):
    def test(self, handler):
        return os.path.isfile((handler.full_path))
    
    def act(self, handler):
        self.handle_file(handler,handler.full_path)

#处理python脚本        
class Case_cgi_file(BaseHandler):
    def run_cgi(self, handler):
        print('dfs')
        print(handler.full_path)
        data=subprocess.getoutput(['python',handler.full_path])
        print('data={}'.format(data))
        #python3默认使用unicode,需要encode('utf-8')
        return handler.send_content(data.encode('utf-8'))
        
    def test(self,handler):
        return os.path.isfile(handler.full_path) and \
               handler.full_path.endswith('.py')
    def act(self,handler):
        self.run_cgi(handler)

requestHandler.py

from http.server import BaseHTTPRequestHandler,HTTPServer
import os
from simpleServer.handler import *


class RequestHandler(BaseHTTPRequestHandler):
    Cases = [Case_cgi_file(),Case_directory_idnex_file(),Case_existing_file() ,]
    
    # How to display an error.
    Error_Page = """\
        <html>
        <body>
        <h1>Error accessing {path}</h1>
        <p>{msg}</p>
        </body>
        </html>
        """
    
    # Classify and handle request.
    def do_GET(self):
        try:
            # 使用join会有问题,目前还没搞清楚+可以,join会有问题
            self.full_path = os.getcwd()+self.path
            # Figure out how to handle it.
            print('cases{}'.format(self.Cases))
            for case in self.Cases:
                if case.test(self):
                    case.act(self)
                    break
        
        # 处理异常
        except Exception as msg:
            print(msg)
            self.handle_error(msg)
    
    # Handle unknown objects.
    def handle_error(self, msg):
        content = self.Error_Page.format(path=self.path, msg=msg)
        self.send_content(content.encode('utf-8'), 404)
    
    # Send actual content.
    def send_content(self, content, status=200):
        self.send_response(status)
        self.send_header("Content-type", "text/html")
        self.send_header("Content-Length", str(len(content)))
        self.end_headers()
        self.wfile.write(content)

if __name__=="__main__":
    severAddress=('',8000)
    server=HTTPServer(severAddress,RequestHandler)
    server.serve_forever()

参考附录

1, pyton:pep-0333 2, flask作者博客文章:getting-started-with-wsgi 3, 自己写一个 wsgi 服务器运行 Django 、Tornado 等框架应用 4, 500L:a-simple-web-server 5, python wsgi简介 6, 从零开始搭建论坛(二):Web服务器网关接口 7, python的 WSGI 简介 8,本文github源码

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python运算符重载

    在Python语言中提供了类似于C++的运算符重在功能: 一下为Python运算符重在调用的方法如下: Method        Overloads   ...

    py3study
  • Python 3 之 运算符重载详解

    实际上,“运算符重载”只是意味着在类方法中拦截内置的操作……当类的实例出现在内置操作中,Python自动调用你的方法,并且你的方法的返回值变成了相应操作的结果。...

    py3study
  • python3 函数迭代器

    迭代器协议,是指对象(实例)能够使用next函数获取下一项数据,在没有下一项数据之前触发一个StopIteration异常来终止迭代

    py3study
  • 用 Python 实现简易 Web 服务器

    花下猫语:上篇文章推荐了一本神书《500 Lines or Less》(点此阅读),有几位读者留言问是否有中文版。很遗憾,还没有。不过我在文中也说了,Githu...

    Python猫
  • Metal入门教程(四)灰度计算

    Metal入门教程(一)图片绘制 Metal入门教程(二)三维变换 Metal入门教程(三)摄像头采集渲染

    落影
  • python pyqt5 装饰器、信号、槽

    from PyQt5 import QtCore from PyQt5.QtWidgets import QApplication, QWidget, QHB...

    用户5760343
  • 基于SceneKit的3D模型触碰事件

    流程如下: 1.获取到手指在屏幕的位置 2.然后转换到SCNView上 3.然后返回与手指点击方向的所有3D物体 ######主要代码如下 - (void)to...

  • Pytorch 使用 nii数据做输入数据的操作

    使用pix2pix-gan做医学图像合成的时候,如果把nii数据转成png格式会损失很多信息,以为png格式图像的灰度值有256阶,因此直接使用nii的医学图像...

    砸漏
  • PyQt5 技巧篇-复选框绑定行内容,全选、清空、展示选中的内容功能实现演示,设置复选框选中,检查复选框选中状态

    我设置两个有序序列,分别存储对应的复选框和行内容。 我的行内容是用的label标签。

    小蓝枣
  • 一个Python3和Python2的range差异

    Python 3 中执行100000000 in range(100000001)会比Python 2快的非常多。

    用户1416054

扫码关注云+社区

领取腾讯云代金券