当前位置: 首页 > 工具软件 > miniWEB APP > 使用案例 >

mini-web框架

弓举
2023-12-01

文件结构

html/index.html
static											#存放静态文件
templates/(index.html  center.html)				#框架模板
web/myWeb.py
webSwever.py

webSwever.py

import time, re, socket, sys, multiprocessing


class WSGIServer(object):
    def __init__(self, docRoot, app):
        # 创建服务端连接
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 地址复用
        self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # 绑定地址和端口
        self.s.bind(("", 8080))
        # 主动连接改为被动监听
        self.s.listen(128)
        # 设置根目录
        self.docRoot = docRoot
        # 把创建来的app变为对象的app
        self.app = app

    # 运行服务器
    def runServer(self):
        while True:
            # 接收客户端的请求
            newS, _ = self.s.accept()

            # newS.settimeout(3)
            # 创建新进程,处理客户端请求
            newProcess = multiprocessing.Process(target=self.dealWithRequest, args=(newS,))
            # 启动子进程
            newProcess.start()

    # 设置动态数据的请求头
    def setResponse(self, status, headers):
        # 设置默认请求头的数据
        responseHeaderDefault = [
            ("Data", time.ctime()),
            ("Server", "LINUX-python mini web server")
        ]

        # 拼接响应头部数据
        self.headers = [status, responseHeaderDefault + headers]

    # 设置定义处理客户端请求的函数
    def dealWithRequest(self, newS):
        while True:
            try:   
                # 接受客户端的数据
                content = newS.recv(1024).decode("utf-8")
            # 捕获异常
            except Exception as ret:
                print("========>", ret)
                newS.close()
                return

            # 判断客户端是不是要关闭连接
            if not content:
                # 没数据关闭连接
                newS.close()
                return

            # 处理数据,进行行切片
            requestLines = content.splitlines()

            # 获取网站的请求路径
            ret = re.match("[^/]+(/[^ ]*)", requestLines[0])

            # 判断请求的路径
            if ret.group(1) == "/":
                # 如果是根路径,让他获取index页面
                pathName = ret.group(1) + "index.html"
            else:
                # 如果不是根路径,返回原有路径赋值
                pathName = ret.group(1)

            # 处理静态请求
            if not pathName.endswith(".py"):
                # 异常处理
                try:
                    f = open(self.docRoot + pathName, "r")
                # 没有读取数据,捕获异常
                except Exception as ret:
                    # 返回异常的响应头和响应体
                    responseBady = "file not found, Please input right url"
                    responseHeader = "HTTP/1.1 404 not found\r\n"
                    responseHeader += "Content-Type: text/html; charset=utf-8\r\n"
                    responseHeader += "Content-Length: %d\r\n" % (len(responseBady))
                    responseHeader += "\r\n"

                    # 拼接异常响应数据
                    response = responseHeader + responseBady

                # 没有异常
                else:
                    # 读取文件数据
                    content = f.read()
                    # 返回响应头和响应体
                    responseBody = content
                    responseHeader = "HTTP/1.1 200 OK\r\n"
                    responseHeader += "Content-Type: text/html; charset=utf-8\r\n"
                    responseHeader += "Content-Length: %d\r\n" % (len(responseBody))
                    responseHeader += "\r\n"

                    # 拼接响应数据
                    response = responseHeader + responseBody

                # 将响应数据发送给客户端
                newS.send(response.encode("utf-8"))
            
            # 处理动态请求
            else:
                # 存储所有需要处理的请求的kv
                requestDict = {"pathName": pathName}

                # 通过myWeb下的app函数处理动态请求,获取响应数据
                responseBody = self.app(requestDict, self.setResponse)

                # 设置响应头
                responseHeader = "HTTP/1.1 {status}\r\n".format(status=self.headers[0])
                responseHeader += "Content-Type: text/html; charset=utf-8\r\n"
                responseHeader += "Content-Length: %d\r\n" % len(responseBody)

                # 设置响应头
                for tempHead in self.headers[1]:
                    responseHeader += "{0}:{1}\r\n".format(*tempHead)

                # 拼接响应数据
                response = responseHeader + "\r\n" + responseBody

                # 发送给客户端
                newS.send(response.encode("utf-8"))


# 设置静态资源访问的路径
gStaticDocumentRoot = "./html"
# 设置动态资源访问的路径
gDynamicDocumentRoot = "./web"


# 定义服务器的入口
def main():
    # 判断程序参数符不符合要求
    if len(sys.argv) == 2:
        # 获取程序的参数,获取要执行的函数名
        webModuleAppName = sys.argv[1]
    else:
        print("Please input like 'python fileName modelName:applicationName'")

    # 导入程序传参模块名以及应用名
    ret = re.match(r"([^:]*):(.*)", webModuleAppName)   

    # 获取模块以及模块名
    modelName = ret.group(1)
    appName = ret.group(2)

    # 添加模块路径到代码环境变量中
    sys.path.append(gDynamicDocumentRoot)

    # 导入模块名
    model = __import__(modelName)

    # 将模块内的app应用变成可用的对象或者函数
    app = getattr(model, appName)

    # 初始化对象并运行服务器
    http = WSGIServer(gStaticDocumentRoot, app)
    http.runServer()


if __name__ == "__main__":
    main()

web/myWeb.py

import time, re

# 定义模板文件存放位置
templateRoot = "./templates"


# 返回请求index.py获取的文件
def index(fileName):
    # 异常处理
    try:
        # 将文件名的后缀替换为.html
        fileName = fileName.replace(".py", ".html")
        # 打开文件
        f = open(templateRoot + fileName)
    # 捕获异常
    except Exception as ret:
        return "%s" % ret
    # 返回数据
    else:
        # 保存打开的数据
        content = f.read()
        # 关闭打开的文件
        f.close()

        # 准备替换的数据
        dataFromMysql = "等待数据中....(>_<)\n %s" % time.ctime()

        # 进行模板数据替换
        content = re.sub(r"\{%content%\}", dataFromMysql, content)

        # 返回数据
        return content


# 返回请求center.py获取的文件
def center(fileName):
    # 异常处理
    try:
        # 将文件名的后缀替换为.html
        fileName = fileName.replace(".py", ".html")
        # 打开问文件
        f = open(templateRoot + fileName)
    # 捕获异常
    except Exception as ret:
        return "%s" % ret
    # 返回数据
    else:
        # 保存读取的数据
        content = f.read()
        # 关闭打开的文件
        f.close()

        # 准备替换的文件
        dataFromMysql = "无法显示数据(>_<)\n %s " % time.ctime()

        # 进行模板数据替换
        content = re.sub(r"\{%content%\}", dataFromMysql, content)

        # 返回数据
        return content


def app(requestDict, setResponse):
    # 定义状态码
    status = 200
    # 定义响应头
    responseHeader = [('Content-Type', 'text/html')]
    # 设置返回的响应头
    setResponse(status, responseHeader)
   
    # 获取客户端请求路径 
    pathName = requestDict["pathName"]

    # 根据客户端的请求,返回相应的请求页面
    if pathName == "/index.py":
        # 调用处理index页面的函数
        return index(pathName)
    elif pathName == "/center.py":
        # 调用处理center页面的函数
        return center(pathName)
    else:
        # 没有页面返回的数据
        return str(requestDict) + 'sorry! requeset page not found--->%s\n' % time.ctime()

templates/index.html

{%content%} 
<br>
<li>this is index.html</li> 

templates/center.html

{%content%} 
<br>
<li>this is center.html</li>

html/index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"> 
<title>为 HTML 添加新元素</title>
<script>
document.createElement("myHero")
</script>
<style>
myHero {
    display: block;
    background-color: #ddd;
    padding: 50px;
    font-size: 30px;
}
</style> 
</head>
 
<body>
 
<h1>我的第一个标题</h1>
 
<p>我的第一个段落</p>
 
<myHero>我的第一个新元素</myHero>
 
</body>
</html>
 类似资料: