溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么使用Python開發(fā)自定義Web框架

發(fā)布時(shí)間:2022-07-29 13:49:23 來源:億速云 閱讀:126 作者:iii 欄目:開發(fā)技術(shù)

這篇“怎么使用Python開發(fā)自定義Web框架”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“怎么使用Python開發(fā)自定義Web框架”文章吧。

開發(fā)自定義Web框架

接收web服務(wù)器的動(dòng)態(tài)資源請(qǐng)求,給web服務(wù)器提供處理動(dòng)態(tài)資源請(qǐng)求的服務(wù)。根據(jù)請(qǐng)求資源路徑的后綴名進(jìn)行判斷:

如果請(qǐng)求資源路徑的后綴名是.html則是動(dòng)態(tài)資源請(qǐng)求, 讓web框架程序進(jìn)行處理。

否則是靜態(tài)資源請(qǐng)求,讓web服務(wù)器程序進(jìn)行處理。

1.開發(fā)Web服務(wù)器主體程序

1、接受客戶端HTTP請(qǐng)求(底層是TCP)

# -*- coding: utf-8 -*-
# @File  : My_Web_Server.py
# @author: Flyme awei 
# @email : 1071505897@qq.com
# @Time  : 2022/7/24 21:28


from socket import *
import threading


# 開發(fā)自己的Web服務(wù)器主類
class MyHttpWebServer(object):

    def __init__(self, port):
        # 創(chuàng)建 HTTP服務(wù)的 TCP套接字
        server_socket = socket(AF_INET, SOCK_STREAM)
        # 設(shè)置端口號(hào)互用,程序退出之后不需要等待,直接釋放端口
        server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, True)
        # 綁定 ip和 port
        server_socket.bind(('', port))
        # listen使套接字變?yōu)榱吮粍?dòng)連接
        server_socket.listen(128)
        self.server_socket = server_socket

    # 處理請(qǐng)求函數(shù)
    @staticmethod  # 靜態(tài)方法
    def handle_browser_request(new_socket):
        # 接受客戶端發(fā)來的數(shù)據(jù)
        recv_data = new_socket.recv(4096)
        # 如果沒有數(shù)據(jù),那么請(qǐng)求無效,關(guān)閉套接字,直接退出
        if len(recv_data) == 0:
            new_socket.close()
            return
            
# 啟動(dòng)服務(wù)器,并接受客戶端請(qǐng)求
    def start(self):
        # 循環(huán)并多線程來接收客戶端請(qǐng)求
        while True:
            # accept等待客戶端連接
            new_socket, ip_port = self.server_socket.accept()
            print("客戶端ip和端口", ip_port)
            # 一個(gè)客戶端的請(qǐng)求交給一個(gè)線程來處理
            sub_thread = threading.Thread(target=MyHttpWebServer.handle_browser_request, args=(new_socket, ))
            # 設(shè)置當(dāng)前線程為守護(hù)線程
            sub_thread.setDaemon(True)
            sub_thread.start()  # 啟動(dòng)子線程


# Web 服務(wù)器程序的入口
def main():
    web_server = MyHttpWebServer(8080)
    web_server.start()


if __name__ == '__main__':
    main()

2、判斷請(qǐng)求是否是靜態(tài)資源還是動(dòng)態(tài)資源

 # 對(duì)接收的字節(jié)數(shù)據(jù)進(jìn)行轉(zhuǎn)換為字符數(shù)據(jù)
        request_data = recv_data.decode('utf-8')
        print("瀏覽器請(qǐng)求的數(shù)據(jù):", request_data)
        request_array = request_data.split(' ', maxsplit=2)

        # 得到請(qǐng)求路徑
        request_path = request_array[1]
        print("請(qǐng)求的路徑是:", request_path)
        if request_path == "/":
            # 如果請(qǐng)求路徑為根目錄,自動(dòng)設(shè)置為:/index.html
            request_path = "/index.html"
        # 判斷是否為:.html 結(jié)尾
        if request_path.endswith(".html"):
            "動(dòng)態(tài)資源請(qǐng)求"
           pass
        else:
            "靜態(tài)資源請(qǐng)求"
            pass

 3、如果靜態(tài)資源怎么處理?

怎么使用Python開發(fā)自定義Web框架

"靜態(tài)資源請(qǐng)求"
            # 根據(jù)請(qǐng)求路徑讀取/static 目錄中的文件數(shù)據(jù),相應(yīng)給客戶端
            response_body = None  # 響應(yīng)主體
            response_header = None  # 響應(yīng)頭的第一行
            response_first_line = None  # 響應(yīng)頭內(nèi)容
            response_type = 'test/html'  # 默認(rèn)響應(yīng)類型
            try:
                # 讀取 static目錄中相對(duì)應(yīng)的文件數(shù)據(jù),rb模式是一種兼容模式,可以打開圖片,也可以打開js
                with open('static'+request_path, 'rb') as f:
                    response_body = f.read()
                if request_path.endswith('.jpg'):
                    response_type = 'image/webp'

                response_first_line = 'HTTP/1.1 200 OK'
                response_header = 'Content-Length:' + str(len(response_body)) + '\r\n' + \
                                  'Content-Type: ' + response_type + '; charset=utf-8\r\n' + \
                                  'Date:' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\r\n' + \
                                  'Server: Flyme awei Server\r\n'

            # 瀏覽器讀取的文件可能不存在
            except Exception as e:
                with open('static/404.html', 'rb') as f:
                    response_body = f.read()  # 響應(yīng)的主體頁(yè)面內(nèi)容
                # 響應(yīng)頭
                response_first_line = 'HTTP/1.1 404 Not Found\r\n'
                response_header = 'Content-Length:'+str(len(response_body))+'\r\n' + \
                                  'Content-Type: text/html; charset=utf-8\r\n' + \
                                  'Date:' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\r\n' + \
                                  'Server: Flyme awei Server\r\n'
            # 最后都會(huì)執(zhí)行的代碼
            finally:
                # 組成響應(yīng)數(shù)據(jù)發(fā)送給(客戶端)瀏覽器
                response = (response_first_line + response_header + '\r\n').encode('utf-8') + response_body
                new_socket.send(response)
                # 關(guān)閉套接字
                new_socket.close()

怎么使用Python開發(fā)自定義Web框架

靜態(tài)資源請(qǐng)求驗(yàn)證:

怎么使用Python開發(fā)自定義Web框架

4、如果動(dòng)態(tài)資源又怎么處理

if request_path.endswith(".html"):
            "動(dòng)態(tài)資源請(qǐng)求"
            # 動(dòng)態(tài)資源的處理交給Web框架來處理,需要把請(qǐng)求參數(shù)交給Web框架,可能會(huì)有多個(gè)參數(shù),采用字典結(jié)構(gòu)
            params = {
                'request_path': request_path
            }
            # Web框架處理動(dòng)態(tài)資源請(qǐng)求后,返回一個(gè)響應(yīng)
            response = MyFramework.handle_request(params)
            new_socket.send(response)
            new_socket.close()

5、關(guān)閉Web服務(wù)器

new_socket.close()

Web服務(wù)器主體框架總代碼展示:

# -*- coding: utf-8 -*-
# @File  : My_Web_Server.py
# @author: Flyme awei 
# @email : 1071505897@qq.com
# @Time  : 2022/7/24 21:28


import sys
import time
from socket import *
import threading
import MyFramework


# 開發(fā)自己的Web服務(wù)器主類
class MyHttpWebServer(object):

    def __init__(self, port):
        # 創(chuàng)建 HTTP服務(wù)的 TCP套接字
        server_socket = socket(AF_INET, SOCK_STREAM)
        # 設(shè)置端口號(hào)互用,程序退出之后不需要等待,直接釋放端口
        server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, True)
        # 綁定 ip和 port
        server_socket.bind(('', port))
        # listen使套接字變?yōu)榱吮粍?dòng)連接
        server_socket.listen(128)
        self.server_socket = server_socket

    # 處理請(qǐng)求函數(shù)
    @staticmethod  # 靜態(tài)方法
    def handle_browser_request(new_socket):
        # 接受客戶端發(fā)來的數(shù)據(jù)
        recv_data = new_socket.recv(4096)
        # 如果沒有數(shù)據(jù),那么請(qǐng)求無效,關(guān)閉套接字,直接退出
        if len(recv_data) == 0:
            new_socket.close()
            return

        # 對(duì)接收的字節(jié)數(shù)據(jù)進(jìn)行轉(zhuǎn)換為字符數(shù)據(jù)
        request_data = recv_data.decode('utf-8')
        print("瀏覽器請(qǐng)求的數(shù)據(jù):", request_data)
        request_array = request_data.split(' ', maxsplit=2)

        # 得到請(qǐng)求路徑
        request_path = request_array[1]
        print("請(qǐng)求的路徑是:", request_path)
        if request_path == "/":
            # 如果請(qǐng)求路徑為根目錄,自動(dòng)設(shè)置為:/index.html
            request_path = "/index.html"
        # 判斷是否為:.html 結(jié)尾
        if request_path.endswith(".html"):
            "動(dòng)態(tài)資源請(qǐng)求"
            # 動(dòng)態(tài)資源的處理交給Web框架來處理,需要把請(qǐng)求參數(shù)交給Web框架,可能會(huì)有多個(gè)參數(shù),采用字典結(jié)構(gòu)
            params = {
                'request_path': request_path
            }
            # Web框架處理動(dòng)態(tài)資源請(qǐng)求后,返回一個(gè)響應(yīng)
            response = MyFramework.handle_request(params)
            new_socket.send(response)
            new_socket.close()
        else:
            "靜態(tài)資源請(qǐng)求"
            # 根據(jù)請(qǐng)求路徑讀取/static 目錄中的文件數(shù)據(jù),相應(yīng)給客戶端
            response_body = None  # 響應(yīng)主體
            response_header = None  # 響應(yīng)頭的第一行
            response_first_line = None  # 響應(yīng)頭內(nèi)容
            response_type = 'test/html'  # 默認(rèn)響應(yīng)類型
            try:
                # 讀取 static目錄中相對(duì)應(yīng)的文件數(shù)據(jù),rb模式是一種兼容模式,可以打開圖片,也可以打開js
                with open('static'+request_path, 'rb') as f:
                    response_body = f.read()
                if request_path.endswith('.jpg'):
                    response_type = 'image/webp'

                response_first_line = 'HTTP/1.1 200 OK'
                response_header = 'Content-Length:' + str(len(response_body)) + '\r\n' + \
                                  'Content-Type: ' + response_type + '; charset=utf-8\r\n' + \
                                  'Date:' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\r\n' + \
                                  'Server: Flyme awei Server\r\n'

            # 瀏覽器讀取的文件可能不存在
            except Exception as e:
                with open('static/404.html', 'rb') as f:
                    response_body = f.read()  # 響應(yīng)的主體頁(yè)面內(nèi)容
                # 響應(yīng)頭
                response_first_line = 'HTTP/1.1 404 Not Found\r\n'
                response_header = 'Content-Length:'+str(len(response_body))+'\r\n' + \
                                  'Content-Type: text/html; charset=utf-8\r\n' + \
                                  'Date:' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\r\n' + \
                                  'Server: Flyme awei Server\r\n'
            # 最后都會(huì)執(zhí)行的代碼
            finally:
                # 組成響應(yīng)數(shù)據(jù)發(fā)送給(客戶端)瀏覽器
                response = (response_first_line + response_header + '\r\n').encode('utf-8') + response_body
                new_socket.send(response)
                # 關(guān)閉套接字
                new_socket.close()

    # 啟動(dòng)服務(wù)器,并接受客戶端請(qǐng)求
    def start(self):
        # 循環(huán)并多線程來接收客戶端請(qǐng)求
        while True:
            # accept等待客戶端連接
            new_socket, ip_port = self.server_socket.accept()
            print("客戶端ip和端口", ip_port)
            # 一個(gè)客戶端的請(qǐng)求交給一個(gè)線程來處理
            sub_thread = threading.Thread(target=MyHttpWebServer.handle_browser_request, args=(new_socket, ))
            # 設(shè)置當(dāng)前線程為守護(hù)線程
            sub_thread.setDaemon(True)
            sub_thread.start()  # 啟動(dòng)子線程


# Web 服務(wù)器程序的入口
def main():
    web_server = MyHttpWebServer(8080)
    web_server.start()


if __name__ == '__main__':
    main()

2.開發(fā)Web框架主體程序

1、根據(jù)請(qǐng)求路徑,動(dòng)態(tài)的響應(yīng)對(duì)應(yīng)的數(shù)據(jù)

# -*- coding: utf-8 -*-
# @File  : MyFramework.py
# @author: Flyme awei 
# @email : 1071505897@qq.com
# @Time  : 2022/7/25 14:05

import time

# 自定義Web框架


# 處理動(dòng)態(tài)資源請(qǐng)求的函數(shù)
def handle_request(parm):
    request_path = parm['request_path']

    if request_path == '/index.html':  # 當(dāng)前請(qǐng)求路徑有與之對(duì)應(yīng)的動(dòng)態(tài)響應(yīng),當(dāng)前框架只開發(fā)了 index.html的功能
        response = index()
        return response
    else:
        # 沒有動(dòng)態(tài)資源的數(shù)據(jù),返回404頁(yè)面
        return page_not_found()


# 當(dāng)前 index函數(shù),專門處理index.html的請(qǐng)求
def index():
    # 需求,在頁(yè)面中動(dòng)態(tài)顯示當(dāng)前系統(tǒng)時(shí)間
    data = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
    response_body = data
    response_first_line = 'HTTP/1.1 200 OK\r\n'
    response_header = 'Content-Length:' + str(len(response_body)) + '\r\n' + \
                      'Content-Type: text/html; charset=utf-8\r\n' + \
                      'Date:' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\r\n' + \
                      'Server: Flyme awei Server\r\n'
    response = (response_first_line + response_header + '\r\n' + response_body).encode('utf-8')
    return response


def page_not_found():
    with open('static/404.html', 'rb') as f:
        response_body = f.read()  # 響應(yīng)的主體頁(yè)面內(nèi)容
    # 響應(yīng)頭
    response_first_line = 'HTTP/1.1 404 Not Found\r\n'
    response_header = 'Content-Length:' + str(len(response_body)) + '\r\n' + \
                      'Content-Type: text/html; charset=utf-8\r\n' + \
                      'Date:' + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + '\r\n' + \
                      'Server: Flyme awei Server\r\n'

    response = (response_first_line + response_header + '\r\n').encode('utf-8') + response_body
    return response

2、如果請(qǐng)求路徑,沒有對(duì)應(yīng)的響應(yīng)數(shù)據(jù)也需要返回404頁(yè)面

怎么使用Python開發(fā)自定義Web框架

3.使用模板來展示響應(yīng)內(nèi)容

1、自己設(shè)計(jì)一個(gè)模板 index.html ,中有一些地方采用動(dòng)態(tài)的數(shù)據(jù)來替代

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>首頁(yè) - 電影列表</title>
    <link href="/css/bootstrap.min.css" rel="stylesheet">
    <script src="/js/jquery-1.12.4.min.js"></script>
    <script src="/js/bootstrap.min.js"></script>
</head>

<body>
<div class="navbar navbar-inverse navbar-static-top ">
        <div class="container">
        <div class="navbar-header">
                <button class="navbar-toggle" data-toggle="collapse" data-target="#mymenu">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                 </button>
                 <a href="#" class="navbar-brand">電影列表</a>
        </div>
        <div class="collapse navbar-collapse" id="mymenu">
                <ul class="nav navbar-nav">
                        <li class="active"><a href="">電影信息</a></li>
                        <li><a href="">個(gè)人中心</a></li>
                </ul>
        </div>
        </div>
</div>
<div class="container">

    <div class="container-fluid">

        <table class="table table-hover">
            <tr>
                    <th>序號(hào)</th>
                    <th>名稱</th>
                    <th>導(dǎo)演</th>
                    <th>上映時(shí)間</th>
                    <th>票房</th>
                    <th>電影時(shí)長(zhǎng)</th>
                    <th>類型</th>
                    <th>備注</th>
                    <th>刪除電影</th>
            </tr>
            {%datas%}
        </table>
    </div>
</div>
</body>
</html>

2、怎么替代,替代什么數(shù)據(jù)

response_body = response_body.replace('{%datas%}', data)

怎么使用Python開發(fā)自定義Web框架

4.開發(fā)框架的路由列表功能

1、以后開發(fā)新的動(dòng)作資源的功能,只需要:

a、增加一個(gè)條件判斷分支

b、增加一個(gè)專門處理的函數(shù)

2、路由: 就是請(qǐng)求的URL路徑和處理函數(shù)直接的映射。

3、路由表

請(qǐng)求路徑處理函數(shù)
/index.htmlindex函數(shù)
/user_info.htmluser_info函數(shù)
# 定義路由表
route_list = {
    ('/index.html', index),
    ('/user_info.html', user_info)
}


for path, func in route_list:
    if request_path == path:
        return func()
    else:
        # 沒有動(dòng)態(tài)資源的數(shù)據(jù),返回404頁(yè)面
        return page_not_found()

注意:用戶的動(dòng)態(tài)資源請(qǐng)求,通過遍歷路由表找到對(duì)應(yīng)的處理函數(shù)來完成的。

5.采用裝飾器的方式添加路由

1、采用帶參數(shù)的裝飾器

# -*- coding: utf-8 -*-
# @File  : My_Web_Server.py
# @author: Flyme awei 
# @email : 1071505897@qq.com
# @Time  : 2022/7/24 21:28


# 定義路由表
route_list = []
# route_list = {
# ('/index.html', index),
# ('/user_info.html', user_info)
# }


# 定義一個(gè)帶參數(shù)的裝飾器
def route(request_path):  # 參數(shù)就是URL請(qǐng)求
    def add_route(func):
        # 添加路由表
        route_list.append((request_path, func))

        @wraps(func)
        def invoke(*args, **kwargs):
            # 調(diào)用指定的處理函數(shù),并返回結(jié)果
            return func()
        return invoke
    return add_route


# 處理動(dòng)態(tài)資源請(qǐng)求的函數(shù)
def handle_request(parm):
    request_path = parm['request_path']

    # if request_path == '/index.html':  # 當(dāng)前請(qǐng)求路徑有與之對(duì)應(yīng)的動(dòng)態(tài)響應(yīng),當(dāng)前框架只開發(fā)了 index.html的功能
    #     response = index()
    #     return response
    # elif request_path == '/user_info.html':  # 個(gè)人中心的功能
    #     return user_info()
    # else:
    #     # 沒有動(dòng)態(tài)資源的數(shù)據(jù),返回404頁(yè)面
    #     return page_not_found()
    for path, func in route_list:
        if request_path == path:
            return func()
        else:
            # 沒有動(dòng)態(tài)資源的數(shù)據(jù),返回404頁(yè)面
            return page_not_found()

2、在任何一個(gè)處理函數(shù)的基礎(chǔ)上增加一個(gè)添加路由的功能

@route('/user_info.html')

小結(jié):使用帶參數(shù)的裝飾器,可以把我們的路由自動(dòng)的,添加到路由表中。

6.電影列表頁(yè)面的開發(fā)案例

怎么使用Python開發(fā)自定義Web框架

1、查詢數(shù)據(jù)

my_web.py

# -*- coding: utf-8 -*-
# @File  : My_Web_Server.py
# @author: Flyme awei 
# @email : 1071505897@qq.com
# @Time  : 2022/7/24 21:28


import socket
import sys
import threading
import time
import MyFramework


# 開發(fā)自己的Web服務(wù)器主類
class MyHttpWebServer(object):

    def __init__(self, port):
        # 創(chuàng)建HTTP服務(wù)器的套接字
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 設(shè)置端口號(hào)復(fù)用,程序退出之后不需要等待幾分鐘,直接釋放端口
        server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        server_socket.bind(('', port))
        server_socket.listen(128)
        self.server_socket = server_socket

    # 處理瀏覽器請(qǐng)求的函數(shù)
    @staticmethod
    def handle_browser_request(new_socket):
        # 接受客戶端發(fā)送過來的數(shù)據(jù)
        recv_data = new_socket.recv(4096)
        # 如果沒有收到數(shù)據(jù),那么請(qǐng)求無效,關(guān)閉套接字,直接退出
        if len(recv_data) == 0:
            new_socket.close()
            return

        # 對(duì)接受的字節(jié)數(shù)據(jù),轉(zhuǎn)換成字符
        request_data = recv_data.decode('utf-8')
        print("瀏覽器請(qǐng)求的數(shù)據(jù):", request_data)
        request_array = request_data.split(' ', maxsplit=2)
        # 得到請(qǐng)求路徑
        request_path = request_array[1]
        print('請(qǐng)求路徑是:', request_path)

        if request_path == '/':  # 如果請(qǐng)求路徑為跟目錄,自動(dòng)設(shè)置為/index.html
            request_path = '/index.html'

        # 根據(jù)請(qǐng)求路徑來判斷是否是動(dòng)態(tài)資源還是靜態(tài)資源
        if request_path.endswith('.html'):
            '''動(dòng)態(tài)資源的請(qǐng)求'''
            # 動(dòng)態(tài)資源的處理交給Web框架來處理,需要把請(qǐng)求參數(shù)傳給Web框架,可能會(huì)有多個(gè)參數(shù),所有采用字典機(jī)構(gòu)
            params = {
                'request_path': request_path,
            }
            # Web框架處理動(dòng)態(tài)資源請(qǐng)求之后,返回一個(gè)響應(yīng)
            response = MyFramework.handle_request(params)
            new_socket.send(response)
            new_socket.close()


        else:
            '''靜態(tài)資源的請(qǐng)求'''
            response_body = None  # 響應(yīng)主體
            response_header = None  # 響應(yīng)頭
            response_first_line = None  # 響應(yīng)頭的第一行
            # 其實(shí)就是:根據(jù)請(qǐng)求路徑讀取/static目錄中靜態(tài)的文件數(shù)據(jù),響應(yīng)給客戶端
            try:
                # 讀取static目錄中對(duì)應(yīng)的文件數(shù)據(jù),rb模式:是一種兼容模式,可以打開圖片,也可以打開js
                with open('static' + request_path, 'rb') as f:
                    response_body = f.read()
                if request_path.endswith('.jpg'):
                    response_type = 'image/webp'
                response_first_line = 'HTTP/1.1 200 OK'
                response_header = 'Server: Laoxiao_Server\r\n'

            except Exception as e:  # 瀏覽器想讀取的文件可能不存在
                with open('static/404.html', 'rb') as f:
                    response_body = f.read()  # 響應(yīng)的主體頁(yè)面內(nèi)容(字節(jié))
                # 響應(yīng)頭 (字符數(shù)據(jù))
                response_first_line = 'HTTP/1.1 404 Not Found\r\n'
                response_header = 'Server: Laoxiao_Server\r\n'
            finally:
                # 組成響應(yīng)數(shù)據(jù),發(fā)送給客戶端(瀏覽器)
                response = (response_first_line + response_header + '\r\n').encode('utf-8') + response_body
                new_socket.send(response)
                new_socket.close()  # 關(guān)閉套接字

    # 啟動(dòng)服務(wù)器,并且接受客戶端的請(qǐng)求
    def start(self):
        # 循環(huán)并且多線程來接受客戶端的請(qǐng)求
        while True:
            new_socket, ip_port = self.server_socket.accept()
            print("客戶端的ip和端口", ip_port)
            # 一個(gè)客戶端請(qǐng)求交給一個(gè)線程來處理
            sub_thread = threading.Thread(target=MyHttpWebServer.handle_browser_request, args=(new_socket,))
            sub_thread.setDaemon(True)  # 設(shè)置當(dāng)前線程為守護(hù)線程
            sub_thread.start()  # 子線程要啟動(dòng)


# web服務(wù)器程序的入口
def main():
    web_server = MyHttpWebServer(8080)
    web_server.start()


if __name__ == '__main__':
    main()

MyFramework.py

# -*- coding: utf-8 -*-
# @File  : My_Web_Server.py
# @author: Flyme awei 
# @email : 1071505897@qq.com
# @Time  : 2022/7/24 21:28


import time
from functools import wraps
import pymysql

# 定義路由表
route_list = []


# route_list = {
#     # ('/index.html',index),
#     # ('/userinfo.html',user_info)
# }

# 定義一個(gè)帶參數(shù)裝飾器
def route(request_path):  # 參數(shù)就是URL請(qǐng)求
    def add_route(func):
        # 添加路由到路由表
        route_list.append((request_path, func))

        @wraps(func)
        def invoke(*arg, **kwargs):
            # 調(diào)用我們指定的處理函數(shù),并且返回結(jié)果
            return func()

        return invoke

    return add_route


# 處理動(dòng)態(tài)資源請(qǐng)求的函數(shù)
def handle_request(params):
    request_path = params['request_path']

    for path, func in route_list:
        if request_path == path:
            return func()
    else:
        # 沒有動(dòng)態(tài)資源的數(shù)據(jù),返回404頁(yè)面
        return page_not_found()
    # if request_path =='/index.html': # 當(dāng)前的請(qǐng)求路徑有與之對(duì)應(yīng)的動(dòng)態(tài)響應(yīng),當(dāng)前框架,我只開發(fā)了index.html的功能
    #     response = index()
    #     return response
    #
    # elif request_path =='/userinfo.html': # 個(gè)人中心的功能,user_info.html
    #     return user_info()
    # else:
    #     # 沒有動(dòng)態(tài)資源的數(shù)據(jù),返回404頁(yè)面
    #     return page_not_found()


# 當(dāng)前user_info函數(shù),專門處理userinfo.html的動(dòng)態(tài)請(qǐng)求
@route('/userinfo.html')
def user_info():
    # 需求:在頁(yè)面中動(dòng)態(tài)顯示當(dāng)前系統(tǒng)時(shí)間
    date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
    # response_body =data

    with open('template/user_info.html', 'r', encoding='utf-8') as f:
        response_body = f.read()

    response_body = response_body.replace('{%datas%}', date)

    response_first_line = 'HTTP/1.1 200 OK\r\n'
    response_header = 'Server: Laoxiao_Server\r\n'

    response = (response_first_line + response_header + '\r\n' + response_body).encode('utf-8')
    return response


# 當(dāng)前index函數(shù),專門處理index.html的請(qǐng)求
@route('/index.html')
def index():
    # 需求:從數(shù)據(jù)庫(kù)中取得所有的電影數(shù)據(jù),并且動(dòng)態(tài)展示
    # date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
    # response_body =data
    # 1、從MySQL中查詢數(shù)據(jù)
    conn = pymysql.connect(host='localhost', port=3306, user='root', password='******', database='test', charset='utf8')
    cursor = conn.cursor()
    cursor.execute('select * from t_movies')
    result = cursor.fetchall()
    # print(result)

    datas = ""
    for row in result:
        datas += '''<tr>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td>%s 億人民幣</td>
                <td>%s</td>
                <td>%s</td>
                <td>%s</td>
                <td> <input type='button'  value='刪除'/> </td>
                </tr>
                ''' % row
    print(datas)

    # 把查詢的數(shù)據(jù),轉(zhuǎn)換成動(dòng)態(tài)內(nèi)容
    with open('template/index.html', 'r', encoding='utf-8') as f:
        response_body = f.read()

    response_body = response_body.replace('{%datas%}', datas)

    response_first_line = 'HTTP/1.1 200 OK\r\n'
    response_header = 'Server: Laoxiao_Server\r\n'

    response = (response_first_line + response_header + '\r\n' + response_body).encode('utf-8')
    return response


# 處理沒有找到對(duì)應(yīng)的動(dòng)態(tài)資源
def page_not_found():
    with open('static/404.html', 'rb') as f:
        response_body = f.read()  # 響應(yīng)的主體頁(yè)面內(nèi)容(字節(jié))
    # 響應(yīng)頭 (字符數(shù)據(jù))
    response_first_line = 'HTTP/1.1 404 Not Found\r\n'
    response_header = 'Server: Laoxiao_Server\r\n'
    response = (response_first_line + response_header + '\r\n').encode('utf-8') + response_body
    return response

2、根據(jù)查詢的數(shù)據(jù)得到動(dòng)態(tài)的內(nèi)容

怎么使用Python開發(fā)自定義Web框架

以上就是關(guān)于“怎么使用Python開發(fā)自定義Web框架”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI