Flask應(yīng)用示例7 - 羅列所有API

1. 概述

本文介紹如何查詢flask服務(wù)所有的api。
通過(guò)swagger的方式,會(huì)自動(dòng)生成接口文檔,描述更詳細(xì),功能更強(qiáng)大。但是,對(duì)代碼的侵入性太強(qiáng)。
所以,通過(guò)flask原生的工具,挺好。

2. 獲取Api列表的幾種方式

2.1. flask routes

進(jìn)入到flask應(yīng)用root目錄,執(zhí)行flask routes

$ flask routes
Endpoint                                Methods  Rule
--------------------------------------  -------  ------------------------------
geoip_service.get_ip_location           GET      /api/v1/geoips
login_log_service.query_logs            GET      /api/v1/logs/
ping                                    GET      /ping
sentry                                  GET      /sentry
static                                  GET      /<path:filename>
subuser_service.account_login           POST     /api/v1/subusers/login/account
subuser_service.create_a_sub_user       POST     /api/v1/subusers/
subuser_service.delete_a_sub_user       DELETE   /api/v1/subusers/<int:id>
subuser_service.modify_a_sub_user       PUT      /api/v1/subusers/<int:id>
subuser_service.query_sub_users         GET      /api/v1/subusers/
user_service.account_login              POST     /api/v1/users/login/account
user_service.create_a_enterprise_user   POST     /api/v1/users/enterprise
user_service.create_a_individual_user   POST     /api/v1/users/individual
user_service.create_a_individual_user   POST     /api/v1/users/
user_service.delete_a_user              DELETE   /api/v1/users/<int:id>
user_service.email_login                POST     /api/v1/users/login/email
user_service.mobile_login               POST     /api/v1/users/login/mobile
user_service.modify_a_user              PUT      /api/v1/users/<int:id>
user_service.query_default_permissions  GET      /api/v1/users/permissions
user_service.query_users                GET      /api/v1/users/
user_service.verify_email               POST     /api/v1/users/verify/email
user_service.verify_mobile              POST     /api/v1/users/verify/mobile

2.2. flask shell

$ flask shell
Python 3.6.9 (default, Jan 26 2021, 15:33:00) 
[GCC 8.4.0] on linux
App: passport.app [dev]
Instance: /home/shuzhang/code/passport/instance
>>> app.url_map
Map([<Rule '/api/v1/subusers/login/account' (POST, OPTIONS) -> subuser_service.account_login>,
 <Rule '/api/v1/users/verify/mobile' (POST, OPTIONS) -> user_service.verify_mobile>,
 <Rule '/api/v1/users/verify/email' (POST, OPTIONS) -> user_service.verify_email>,
 <Rule '/api/v1/users/login/account' (POST, OPTIONS) -> user_service.account_login>,
 <Rule '/api/v1/users/login/mobile' (POST, OPTIONS) -> user_service.mobile_login>,
 <Rule '/api/v1/users/login/email' (POST, OPTIONS) -> user_service.email_login>,
 <Rule '/api/v1/users/permissions' (GET, HEAD, OPTIONS) -> user_service.query_default_permissions>,
 <Rule '/api/v1/users/individual' (POST, OPTIONS) -> user_service.create_a_individual_user>,
 <Rule '/api/v1/users/enterprise' (POST, OPTIONS) -> user_service.create_a_enterprise_user>,
 <Rule '/api/v1/subusers/' (POST, OPTIONS) -> subuser_service.create_a_sub_user>,
 <Rule '/api/v1/subusers/' (GET, HEAD, OPTIONS) -> subuser_service.query_sub_users>,
 <Rule '/api/v1/geoips' (GET, HEAD, OPTIONS) -> geoip_service.get_ip_location>,
 <Rule '/api/v1/users/' (POST, OPTIONS) -> user_service.create_a_individual_user>,
 <Rule '/api/v1/users/' (GET, HEAD, OPTIONS) -> user_service.query_users>,
 <Rule '/api/v1/logs/' (GET, HEAD, OPTIONS) -> login_log_service.query_logs>,
 <Rule '/sentry' (GET, HEAD, OPTIONS) -> sentry>,
 <Rule '/ping' (GET, HEAD, OPTIONS) -> ping>,
 <Rule '/api/v1/subusers/<id>' (OPTIONS, DELETE) -> subuser_service.delete_a_sub_user>,
 <Rule '/api/v1/subusers/<id>' (PUT, OPTIONS) -> subuser_service.modify_a_sub_user>,
 <Rule '/api/v1/users/<id>' (OPTIONS, DELETE) -> user_service.delete_a_user>,
 <Rule '/api/v1/users/<id>' (PUT, OPTIONS) -> user_service.modify_a_user>,
 <Rule '/<filename>' (GET, HEAD, OPTIONS) -> static>])

2.3. manager command

  • 代碼
@manager.command
def list_routes():
    import urllib
    from passport.app import create_app
    app = create_app()

    output = []
    for rule in app.url_map.iter_rules():
        methods = ','.join(rule.methods)
        line = urllib.parse.unquote("{:50s} {:20s} {}".format(rule.endpoint, methods, rule))
        output.append(line)

    for line in sorted(output):
        print(line)
  • 控制臺(tái)執(zhí)行命令
$ python manage.py test list_routes
geoip_service.get_ip_location                      HEAD,OPTIONS,GET     /api/v1/geoips
login_log_service.query_logs                       HEAD,OPTIONS,GET     /api/v1/logs/
ping                                               HEAD,OPTIONS,GET     /ping
sentry                                             HEAD,OPTIONS,GET     /sentry
static                                             HEAD,OPTIONS,GET     /<path:filename>
subuser_service.account_login                      POST,OPTIONS         /api/v1/subusers/login/account
subuser_service.create_a_sub_user                  POST,OPTIONS         /api/v1/subusers/
subuser_service.delete_a_sub_user                  OPTIONS,DELETE       /api/v1/subusers/<int:id>
subuser_service.modify_a_sub_user                  PUT,OPTIONS          /api/v1/subusers/<int:id>
subuser_service.query_sub_users                    HEAD,OPTIONS,GET     /api/v1/subusers/
user_service.account_login                         POST,OPTIONS         /api/v1/users/login/account
user_service.create_a_enterprise_user              POST,OPTIONS         /api/v1/users/enterprise
user_service.create_a_individual_user              POST,OPTIONS         /api/v1/users/
user_service.create_a_individual_user              POST,OPTIONS         /api/v1/users/individual
user_service.delete_a_user                         OPTIONS,DELETE       /api/v1/users/<int:id>
user_service.email_login                           POST,OPTIONS         /api/v1/users/login/email
user_service.mobile_login                          POST,OPTIONS         /api/v1/users/login/mobile
user_service.modify_a_user                         PUT,OPTIONS          /api/v1/users/<int:id>
user_service.query_default_permissions             HEAD,OPTIONS,GET     /api/v1/users/permissions
user_service.query_users                           HEAD,OPTIONS,GET     /api/v1/users/
user_service.verify_email                          POST,OPTIONS         /api/v1/users/verify/email
user_service.verify_mobile                         POST,OPTIONS         /api/v1/users/verify/mobile

2.4. flask api

  • 代碼
all_links_template = '''
<table border="1">
    <tr>
        <th>Endpoint</th>
        <th>Methods</th>
        <th>Url</th>
    </tr>
    {% for endpoint, methods, url in links %}
    <tr>
        <td>{{endpoint}}</td>
        <td>{{methods}}</td>
        <td>{{url}}</td>
    </tr>
    {% endfor %}
</table>
'''

@app.route("/all-links")
def all_links():
    from flask import render_template_string
    links = []
    for rule in app.url_map.iter_rules():
        methods = ','.join(rule.methods)
        links.append((rule.endpoint, methods, rule))
    return render_template_string(all_links_template, links=links)
  • 瀏覽器結(jié)果


    API列表

3. 總結(jié)

按照上述方法,可以獲取到api列表,幫忙我們更好地實(shí)現(xiàn)團(tuán)隊(duì)內(nèi)分享和溝通。
提一些優(yōu)化,如果可以看到api request和response就更好了。

  • 可以在endpoint增加gitlab的連接,這樣直接看源碼
  • 也可以在endpoint函數(shù)增加一些注釋或參數(shù),添加到#2.4的表格,比如接口描述、接口request參數(shù)等
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容