Flask搭建api服务-生成API文档

前面讲到了Flask实现api,但api是给别人用的,就要告诉别人如何发现api,以及api的用途、名称、出参、入参,生成api文档的做法有好多种,本文选了一种最简单的方式。

核心就是通过app.view_functions 这个字典找到每个API 的endpoint所绑定的方法,然后访问方法的名字和文档即可

从路由中搜索api,在这里可以构筑规则

def get_api_map():
    """Search API from rules, if match the pattern then we said it is API."""
    for rule in app.url_map.iter_rules():
        if 'docs' not in str(rule) and 'static' not in str(rule):
            yield str(rule), rule.endpoint

建立两个路由,一个是api docs的首页,一个是各个api的规则定义

@app.route('/', methods=['GET'])
def index():
    """List all API to this page, api_map contains each api url + endpoint."""
    api_map = sorted(list(get_api_map()))
    index_url = url_for('index', _external=True)
    api_map = [(index_url + x[0][1:], x[1]) for x in api_map]
    return render_template('api_index.html', api_map=api_map)
@app.route('/docs/<endpoint>', methods=['GET'])def docs(endpoint):
    """Document page for an endpoint."""
    api = {
        'endpoint': endpoint,
        'methods': [],
        'doc': '',
        'url': '',
        'name': ''
    }

    try:
        func = app.view_functions[endpoint]

        api['name'] = _get_api_name(func)
        api['doc'] = _get_api_doc(func)

        for rule in app.url_map.iter_rules():
            if rule.endpoint == endpoint:
                api['methods'] = ','.join(rule.methods)
                api['url'] = str(rule)

    except:
        api['doc'] = 'Invalid api endpoint: "{}"!'.format(endpoint)

    return render_template('api_docs.html', api=api)

获取api的名称和api文档内容

def _get_api_name(func):
    """e.g. Convert 'do_work' to 'Do Work'"""
    words = func.__name__.split('_')
    words = [w.capitalize() for w in words]
    return ' '.join(words)


def _get_api_doc(func):
    if func.__doc__:
        return func.__doc__
    else:
        return 'No doc found for this API!'

在原有的api函数内,补充晚上像个接口定义,包括入参、出参、名称、描述等等

@app.route('/getdimdict', methods=['GET', 'POST'])
def getdimdict():
    """

接口名称:        /getdimdict 获取指标库的维度字典
    接口描述:
        获取指标库的维度字典,
    接口入参:        get方法
        参数无
    接口出参:        json格式        data = {

"code":"200",
                  “info":"处理成功"
                  "result":{
                    "typecode": "datelevel\",
                    "typename": "\u65e5\\u671f\\u5c42\\u7ea7\",
                    "dimcode": "01",
                    "dimname": "\\u5e74\"
                  }
                }
    """
    params = {}
    retinfo = {}
    errorflag = False
    retinfo['code'] = 200
    retinfo['info'] = '处理成功'
    retinfo['result'] = ''
    sqltext = config[DBSECTION]['getdimdict']
    jsonstr = getsqlresultjson(db, sqltext, params)
    retinfo['result'] = jsonstr
    response = jsonify(retinfo)
    response.status_code = 200
    return response

定义html的base页面-layout.html

{% extends "bootstrap/base.html" %}
{% block title %}Home{% endblock %}

{% block styles %}
    {{ super() }}
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
{% endblock %}


{% block content %}
    <div id="wrap">
    <!-- Begin nav bar -->
        <div class="navbar navbar-inverse navbar-fixed-top">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    <a class="navbar-brand" href=" ">API DOC DEMO</ a>
                </div>
                <div class="collapse navbar-collapse">
                    <ul class="nav navbar-nav">
                        <li class="active">< a href="/">Home</ a></li>
                    </ul>
                </div>
            </div>
        </div>
        <!-- Begin page content -->
        <div class="container">
            <ul class="breadcrumb">
                <li>< a href="/">Home</ a></li>
                {% block breadcrumb_nav %}{% endblock %}
            </ul>
            <div class="page-header">
                {% block page_header %}{% endblock %}
            </div>
        {% block content_area %}{% endblock %}
        </div>
    </div>
    <div id="footer">
        <div class="container">
            <p class="text-muted credit">Copyright  < a href="https://github.com/tobyqin/">Toby Qin</ a>
                - < a href="https://github.com/tobyqin/flask_api_doc">Source at Github</ a></p >
        </div>
    </div>
{% endblock %}
api_index.html

{% extends "./layout.html" %}
{% block title %}API Root{% endblock %}

{% block breadcrumb_nav %}
    <li>< a href="{{ url_for('index') }}">Api Root</ a></li>
{% endblock %}

{% block page_header %}
    <h1>Api Root</h1>
{% endblock %}

{% block content_area %}
<pre>{
{% fo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值