实验6、Flask API使用示例和拓展
实验介绍
1. 实验内容
Flask 提供了多种API拓展,本节我们主要学习基于RESTful的Flask应用程序设计
2. 实验要点
- 学习和掌握多种RESTful的设计模式
3.实验环境
- Centos 7.9
4. 工作目录
本实验的工作目录为: /experiment
Flask RESTful
我们的Flask RESTful示例应用程序是一种尊重REST体系结构约束的应用程序。但是,它不像协议,开发人员在遵循REST约束的同时实现功能时也很灵活。
现代的Web应用程序允许客户端以无状态的方式在易于阅读且稳定的端点上请求资源。
让我们也在Flask RESTful示例应用程序中以RESTful方式实现一些功能。
我们有一种存储和提供与专辑和歌曲相关的数据的方法。让我们使用Flask RESTful扩展实现API。
启动MongoDB服务
mongod --dbpath /var/lib/mongodb --logpath /var/log/mongodb/mongod.log --fork
首先,使用以下命令安装Flask RESTful。(安装过程已完成,无需再次操作)
pip install flask_restful
为了便于维护和理解,让我们在app目录中创建一个名为api.py的文件,并在其中提及以下代码行。现在,考虑类似于Flask Views的API。
我们将实现与HTTP动词(get, post, delete)相对应的功能,以在客户端向应用程序的服务器端点发送请求时做出响应。
在app/__init__.py下添加
from flask import request
from flask_restful import Resource, reqparse, abort, Api
api = Api(app, prefix="/myapi/v1")
def abort_if_song_doesnt_exist(song_name):
if song_name not in SONGS:
abort(404, message="Song {} doesn't exist".format(song_name))
parser = reqparse.RequestParser()
parser.add_argument('title')
parser.add_argument('singer')
SONGS = {
'Song1': {
'title': 'Past Life',
'singer': 'Selena Gomez'
}
}
class Songs(Resource):
def get(self):
return {'songs': SONGS}
def post(self):
args = parser.parse_args(strict=True)
song_name = int(max(SONGS.keys()).lstrip('Song')) + 1
song_name = 'Song%d' % song_name
SONGS[song_name] = {'title': args['title'], 'singer': args['singer']}
return {
song_name: SONGS[song_name]
}, 201
api.add_resource(Songs, '/songs')
class Song(Resource):
def get(self, song_name):
abort_if_song_doesnt_exist(song_name)
return {
song_name: SONGS[song_name]
}
def delete(self, song_name):
abort_if_song_doesnt_exist(song_name)
del SONGS[song_name]
return '', 204
def put(self, song_name):
args = parser.parse_args(strict=True)
abort_if_song_doesnt_exist(song_name)
SONGS[song_name] = {'title': args['title'], 'singer': args['singer']}
return {
song_name: SONGS[song_name]
}, 201
api.add_resource(Song, '/songs/<string:song_name>')
通过将Flask-RESTful的Resource抽象类作为子类,我们创建了两个资源,即Songs和Song。名为Songs的类有两个与两个HTTP动词相对应的get和post方法。分别为GET和POST。
当客户请求时,“Song”资源将所有歌曲提供给已注册的端点,并在将数据发布到同一端点时将歌曲添加到现有歌曲列表中。
同样,对于Song类,使用get,delete和put方法实现HTTP GET,DELETE和PUT。方法get发送请求的歌曲作为JSON的响应,方法delete从SONGS中删除歌曲,而put方法更新SONGS中的现有歌曲。
现在,启动服务器。
安装并使用curl测试功能
yum install curl
获取songs
curl -k http://localhost:8080/myapi/v1/songs

现在使用下面的命令增添歌曲
curl -k -d "title=Summer Days&singer=Martin Garrix" http://localhost:8080/myapi/v1/songs

如果我们像在上一个命令中一样查询歌曲列表,我们将在响应中得到两首歌曲。
curl -k http://localhost:8080/myapi/v1/songs

需要注意的重要一点是,我们添加的歌曲在运行开发服务器的单个过程中是持久存在的。这意味着该进程关闭后,所有新数据都将丢失。
此外,创建API v1版本的任务似乎是多余的,并且与我们借助表单和视图将数据保存在应用程序中的方式不同。
通常,RESTful API的实现需要从客户端获取数据,在客户端和服务器端之间进行封送处理以及在我们创建的数据库模型的帮助下实现持久性。
此外,可以保护端点以防止意外的输入。
因此,我们建议上述示例仅用于学习使用HTTP方法的REST体系结构的概念和约束。请记住,这只是创建Web服务的多种方式中的一种。此外,有许多方法可以实现REST体系结构。
我们鼓励读者进一步探索REST如何使用其他协议(不仅是JSON和HTTP)具有不同的文件格式和自定义方法。为了让您大致了解一种生产用途,我们提供以下示例。
我们使用Flask-Appbuilder BaseApi在不同的端点下实现类似的功能。打开__init__.py文件,并使用以下代码进行更新。
from flask import request
from flask_restful import Resource, reqparse, abort
from flask_appbuilder.api import BaseApi, expose
def abort_if_song_doesnt_exist(song_name):
if song_name not in SONGS:
abort(404, message="Song {} doesn't exist".format(song_name))
parser = reqparse.RequestParser()
parser.add_argument('title')
parser.add_argument('singer')
SONGS = {
'Song1': {
'title': 'Past Life',
'singer': 'Selena Gomez'
}
}
class SongsApi(BaseApi):
resource_name = 'songs'
@expose("/", methods=['POST', 'GET'])
def songs(self):
if request.method == 'GET':
return self.response(200, songs=SONGS)
else:
args = parser.parse_args(strict=True)
song_name = int(max(SONGS.keys()).lstrip('Song')) + 1
song_name = 'Song%d' % song_name
SONGS[song_name] = {'title': args['title'], 'singer': args['singer']}
return self.response(201, song=SONGS[song_name])
appbuilder.add_api(SongsApi)
class SongApi(BaseApi):
resource_name = 'songs'
@expose("/<string:song_name>", methods=['GET', 'DELETE', 'PUT'])
def song(self, song_name):
if request.method == 'GET':
abort_if_song_doesnt_exist(song_name)
return self.response(200, song_name=SONGS[song_name])
elif request.method == 'DELETE':
abort_if_song_doesnt_exist(song_name)
del SONGS[song_name]
return self.response(204, message="OK")
elif request.method == 'PUT':
args = parser.parse_args(strict=True)
abort_if_song_doesnt_exist(song_name)
SONGS[song_name] = {'title': args['title'], 'singer': args['singer']}
return self.response(201, song_name=SONGS[song_name])
else:
self.response_404()
appbuilder.add_api(SongApi)
现在我们为其添加测试函数test_api.py
def test_v1_songs(client):
resp = client.get("/api/v1/songs/")
assert 200 == resp.status_code
def test_v1_add_song(client):
data = {
"title": "Summer Days",
"singer": "Martin Garrix"
}
resp = client.post("/api/v1/songs/", data=data)
assert 201 == resp.status_code
输入pytest test_api.py得到如下结果

Flask-Appbuilder还有助于提供Swagger UI来列出并尝试已发布的API。打开config.py并使用以下所示的配置对其进行更新。
FAB_API_SWAGGER_UI=True
现在启动服务器并访问到https://localhost:8080/swagge/v1,您将能够看到Swagger视图,如下所示。

现在,让我们为现有的数据库模型创建API。我们需要使用Flask-Appbuilder的ModelApi。
在__init__.py内添加为
from flask_appbuilder.api import ModelRestApi
from .models import Song as SongModel
from flask_appbuilder.models.sqla.interface import SQLAInterface
class MySongModelApi(ModelRestApi):
resource_name="newsongs"
datamodel = SQLAInterface(SongModel)
appbuilder.add_api(MySongModelApi)
现在启动服务器并访问到https://localhost:8080/swagge/v1,您将能够看到Swagger视图,如下所示。

您可以从Swagger视图中尝试使用API,也可以通过将curl发送到端口来进行尝试。
Flask API
Flask API是一个与Django REST框架非常相似的框架。您可以在此处访问Flask API文档。它是Flask框架的直接替代品。
我们可以选择任何上述示例,以在应用程序中实现Flask REST API驱动的功能。
Flask RestPlus
Flask RestPlus
Flask RestPlus是Flask的又一个扩展,可帮助使用Flask创建REST API。该项目已分叉到另一个名为Flask-RESTX的扩展中,并且不再维护。
该项目有大量的装饰器来描述API,并使用Swagger公开其文档。您可以在此处查看该项目的详细信息。
pip install flask_restplus
实验总结
总结
我们借助两个扩展(Flask API和Flask-RESTful)扩展了Flask扩展的概念。
通常,我们都遵循REST体系结构原理和约束来实现RESTful Web服务的规则
在我们的下一个教程中,我们将介绍Django和Flask框架之间的比较,以帮助我们的读者了解这两个框架的优缺点。它还将有助于根据特定项目要求选择一个框架与另一个框架。
常见问题
Q:如何使用Flask创建REST API?
A:我们可以将Flask框架与其他Flask扩展一起使用,例如Flask-RESTful,Flask API,Flask RESTX,Connexion等,以创建基于REST API的Web应用程序。大多数扩展都可以与Flask框架的其他内置功能以及任何其他现有的ORM/Libraries一起使用。
Q:什么是REST API示例?
A:本教程中提供了一个实现RESTFul API的示例应用程序。Flask-RESTful已用于创建示例应用程序。阅读本教程中有关Flask RESTful示例的部分。
Q:RESTful API的用途是什么?
A:一个通常使用HTTP请求并具有HTTP谓词(例如GET,POST,PUT等)的相应后端方法的应用程序编程接口被称为RESTful API。这样的应用程序遵循REST架构原理和约束来实现其功能。
实验6、Flask API使用示例和拓展的更多相关文章
- ASP.NET Web API 开篇示例介绍
ASP.NET Web API 开篇示例介绍 ASP.NET Web API 对于我这个初学者来说ASP.NET Web API这个框架很陌生又熟悉着. 陌生的是ASP.NET Web API是一个全 ...
- 老李推荐:第3章3节《MonkeyRunner源码剖析》脚本编写示例: MonkeyImage API使用示例 1
老李推荐:第3章3节<MonkeyRunner源码剖析>脚本编写示例: MonkeyImage API使用示例 在上一节的第一个“增加日记”的示例中,我们并没有看到日记是否真的增加成功 ...
- 老李推荐: 第3章1节《MonkeyRunner源码剖析》脚本编写示例: MonkeyRunner API使用示例
老李推荐: 第3章1节<MonkeyRunner源码剖析>脚本编写示例: MonkeyRunner API使用示例 MonkeyRunner这个类可以说是编写monkeyrunner脚 ...
- HTML 百度地图API调用示例源码
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- Jedis API 详细示例
Jedis API 详细示例 https://www.jianshu.com/p/125357ee7651
- Java8新特性时间日期库DateTime API及示例
Java8新特性的功能已经更新了不少篇幅了,今天重点讲解时间日期库中DateTime相关处理.同样的,如果你现在依旧在项目中使用传统Date.Calendar和SimpleDateFormat等API ...
- Python Flask API实现方法-测试开发【提测平台】阶段小结(一)
微信搜索[大奇测试开],关注这个坚持分享测试开发干货的家伙. 本篇主要是对之前几次分享的阶阶段的总结,温故而知新,况且虽然看起来是一个小模块简单的增删改查操作,但其实涉及的内容点是非常的密集的,是非常 ...
- SharePoint 2013 Search REST API 使用示例
前言:在SharePoint2013中,提供Search REST service搜索服务,你可以在自己的客户端搜索方法或者移动应用程序中使用,该服务支持REST web request.你可以使用K ...
- ASP.NET Web API 入门示例详解
REST服务已经成为最新的服务端开发趋势,ASP.NET Web API即为.NET平台的一种轻量级REST架构. ASP.NET Web API直接借鉴了ASP.NET MVC的设计,两者具有非常类 ...
随机推荐
- 【vue-06】webpack npm
什么是Webpack Webpack是一款模块加载器兼打包工具,他能把各种资源,比如js,css,less转化成一个静态文件,减少页面的请求,提高效率. 安装Webpack 在安装webpack之前, ...
- 【vue-05】vue-cli
Vue-router官网 安装 vue-router是一个插件包,所以我们还是需要用npm 来进行安装.打开命令行工具,进入你的项目目录,输入下面命令. npm install vue-router ...
- @shiro.hasPermission 使用
在页面上加上@shiro.hasPermission 如下用.ftl为例子: 当加上shiro标签后,会与后台代码结合使用: 需要继承AuthorizingRealm 下的 protected Au ...
- 【Azure Developer】使用Microsoft Graph API 批量创建用户,先后遇见的三个错误及解决办法
问题描述 在先前的一篇博文中,介绍了如何使用Microsoft Graph API来创建Azure AD用户(博文参考:[Azure Developer]使用Microsoft Graph API 如 ...
- BUAA-OO-第四单元总结——终章
面向对象第四单元博客总结--终章 第四单元作业设计 第13次作业设计 类和对应方法属性设计 类设计如下图所示 本次作业主要涉及六个类,其中包括主类 Main ,通用Map类 UmlElementIdM ...
- mysql枚举和集合
create table consumer( id int, name char(16), sex enum('male','female','other'), level enum('vip1',' ...
- MD5加密以及登录获取设置token
MD5简介 MD5是不可逆的加密算法,基本上是不可破解的,网上有些破解网站,其实是利用了穷举法,因为MD5生成的串是一样的,他们会将常规的密码生成MD5加密串,保存,然后破解的时候去穷举比对.(应对之 ...
- [Linux] Linux C编程一站式学习 Part.2
C语言本质 计算机中数的表示 浮点数:符号位+指数部分(2的多少次方)+尾数部分(小数点后的数字) 用偏移的指数(Biased Exponent)表示负指数 正规化(Normalize):尾数部分最高 ...
- 所有的 Unix Like 系统都会内建 vi 文书编辑器。vim 是vi的升级版本,它不仅兼容vi的所有指令 ,而且还有一些新的特性在里面。
所有的 Unix Like 系统都会内建 vi 文书编辑器.vim 是vi的升级版本,它不仅兼容vi的所有指令 ,而且还有一些新的特性在里面. https://blog.csdn.net/carolz ...
- dmidecode -t1 | egrep "Manufacturer|Product Name"
# dmidecode -t1 | egrep "Manufacturer|Product Name" Manufacturer: Loongson Product Name: L ...