目录

    • 1. 项目概述
    • 2. 项目结构
    • 3. 核心组件解析
      • 3.1 动态模块注册系统 (`api/__init__.py`)
      • 3.2 应用程序入口 (`setup_demo.py`)
    • 4. 模块开发指南
      • 4.1 标准模块 (`*_app.py`)
      • 4.2 SDK模块 (`sdk/*.py`)
    • 5. URL路径规则
    • 6. 如何使用
      • 6.1 启动应用
      • 6.2 添加新模块
    • 7. 工作原理

1. 项目概述

这个项目是一个基于Flask的动态模块注册系统,它允许你以一种模块化的方式组织API端点,并且能够自动发现和注册这些模块。这种架构特别适合构建可扩展的Web API服务,让你可以轻松地添加新功能而无需修改核心代码。

2. 项目结构

flask_path_test/
├── .venv/                  # Python虚拟环境目录
├── api/                    # API模块目录
│   ├── __init__.py         # 核心功能:动态模块注册系统
│   ├── product_app.py      # 产品模块
│   ├── user_app.py         # 用户模块
│   └── sdk/                # SDK模块目录
│       └── auth.py         # 认证SDK模块
├── .gitignore              # Git忽略文件配置
├── .python-version         # Python版本配置文件
├── pyproject.toml          # 项目配置文件
├── README.md               # 项目说明文档
├── setup_demo.py           # 应用程序入口文件
└── uv.lock                 # 依赖锁定文件

环境准备

uv init
uv venv
source .venv/bin/activate
uv pip install flask

3. 核心组件解析

3.1 动态模块注册系统 (api/__init__.py)

这个文件是整个系统的核心,它实现了以下功能:

  • 自动发现模块:搜索所有符合命名规则的模块文件
  • 动态加载模块:使用Python的importlib机制动态加载模块
  • 注册Flask蓝图:将每个模块注册为Flask蓝图,并设置合适的URL前缀
  • 提供主页视图:显示所有已注册的模块及其URL

关键函数:

  • search_pages_path():搜索所有以_app.py结尾的文件和SDK目录下的Python文件
  • register_page():将找到的模块文件注册为Flask蓝图
  • auto_register_pages():自动注册所有找到的模块
    代码:
import sys
from pathlib import Path
from importlib.util import spec_from_file_location, module_from_spec
from flask import Flask, Blueprint# 创建Flask应用
app = Flask(__name__)
API_VERSION = "v1"
registered_urls = []def search_pages_path(pages_dir):"""搜索页面路径"""app_path_list = [path for path in pages_dir.glob("*_app.py") if not path.name.startswith(".")]# 搜索根目录下的sdkapi_sdk_path_list = [path for path in pages_dir.glob("*sdk/*.py") if not path.name.startswith(".")]app_path_list.extend(api_sdk_path_list)return app_path_listdef register_page(page_path):"""注册页面模块为Flask蓝图"""path = f"{page_path}"# 获取页面名称(去掉_app后缀)page_name = page_path.stem.rstrip("_app")# 构建模块名称module_name = ".".join(page_path.parts[page_path.parts.index("api"): -1] + (page_name,))print(f"module_name: {module_name}")# 动态加载模块spec = spec_from_file_location(module_name, page_path)page = module_from_spec(spec)# 先设置app和manager,再执行模块代码page.app = apppage.manager = Blueprint(page_name, module_name)sys.modules[module_name] = pagespec.loader.exec_module(page)# 获取页面名称(可能在模块中重新定义)page_name = getattr(page, "page_name", page_name)# 确定URL前缀sdk_path = "\\sdk\\" if sys.platform.startswith("win") else "/sdk/"url_prefix = (f"/api/{API_VERSION}" if sdk_path in path else f"/{API_VERSION}/{page_name}")print(f"url_prefix: {url_prefix}")# 注册蓝图app.register_blueprint(page.manager, url_prefix=url_prefix)return url_prefixdef auto_register_pages():"""自动注册所有页面模块"""global registered_urls# 创建api目录结构api_dir = Path("api")api_dir.mkdir(exist_ok=True)# 搜索并注册所有页面page_paths = search_pages_path(api_dir)result = []print(page_paths)for page_path in page_paths:try:url_prefix = register_page(page_path)result.append((page_path.name, url_prefix))print(f"已注册模块: {page_path.name} -> {url_prefix}")except Exception as e:print(f"注册模块 {page_path.name} 失败: {e}")return result@app.route('/')
def index():"""主页显示所有注册的模块"""global registered_urlshtml = "<h1>Flask 动态模块注册演示</h1>"html += "<h2>已注册的模块:</h2><ul>"for module_name, url_prefix in registered_urls:html += f"<li><strong>{module_name}</strong>: <a href='{url_prefix}'>{url_prefix}</a></li>"html += "</ul>"html += "<p>访问上面的链接查看各个模块的功能</p>"return html

3.2 应用程序入口 (setup_demo.py)

这个文件是应用程序的入口点,它:

  • 导入核心组件
  • 调用auto_register_pages()注册所有模块
  • 启动Flask应用服务器
from api import app, auto_register_pages, registered_urls# 如果需要,可以在这里进行额外的配置
# app.config['SOME_CONFIG'] = 'some_value'# 运行应用程序
if __name__ == '__main__':# 清空已注册的URL列表registered_urls.clear()# 手动注册所有模块result = auto_register_pages()registered_urls.extend(result)print(f"已注册的URL: {registered_urls}")# 运行应用程序app.run(debug=True, port=5000)

4. 模块开发指南

4.1 标准模块 (*_app.py)

标准模块文件需要遵循以下规则:

  1. 文件名必须以_app.py结尾(例如:user_app.pyproduct_app.py
  2. 模块中可以定义page_name变量来自定义URL路径(可选)
  3. 使用@manager.route()装饰器定义路由

示例(product_app.py):

from flask import jsonify# 可以自定义页面名称
page_name = "products"@manager.route('/')
def product_list():"""产品列表接口"""return jsonify({"message": "产品模块","products": [{"id": 1, "name": "笔记本电脑", "price": 5999},{"id": 2, "name": "智能手机", "price": 2999}]})@manager.route('/<int:product_id>')
def product_detail(product_id):"""产品详情接口"""return jsonify({"message": f"产品详情 - ID: {product_id}","product": {"id": product_id, "name": f"产品{product_id}", "price": 1000 + product_id * 100}})

示例(user_app.py):

from flask import jsonify@manager.route('/')
def user_list():"""用户列表接口"""return jsonify({"message": "用户模块","users": [{"id": 1, "name": "张三", "email": "zhangsan@example.com"},{"id": 2, "name": "李四", "email": "lisi@example.com"}]})@manager.route('/<int:user_id>')
def user_detail(user_id):"""用户详情接口"""return jsonify({"message": f"用户详情 - ID: {user_id}","user": {"id": user_id, "name": f"用户{user_id}", "email": f"user{user_id}@example.com"}})

4.2 SDK模块 (sdk/*.py)

SDK模块放置在api/sdk/目录下,它们会被自动注册到/api/v1路径下。

示例(sdk/auth.py):

from flask import jsonify, request@manager.route('/', methods=['GET'])
def login():"""登录接口"""return jsonify({"message": "SDK认证模块 - 登录","token": "fake_jwt_token_12345","expires_in": 3600})

5. URL路径规则

系统会根据模块类型和名称自动生成URL路径:

  • 标准模块:/v1/{page_name}/
    • 例如:/v1/products//v1/user/
  • SDK模块:/api/v1/
    • 例如:/api/v1/(auth模块)

6. 如何使用

6.1 启动应用

uv run setup_demo.py

在这里插入图片描述

在这里插入图片描述

应用将在http://localhost:5000启动,访问主页可以看到所有已注册的模块列表。

6.2 添加新模块

  1. api/目录下创建新的*_app.py文件
  2. 定义路由函数
  3. 重启应用,新模块会被自动发现和注册

示例(创建新的order_app.py):

from flask import jsonify# 可以自定义页面名称
page_name = "orders"@manager.route('/')
def order_list():"""订单列表接口"""return jsonify({"message": "订单模块","orders": [{"id": 1, "product_id": 1, "user_id": 1, "status": "已付款"},{"id": 2, "product_id": 2, "user_id": 2, "status": "待发货"}]})

7. 工作原理

  1. setup_demo.py启动时调用auto_register_pages()
  2. auto_register_pages()搜索所有符合规则的模块文件
  3. 对每个找到的文件,调用register_page()进行注册
  4. register_page()动态加载模块,并将其注册为Flask蓝图
  5. 所有注册的URL保存在registered_urls列表中,并在主页中显示

这个Flask动态模块注册系统提供了一种优雅的方式来组织和扩展你的API服务。通过遵循简单的命名约定和目录结构,你可以轻松添加新功能而无需修改核心代码。这种模块化的设计特别适合大型项目,让团队成员可以独立开发不同的功能模块。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/84962.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/84962.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/84962.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM 内存、JMM内存与集群机器节点内存的联系

目录 1、JVM 内存 1.1、分配机制 1.2、jvm模型位置 1.3、字节码内存块 2、JMM内存 2.1、JMM模型 2.2、工作流程图 1、工作内存与主内存的交互 2. 多线程下的主内存与堆内存交互 2.3、 主内存与工作内存的同步方案 1、volatile 2、synchronized 3、final 3、内存使…

学习昇腾开发的第一天--环境配置

1、昇腾社区官网&#xff1a;昇腾社区官网-昇腾万里 让智能无所不及 2、产品-->选择开发者套件-->点击制卡工具的下载&#xff1a;资源-Atlas 200I DK A2-昇腾社区 3、如果制卡工具不能使用在线制卡&#xff0c;可以下载镜像到本地使用本地制卡&#xff1a;Linux系统制…

Android WebView 深色模式适配方案总结

Android WebView 深色模式适配方案总结 在 Android WebView 中适配深色模式&#xff08;Dark Mode&#xff09;是一个常见的需求&#xff0c;尤其是当加载的网页没有原生支持 prefers-color-scheme 时。本文将介绍 3 种主流方案&#xff0c;并分析它们的优缺点&#xff0c;帮助…

项目练习:使用mybatis的foreach标签,实现union all的拼接语句

文章目录 一、需求说明二、需求分析三、代码实现四、报表效果 一、需求说明 在sql查询数据后&#xff0c;对数据分组统计。并最后进行总计。 二、需求分析 最终&#xff0c;我想用sql来实现这个统计和查询的功能。 那么&#xff0c;怎么又查询&#xff0c;又统计了&#xf…

7.7 Extracting and saving responses

Chapter 7-Fine-tuning to follow instructions 7.7 Extracting and saving responses 在本节中&#xff0c;我们保存测试集响应以便在下一节中评分&#xff0c;除此之外保存模型的副本以供将来使用。 ​ 首先&#xff0c;让我们简单看看finetuned模型生成的响应 torch.manu…

计算机网络第3章(上):数据链路层全解析——组帧、差错控制与信道效率

目录 一、数据链路层的功能二、组帧2.1 字符计数法&#xff08;Character Count&#xff09;2.2 字符填充法&#xff08;Character Stuffing&#xff09;2.3 零比特填充法2.4 违规编码法 三、差错控制3.1 检错编码&#xff08;奇偶校验码&#xff09;3.2 循环冗余校验&#xff…

铸铁试验平台的重要性及应用前景

铸铁作为一种重要的金属材料&#xff0c;在工业生产中扮演着举足轻重的角色。为了确保铸铁制品的质量和性能&#xff0c;铸铁材料的试验是必不可少的环节。而铸铁试验平台则是进行铸铁试验的关键设备之一&#xff0c;它为铸铁材料的研究和开发提供了重要的技术支持。本文将探讨…

std::shared_ptr引起内存泄漏的例子

目录 一、循环引用&#xff08;最常见场景&#xff09; 示例代码 内存泄漏原因 二、共享指针管理的对象包含自身的 shared_ptr 示例代码 内存泄漏&#xff08;或双重释放&#xff09;原因 三、解决方案 1. 循环引用&#xff1a;使用 std::weak_ptr 2. 对象获取自身的 …

AI 知识数据库搭建方案:从需求分析到落地实施

AI 知识数据库的搭建需结合业务场景、数据特性与技术架构&#xff0c;形成系统化解决方案。以下是一套完整的搭建框架&#xff0c;涵盖规划、设计、实施及优化全流程&#xff1a; 一、前期规划&#xff1a;需求分析与目标定义 1. 明确业务场景与知识需求 场景导向&#xff1a…

Tensorflow 基础知识:变量、常量、占位符、Session 详解

在深度学习领域,TensorFlow 是一个广泛使用的开源机器学习框架。想要熟练使用 TensorFlow 进行模型开发,掌握变量、常量、占位符和 Session 这些基础知识是必不可少的。接下来,我们就深入了解一下它们的概念、用处,并通过代码示例进行演示。 一、常量(Constant) 常量,顾…

linux 常见问题之如何清除大文件的内容

linux 常见问题之如何清除大文件的内容 在 Linux 系统中&#xff0c;我们有时会遇到文件随着时间增长变得巨大&#xff0c;最常见的就是服务器的日志文件&#xff0c;随着时间的推移占用大量的磁盘空间&#xff0c;下面介绍如何清楚大文件的内容&#xff0c;当然避免文件内容过…

薛定谔的猫思想实验如何推演到量子计算

前言 这是我的选修课作业&#xff0c;但是我并不喜欢小论文方式的写法&#xff0c;死板又老套。先在这打一份底稿。 薛定谔的猫 可能一说到量子这个关键词&#xff0c;大家第一时间都会想到的是“薛定谔的猫”。 实验介绍 薛定谔的猫是一个著名的思想实验&#xff0c;由奥…

嵌入式开发中fmacro-prefix-map选项解析

在嵌入式开发中&#xff0c;-fmacro-prefix-map 是 GCC 和 Clang 等编译器提供的一个路径映射选项&#xff0c;主要用于在预处理阶段重写宏定义中出现的绝对路径。它的核心目的是解决以下问题&#xff1a; 核心作用 构建可重现性 消除编译输出&#xff08;如 .o、.d 文件&…

Javaweb学习——day3(Servlet 中处理表单数据)

文章目录 一、概念学习1. GET vs POST 请求方式的区别2. HttpServletRequest 获取表单数据 二、代码讲解与练习第 1 步&#xff1a;在 webapp 下创建 login.html第 2 步&#xff1a;在 com.example 包下创建 LoginServlet第 3 步&#xff1a;修改 web.xml 注册 LoginServlet第 …

在 iOS 开发中单独解析域名为 IP

1 为什么要自己解析? 典型场景说明劫持/污染检测比较 系统解析 与 自建 DNS 的差异QoS / CDN 选路对每个候选 IP 做 RT/丢包测速系统 API(NSURLSession / Network.framework)在「真正建立连接之前」不会把解析结果暴露出来,因此需要主动解析一步。 2 API 选型概览 API是否过…

YOLOv1 技术详解:正负样本划分与置信度设计

&#x1f50d; YOLOv1 技术详解&#xff1a;正负样本划分与置信度设计 一、前言 YOLOv1 是目标检测领域中具有划时代意义的算法之一&#xff0c;它将检测任务统一为一个回归问题&#xff0c;实现了“You Only Look Once”的端到端实时检测。其中&#xff0c;正负样本的划分机…

为 Nginx 配置 HTTPS(以 n8n 为例)完整教程【CentOS 7】

在部署如 n8n 这类自动化平台时&#xff0c;为了保障数据传输安全&#xff0c;我们通常会使用 HTTPS 访问。本文将以 n8n.example.com 为例&#xff0c;介绍如何在 CentOS 7 系统中通过 Nginx 为本地运行在端口 5678 的 n8n 服务配置免费 SSL 证书&#xff08;Let’s Encrypt&a…

Elasticsearch从安装到实战、kibana安装以及自定义IK分词器/集成整合SpringBoot详细的教程ES(四)查询、排序、分页、高亮

基础代码 package com.test.xulk;import com.alibaba.fastjson.JSON; import com.test.xulk.es.esdoc.HotelDoc; import com.test.xulk.es.service.IHotelService; import org.apache.http.HttpHost; import org.elasticsearch.action.search.SearchRequest; import org.elast…

一个数组样式上要分成两个

如图所示&#xff0c;要有一个区分来显示&#xff0c;如果一开始就是这样还可以有很多种处理方式&#xff0c;但是这个后期一直在调整所以不好重做因为开发已经完成&#xff0c;加上很多地方联动改的地方太多&#xff0c;所以采用了一个比较笨的方法 <ul class"classif…

NLP进化史:从规则模板到思维链推理,七次范式革命全解析

“语言不是神的创造物&#xff0c;而是平凡人类的产物。”——诺姆乔姆斯基 自然语言处理&#xff08;NLP&#xff09;的发展史&#xff0c;就是人类试图教会机器理解语言本质的探索史。本文将带您穿越70年技术长河&#xff0c;揭示NLP领域关键的范式转换里程碑。 一、规则驱动…