使用flask_restful快速构建接口

news2025/3/30 3:06:03

Flask-RESTful 是一个用于快速构建 RESTful API 的 Flask 扩展。它简化了创建、管理和文档化 REST API 的过程。利用 Flask-RESTful,你可以更容易地将你的 Flask 应用程序组织成 RESTful 原则的风格

安装包

pip install flask_restful

 快速构建接口

from flask import Flask
from flask_restful import reqparse, Resource, Api

app = Flask(__name__)
# 步骤一:创建了一个Flask应用实例

api = Api(app)
# 步骤二:创建restful的API
# 通过将Flask应用实例app传递给Api类来创建API对象。这一步是在告诉Flask-RESTful这个API将基于哪个Flask应用


class HelloWorld(Resource):
    # 定义了一个名为HelloWorld的类,它继承自Resource。在该类内部定义了一个get方法,当有HTTP GET请求到达与之关联的URL时,就会调用此方法
    def get(self):
        return {'hello': 'world'}


api.add_resource(HelloWorld, '/helloworld')
# 使用add_resource方法将HelloWorld资源类绑定到特定的URL路径/helloworld上。这意味着当用户访问http://<your-server>/helloworld时,会触发HelloWorld类中的get方法
if __name__ == '__main__':
    # 启动app
    app.run(debug=True)
"""
def run(
        self,
        host: str | None = None,
        port: int | None = None,
        debug: bool | None = None,
        load_dotenv: bool = True,
        **options: t.Any,
    ) -> None:
"""
# run函数的参数有host,port,我们就可以指定ip+端口启动flask

 这样我们就可以快速的通过flask+flask_restful构建出来一个接口,默认启动地址是http://127.0.0.1:5000 ,我们使用postman测试一下

这样我们就快速的实现了一个简单的接口

get请求传参

get请求传参可以放在url中,也可以放在请求头中,我们来查看如何进行传参

参数在url的?之前

class HelloWorld(Resource):
    def get(self, name):
        return {'hello': name}


api.add_resource(HelloWorld, '/helloworld/<string:name>')
# <string:name> 会将这个参数转为字符串,也可以是int,float等等,就可以传主键各种的

参数在url的?之后

方法一:直接从原始数据拿
class HelloWorld(Resource):
    def get(self):
        name = request.args.get('name')
        return {'hello': name}


api.add_resource(HelloWorld, '/helloworld')
from flask import Flask, request

通过导入request来到args里面去取值,这样就拿到原始的参数

方法二: 用解析器获取
class HelloWorld(Resource):
    def get(self):
        parser = reqparse.RequestParser()
        # 初始化了一个 RequestParser 实例,用于解析传入的请求
        parser.add_argument('name', type=str, required=True, help="Please enter your name", location='args')
        """
        向 RequestParser 添加了一个新的参数规则
        'name':这是你期望从请求中获取的参数名称
        type=str:指定该参数的数据类型应为字符串
        required=True:表示这个参数是必需的。如果请求中没有提供这个参数,API 会返回一个错误响应
        help="Please enter your name":当提供的参数不符合要求时(例如缺失),将返回给客户端的错误信息
        location='args':指定了查找参数的位置。这里的 'args' 表示查询参数(即 URL 中问号后的键值对)
        这个在django中的话,其实可以理解为他序列化器的反序列化字段,会对传入的参数进行校验,不同的是django需要我们将request里面的参数传到序列化器
        """
        args = parser.parse_args()
        # 调用 parse_args() 方法将会根据之前定义的规则解析请求,并返回包含所有参数的字典
        name = args['name']
        # 从字典里面拿到参数
        return {'hello': name}

post请求传参

因为是restful规范的,所以只需要我们在类中写一个post请求的函数名,用post请求访问这个函数就可以直接触发post请求了

为了简化,下面所有的post请求我都用请求体传参,虽然post请求也可以请求头,解析跟get一样的,参考get请求即可

方法一:直接从原始数据拿
class HelloWorld(Resource):
    def post(self):
        print(request.data)
        # b'{\r\n    "name":"zh"\r\n}'
        name = json.loads(request.data)['name']
        return {'message': f'Hello World!{name}'}

上面我们直接拿到post请求请求体里面的原始json数据,需要我们反序列化然后直接从字典里面去拿到请求体里面的值

方法二:用解析器获取
class HelloWorld(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('name', type=str, required=True, help="Please enter your name", location='json')
        """
        这个与get请求不同就是在location的参数,json代表从请求体里面获取
        """
        args = parser.parse_args()
        name = args['name']
        return {'message': f'Hello World!{name}'}

解析器参数

location参数

# Look only in the POST body 表单
parser.add_argument('name', type=str, location='form')

# Look only in the querystring 请求地址?后面的参数
parser.add_argument('name', type=str, location='args')

# From the request headers
parser.add_argument('name-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'])

 其他参数

default:默认值,如果这个参数没有值,那么将使用这个参数指定的值。
required:是否必须。默认为False,如果设置为True,那么这个参数就必须提交上来。
type:这个参数的数据类型,如果指定,那么将使用指定的数据类型来强制转换提交上来的值。
choices:选项。提交上来的值只有满足这个选项中的值才符合验证通过,否则验证不通过。
help:错误信息。如果验证失败后,将会使用这个参数指定的值作为错误信息。
trim:是否要去掉前后的空格

自定义返回格式

在 Flask-RESTful 中,你可以使用 fields 模块和 marshal_with 装饰器来定义和控制 API 响应的格式。这允许你指定哪些字段应该包含在输出中,以及这些字段的数据类型和格式

class HelloWorld(Resource):    
    resource_fields = {
        'name': fields.String,
        'age': fields.Integer,
        'height': fields.Float,
    }

    @marshal_with(resource_fields)
    def post(self):
        result = {'name': 'John Doe', 'age': '30', 'height': 1.75}
        return result

在上面的代码中,我们原始数据中的age是字符类型,但是我们定义的返回是整型,最终调用接口发现结果还是整型

证明在返回的过程中,marshal_with装饰器对result的内容进行了与resource_fields类型匹配与转化,如果我们把age改为String看结果

会发现直接就把成字符串返回出去了,证明确实是上面的猜想没错,这个过程可以理解django中序列化器的序列化,直接将我们查到的数据库数据按照指定类型响应出去

如果我们返回是的一个空,他还是会把这些定义好的参数返回出去,只是内容是空的

流式返回

from flask import Flask, request, Response
from flask_restful import Api, Resource, fields, marshal_with, reqparse

app = Flask(__name__)

api = Api(app)


def generate():
    """模拟一个长时间运行的任务"""
    for i in range(10):
        yield f"data chunk {i}\n"
        # 模拟延迟
        import time
        time.sleep(1)


class HelloWorld(Resource):
    def post(self):
        return Response(generate(), mimetype='text/plain')

响应就会是这样的

关于mimetype

这里 Response 对象被创建时指定了 mimetype='text/plain'。这意味着无论 generate() 生成器函数产生的数据是什么,都会被当作纯文本发送给客户端。当客户端接收到这个响应时,它将根据 text/plain MIME 类型来决定如何处理该响应内容——通常是直接显示或以文本形式处理。

其他常见的 MIME 类型

这里有一些其他常用的 MIME 类型的例子:

  • text/html: HTML 格式的文本。

  • application/json: JSON 格式的数据。

  • application/xml: XML 格式的数据。

  • image/jpeg: JPEG 格式的图片。

  • application/pdf: PDF 文档 

flask_restful+OpenAI调用千问

 调用大模型参考:如何通过OpenAI接口调用通义千问模型_大模型服务平台百炼(Model Studio)-阿里云帮助中心

配置api_key: 通义千问模型的completions接口_大模型服务平台百炼(Model Studio)-阿里云帮助中心

from flask import Flask, Response
from flask_restful import Api, Resource, fields, reqparse

app = Flask(__name__)

api = Api(app)
from openai import OpenAI

client = OpenAI(
    # 若没有配置环境变量,请用百炼API Key将下行替换为:api_key="sk-xxx",
    api_key='',
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",  # 填写DashScope SDK的base_url
)


def wq_completion(user_input):
    completions = client.completions.create(
        model="qwen2.5-coder-32b-instruct",
        prompt=user_input,
        stream=True
    )
    for completion in completions:
        yield completion.choices[0].text


class HelloWorld(Resource):
    resource_fields = {
        'name': fields.String,
        'age': fields.String,
        'height': fields.Float,
    }

    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('input', type=str, required=True, help="Please enter your input", location='json')
        args = parser.parse_args()
        input = args['input']
        return Response(wq_completion(input), mimetype='text/plain')


api.add_resource(HelloWorld, '/helloworld')
if __name__ == '__main__':
    app.run()

前面有个问号,很奇怪,应该是返回的问题,查看一下原始数据

第一句有一个?号加换号,那我们就进行处理一下 

def wq_completion(user_input):
    completions = client.completions.create(
        model="qwen2.5-coder-32b-instruct",
        prompt=user_input,
        stream=True
    )
    for completion in completions:
        text = completion.choices[0].text
        if '?' in text:
            text = text.replace('?', '').replace('?', '').strip('\n')
        if text:
            yield text

# 这个问题挺奇怪的,可能是这个模型特别的问题,这样就正常了

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

centos 7 部署FTP 服务用shell 搭建脚本,使用时稍微修改自己所需需求

#!/bin/bash # 检查是否为 root 用户 if [ "$(id -u)" ! "0" ]; then echo "此脚本需要以 root 用户身份运行。" exit 1 fi # 安装 vsftpd yum install vsftpd -y # 备份原始配置文件 cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd…

Hadoop集群搭建(hdfs、yarn)

Hadoop 是 Apache 软件基金会旗下的一个开源项目&#xff0c;是用于处理大数据的分布式系统基础架构&#xff0c;被广泛应用于大数据存储、处理和分析等场景。 一、核心组件 1、Hadoop 分布式文件系统&#xff08;HDFS&#xff09; 具有高容错性&#xff0c;能在低成本硬件上…

Keepalived 实现高可用方案

Keepalived简介 ‌Keepalived‌ 是一个基于 ‌VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;协议‌的高可用性解决方案&#xff0c;主要用于实现‌服务故障自动切换&#xff08;Failover&#xff09;和负载均衡‌。通过管理虚拟 IP&#xff08;VIP&#xf…

医学图像分割数据集肺分割数据labelme格式6299张2类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图像分辨率&#xff1a;1024x1024 图片数量(jpg文件个数)&#xff1a;6299 标注数量(json文件个数)&#xff1a;6299 标注类别数&#xff1a;2 标注类别名称:["leftl…

C语言复习笔记--函数递归

在学习了函数之后,函数递归是我们必然会接触到的课题,下面就让我们看下函数递归相关的知识. 递归是什么&#xff1f; 递归这个词看着就不那么好理解,那么什么是递归呢?递归其实是⼀种解决问题的⽅法,在C语⾔中,递归就是函数自己调用自己. 写⼀个史上最简单的C语⾔递归代码: …

husky的简介以及如果想要放飞自我的解决方案

husky 是一个 Git Hooks 管理工具&#xff0c;它的主要作用是 在 Git 提交&#xff08;commit&#xff09;、推送&#xff08;push&#xff09;等操作时执行自定义脚本&#xff0c;比如代码检查&#xff08;Lint&#xff09;、单元测试&#xff08;Test&#xff09;、格式化代码…

侯捷 C++ 课程学习笔记:现代 C++ 中的移动语义与完美转发深度解析

1. 前言&#xff1a;为什么我们需要移动语义&#xff1f; 在侯捷老师的《C11/14/17 新特性详解》课程中&#xff0c;移动语义&#xff08;Move Semantics&#xff09;被称作"C近十年来最重要的革新"。传统C中饱受诟病的深拷贝性能问题&#xff0c;在现代C中通过移动语…

23种设计模式-结构型模式-适配器

文章目录 简介场景问题解决方案建立中间转换层关键收益 总结 简介 使接口不兼容的类实现协同工作&#xff0c;通过引入中间层实现客户端接口和服务端接口的兼容。典型场景比如整合第三方类库或遗留系统时保持代码兼容。 场景 假设你正在开发一个股票监控程序。这个程序会下…

美亚科技业绩波动明显:现金流为负,四起未决诉讼涉金额1700万

《港湾商业观察》施子夫 近期&#xff0c;广东美亚旅游科技集团股份有限公司&#xff08;以下简称&#xff0c;美亚科技&#xff09;披露第二轮审核问询函的回复。从两轮问询函监管层提出的问题来看&#xff0c;有关美亚科技业绩增长的合理性、募投项目的必要性及合理性、经营…

PyTorch 深度学习实战(21):元强化学习与 MAML 算法

一、元强化学习原理 1. 元学习核心思想 元强化学习&#xff08;Meta-RL&#xff09;旨在让智能体快速适应新任务&#xff0c;其核心是通过任务分布学习共享知识。与传统强化学习的区别在于&#xff1a; 对比维度传统强化学习元强化学习目标解决单一任务快速适应任务分布中的…

23中设计模式-迭代器(Iterator)设计模式

迭代器设计模式 &#x1f6a9;什么是迭代器设计模式&#xff1f;&#x1f6a9;迭代器设计模式的特点&#x1f6a9;迭代器设计模式的结构&#x1f6a9;迭代器设计模式的优缺点&#x1f6a9;迭代器设计模式的Java实现&#x1f6a9;代码总结&#x1f6a9;总结 &#x1f6a9;什么是…

Word中公式自动标号带章节编号

&#xff08;1&#xff09;插入一行三列的表格&#xff0c;设置宽度分别为0.5&#xff0c;13.39和1.5&#xff0c;设置纵向居中&#xff0c;中间列居中对齐&#xff0c;最右侧列靠右对齐&#xff0c;设置段落如下 &#xff08;2&#xff09;插入域代码 【Word】利用域代码快速实…

【Spring AI】基于专属知识库的RAG智能问答小程序开发——功能优化:用户鉴权主体功能开发

系列文章目录 【Spring AI】基于专属知识库的RAG智能问答小程序开发——完整项目&#xff08;含完整前端后端代码&#xff09;【Spring AI】基于专属知识库的RAG智能问答小程序开发——代码逐行精讲&#xff1a;核心ChatClient对象相关构造函数【Spring AI】基于专属知识库的R…

[7-01-03].SpringBoot3集成MinIo

MinIO学习大纲 一、Spingboot整合MinIo 第1步&#xff1a;搭建SpringBoot项目&#xff1a; 第2步&#xff1a;引入minio依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi&q…

ISIS-3 LSDB链路状态数据库同步

上一章我们介绍了ISIS的邻居建立关系以及ISIS的路由器角色有哪些,在不同的网络类型当中建立邻居关系有什么不同,并且以实验案例抓包的形式给大家进一步介绍了建立的过程。 这一章我们来介绍ISIS中是如何实现链路状态数据库同步的,与OSPF的链路状态同步有什么不同,在不同网络类…

快速入手-基于Django的Form和ModelForm操作(七)

1、Form组件 2、ModelForm操作 3、给前端表单里在django里添加class相关属性值 4、前端 5、后端form 新增数据处理 6、更新数据处理

Springboot集成Debezium监听postgresql变更

1.创建springboot项目引入pom <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>io.debezium</groupI…

Ubuntu22.04搭建freeradius操作说明

Ubuntu22.04搭建freeradius操作说明 更新依赖库 sudo apt update sudo apt install build-essential sudo apt install libtalloc-dev sudo apt install libssl-dev 按照freeradius sudo apt install freeradius 修改freeradius配置 文件路径如下 /etc/freeradius/3.…

【重装系统】全流程记录,在 MacOS 的电脑上烧录 Ubuntu 启动盘

背景 Ubuntu 无法联网&#xff0c;排查下来应该是网卡驱动的问题&#xff0c;安装驱动的过程中又缺失各种包需要网络&#xff0c;陷入死循环。 全流程以及相关资料 整体流程参考&#xff1a;【史上最全】重装ubuntu20.04系统基本环境配置 烧录启动盘启动盘插入需要重装的服务…

去中心化金融

什么是去中心化金融 去中心化金融&#xff08;Decentralized Finance&#xff0c;简称 DeFi&#xff09;是一种基于区块链技术构建的金融系统&#xff0c;旨在通过去除传统金融机构&#xff08;如银行、证券公司等&#xff09;作为中介&#xff0c;提供各种金融服务。这些服务…