Skip to content

Commit 2c72559

Browse files
committed
fix and optimize plugin router inject
1 parent 2c577c9 commit 2c72559

File tree

6 files changed

+40
-37
lines changed

6 files changed

+40
-37
lines changed

backend/app/admin/api/v1/sys/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
router.include_router(dept_router, prefix='/depts', tags=['系统部门'])
2323
router.include_router(dict_data_router, prefix='/dict-datas', tags=['系统字典数据'])
2424
router.include_router(dict_type_router, prefix='/dict-types', tags=['系统字典类型'])
25-
router.include_router(menu_router, prefix='/menus', tags=['系统目录'])
25+
router.include_router(menu_router, prefix='/menus', tags=['系统菜单'])
2626
router.include_router(role_router, prefix='/roles', tags=['系统角色'])
2727
router.include_router(user_router, prefix='/users', tags=['系统用户'])
2828
router.include_router(data_rule_router, prefix='/data-rules', tags=['系统数据权限规则'])

backend/core/registrar.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from fastapi_pagination import add_pagination
1111
from starlette.middleware.authentication import AuthenticationMiddleware
1212

13-
from backend.app.router import router
1413
from backend.common.exception.exception_handler import register_exception
1514
from backend.common.log import set_customize_logfile, setup_logging
1615
from backend.core.conf import settings
@@ -159,8 +158,11 @@ def register_router(app: FastAPI):
159158
dependencies = [Depends(demo_site)] if settings.DEMO_MODE else None
160159

161160
# API
162-
new_router = plugin_router_inject(router)
163-
app.include_router(new_router, dependencies=dependencies)
161+
plugin_router_inject()
162+
163+
from backend.app.router import router # 必须在插件路由注入后导入
164+
165+
app.include_router(router, dependencies=dependencies)
164166

165167
# Extra
166168
ensure_unique_route_names(app)

backend/main.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,5 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
3-
from pathlib import Path
4-
5-
import uvicorn
6-
73
from backend.core.registrar import register_app
84

95
app = register_app()
10-
11-
12-
if __name__ == '__main__':
13-
# 如果你喜欢在 IDE 中进行 DEBUG,main 启动方法会很有帮助
14-
# 如果你喜欢通过 print 方式进行调试,建议使用 fastapi cli 方式启动服务
15-
try:
16-
config = uvicorn.Config(app=f'{Path(__file__).stem}:app', reload=True)
17-
server = uvicorn.Server(config)
18-
server.run()
19-
except Exception as e:
20-
raise e

backend/plugin/notice/schema/notice.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class NoticeSchemaBase(SchemaBase):
1313
type: int
1414
author: str
1515
source: str
16-
status: StatusType = Field(StatusType.enable)
16+
status: StatusType = Field(default=StatusType.enable)
1717
content: str
1818

1919

backend/plugin/tools.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
3-
import importlib
43
import inspect
54
import os
65
import warnings
@@ -10,6 +9,7 @@
109
from fastapi import APIRouter
1110

1211
from backend.core.path_conf import PLUGIN_DIR
12+
from backend.utils.import_parse import import_module_cached
1313

1414

1515
def get_plugins() -> list[str]:
@@ -32,19 +32,18 @@ def get_plugin_models() -> list:
3232
plugins = get_plugins()
3333
for plugin in plugins:
3434
module_path = f'backend.plugin.{plugin}.model'
35-
module = importlib.import_module(module_path)
35+
module = import_module_cached(module_path)
3636
for name, obj in inspect.getmembers(module):
3737
if inspect.isclass(obj):
3838
classes.append(obj)
3939
return classes
4040

4141

42-
def plugin_router_inject(router: APIRouter) -> APIRouter:
42+
def plugin_router_inject() -> None:
4343
"""
4444
插件路由注入
4545
46-
:param router: 源总路由器
47-
:return: 注入插件路由后的总路由器
46+
:return:
4847
"""
4948
plugins = get_plugins()
5049
for plugin in plugins:
@@ -66,17 +65,17 @@ def plugin_router_inject(router: APIRouter) -> APIRouter:
6665

6766
# 路由注入
6867
if app_name:
69-
# 非独立应用:将插件中的路由注入到源程序对应模块的路由中
68+
# 非独立应用:将插件路由注入到对应模块的路由中
7069
for root, _, api_files in os.walk(plugin_api_path):
7170
for file in api_files:
7271
if file.endswith('.py') and file != '__init__.py':
73-
api_files_path = os.path.join(root, file)
72+
file_path = os.path.join(root, file)
7473

7574
# 获取插件路由模块
76-
path_to_module_str = os.path.relpath(api_files_path, PLUGIN_DIR).replace(os.sep, '.')[:-3]
75+
path_to_module_str = os.path.relpath(file_path, PLUGIN_DIR).replace(os.sep, '.')[:-3]
7776
module_path = f'backend.plugin.{path_to_module_str}'
7877
try:
79-
module = importlib.import_module(module_path)
78+
module = import_module_cached(module_path)
8079
except ImportError as e:
8180
raise ImportError(f'导入模块 {module_path} 失败:{e}') from e
8281
plugin_router = getattr(module, 'router', None)
@@ -91,7 +90,7 @@ def plugin_router_inject(router: APIRouter) -> APIRouter:
9190
relative_path = os.path.relpath(root, plugin_api_path)
9291
target_module_path = f'backend.app.{app_name}.api.{relative_path.replace(os.sep, ".")}'
9392
try:
94-
target_module = importlib.import_module(target_module_path)
93+
target_module = import_module_cached(target_module_path)
9594
except ImportError as e:
9695
raise ImportError(f'导入目标模块 {target_module_path} 失败:{e}') from e
9796
target_router = getattr(target_module, 'router', None)
@@ -102,18 +101,21 @@ def plugin_router_inject(router: APIRouter) -> APIRouter:
102101
target_router.include_router(
103102
router=plugin_router,
104103
prefix=prefix,
105-
tags=tags if type(tags) is list else [tags],
104+
tags=tags if tags == [] else [tags],
106105
)
107106
else:
108-
# 独立应用:将插件中的路由直接注入到 app 中
107+
# 独立应用:将插件中的路由直接注入到总路由中
109108
module_path = f'backend.plugin.{plugin}.api.router'
110109
try:
111-
target_module = importlib.import_module(module_path)
110+
module = import_module_cached(module_path)
112111
except ImportError as e:
113112
raise ImportError(f'导入目标模块 {module_path} 失败:{e}') from e
114-
target_router = getattr(target_module, 'router', None)
115-
if not target_router or not isinstance(target_router, APIRouter):
113+
plugin_router = getattr(module, 'router', None)
114+
if not plugin_router or not isinstance(plugin_router, APIRouter):
116115
raise AttributeError(f'目标模块 {module_path} 中没有有效的 router,请检查插件文件是否完整')
117-
router.include_router(target_router)
116+
target_module_path = 'backend.app.router'
117+
target_module = import_module_cached(target_module_path)
118+
target_router = getattr(target_module, 'router')
118119

119-
return router
120+
# 将插件路由注入到目标 router 中
121+
target_router.include_router(plugin_router)

backend/run.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
import uvicorn
4+
5+
if __name__ == '__main__':
6+
# 为什么独立此启动文件:https://stackoverflow.com/questions/64003384
7+
# 如果你喜欢在 IDE 中进行 DEBUG,可在 IDE 中直接右键启动此文件
8+
# 如果你喜欢通过 print 方式进行调试,建议使用 fastapi cli 方式启动服务
9+
try:
10+
config = uvicorn.Config(app='backend.main:app', reload=True)
11+
server = uvicorn.Server(config)
12+
server.run()
13+
except Exception as e:
14+
raise e

0 commit comments

Comments
 (0)