当前位置:网站首页>Flask搭建api服务-生成API文档
Flask搭建api服务-生成API文档
2022-07-07 15:33:00 【python与大数据分析】
前面讲到了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>{
{% for i in api_map %} "<a href="/docs/{{ i[1] }}">{{ i[0] }}</a>"{{ ",\n" if not loop.last }}{% endfor %}
}</pre>
{% endblock %}api_docs.html
{% extends "./layout.html" %}
{% block title %}API - {{ api['name'] }}{% endblock %}
{% block breadcrumb_nav %}
<li><a href="{{ url_for('index') }}">Api Root</a></li>
<li><a href="{{ api['url'] }}">{{ api['name'] }}</a></li>
{% endblock %}
{% block page_header %}
<h1>{{ api['name'] | upper }}</h1>
{% endblock %}
{% block content_area %}
<pre>
<b>Target:</b><span><a href="{{ api['url'] }}">{{ api['url'] }}</a></span>
<b>Allow :</b> <span>{{ api['methods'] }}</span>
<b>Usage :</b> <span>{{ api['doc'] }}</span>
</pre>
{% endblock %}api首页的页面如下:
具体api的像个文档
最后,谢谢关注,谢谢支持!
边栏推荐
猜你喜欢

Opencv personal notes

应用在温度检测仪中的温度传感芯片

二叉搜索树(特性篇)

Personal notes of graphics (2)

整理几个重要的Android知识,高级Android开发面试题

最新Android面试合集,android视频提取音频

Process from creation to encapsulation of custom controls in QT to toolbar (I): creation of custom controls

skimage学习(1)

使用JSON.stringify()去实现深拷贝,要小心哦,可能有巨坑

A tour of gRPC:03 - proto序列化/反序列化
随机推荐
skimage学习(2)——RGB转灰度、RGB 转 HSV、直方图匹配
QML初学
【Seaborn】组合图表:FacetGrid、JointGrid、PairGrid
C语言进阶——函数指针
Personal notes of graphics (1)
LeetCode 213. Home raiding II daily question
Lie cow count (spring daily question 53)
Deep listening array deep listening watch
Interface oriented programming
Test case management tool recommendation
作为Android开发程序员,android高级面试
Temperature sensor chip used in temperature detector
【Seaborn】组合图表、多子图的实现
LeetCode 1043. Separate the array to get the maximum and daily questions
Shallow understanding Net core routing
Sort out several important Android knowledge and advanced Android development interview questions
Seaborn数据可视化
编程模式-表驱动编程
time标准库
ORACLE进阶(六)ORACLE expdp/impdp详解