实验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的设计,两者具有非常类 ...
随机推荐
- <JVM上篇:内存与垃圾回收篇>04-虚拟机栈
笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...
- .Net 中两分钟集成敏感词组件
现如今大部分服务都会有用户输入,为了服务的正常运行,很多时候不得不针对输入进行敏感词的检测.替换.如果人工做这样的工作,不仅效率低,成本也高.所以,先让代码去处理输入,成为了经济方便的途径.水弟在这里 ...
- MzzTxx——团队贡献分分配方案
项目 内容 这个作业属于哪个课程 2021春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 团队贡献分分配规则制定 我在这个课程的目标是 进一步提升工程化开发能力,积累团队协作经验,熟悉全栈 ...
- CRM的未来发展前景有哪些?
随着时代的发展,近年来越来越多的国内中小企业开始采用CRM客户关系管理系统,CRM从此不再是大企业的专利,也开始让中小企业得以不断成长.国内CRM行业的发展越来越快, 它的前景是什么?今天小Z就来给大 ...
- Java·Maven的安装与配置
阅文时长 | 0.58分钟 字数统计 | 937.6字符 主要内容 | 1.引言&背景 2.Maven的下载与安装 3.Maven全局配置 4.Settings.xml文件的配置 5.远程仓库 ...
- [bug] Python AttributeError: module 'web' has no attribute 'application'
原因 文件名是web.py,与包名web冲突 解决 重命名文件,再运行
- [BD] Flume
什么是Flume 采集日志,存在HDFS上 分布式.高可用.高可靠的海量日志采集.聚合和传输系统 支持在日志系统中定制各类数据发送方,用于收集数据 支持对数据进行简单处理,写到数据接收方 组件 sou ...
- [DB] Zookeeper
介绍 相当于"数据库",类似linux.hdfs的属性文件结构 分布式协调框架,实现HA(High Availability) 分布式锁管理框架 保证数据在zookeeper集群之 ...
- [刷题] 17 Letter Combinations of a Phone Number
要求 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合 1 不对应任何字母 示例 输入:"23" 输出:["ad", "ae&q ...
- 1.4 重置root用户密码
图1-45 系统的欢迎界面 1.4 重置root用户密码 平日里让运维人员头疼的事情已经很多了,因此偶尔把Linux系统的密码忘记了并不用慌,只需简单几步就可以完成密码的重置工作.但是,如果您是第一 ...