透過掃包的方式獲取app.api.v1
(這個是你的紅圖所在的包)下的所有module
透過判斷這個module下有api的屬性並且是Redprint
if hasattr(module, "api") and isinstance(module.api,Redprint):
滿足這兩個條件就可以呼叫module.api.register(bp_v1)
方法把對應的紅圖註冊了
app.api.v1.__init__.py
import importlib
import pkgutil
from flask import Blueprint
from app.libs.redprint import Redprint
def create_blueprint_v1():
bp_v1 = Blueprint('v1', __name__)
modules = find_modules("app.api.v1")
for module in modules:
if hasattr(module, "api") and isinstance(module.api,Redprint):
module.api.register(bp_v1)
return bp_v1
def find_modules(package_name):
# 匯入指定的包
package = importlib.import_module(package_name)
# 獲取包的路徑
package_path = package.__path__
modules = []
# 遍歷包下的所有模組
for module_info in pkgutil.iter_modules(package_path):
# 獲取模組的完整名稱
module_full_name = f"{package_name}.{module_info.name}"
try:
# 匯入模組
module = importlib.import_module(module_full_name)
modules.append(module)
except ImportError as e:
print(f"Failed to import {module_full_name}: {e}")
return modules
redprint.py
class Redprint:
def __init__(self, name):
self.name = name
self.mound = []
def route(self, rule, **options):
def decorator(f):
self.mound.append((f, rule, options))
return f
return decorator
def register(self, bp, url_prefix=None):
if url_prefix is None:
url_prefix = '/' + self.name
for f, rule, options in self.mound:
endpoint = f'{self.name}+{options.pop("endpoint", f.__name__)}'
bp.add_url_rule(url_prefix + rule, endpoint, f, **options)
藍圖註冊到app
def register_blueprints(app):
from app.api.v1 import create_blueprint_v1
app.register_blueprint(create_blueprint_v1(), url_prefix='/v1')
def create_app():
app = Flask(__name__)
...
register_blueprints(app)
...
使用
app.api.v1.user.py
api = Redprint('user')
@api.route('/<int:uid>', methods=['GET'])
@auth.login_required
def super_get_user(uid):
...
@api.route('', methods=['GET'])
@auth.login_required
def get_user():
...