Python 基于http.server模块实现简单http服务的代码举例

2025-08-20 10:50

本文主要是介绍Python 基于http.server模块实现简单http服务的代码举例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa...

测试环境

win11专业版

python 3.9

代码实现

# -*- coding:utf-8 -*-
import json
import traceback
import uuid
from http.server import HTTPServer, ThreadingHTTPServer, BaseHTTPRequestHandler
from urllib.parse import urlparse, parse_qs
class MyHTTPRequestHandler(BaseHTTPRequestHandler):
    def _send_response(self, status_code, content_type, body):
        '''发送响应信息'''
        self.send_response(status_code)
        self.send_header('Content-type', content_type)
        self.send_header('Cache-Control', 'no-store')  # 防止缓存旧编码响应
        self.end_headers()
        self.wfile.write(body.encode('utf-8'))
    def _handle_home(self):
        '''访问主页请求处理'''
        html = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><h1>Home Page</h1>'
        self._send_response(200, 'text/html; charset=utf-8', html)
    def _handle_404(self):
        '''请求不存在资源处理''China编程'
        # json_respose = {"success": False, "message": "Not Found"}
        # self._send_response(404, 'application/json;charset=utf-8', json.dumps(json_respose))
        # Content-Type 指定 charset=utf-8 可避免浏览器GET请求,界面中文显示乱码问题
        self._send_response(404, 'text/html; charset=utf-8', "<h1>404 Not Found</h1>")
    def _handle_login(self, login_req_data):
        '''处理登录请求'''
        try:
            data = json.loads(login_req_data)
            username = data.get('username')
            password = data.get('password')
            ip = data.get('ip')
            response = {
                'code': 0,
                'token': uuid.uuid4().hex,
                'description': 'success'
            }
            self._send_response(200, 'application/json; charset=utf-8', json.dumps(response))
        except Exception as e:
            error_msg = traceback.format_exc()
            print(error_msg)
            response = {
                'code': 1,
                'token': '',
                'description': error_msg
            }
            self._send_response(500, 'application/json; charset=utf-8', json.dumps(response))
    def do_GET(self):
        '''处理GET请求'''
        parsed_path = urlparse(self.path)
        path = parsed_path.path
        query_params = parse_qs(parsed_path.query)  # 获取URL携带的查询参数
        # print('收到GET请求参数:', query_params)
        if path == '/':
            self._handle_home()
        else:
            self._handle_404()
    def do_POST(self):
        '''处理POST请求'''
        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length)
        parsed_path = urlparse(self.path)
        path = parsed_path.path
        query_params = parse_qs(parsed_path.query)  # 获取URL 查询参数
        # print("收到POST数据:", post_data.decode())
        # 路由匹配逻辑
        if path == '/':
            self._handle_home()
        elif path == '/north/login':
            self._handle_login(post_data.decode())
        else:
            self._handle_404() 
if __name__ == '__main__':
    # server = HTTPServer(('0.0.0.0', 8000), MyHandler) # 阻塞式运行
    server = ThreadingHTTPServer(('localhost', 8000), MyHTTPRpythonequestHandler)
    print('正在启动服务,访问地址:http://localhost:8000')
    server.serve_forever()

扩展:如果我们希望服务在处理请求的时,调用其它类实例的方法,或者更新其它类实例的属性,咋处理呢?

答案:将其它类实例初始化为RequestHandler的类属性,然后在相关请求处理函数中进行调用

示例

class Subsystem():
    def __init__(self, http_server_port):
        self.http_server_port = http_server_port
        self.server = ThreadingHTTPServer(('0.0.0.0', self.http_server_port), lambda *args: MyHTTPRequestHandler(self, *args))
        self.north_server_info = {}
    def start_http_server(self):
        self.server.serve_forever()
    def push_data(self, data):
        '''测试函数'''
        logger.info(f'pushing data to server')
    def update_north_server_info(self, data):
        '''测试函数'''
        self.north_server_info[data.get('ip')] = data
class MyHTTPRequestHandler(BaseHTTPRequestHandler):
    def __init__(self, subsystem, *args, **kwargs):
        self.subsystem = subsystem  # 保存SubSystem实例引用
        super().__init__(*args, **kwargs)
    # ....略
    def _handle_login(self, login_req_data):
        '''处理登录请求'''
        try:
            data = json.loads(login_req_data)
            username = data.get('username')
            password = data.get('password')
            ip = data.get('ip')
            response = {
                'code': 0,
                'token': uuid.uuid4().hex,
                'description': 'success'
            }
            self.subsystem.push_data('')
            self.subsystem.update_north_server_info({'username': username, 'password': password, 'ip': ip})
            self._send_response(200, 'application/json; charset=utf-8', json.dumps(response))
        except Exception as e:
            error_msg = traceback.format_exc()
            logger.error(error_msg)
            response = {
                'code': 1,
                'token':'',
                'description': error_msg
            }
            self._send_response(500, 'application/json; charset=utf-8', json.dumps(response))
# 测试
if __name__ == '__main__':
    http_port = 8000
    for i in range(2):
        system = Subsystem(http_port)
        thread = threading.Thread(target=system.start_http_server)
        thread.start()
        http_port += 1

相关介绍

模块简介

http.server 模块定义了用于实现HTTP服务器(Web服务器)的类。

其中一个类,HTTPServersocketserver.TCPServer子类。它创建并监听HTTP套接字,将请求分派给处理程序。创建和运行服务器的代码示例如下:

def run(server_class=HTTPServer, handler_class=BaseHTTPRequestHandler):
    server_address = ('', 8000)
    httpd = server_class(server_address, handler_class)
    httpd.serve_forever()

类及相关函数简介

  • class http.server.HTTPServer(server_address, RequestHandlerClass)
  • 该类基于基于TCPServer 类构建,通过将将server地址存储为名为server_nameserver_port的实例变量。通过handler访问服务,通常是通过handler的server 实例变量
  • class http.server.ThreadingHTTPServer(server_address, RequestHandlerClass)
  • HTTPServer一样,除了通过使用 ThreadingMixIn使用线程处理请求。 3.7版本中新增

HTTPServer 和ThreadingHTTPServer 必须在实例化时给它一个RequestHandlerClass,此模块提供了三种不同的变体:

  • class http.server.BaseHTTPRequestHandler(request, client_address, server)
  • 此类用于处理到达服务器的HTTP请求。就其本身而言,它无法响应任何实际的HTTP请求;它必须被子类化以处理每个请求方法(例如GETPOST)。BaseHTTPRequestHandler提供了许多类和实例变量以及子类使用的方法。
  • BaseHTTPRequestHandler实例变量:
  • BaseHTTPRequestHandler属性:
  • BaseHTTPRequestHandler实例方法:
  • client_address
  • 包含一个 (host, port) 形式,表示客户端地址的元组
  • server
  • 包含服务器实例
  • close_connection
  • handle_one_request() 返回前需要设置的布尔值。指示是否可能需要另一个请求,或者是否应该关闭连接。
  • requestline
  • 包含HTTP请求行的字符串表示,不含终止CRLF。此属性应通过[handle_one_request()设置。如果没有处理有效的请求行,则应将其设置为空字符串。
  • command
  • 包含命令(请求类型)。例如,'GET'.
  • path
  • 包含请求路径。 如果URL的查询参数部分存在,则path包括查询参数。
  • request_version
  • 包含请求版本字符串,形如'HTTP/1.0'`。
  • headers
  • 保存由 MessageClass类变量指定的类的实例。此实例解析和管理HTTP请求中的请求头。parse_headers()函数来自 http.client,用于解析标头,它要求http请求提供有效的RFC 2822样式请求头。
  • rfile
  • 一个io.BufferedIOBase 输入流,准备从可选输入数据的开头读取。
  • wfile
  • 包含用于将响应写回客户端的输出流。在写入此流时,必须正确遵守HTTP协议,以实现与HTTP客户端的成功交互操作。在3.6版本中更改:这是一个 io.BufferedIOBase 流。
  • server_version
  • 指定服务器软件版本。你可能希望覆盖此内容。格式是多个空格分隔的字符串,其中每个字符串的格式为name[/version]。例如,'BaseHTTP/0.2'
  • sys_version
  • 包含Python系统版本,其形式和 version_string方法及 server_version]类变量使用的相同。例如,'Python/1.4'
  • error_message_for编程China编程mat
  • 指定send_error()应使用的格式字符串,用于构建对客户端的错误响应的。默认情况下,基于传递给send_error的状态代码,用responds中的变量填充该字符串。
  • error_content_type
  • 指定发送到客户端的错误响应的Content-Type HTTP请求头。默认值为 'text/html'
  • protocol_version
  • 这指定了响应中使用的HTTP协议版本。如果设置为'HTTP/1.1',服务器将允许HTTP持久连接;但是,服务器在对客户端的所有响应中必须包含一个准确的Content-Length请求头(使用send_header())。为了向后兼容,设置默认为“HTTP/1.0”。
  • MessageClass
  • 指定一个email.message.Message之类的类,用于解析HTTP头。通常,这是不可覆盖的,默认为http.client.HTTPMessage
  • responses
  • 此属性包含整数错误代码到包含短消息和长消息的两个元素元组的映射。例如,{code: (shortmessage, longmessage)}*shortmessage*通常用作错误响应中的message键,longmessage用作explain键。供send_response_onlysend_error()方法使用。
  • handle()
  • 调用handle_one_request()实现适当的do_*() 方法。
  • handle_one_request()
  • 此方法将解析请求并将其分发到适当的do_*()方法。你应永远不需要重写它。
  • handle_expect_100()
  • 当符合HTTP/1.1标准的服务器收到 Expect: 100-continupythone请求头时,它会以 100 Continue 和“ 200 OK 头作为响应。如果服务器不希望客户端继续,则可以重写此方法以引发错误。例如,服务器可以选择发送417 Expectation Failed 作为响应头,并返回False
  • 3.2版本中的新功能
  • send_error(code, message=None, explain=None)
  • 向客户端发送并http://www.chinasem.cn记录完整的错误回复。数字code指定HTTP错误代码,message作为可选的、简短的、人类可读的错误描述。explain参数可用于提供有关错误的更详细信息;它将使用 error_message_format 属性进行格式化,并在一组完整的标头之后作为响应体发出。response属性包含message和explain的默认值,如果没有提供值,将使用这些值;对于未知代码,两者的默认值都是字符串???。如果方法是HEAD或响应代码是以下代码之一:
  • 1xx, 204 No Content, 205 Reset Content, 304 Not Modified,则请求体将为空。
  • 在版本3.4中变更:错误响应包含Content-Length头。添加了explain参数。
  • send_response(code, message=None)
  • 添加一个响应头添加到headers缓冲区,并记录接受的请求。HTTP响应行被写入内部缓冲区,后面跟随Server和Date响应头。这两个响应头的值分别从version_string() 和date_time_string()方法中获取。如果服务器不打算使用send_header()发送任何其他请求头,则send_response()后面应该跟一个end_headers()调用。
  • 3.3版本中变更:header存储在内部缓冲区,且需要显示调用end_headers()
  • send_header(keyword, value)
  • 将HTTP头添加到内部缓冲区,当end_headers()或者flush_headers()被调用时,该缓冲区中的内容将被写入到输出流。keyword应指定header,value指定其值。请注意,在send_headers调用完成后,必须调用end_headers()才能完成操作。
  • 版本3.2中变更:HTTP头存储在内部缓冲区中
  • send_response_only(code, message=None)
  • 仅发送响应头,服务器向客户端发送100 Continue 响应时使用。响应头未缓冲,直接发送到输出流。如果未指定message,则发送与响应code对应的HTTP消息。
  • 版本3.2中的新功能
  • end_headers()
  • 在header缓冲区中添加一个空行(表示响应中HTTP头的结束)并调用flush_headers()
  • 版本3.2中变更:缓冲的HTTP头被写入输出流
  • flush_headers()
  • 最后将HTTP头发送到输出流并刷新内部HTTP头缓冲区。3.3版本中的新功能。
  • log_request(code='-', size='-')
  • 记录已接受(成功)的请求。code应指定与响应关联的数字HTTP code。如果可获取响应的大小,则应将其作为size参数传递。
  • log_error(...)
  • 当请求无法满足时记录错误。默认情况下,它将消息传递给log_message(),因此它采用相同的参数(format和其它参数)。
  • log_message(format, ...)
  • 将任意消息记录到sys.stderr。这通常会被重写以创建自定义错误日志记录机制。format参数是一个标准的类printf风格的格式字符串,其中log_message()的附加参数作为格式化的输入。客户端ip地址和当前日期和时间都会作为记录的每条消息的前缀。
  • version_string()
  • 返回服务器软件的版本字符串。这是server_version以及sys_version属性的混合。
  • date_time_string(timestamp=None)
  • 返回timestamp给出的日期和时间(必须为None或采用time.time()返回的格式),格式化为消息头。如果省略timestamp,则使用当前日期和时间。结果看起来像'Sun, 06 Nov 1994 08:49:37 GMT'
  • log_date_time_string()
  • 返回当前日期和时间,格式化为日志记录格式。
  • address_string()
  • 返回客户端地址。
  • 3.3版本中变更:以前执行了名称查找。为了避免名称解析延迟,它现在总是返回IP地址。
  • class http.server.SimpleHTTPRequestHandler(request, client_address, server, directory=None)
  • 介绍略
  • class http.server.``CGIHTTPRequestHandler(*request*, client_address, server)
  • 介绍略

参考链接

https://docs.python.org/3.9/library/http.server.html

到此这篇关于Python 基于http.server模块实现简单http服务的文章就介绍到这了,更多相关Python http.server模块http服务内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!

这篇关于Python 基于http.server模块实现简单http服务的代码举例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1155827

相关文章

Python自动化处理PDF文档的操作完整指南

《Python自动化处理PDF文档的操作完整指南》在办公自动化中,PDF文档处理是一项常见需求,本文将介绍如何使用Python实现PDF文档的自动化处理,感兴趣的小伙伴可以跟随小编一起学习一下... 目录使用pymupdf读写PDF文件基本概念安装pymupdf提取文本内容提取图像添加水印使用pdfplum

SpringBoot集成XXL-JOB实现任务管理全流程

《SpringBoot集成XXL-JOB实现任务管理全流程》XXL-JOB是一款轻量级分布式任务调度平台,功能丰富、界面简洁、易于扩展,本文介绍如何通过SpringBoot项目,使用RestTempl... 目录一、前言二、项目结构简述三、Maven 依赖四、Controller 代码详解五、Service

GO语言短变量声明的实现示例

《GO语言短变量声明的实现示例》在Go语言中,短变量声明是一种简洁的变量声明方式,使用:=运算符,可以自动推断变量类型,下面就来具体介绍一下如何使用,感兴趣的可以了解一下... 目录基本语法功能特点与var的区别适用场景注意事项基本语法variableName := value功能特点1、自动类型推

Python从Word文档中提取图片并生成PPT的操作代码

《Python从Word文档中提取图片并生成PPT的操作代码》在日常办公场景中,我们经常需要从Word文档中提取图片,并将这些图片整理到PowerPoint幻灯片中,手动完成这一任务既耗时又容易出错,... 目录引言背景与需求解决方案概述代码解析代码核心逻辑说明总结引言在日常办公场景中,我们经常需要从 W

基于Python实现自动化邮件发送系统的完整指南

《基于Python实现自动化邮件发送系统的完整指南》在现代软件开发和自动化流程中,邮件通知是一个常见且实用的功能,无论是用于发送报告、告警信息还是用户提醒,通过Python实现自动化的邮件发送功能都能... 目录一、前言:二、项目概述三、配置文件 `.env` 解析四、代码结构解析1. 导入模块2. 加载环

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

使用shardingsphere实现mysql数据库分片方式

《使用shardingsphere实现mysql数据库分片方式》本文介绍如何使用ShardingSphere-JDBC在SpringBoot中实现MySQL水平分库,涵盖分片策略、路由算法及零侵入配置... 目录一、ShardingSphere 简介1.1 对比1.2 核心概念1.3 Sharding-Sp

Python Counter 函数使用案例

《PythonCounter函数使用案例》Counter是collections模块中的一个类,专门用于对可迭代对象中的元素进行计数,接下来通过本文给大家介绍PythonCounter函数使用案例... 目录一、Counter函数概述二、基本使用案例(一)列表元素计数(二)字符串字符计数(三)元组计数三、C

Java+AI驱动实现PDF文件数据提取与解析

《Java+AI驱动实现PDF文件数据提取与解析》本文将和大家分享一套基于AI的体检报告智能评估方案,详细介绍从PDF上传、内容提取到AI分析、数据存储的全流程自动化实现方法,感兴趣的可以了解下... 目录一、核心流程:从上传到评估的完整链路二、第一步:解析 PDF,提取体检报告内容1. 引入依赖2. 封装

使用Spring Cache本地缓存示例代码

《使用SpringCache本地缓存示例代码》缓存是提高应用程序性能的重要手段,通过将频繁访问的数据存储在内存中,可以减少数据库访问次数,从而加速数据读取,:本文主要介绍使用SpringCac... 目录一、Spring Cache简介核心特点:二、基础配置1. 添加依赖2. 启用缓存3. 缓存配置方案方案