【问题标题】:How to use url_map.iter_rules with blueprint object instead of app如何将 url_map.iter_rules 与蓝图对象而不是应用程序一起使用
【发布时间】:2016-04-12 05:11:05
【问题描述】:

我有一个蓝图对象“api”和一个 apis.py 文件,其中我有许多使用 api.route 注释定义的 API。例如:

@api.route('/', methods=['GET'])
def get_info():

我想迭代并获取我拥有的所有 API 的摘要,这些 API 与我们在 app 对象上使用“url_map.iter_rules”时得到的相同。我们如何使用 api 蓝图对象来做到这一点?我已经使用

在我的 init.py 文件中注册了蓝图
from .api_1 import api as api_blueprint
app.register_blueprint(api_blueprint)

【问题讨论】:

    标签: python flask flask-restful


    【解决方案1】:

    我认为,如果您在注册蓝图后致电app.url_map.iter_rules(),您也会获得子域的所有端点,例如

    api.py

    from flask import Blueprint
    api = Blueprint('api', __name__)
    @api.route('/')
    def call_api():
            return ""
    

    init.py:

    from flask import Flask, Blueprint
    from api import api
    
    public = Blueprint('public', __name__)
    @public.route('/')
    def home():
            return render_template('public/home.html')
    
    
    app = Flask(__name__)
    app.register_blueprint(public)
    app.register_blueprint(api, subdomain='api')
    print(list(app.url_map.iter_rules()))
    
    [<Rule 'api|/' (GET, HEAD, OPTIONS) -> api.call_api>,
     <Rule '/' (GET, HEAD, OPTIONS) -> public.home>,
     <Rule '/static/<filename>' (GET, HEAD, OPTIONS) -> static>]
    

    【讨论】:

    • 我在 init.py 中启动我的应用程序对象,如我的问题所示,然后我有另一个名为 apis.py 的文件,其中定义了我的所有 API。所以我没有在 apis.py 文件中注册蓝图,也没有 app 对象。我只是使用from . import api 在 apis.py 中导入蓝图。你能告诉我我需要在我的 apis.py 或 init.py 中包含什么吗?我需要将其作为单独的 API api.route('/api/help', methods = ['GET']),并且我已经有了在此中使用 app 对象使用 app.url_map.iter_rules() 的代码
    • 我要使用:whch 读取文档字符串:@api.route('/api/help', methods = ['GET']) def help(): func_list = {} for rule in app.url_map.iter_rules(): if rule.endpoint != 'static': docstring = app.view_functions[rule.endpoint].__doc__ if docstring: func_list[docstring] = rule.rule return jsonify(func_list)
    • 好的,所以我重新排列了答案中的模块,这是否符合您现在的情况?您不需要模块中的应用程序对象。
    • public.route('/') 是干什么用的?我们不能跳过这个吗?另外我希望这个输出是 json 格式的 key:value = function_name:url 有可能吗?
    • 我猜你可以跳过它,但你可能不应该,公开这个“默认”路由进行健康检查以查看你的服务是否正在运行是个好主意。如果需要 json,则需要编写一些代码来解析输出并放入 dict
    【解决方案2】:

    如果您觉得它有用,我创建了一个函数,根据在主应用程序中注册的蓝图向我显示(仅用于测试)每个 url。 这是我发现能够打印通过它们所属的蓝图将它们分开的端点的唯一解决方案。 当然,您可以创建一个函数,以便通过以字符串格式传递名称或蓝图本身来打印仅其中一个蓝图的 url_map。 以下是示例:

    from flask.logging import create_logger
    def log_routes(app: Flask):
    
        log = create_logger(app)
    
        with app.app_context():
            """
            Maps every single endpoint for blueprint registered in the main application.
            Also shows methos available for each endpoint
            """
    
            log.info('MAP ROUTER')
            bps = app.blueprints
            for bp in bps:
                print('', end='\n')
                log.info(f'BLUEPRINT RULES: "{bp}"')
                for ep in app.url_map.iter_rules():
                    bp_name = ep.endpoint.split('.')[0]
                    if bp_name == bp:
                        log.debug(f'Endpoint: {ep} methods={ep.methods}')
    

    下面是一个函数示例,该函数仅采用您需要从中获取其 url_map 的蓝图名称:

    def log_blueprint_urls(app: Flask, bp_name: str):
    
        log = create_logger(app)
    
        with app.app_context():
            """
            Maps every single endpoint for an specific blueprint in the main application.
            Also shows methos available for each endpoint
            """
            bps = app.blueprints
            if bp_name in bps:
                log.info(f'MAP ROUTER FOR BLUEPRINT "{bp_name}"')
    
                for ep in app.url_map.iter_rules():
                    bp_name = ep.endpoint.split('.')[0]
                    if bp_name == bp_name:
                        log.debug(f'Endpoint: {ep} methods={ep.methods}')
            else:
                log.critical(
                    f'BLUEPRINT "{bp_name}" has not registered in main application')
    

    【讨论】:

      猜你喜欢
      • 2016-01-21
      • 1970-01-01
      • 1970-01-01
      • 2019-12-11
      • 2016-01-14
      • 2018-05-22
      • 2010-11-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多