Restful 是 Flask 的扩展,增加了对快速构建 REST api 的支持。它是一个轻量级的概念,与您现有的 ORM/librarie 一起工作。Restful 鼓励最小化设置的最佳实践。如果你熟悉Flask,Flask-RESTful 应该很容易。

关于flask的使用,参考我的之前的博客:https://blog.csdn.net/shifengboy/article/details/114274271

flask-restful官方文档:https://flask-restful.readthedocs.io/en/lates

中文文档:http://www.pythondoc.com/Flask-RESTful/

flask-restful 安装

pip install flask-restful

flask-restful使用

简单上手

from flask import Flask
from flask_restful import Resource, Api app = Flask(__name__)
api = Api(app) class HelloWorld(Resource):
def get(self):
return {'hello': 'world'} api.add_resource(HelloWorld, '/') if __name__ == '__main__':
app.run(debug=True)

运行结果:

$ curl http://127.0.0.1:5000/
{"hello": "world"}

Resourceful 路由

Flask-RESTful 提供的主要构建块是资源。资源构建在 Flask 可插入视图之上,只需在资源上定义方法,就可以轻松访问多个 HTTP 方法。一个 todo 应用程序的基本 CRUD 资源是这样的:

from flask import Flask, request
from flask_restful import Resource, Api app = Flask(__name__)
api = Api(app) todos = {} class TodoSimple(Resource):
def get(self, todo_id):
return {todo_id: todos[todo_id]} def put(self, todo_id):
todos[todo_id] = request.form['data']
return {todo_id: todos[todo_id]} api.add_resource(TodoSimple, '/<string:todo_id>') if __name__ == '__main__':
app.run(debug=True)

运行结果:

chenshifengdeMacBook-Pro:~ chenshifeng$ curl http://localhost:5000/todo1 -d "data=Remember the milk" -X PUT
{
"todo1": "Remember the milk"
}
chenshifengdeMacBook-Pro:~ chenshifeng$ curl http://localhost:5000/todo1
{
"todo1": "Remember the milk"
}
chenshifengdeMacBook-Pro:~ chenshifeng$ curl http://localhost:5000/todo2 -d "data=Change my brakepads" -X PUT
{
"todo2": "Change my brakepads"
}
chenshifengdeMacBook-Pro:~ chenshifeng$ curl http://localhost:5000/todo2
{
"todo2": "Change my brakepads"
}
chenshifengdeMacBook-Pro:~ chenshifeng$

Restful 能够从 view 方法中理解多种返回值。类似于 Flask,你可以返回任何可迭代的并且它将被转换成一个响应,包括原始 Flask 响应对象。还支持使用多个返回值设置响应代码和响应头,如下所示:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
@author:chenshifeng
@file:flask_restful_demo.py
@time:2021/03/05
"""
from flask import Flask, request
from flask_restful import Resource, Api app = Flask(__name__)
api = Api(app) class Todo1(Resource):
def get(self):
# Default to 200 OK
return {'task': 'Hello world'} class Todo2(Resource):
def get(self):
# Set the response code to 201
return {'task': 'Hello world'}, 201 class Todo3(Resource):
def get(self):
# Set the response code to 201 and return custom headers
return {'task': 'Hello world'}, 201, {'Etag': 'some-opaque-string'} api.add_resource(Todo1,'/todo1')
api.add_resource(Todo2,'/todo2')
api.add_resource(Todo3,'/todo3') if __name__ == '__main__':
app.run(debug=True)

运行结果:

chenshifengdeMacBook-Pro:~ chenshifeng$ curl -i  http://127.0.0.1:5000/todo1
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 30
Server: Werkzeug/1.0.1 Python/3.9.2
Date: Fri, 05 Mar 2021 16:08:28 GMT {
"task": "Hello world"
}
chenshifengdeMacBook-Pro:~ chenshifeng$ curl -i http://127.0.0.1:5000/todo2
HTTP/1.0 201 CREATED
Content-Type: application/json
Content-Length: 30
Server: Werkzeug/1.0.1 Python/3.9.2
Date: Fri, 05 Mar 2021 16:08:32 GMT {
"task": "Hello world"
}
chenshifengdeMacBook-Pro:~ chenshifeng$ curl -i http://127.0.0.1:5000/todo3
HTTP/1.0 201 CREATED
Content-Type: application/json
Content-Length: 30
Etag: some-opaque-string
Server: Werkzeug/1.0.1 Python/3.9.2
Date: Fri, 05 Mar 2021 16:08:34 GMT {
"task": "Hello world"
}
chenshifengdeMacBook-Pro:~ chenshifeng$

Endpoints 端点

很多时候,在一个 API 中,你的资源会有多个 url。可以将多个 url 传递给 Api 对象上的 add _ resource ()方法。每一个都将被路由到Resource

api.add_resource(HelloWorld,
'/',
'/hello')

您还可以将路径的某些部分作为变量匹配到Resource。

api.add_resource(Todo,
'/todo/<int:todo_id>', endpoint='todo_ep')

演示代码:

from flask import Flask
from flask_restful import Resource, Api app = Flask(__name__)
api = Api(app) class HelloWorld(Resource):
def get(self):
return {'hello': 'world'} class Todo(Resource):
def get(self, todo_id):
# Default to 200 OK
return {'task': 'Hello world'} api.add_resource(HelloWorld, '/', '/hello')
api.add_resource(Todo, '/todo/<int:todo_id>', endpoint='todo_ep') if __name__ == '__main__':
app.run(debug=True)

演示结果:

chenshifengdeMacBook-Pro:~ chenshifeng$ curl  http://127.0.0.1:5000/
{
"hello": "world"
}
chenshifengdeMacBook-Pro:~ chenshifeng$ curl http://127.0.0.1:5000/hello
{
"hello": "world"
}
chenshifengdeMacBook-Pro:~ chenshifeng$ curl http://127.0.0.1:5000/todo/1
{
"task": "Hello world"
}
chenshifengdeMacBook-Pro:~ chenshifeng$ curl http://127.0.0.1:5000/todo/2
{
"task": "Hello world"
}

参数解析

虽然 Flask 可以方便地访问请求数据(即 querystring 或 POST 表单编码的数据) ,但验证表单数据仍然是一件痛苦的事情。使用类似于 argparse 的库对请求数据验证提供内置支持。

from flask import Flask
from flask_restful import reqparse, Api, Resource app = Flask(__name__)
api = Api(app) parser = reqparse.RequestParser()
parser.add_argument('rate', type=int, help='Rate to charge for this resource') class Todo(Resource):
def post(self):
args = parser.parse_args()
print(args)
# Default to 200 OK
return {'task': 'Hello world'} api.add_resource(Todo,'/todos' ) if __name__ == '__main__':
app.run(debug=True)
chenshifengdeMacBook-Pro:~ chenshifeng$ curl -d 'rate=100' http://127.0.0.1:5000/todos
{
"task": "Hello world"
}
chenshifengdeMacBook-Pro:~ chenshifeng$ curl -d 'rate=foo' http://127.0.0.1:5000/todos
{
"message": {
"rate": "Rate to charge for this resource"
}
}

与 argparse 模块不同,reqparse. RequestParser.parse _ args ()返回 Python 字典,而不是自定义数据结构。

输入模块提供了许多常用的转换函数,例如 inputs.date ()和 inputs.url ()。

使用 strict = True 调用 parse _ args 可以确保在请求包含您的解析器没有定义的参数时抛出错误。

args = parser.parse_args(strict=True)
$ curl -d 'rate2=foo' http://127.0.0.1:5000/todos
{
"message": "Unknown arguments: rate2"
}

数据格式化

默认情况下,在你的返回迭代中所有字段将会原样呈现。尽管当你刚刚处理 Python 数据结构的时候,觉得这是一个伟大的工作,但是当实际处理它们的时候,会觉得十分沮丧和枯燥。为了解决这个问题,Flask-RESTful 提供了 fields 模块和 marshal_with() 装饰器。类似 Django ORM 和 WTForm,你可以使用 fields 模块来在你的响应中格式化结构。

from flask import Flask
from flask_restful import fields, marshal_with, Resource, Api app = Flask(__name__)
api = Api(app) resource_fields = {
'task': fields.String,
'uri': fields.Url('todo')
} class TodoDao(object):
def __init__(self, todo_id, task):
self.todo_id = todo_id
self.task = task # This field will not be sent in the response
self.status = 'active' class Todo(Resource):
@marshal_with(resource_fields)
def get(self, **kwargs):
return TodoDao(todo_id='my_todo', task='Remember the milk') api.add_resource(Todo,'/todo') if __name__ == '__main__':
app.run(debug=True)

上面的例子接受一个 python 对象并准备将其序列化。marshal_with() 装饰器将会应用到由 resource_fields 描述的转换。从对象中提取的唯一字段是 task。fields.Url 域是一个特殊的域,它接受端点(endpoint)名称作为参数并且在响应中为该端点生成一个 URL。许多你需要的字段类型都已经包含在内。请参阅 fields 指南获取一个完整的列表。

$ curl  http://127.0.0.1:5000/todo
{
"task": "Remember the milk",
"uri": "/todo"
}

完整例子

from flask import Flask
from flask_restful import reqparse, abort, Api, Resource app = Flask(__name__)
api = Api(app) TODOS = {
'todo1': {'task': 'build an API'},
'todo2': {'task': '?????'},
'todo3': {'task': 'profit!'},
} def abort_if_todo_doesnt_exist(todo_id):
if todo_id not in TODOS:
abort(404, message="Todo {} doesn't exist".format(todo_id)) parser = reqparse.RequestParser()
parser.add_argument('task') # Todo
# shows a single todo item and lets you delete a todo item
class Todo(Resource):
def get(self, todo_id):
abort_if_todo_doesnt_exist(todo_id)
return TODOS[todo_id] def delete(self, todo_id):
abort_if_todo_doesnt_exist(todo_id)
del TODOS[todo_id]
return '', 204 def put(self, todo_id):
args = parser.parse_args()
task = {'task': args['task']}
TODOS[todo_id] = task
return task, 201 # TodoList
# shows a list of all todos, and lets you POST to add new tasks
class TodoList(Resource):
def get(self):
return TODOS def post(self):
args = parser.parse_args()
todo_id = int(max(TODOS.keys()).lstrip('todo')) + 1
todo_id = 'todo%i' % todo_id
TODOS[todo_id] = {'task': args['task']}
return TODOS[todo_id], 201 ##
## Actually setup the Api resource routing here
##
api.add_resource(TodoList, '/todos')
api.add_resource(Todo, '/todos/<todo_id>') if __name__ == '__main__':
app.run(debug=True)

获取列表

$ curl http://localhost:5000/todos
{
"todo1": {
"task": "build an API"
},
"todo2": {
"task": "?????"
},
"todo3": {
"task": "profit!"
}
}

获取一个单独的任务

$ curl http://localhost:5000/todos/todo3
{
"task": "profit!"
}

删除一个任务

$ curl http://localhost:5000/todos/todo2 -X DELETE -v
* Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 5000 failed: Connection refused
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5000 (#0)
> DELETE /todos/todo2 HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.64.1
> Accept: */*
>
* HTTP 1.0, assume close after body
< HTTP/1.0 204 NO CONTENT
< Content-Type: application/json
< Server: Werkzeug/1.0.1 Python/3.9.2
< Date: Sat, 06 Mar 2021 03:29:33 GMT
<
* Closing connection 0

增加一个新的任务

$ curl http://localhost:5000/todos -d "task=something new" -X POST -v
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 5000 failed: Connection refused
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5000 (#0)
> POST /todos HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Length: 18
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 18 out of 18 bytes
* HTTP 1.0, assume close after body
< HTTP/1.0 201 CREATED
< Content-Type: application/json
< Content-Length: 32
< Server: Werkzeug/1.0.1 Python/3.9.2
< Date: Sat, 06 Mar 2021 03:31:02 GMT
<
{
"task": "something new"
}
* Closing connection 0

更新一个任务

$  curl http://localhost:5000/todos/todo3 -d "task=something different" -X PUT -v
* Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 5000 failed: Connection refused
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5000 (#0)
> PUT /todos/todo3 HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Length: 24
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 24 out of 24 bytes
* HTTP 1.0, assume close after body
< HTTP/1.0 201 CREATED
< Content-Type: application/json
< Content-Length: 38
< Server: Werkzeug/1.0.1 Python/3.9.2
< Date: Sat, 06 Mar 2021 03:32:44 GMT
<
{
"task": "something different"
}
* Closing connection 0

获取最新列表

$ curl http://localhost:5000/todos
{
"todo1": {
"task": "build an API"
},
"todo3": {
"task": "something different"
},
"todo4": {
"task": "something new"
}
}

Python flask-restful框架讲解的更多相关文章

  1. python Flask restful框架

    框架地址:https://github.com/flask-restful/flask-restful 文档:http://flask-restful.readthedocs.io/en/0.3.5/ ...

  2. Python Flask Web 框架入门

    Python Flask 目录 本文主要借鉴 letiantian 的文章 http://www.letiantian.me/learn-flask/ 一.简介 二.安装 三.初始化Flask 四.获 ...

  3. 比我的脸还干的gan货——Python Flask Web 框架入门

    Flask是一个轻量级的基于Python的web框架. 本文适合有一定HTML.Python.网络基础的同学阅读. 1. 简介 这份文档中的代码使用 Python 3 运行.是的,所以读者需要自己在电 ...

  4. Python Flask Restful

    Flask  Restful 1.flask restful 在flask基础上进行一些封装,主要用于实现restful接口 2.restful的理解 1)URI(统一资源标识符):每一个URI代表一 ...

  5. python Flask web框架

    目录: --> Flask --> 配置文件 --> 配置文件解析 --> 配置文件导入 --> 路由 --> 路由参数 --> 常用路由匹配 --> ...

  6. python + flask轻量级框架

    from flask import Flask,jsonify,make_response,abort,Response,request from flask_restful import Api,R ...

  7. Python Flask 实现移动端应用接口(API)

    引言 目前,Web 应用已形成一种趋势:业务逻辑被越来越多地移到客户端,逐渐完善为一种称为富互联网应用(RIA,rich Internet application)的架构.在 RIA 中,服务器的主要 ...

  8. 用Python手把手教你搭建一个web框架-flask微框架!

    在之前的文章当中,小编已经教过大家怎么搭建一个Django框架,今天我们来探索另外的一种框架的搭建,这个框架就是web框架-flask微框架啦!首先我们带着以下的几个问题来阅读本文: 1.flask是 ...

  9. [转]python实现RESTful服务(基于flask)

    python实现RESTful服务(基于flask) 原文: https://www.jianshu.com/p/6ac1cab17929  前言 上一篇文章讲到如何用java实现RESTful服务, ...

  10. python三大web框架Django,Flask,Flask,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架

    Python几种主流框架 从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python We ...

随机推荐

  1. solidity的函数修改器(modifier)

    内容:modifier的定义.modifier对函数参数的操作.modifier执行的顺序 modifier的定义 官方文档:modifier可以改变函数的行为.可以被继承和重写. 其实modifie ...

  2. MongoDB 副本集搭建 & 副本集扩容

    副本集的搭建 创建多实例目录 [root@redis03 ~]# mkdir /server/mongodb/2801{7,8,9}/{conf,logs,pid,data} -p 编辑多实例配置文件 ...

  3. 近期做的一些DP

    UVa 1625 color length https://blog.csdn.net/Dylan_Frank/article/details/52261424 https://www.cnblogs ...

  4. ZOJ 2563 Long Dominoes(状压DP)题解

    题意:n*m的格子,用1 * 3的矩形正好填满它,矩形不能重叠,问有几种填法 思路:poj2411进阶版.我们可以知道,当连续两行的摆法确定,那么接下来的一行也确定.当第一行还有空时,这时第三行必须要 ...

  5. 末日余晖 PC 版 下载

    末日余晖 PC 版 下载 <末日余晖>(英文名:Farlight 84)一款废土题材的射击游戏 Farlight 84 Official Trailer Farlight 84 官方预告片 ...

  6. Awesome Gatsby blog websites

    Awesome Gatsby blog websites very simple very clean i18n dark mode (css var) demos https://overreact ...

  7. Vue 3 In Action

    Vue 3 In Action $ yarn add vue https://v3.vuejs.org demos refs https://v3.vuejs.org/guide/migration/ ...

  8. Flutter Hackathon 2020

    Flutter Hackathon 2020 https://flutterhackathon.com/#/ Flutter Day https://mp.weixin.qq.com/s/ux17-A ...

  9. js to svg flowchart

    js to svg flowchart flowchart https://flowchart.js.org/ https://github.com/adrai/flowchart.js https: ...

  10. Node.js & BFF & FaaS

    Node.js & BFF & FaaS server https://github.com/PacktPublishing/Node.js-Web-Development-Fourt ...