Flask-RESTful

news/2025/2/5 21:02:36/文章来源:https://www.cnblogs.com/yarightok/p/18093901

 

Flask-RESTful起步

Flask-RESTful是用于快速构建REST API的Flask扩展。

1 安装

pip install flask-restful

2 Hello World

from flask import Flask
from flask_restful import Resource, Apiapp = Flask(__name__)
api = Api(app)class HelloWorldResource(Resource):def get(self):return {'hello': 'world'}def post(self):return {'msg': 'post hello world'}api.add_resource(HelloWorldResource, '/')# 此处启动对于1.0之后的Flask可有可无
if __name__ == '__main__':app.run(debug=True)

 

关于视图

1 为路由起名

通过endpoint参数为路由起名

api.add_resource(HelloWorldResource, '/', endpoint='HelloWorld')

2 蓝图中使用

from flask import Flask, Blueprint
from flask_restful import Api, Resourceapp = Flask(__name__)user_bp = Blueprint('user', __name__)user_api = Api(user_bp)class UserProfileResource(Resource):def get(self):return {'msg': 'get user profile'}user_api.add_resource(UserProfileResource, '/users/profile')app.register_blueprint(user_bp)

3 装饰器

使用method_decorators添加装饰器

  • 为类视图中的所有方法添加装饰器
  def decorator1(func):def wrapper(*args, **kwargs):print('decorator1')return func(*args, **kwargs)return wrapperdef decorator2(func):def wrapper(*args, **kwargs):print('decorator2')return func(*args, **kwargs)return wrapperclass DemoResource(Resource):method_decorators = [decorator1, decorator2]def get(self):return {'msg': 'get view'}def post(self):return {'msg': 'post view'}
  • 为类视图中不同的方法添加不同的装饰器
  class DemoResource(Resource):method_decorators = {'get': [decorator1, decorator2],'post': [decorator1]}# 使用了decorator1 decorator2两个装饰器def get(self):return {'msg': 'get view'}# 使用了decorator1 装饰器def post(self):return {'msg': 'post view'}# 未使用装饰器def put(self):return {'msg': 'put view'}

 

关于请求处理

Flask-RESTful 提供了RequestParser类,用来帮助我们检验和转换请求数据。

from flask_restful import reqparseparser = reqparse.RequestParser()
parser.add_argument('rate', type=int, help='Rate cannot be converted', location='args')
parser.add_argument('name')
args = parser.parse_args()

使用步骤:

  1. 创建RequestParser对象

  2. RequestParser对象中添加需要检验或转换的参数声明

  3. 使用parse_args()方法启动检验处理

  4. 检验之后从检验结果中获取参数时可按照字典操作或对象属性操作

    args.rate
    或
    args['rate']

参数说明

1 required

描述请求是否一定要携带对应参数,默认值为False

  • True 强制要求携带

    若未携带,则校验失败,向客户端返回错误信息,状态码400

  • False 不强制要求携带

    若不强制携带,在客户端请求未携带参数时,取出值为None

class DemoResource(Resource):def get(self):rp = RequestParser()rp.add_argument('a', required=False)args = rp.parse_args()return {'msg': 'data={}'.format(args.a)}

2 help

参数检验错误时返回的错误描述信息

rp.add_argument('a', required=True, help='missing a param')

3 action

描述对于请求参数中出现多个同名参数时的处理方式

  • action='store' 保留出现的第一个, 默认
  • action='append' 以列表追加保存所有同名参数的值
rp.add_argument('a', required=True, help='missing a param', action='append')

4 type

描述参数应该匹配的类型,可以使用python的标准数据类型string、int,也可使用Flask-RESTful提供的检验方法,还可以自己定义

  • 标准类型

    rp.add_argument('a', type=int, required=True, help='missing a param', action='append')
  • Flask-RESTful提供

    检验类型方法在flask_restful.inputs模块中

    • url

    • regex(指定正则表达式)

      from flask_restful import inputs
      rp.add_argument('a', type=inputs.regex(r'^\d{2}&'))
    • natural 自然数0、1、2、3...

    • positive 正整数 1、2、3...

    • int_range(low ,high) 整数范围

      rp.add_argument('a', type=inputs.int_range(1, 10))
    • boolean

  • 自定义

    def mobile(mobile_str):"""检验手机号格式:param mobile_str: str 被检验字符串:return: mobile_str"""if re.match(r'^1[3-9]\d{9}$', mobile_str):return mobile_strelse:raise ValueError('{} is not a valid mobile'.format(mobile_str))rp.add_argument('a', type=mobile)

5 location

描述参数应该在请求数据中出现的位置

# Look only in the POST body
parser.add_argument('name', type=int, location='form')# Look only in the querystring
parser.add_argument('PageSize', type=int, location='args')# From the request headers
parser.add_argument('User-Agent', location='headers')# From http cookies
parser.add_argument('session_id', location='cookies')# From json
parser.add_argument('user_id', location='json')# From file uploads
parser.add_argument('picture', location='files')

也可指明多个位置

parser.add_argument('text', location=['headers', 'json'])

 

关于响应处理

1 序列化数据

Flask-RESTful 提供了marshal工具,用来帮助我们将数据序列化为特定格式的字典数据,以便作为视图的返回值。

from flask_restful import Resource, fields, marshal_withresource_fields = {'name': fields.String,'address': fields.String,'user_id': fields.Integer
}class Todo(Resource):@marshal_with(resource_fields, envelope='resource')def get(self, **kwargs):return db_get_todo()

也可以不使用装饰器的方式

class Todo(Resource):def get(self, **kwargs):data = db_get_todo()return marshal(data, resource_fields)

示例

# 用来模拟要返回的数据对象的类
class User(object):def __init__(self, user_id, name, age):self.user_id = user_idself.name = nameself.age = ageresoure_fields = {'user_id': fields.Integer,'name': fields.String}class Demo1Resource(Resource):@marshal_with(resoure_fields, envelope='data1')def get(self):user = User(1, 'itcast', 12)return userclass Demo2Resource(Resource):def get(self):user = User(1, 'itcast', 12)return marshal(user, resoure_fields, envelope='data2')

2 定制返回的JSON格式

需求

想要接口返回的JSON数据具有如下统一的格式

{"message": "描述信息", "data": {要返回的具体数据}}

在接口处理正常的情况下, message返回ok即可,但是若想每个接口正确返回时省略message字段

class DemoResource(Resource):def get(self):return {'user_id':1, 'name': 'itcast'}

对于诸如此类的接口,能否在某处统一格式化成上述需求格式?

{"message": "OK", "data": {'user_id':1, 'name': 'itcast'}}

解决

Flask-RESTful的Api对象提供了一个representation的装饰器,允许定制返回数据的呈现格式

api = Api(app)@api.representation('application/json')
def handle_json(data, code, headers):# TODO 此处添加自定义处理return resp

Flask-RESTful原始对于json的格式处理方式如下:

代码出处:flask_restful.representations.json

from flask import make_response, current_app
from flask_restful.utils import PY3
from json import dumpsdef output_json(data, code, headers=None):"""Makes a Flask response with a JSON encoded body"""settings = current_app.config.get('RESTFUL_JSON', {})# If we're in debug mode, and the indent is not set, we set it to a# reasonable value here.  Note that this won't override any existing value# that was set.  We also set the "sort_keys" value.if current_app.debug:settings.setdefault('indent', 4)settings.setdefault('sort_keys', not PY3)# always end the json dumps with a new line# see https://github.com/mitsuhiko/flask/pull/1262dumped = dumps(data, **settings) + "\n"resp = make_response(dumped, code)resp.headers.extend(headers or {})return resp

为满足需求,做如下改动即可

@api.representation('application/json')
def output_json(data, code, headers=None):"""Makes a Flask response with a JSON encoded body"""# 此处为自己添加***************if 'message' not in data:data = {'message': 'OK','data': data}# **************************settings = current_app.config.get('RESTFUL_JSON', {})# If we're in debug mode, and the indent is not set, we set it to a# reasonable value here.  Note that this won't override any existing value# that was set.  We also set the "sort_keys" value.if current_app.debug:settings.setdefault('indent', 4)settings.setdefault('sort_keys', not PY3)# always end the json dumps with a new line# see https://github.com/mitsuhiko/flask/pull/1262dumped = dumps(data, **settings) + "\n"resp = make_response(dumped, code)resp.headers.extend(headers or {})return resp

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/879260.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

口胡赛 2025.2.5

T1 首先不要 \(p\) 这个肯定是不能枚举 \(p\) 再直白处理的,因为最快的 Floyd 都要 \(O(n^3)\) 这样。 那么不要 \(p\) 的信息是合并得来的,但是直接合并复杂度也不够,考虑使用经典分治,先加入 \([l,mid]\) 然后递归 \((mid,r]\),撤销 \([l,mid]\),加入 \((mid,r]\),在递…

linux系统语言修改

查看当前系统语言查看已有的语言包修改linux系统语言 指令: gvim /etc/locale.conf 将“ ”的内容替换即可:

基于ESP32的桌面小屏幕实战[7]:第一个工程Hello world!以及打印日志

摘要 本文构建下载了示例工程hello world,并在其中调用esp_log.h中的日志函数打印日志。 1. 创建工程 打开esp目录,把hello world文件夹复制到当前文件夹,并打开hello world文件夹。 cd ~/esp cp -r esp-idf/examples/get-started/hello_world . cd ~/esp/hello_world使用命…

基于Python的Selenium详细教程

本文使用环境:windows11、Python 3.10.5、PyCharm 2022.1.3、Selenium 4.3.0 需要你懂的技术:Python、HTML、CSS、JavaScript一、PyCharm安装配置Selenium本文使用环境:windows11、Python 3.10.5、PyCharm 2022.1.3、Selenium 4.3.0需要你懂的技术:Python、HTML、CSS、Java…

作业01

public class HomeWork01 {public static void main(String[] args) {int n1 = 13;int n2 = 17;int n3 = n1+n2;System.out.println("n3 = "+ n3);//30int n4 = 38;int n5 = n4-n3;System.out.println("n5 ="+n5);//8}}

CROS错误,xhr类型

解决方案:向Web.config里添加此项设置即可

2025省选模拟9

不知道啥2025省选模拟9 网络流专场是吧😅 Delov 的 npy 们 原题链接 一眼网络流,然后不会了。 发现正常顺着限制做做不了,考虑将限制转化一下,以 L 操作为例。 在 \(a_i\) 左侧的点中不超过 \(b_i\) 个,等价于从左往右数第 \(b_i+1\) 个点在 \(a_i\) 右侧。 但还是不好做…

海外社交媒体运营卡成狗?云手机一键“救场”

海外社交媒体运营卡成狗?云手机一键“救场” 在海外社交媒体运营中,运营人员往往会遇到各种挑战,导致运营效率低下,甚至感觉“卡成狗”。而云手机作为一种流行的成熟普及技术工具,可以为海外社交媒体运营带来一定的帮助,实现一键“救场”。以下是对云手机在海外社交媒体运…

MyBatis resultmap结果映射

创建数据库和实体类 首先创建数据库student和teacher,并且每个学生对应一个老师,一个老师可以对应多个学生,数据库如下图: 创建实体类Student1 package com.loubin.pojo;2 3 public class Student {4 private int id;5 private String name;6 7 Teacher teach…

Linguistics-English-Textbooks: 上海外教社: 高校英语专业系列教材(修订版)

新世纪高校英语专业系列教材(修订版) https://we.sflep.com/books/newcenturymajor1.aspx教材特色 配套资源 特点 秉以新《国标》指导下的英语专业课程改革为导向精心架构,体系完备。 凝聚海内外英语专业教育界专家学者智慧,教材编写高屋建瓴、深入 浅出. 兼顾语言基本技能…

OCRmyPDF: 让图片 PDF 可复制、搜索的神器

翻开十年前的工作报告,面对泛黄的纸质合同,整理成摞的文献资料 - 这些场景总离不开扫描仪,将纸张材料转成 PDF 扫描件电子版。 但生成的 PDF 文件像一张张定格照片,既不能复制文字,也无法搜索关键词。 图片 今天推荐的开源项目:OCRmyPDF 专治各种"哑巴PDF"。它…