资讯专栏INFORMATION COLUMN

自动为Flask写的API生成帮助文档

pakolagij / 2186人阅读

摘要:如果能自动生成一个帮助页面那就好了。自动化帮助文档假设我们的都是以的形式书写的,那么最好把的完整列表就放在根目录下面,比如这样方法的实现主要依靠来获取中所有的模板的实现接下来我们来文档化每个具体的方法,最终的展示结果会是这样的。

Flask是Python一个非常轻量的库,可以让你毫不费力地写一个简单的网站。如果你需要写一些后台API或者准备自动化测试数据时,Flask是一个非常不错的选择。

一个API例子

举个例子,我们可以这样写几个API,具体实现暂时略过:

# views/api.py

api = Blueprint("api", __name__)

@api.route("/get_todo", methods=["GET"])
def get_todo():
    """Get all todo tasks."""
    pass


@api.route("/add_todo", methods=["POST"])
def add_todo():
    """
    Add a todo task,  please post data in json format, e.g.

    data = {
              "name":"the title",
              "task":"the detail"
            }
    """
    pass


@api.route("/delete_todo", methods=["GET", "POST"])
def delete_todo():
    """Delete a todo task."""
    pass

一旦你的API完成,你可能需要和调用方沟通调用的细节,最好给一些例子。明明你已经在代码里给所有方法都写了注释,难道还要再把这些注释拿出来重新组织排版一下?

我猜你和我一样,听过这么一句话。

read the fucking manual!

可是谁会去翻代码去看你的注释呢,何况你的代码他们还不一定能看到。如果能自动生成一个帮助页面那就好了。

自动化API帮助文档

假设我们的API都是以 http://127.0.0.1/api/* 的形式书写的,那么最好把API的完整列表就放在根目录下面,比如这样:

view 方法的实现主要依靠 app.url_map 来获取Flask中所有的API:

# views/api.py

def get_api_map():
    """Search API from rules, if match the pattern then we said it is API."""
    for rule in get_app().url_map.iter_rules():
        if re.search(r"/api/.+", str(rule)):
            yield str(rule), rule.endpoint


@api.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("main.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)

模板的实现:

# templates/api_index.html

{% extends "./layout.html" %}

{% block title %}API Root{% endblock %}

{% block breadcrumb_nav %}
    
  • Api Root
  • {% endblock %} {% block page_header %}

    Api Root

    {% endblock %} {% block content_area %}
    {
    {% for i in api_map %}    "{{ i[0] }}"{{ ",
    " if not loop.last }}{% endfor %}
    }
    {% endblock %}

    接下来我们来文档化每个具体的API方法,最终的展示结果会是这样的。

    view 方法的实现思路其实也很明确,我们可以通过 app.view_functions 这个字典找到每个API 的endpoint所绑定的方法,然后访问方法的名字和文档即可。

    # views/main.py
    
    main = Blueprint("main", __name__)
    
    
    @main.route("/", methods=["GET"])
    def index():
        """Redirect home page to docs page."""
        return redirect(url_for("api.index"))
    
    
    @main.route("/docs/", methods=["GET"])
    def docs(endpoint):
        """Document page for an endpoint."""
        api = {
            "endpoint": endpoint,
            "methods": [],
            "doc": "",
            "url": "",
            "name": ""
        }
    
        try:
            func = get_app().view_functions[endpoint]
    
            api["name"] = _get_api_name(func)
            api["doc"] = _get_api_doc(func)
    
            for rule in get_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)
    
    
    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!"

    模板的实现:

    {% extends "./layout.html" %}
    
    {% block title %}API - {{ api["name"] }}{% endblock %}
    
    {% block breadcrumb_nav %}
        
  • Api Root
  • {{ api["name"] }}
  • {% endblock %} {% block page_header %}

    {{ api["name"] | upper }}

    {% endblock %} {% block content_area %}
    Target:{{ api["url"] }}
    Allow : {{ api["methods"] }}
    Usage : {{ api["doc"] }}
    
    {% endblock %}
    GitHub项目地址

    如果你想看完整的例子,可以到我的GitHub去拉一份代码。

    https://github.com/tobyqin/fl...

    只需要三步就可以在你的机器上运行Demo:

    cd /path/to/flask_api/doc
    pip install -r requirements.txt
    python main.py

    如果你觉得Demo不错,欢迎给个Star。有建议或者想法也可以拿来讨论。

    关于作者:

    Toby Qin, Python 技术爱好者,目前从事测试开发相关工作,转载请注明原文出处。

    欢迎关注我的博客 https://betacat.online,你可以到我的公众号中去当吃瓜群众。

    文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

    转载请注明本文地址:https://www.ucloud.cn/yun/44541.html

    相关文章

    • Python使用pywebview开发设计桌面应用的全流程

        当运用桌面应用程序时,有没有有一瞬间,想学习下桌面应用程序开发设计?接下来本文关键为大家介绍了有关Python使用pywebview开发设计桌面应用的资料,必须的小伙伴可以借鉴一下  序言  平时用过Eel做出来的桌面应用感觉就已经够屌了,不过因为Eel是启用Chrome,常常出现一些小毛病,例如窗口大小设定后有的时候不起作用,右键新建菜单没法禁止使用(一眼就能看出来是一个web).并且试了用...

      89542767 评论0 收藏0
    • 使用 Flask-Docs 自动生成 Api 文档

      摘要:影响我写文档的原因可能是代码和文档分离,有时候写完代码会忘记补文档,而且不能及时查看,使用可以解决我的问题,这个插件可以根据代码注释生成文档页面,代码注释改动文档可以及时更新,而且支持离线文档下载。 影响我写文档的原因可能是代码和文档分离,有时候写完代码会忘记补文档,而且不能及时查看,使用 Flask-Docs 可以解决我的问题,这个插件可以根据代码注释生成文档页面,代码注释改动文档可...

      邹强 评论0 收藏0
    • Flask Api 文档管理与 Swagger 上手

      摘要:众数周知,文档的编写和整理工作将花费巨大精力甚至不亚于代码的编写,因此在时间紧任务重的情况下,文档是首先被忽略的工作。是一款非常流行的文档管理交互工具,适用于在团队中的管理,以及服务组件对接。而我们目前需要的是获取文档或文件。 本文最先发布在博客:https://blog.ihypo.net/152551... Flask 是一个以自由度高、灵活性强著称的 Python Web 框架...

      Scholer 评论0 收藏0
    • flask 源码解析:简介

      摘要:简介官网上对它的定位是一个微开发框架。另外一个必须理解的概念是,简单来说就是一套和框架应用之间的协议。功能比较丰富,支持解析自动防止攻击继承变量过滤器流程逻辑支持代码逻辑集成等等。那么,从下一篇文章,我们就正式开始源码之旅了 文章属于作者原创,原文发布在个人博客。 flask 简介 Flask 官网上对它的定位是一个微 python web 开发框架。 Flask is a micro...

      megatron 评论0 收藏0
    • 使用swagger 生成 Flask RESTful API

      摘要:指定筛选条件选择合适的状态码应答中,需要带一个很重要的字段。返回结果针对不同操作,服务器向用户返回的结果应该符合以下规范。如果状态码是,就应该向用户返回出错信息。 什么是 RESTful 什么是REST REST(英文:Representational State Transfer,又称具象状态传输)是Roy Thomas Fielding博士于2000年在他的博士论文 中提出来的一种...

      printempw 评论0 收藏0

    发表评论

    0条评论

    pakolagij

    |高级讲师

    TA的文章

    阅读更多
    最新活动
    阅读需要支付1元查看
    <