前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >为Flask RestAPI集成Swagger UI

为Flask RestAPI集成Swagger UI

作者头像
happy123.me
发布2019-12-30 17:54:33
1.9K0
发布2019-12-30 17:54:33
举报
文章被收录于专栏:乐享123乐享123乐享123

花了半天时间,给chainhorn集成了Swagger;

虽然这种事情已经做过好几遍了,但是不读文档还是没辙;我把这种半吊子形容为“我认识人民币,但是画不出来…T_T”

还是老老实实流水账记一下吧:

依赖组件

restplus能让人很方便的通过几个decorator就可以集成很漂亮的restapi,它提供了api命名空间、Request和Response解析以及Swagger UI的集成

另外,flask-restplus的文档和例子写的非常简洁清晰,赞一个。

用来集成验证机制,支持基本的密码验证、Token验证;短小精悍,够用了

起步

引用官网的例子:

构建api对象

1 2 3 4 5 6 7 8 9 10 11 12

from flask import Flask from flask_restplus import Api, Resource, fields from werkzeug.contrib.fixers import ProxyFix app = Flask(__name__) app.wsgi_app = ProxyFix(app.wsgi_app) api = Api(app, version='1.0', title='Chainhorn API', description='A simple ChainHorn API', ) ns = api.namespace('node', description='node operations')

最重要的是构建了api对象,这样就可以为后面的资源增加url路由、参数解析同能;

下面紧跟着构建了一个nsnamespace对象,作用是为不同的资源,不同的url分组,这样最后反映到界面上好看一点;

修饰

1 2 3 4 5 6 7

@ns.route('') class NodeGetInfo(Resource): @ns_node.doc('get node info') def get(self): '''get node info''' info = spv.getinfo() return {'nodeinfo': info}, 200

最简单的,用@ns.route(''),就定义了根url, 然后后面的套路都是相似的,为资源实现get方法,就直接响应 http Get请求了;

Request参数处理

如果直接在url后面跟参数,那么很方便的用 ns.param定义一下即可: 下面这个函数就直接接受一个 /broadcast/tx12345 这样的tx12345作为参数tx

1 2 3 4 5 6 7 8

@ns.route('/broadcast/<string:tx>') class WalletBroadcastTx(Resource): @ns.doc('broadcast raw tx') @ns.param('tx', 'The transaction hash identifier') def post(self, tx): '''broadcast raw tx''' sendrawtransaction(spv, tx) return {'broadcast': 'ok'}, 200

如果要放在FormData里面,可以用ns.expect来限制;它可以接受一个对象传入;比如上面的例子,要把tx字段放到POST请求的Form Data中,要这样做:

1 2 3 4 5 6 7 8 9

TxModel = {'tx': fields.String(required=True, description='The hex tx')} @ns.route('/broadcast') class WalletBroadcastTx(Resource): @ns.doc('broadcast raw tx') @ns.expect(TxModel, 200) def post(self, tx): '''broadcast raw tx''' sendrawtransaction(spv, api.payload['tx']) return {'broadcast': 'ok'}, 200

Response参数处理

同样的,如果需要返回一个对象,在界面上出现这个对象的详细描述信息,可以用marshal_withmarshal_list_with来修饰;

具体请参考:

https://flask-restplus.readthedocs.io/en/stable/parsing.html

用户验证

例如,为API加上HTTP Token Auth,要用到HTTPTokenAuth对象;

首先我们先定义验证规则:

1 2 3 4 5 6 7 8 9 10 11 12 13

auth = HTTPTokenAuth() tokens = { 'APIKEY':'hello', "APPID": "chainhorn" } @auth.verify_token def verify_token(token): if request.headers.get('APIKEY', '').strip()==tokens['APIKEY'] and \ request.headers.get('APPID', '').strip() == tokens['APPID']: return True else: return False

然后在每个url 请求处理函数前面加上修饰符auth_login_required;比如我们最开始的例子:

1 2 3 4 5 6 7 8 9

@ns.route('') class NodeGetInfo(Resource): @ns.doc('get node info') @auth.login_required def get(self): '''get node info''' info = spv.getinfo() return {'nodeinfo': info}, 200

这样后台验证就有了;那么前台输入呢?

这个例子里面,我们需要前台输入的时候在HTTP Header里面传入两个Key: APIKEY和APPKEY;直接用用Swagger UI自带的组件实现就可以了,把api对象构造为:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

AUTHORIZATIONS = { 'apikey': { 'type': 'apiKey', 'in': 'header', 'name': 'APIKEY' }, 'appid': { 'type': 'apiKey', 'in': 'header', 'name': 'APPID' } } api = Api(app, version='v1', authorizations=AUTHORIZATIONS, security=list(AUTHORIZATIONS.keys()), title='Chainhorn API', description='Chainhorn API', )

这样默认所有的API访问都需要 在HTTP Header中传入两个Key: APIKEY和APPKEY,如果值不对的话就会访问失败;

此时前台的界面是这样的:

Auth1
Auth1

可以点击右上角的Authorize一次性设置所有API的访问密钥;

Auth2
Auth2

也可以在每个API的右上角设置访问密钥;

当然,我们目前的密钥是后台写死的,你可以引入一个三方库为每个用户生成不同的密钥存到数据库里面,然后每次验证~~~

综合例子

最后,在github上面有个集大成的例子,值得推荐

https://github.com/frol/flask-restplus-server-example

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 依赖组件
  • 起步
    • 构建api对象
      • 修饰
        • Request参数处理
          • Response参数处理
            • 用户验证
            • 综合例子
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档