实验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的设计,两者具有非常类 ...
随机推荐
- 攻防世界Web刷题记录(新手区)
攻防世界Web刷题记录(新手区) 1.ViewSource 题如其名 Fn + F12 2.get post 3.robots robots.txt是搜索引擎中访问网站的时候要查看的第一个文件.当一个 ...
- SpringBoot学习笔记:Spring Data Jpa的使用
更多请关注公众号 Spring Data Jpa 简介 JPA JPA(Java Persistence API)意即Java持久化API,是Sun官方在JDK5.0后提出的Java持久化规范(JSR ...
- Pytorch_Part5_迭代训练
VisualPytorch beta发布了! 功能概述:通过可视化拖拽网络层方式搭建模型,可选择不同数据集.损失函数.优化器生成可运行pytorch代码 扩展功能:1. 模型搭建支持模块的嵌套:2. ...
- osg纯手工画球+贴纹理
手动计算球面顶点的坐标,纹理坐标,来画球并贴纹理 其中createSphereGeom()函数的的二个参数为18,意思是在经纬度上每10度设一个点,因为经度一共是180度,180/18=10,相当于横 ...
- 【Mysql】数据库事务,脏读、幻读、不可重复读
一.什么是数据库事务 数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位.事务由事务开始与事务结束之间 ...
- [bug]Flask:KeyError: 'A secret key is required to use CSRF.'
参考 https://blog.csdn.net/huanglianggu/article/details/81263865
- [c++] 内存与变量
内存 程序代码区用来保存指令,常量区.全局数据区.堆.栈都用来保存数据 常量区和全局数据区有时也被合称为静态数据区,意思是这段内存专门用来保存数据,在程序运行期间一直存在 函数被调用时,会将参数.局部 ...
- 在 Linux 中,最直观、最可见的部分就是 文件系统(file system)
在 Linux 中,最直观.最可见的部分就是 文件系统(file system).下面我们就来一起探讨一下关于 Linux 中国的文件系统,系统调用以及文件系统实现背后的原理和思想.这些思想中有一些来 ...
- IT菜鸟之虚拟机VMware的使用
虚拟机安装完成了,以下是虚拟机的使用. 双击快捷方式,打开vmware虚拟机. 点击创建新虚拟机,这里可以选择创建方式,可以点击典型并一路下一步创建,我们这里讲自定义创建. 这里选择兼容版本,大家可以 ...
- 013.Python的文件操作
一 文件操作 fp = open("打开的文件",mode="模式选择",encoding="编码集") open 函数 返回一个文件io对 ...