FastApi中的常见请求类型

FastApi中的常见请求类型

FastAPI

后端开发语言中,我钟情于node,高效的异步处理真是让我眼前一亮,同时,简单易懂的语法也让我非常倾心

但是但是,因为考虑要写一个深度学习算法的后端接口,所以不得不选用python作为后端进行开发,并不是我不喜欢Python,相反,Python作为我的第一语言,我同样非常喜欢,只不过我更喜欢用它来做数据分析

关于Python的后端框架,在Django和fastapi中,我最终选择了fastapi。相当长的一段时间里,我都是用Django在写后端,但是Django太臃肿了,重量级的框架很多地方难以学透,在现在前后端分离的大环境下,Django的模板语法优势也并不大

相反,fastapi只专注于后端接口开发,同时也提供了和node相似的异步处理程序。在学习fastapi过程中,记录了以下几种常见的接口请求方式:

一、主程序构建

在请求之前,先记录一下如何把后端服务跑起来

根目录下创建main.py文件,代码如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:HP
# datetime:2024/6/28 16:30

from fastapi import FastAPI
import uvicorn
from apps.app01 import app01

app = FastAPI()
app.include_router(app01)

if __name__ == '__main__':
    uvicorn.run("main:app", port=8001, reload=True)

两点需要注意:

  1. 路由分发,即app.include_router(app01),路由处理函数写在于main文件同目录下的apps文件夹下,该文件夹下面有一个app01.py的路由处理文件,里面就是各种路由的处理函数,当一个项目同时存在多个子项时,可以创建多个app.py文件,实现路由分发

  2. 服务启动命令uvicorn.run("main:app", port=8001, reload=True),很多情况下,需要在终端执行这句代码以启动服务,但这么操作非常不方便,也记不住,因此,把这行代码写在main函数中,只要运行这个程序,就可以正常启动服务了,注意,reload=True表示自动重启服务,也就是代码改了之后,服务就会自动重启

二、请求类型

请求类型大概包括路径参数、查询参数、请求体参数、form表单上传和文件上传这么几种,其中文件上传是最复杂的,我先把全部的代码放进来,然后一一解释

apps/app01.py中的代码:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:HP
# datetime:2024/6/28 16:30
from fastapi import APIRouter, Form, File, UploadFile
from pydantic import BaseModel
from datetime import date, datetime
from typing import List
import os

app01 = APIRouter()


class User(BaseModel):
    name: str = 'root'  # 默认值
    age: int
    birth: date
    friends: List[int]


# 路径参数
@app01.get('/user/{id}')
async def get_user(id: int):
    print(id)
    return {
        "user_id": id
    }


# 查询参数
@app01.get("/jobs")
async def get_jobs(kd, gj=None, xl=None):
    return {
        "kd": kd,
        "gj": gj,
        "xl": xl,
    }


# 请求体参数
@app01.post("/data")
async def get_data(data: User):
    return data


# form表单数据
@app01.post('/register')
async def register(username: str = Form(), password: str = Form()):
    print(username)
    print('----------')
    print(password)
    return {
        "username": username,
    }


# 上传单个文件
@app01.post('/upload')
async def upload(file: bytes = File()):
    # 这里的file直接就是字节流,没有其他信息
    # 将文件存储到服务器
    # 获取当前时间,精确到毫秒
    current_time = datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3]  # 去掉最后的毫秒部分的最后一位,确保文件名合法
    filename = current_time + '.jpg'
    path = os.path.join('imgs', filename)
    with open(path, 'wb') as f:
        f.write(file)

    return {
        "status": 1,
        "message": "success",
        "file": filename,
    }


# 上传多个文件
@app01.post('/uploads')
async def uploads(files: List[bytes] = File()):
    for file in files:
        print(len(file))
    return {
        "file": len(files)
    }


# 更加常用的文件上传方式,但postman中无法测试,因为数据中不支持UploadFile类型的数据
# 上传单个文件
@app01.post('/uploadFlie')
async def upload_file(file: UploadFile):
    current_time = datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3]  # 去掉最后的毫秒部分的最后一位,确保文件名合法
    filename = current_time + '.jpg'
    path = os.path.join('imgs', filename)
    with open(path, 'wb') as f:
        for line in file.file:
            f.write(line)
    return {
        "origin_name": file.filename,
        "sever_name": filename,
    }


# 上传多个文件
@app01.post('/uploadFiles')
async def upload_files(files: List[UploadFile]):
    print(files)
    return {
        "file": len(files),
    }

1、路径参数

# 路径参数
@app01.get('/user/{id}')
async def get_user(id: int):
    print(id)
    return {
        "user_id": id
    }

请求示例:

image-20240702102934385

请求参数写在路径上,通常用于处理表格中的数据,比较好理解

2、查询参数

# 查询参数
@app01.get("/jobs")
async def get_jobs(kd, gj=None, xl=None):
    return {
        "kd": kd,
        "gj": gj,
        "xl": xl,
    }

postman中的请求示例:

image-20240702103154842

这也挺简单的,以查询参数的形式传递参数,通常来说,就是路由中?后面的都是查询参数,用&分割

3、请求体参数

一般用是post请求中,把参数封装在body(请求体)中

# 请求体参数
@app01.post("/data")
async def get_data(data: User):
    return data

这里用到了pydantic中的BaseModel模型,User模型继承于BaseModel,主要得记住写法

同样看看postman中的请求示例:

image-20240702103648063

在postman中,body参数要写在raw下,这里不是表单数据,不能写在x-www-form-urlencoded中

其实也挺简单的

4、form表单参数

这里正好与第3点请求体参数比较一下

# form表单数据
@app01.post('/register')
async def register(username: str = Form(), password: str = Form()):
    print(username)
    print('----------')
    print(password)
    return {
        "username": username,
    }

fastapi中封装好了Form表单数据的数据类型,这和postman中的x-www-form-urlencoded定义的form数据是一样的

看看postman中的请求示例:

image-20240702104116745

参数位置不一样

5、文件上传

(1)上传单个文件
# 上传单个文件
@app01.post('/upload')
async def upload(file: bytes = File()):
    # 这里的file直接就是字节流,没有其他信息
    # 将文件存储到服务器
    # 获取当前时间,精确到毫秒
    current_time = datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3]  # 去掉最后的毫秒部分的最后一位,确保文件名合法
    filename = current_time + '.jpg'
    path = os.path.join('imgs', filename)
    with open(path, 'wb') as f:
        f.write(file)

    return {
        "status": 1,
        "message": "success",
        "file": filename,
    }

目标,前端上传文件,并将文件保存在服务器中与main.py同名的imgs文件夹下,文件名是当前时间(到毫秒).jpg

注意,这里的file是字节流,可以直接写到文件中,同样,也可以在postman中测试

image-20240702104508468

服务器下的imgs文件夹下多了一张图片

image-20240702104558750

(2)上传多个文件
# 上传多个文件
@app01.post('/uploads')
async def uploads(files: List[bytes] = File()):
    for file in files:
        print(len(file))
    return {
        "file": len(files)
    }

这里没再写文件存储的过程,与上传单个文件差不多,看看postman中的示例:

image-20240702104810492

(3)UploadFile上传单个文件

前面两种情况应该已经能满足大部分情况了,但是,fastapi封装了一种专用于文件上传的UploadFile类,代码如下:

# 更加常用的文件上传方式,但postman中无法测试,因为数据中不支持UploadFile类型的数据
# 上传单个文件
@app01.post('/uploadFlie')
async def upload_file(file: UploadFile):
    current_time = datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3]  # 去掉最后的毫秒部分的最后一位,确保文件名合法
    filename = current_time + '.jpg'
    path = os.path.join('imgs', filename)
    with open(path, 'wb') as f:
        for line in file.file:
            f.write(line)
    return {
        "origin_name": file.filename,
        "sever_name": filename,
    }

因为这是fastapi封装的,postman不兼容,所以postman没法测,用fastapi自带的接口测试文档看下示例:

image-20240702105207200

同样看看服务器端的imgs目录:

image-20240702105303058

可以看到,对应的地方多了一张图片

需要注意的是,这里上传的file,就并不再是纯字节流数据了,而是fastapi封装的UploadFile对象,需要知道这个对象里有哪些内容,可以查看源码,也可以借助编译器逐个去看

(4)UploadFile上传多个文件
# 上传多个文件
@app01.post('/uploadFiles')
async def upload_files(files: List[UploadFile]):
    print(files)
    return {
        "file": len(files),
    }

理解了UploadFile上传单个文件,多个文件就不难了,看看接口测试文档中的示例:

image-20240702105629868

无非是多了个添加item的选项而已

对象里有哪些内容,可以查看源码,也可以借助编译器逐个去看

好了,学习完接口的请求类型,后面应该要学习orm了。。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

容器安全:等保合规性的基石

随着云计算和微服务架构的蓬勃发展,容器技术已经成为现代IT基础设施不可或缺的一部分。在网络安全等级保护制度(等保)的框架下,容器安全的要求日益凸显,成为等保合规性的基石。本文将深入探讨容器安全在等保中的重要性…

nginx的配置文件

nginx.conf 1、全局模块 worker_processes 1; 工作进程数,设置成服务器内核数的2倍(一般不超过8个,超过8个反正会降低性能,4个 1-2个 ) 处理进程的过程必然涉及配置文件和展示页面,也就是涉及打开文件的…

让围绕数据库构建大模型应用更简单方便--DB-GPT

DB-GPT的目的是构建大模型领域的基础设施,通过开发多模型管理(SMMF)、Text2SQL效果优化、RAG框架以及优化、Multi-Agents框架协作、AWEL(智能体工作流编排)等多种技术能力,让围绕数据库构建大模型应用更简单,更方便。 1 处理流程 DB-GPT系…

问题集锦1

01.inner中使用JwtTokenUtil.getUserCode() 前端调用上传(java),上传使用加购 Overridepublic Boolean insertShoppingCart(InsertShoppingCartParamsDto dto) {// 通过userCode,itemCode和supplierCode来判断当前加购人添加到购物车的商品是…

美术馆预约小程序的设计

管理员账户功能包括:系统首页,个人中心,展品信息管理,管理员管理,用户管理,美术馆管理,基础数据管理,论坛管理 微信端账号功能包括:系统首页,美术馆&#xff…

工业路由器与家用路由器的区别

在现代网络环境中,路由器扮演着至关重要的角色。无论是在家庭网络还是在工业网络,选择合适的路由器都至关重要。本文将从多个角度,对工业路由器与家用路由器进行详细比较,帮助您更好地理解二者的区别。 1、安全性 工业路由器&…

API接口测试/Swgger-ui未授权访问

目录 API接口 接口文档 接口测试的方法 单流程 多流程 Swgger-ui未授权访问 在之间的一次面试中面试官问到了API接口测试,我回答的不好,因为自己确实不太会,后面才下去学习了,这里复习和练习一下 API接口 API(…

背景图的动效,非常的炫酷,非一般的感觉。

我们都知道在一些展示型项目中,背景图加上动效后,可以立马让整个设计档次提升了,这次带来了一批背景图的动效图,大家看一下。

震惊!张宇强化36讲1200页,暑期强化高效利用指南!

特别喜欢张宇老师的讲课风格 如果你打算跟张宇老师,那么基础——>强化——>冲刺,你应该这么买书! 张宇老师25版课程大改版,其中,36讲的变动是最大的,张宇老师25版课程把以往的强化课程前移&#xff0…

基于多视点编码光场的全景三维重建方法

欢迎关注GZH《光场视觉》 摘要:在基于光场的一系列应用中,目标的三维重建是基础且关键的任务。普通光场只能重建单一视角而无法重建全景,并且在纹理特征匮乏的区域也无法生成准确的三维信息。针对以上问题,提出一种基于多视点编码…

视频字幕提取在线工具有哪些?总结5个字幕提取工具

平时在沉浸式追剧的时候,我们常常都会被影视剧中的各种金句爆梗而逗得开怀大笑~而真正要用到时候却总是一片头脑空白。其实要记住它们最好的办法便是将其提取留档下来,每次有需要的时候打开就能一下子回顾到~ 今天就来带大家盘一盘视频字幕提取的软件好…

泰雷茲具有首个通过FIPS 140-3 三级认证的HSMs

泰雷兹LunaHsm是业界首款通过FIPS140-33级认证的解决方案,安策引进泰雷兹HSM产品可以帮助您满足您的数据安全合规性需求,阻力企业提高竞争力。 安策提供泰雷茲ThalesLunaHSMs成为首个通过FIPS140-3三级认证的硬件安全模块图 我们很高兴地宣布&#xff0c…

端口聚合基础知识

一、什么是端口聚合 端口聚合是将多个物理端口捆绑在一起,形成一个逻辑链路,以实现带宽增加、提高冗余和负载均衡的技术。端口聚合,也称为以太通道(Ethernet Channel),主要用于交换机之间的连接。在具有多…

困在流量里的“平替国货”

“不是xx买不起,而是xx更有性价比。” 现在很多年轻消费者都把这句话挂在嘴边。比如,“不是羽绒服买不起,而是军大衣更有性价比”“不是洋货买不起,而是国货更有性价比”。 你可以说他们不愿意再当冤大头,偏爱价格更…

3d模型材质吸不了什么原因?怎么解决?---模大狮模型网

3D模型无法吸取材质可能有以下原因: 文件格式不支持:某些文件格式(如STL)不支持嵌入材质信息,因此在导入此类文件后,需要手动为模型添加材质。 材质链接错误:如果模型文件中嵌入了材质信息,但是链接错误&a…

【中项第三版】系统集成项目管理工程师 | 第 2 章 信息技术发展

前言 第2章对应的内容大概率仅考察选择题,通读教程,速战速决。选择题分值预计在2-5分,属于必考的知识点。 2.1 信息技术及其发展 信息技术是在信息科学的基本原理和方法下的关于一切信息的产生、信息的传输、信息的发送、信息的接收等应用技…

Python面试宝典第4题:环形链表

题目 给你一个链表的头节点 head ,判断链表中是否有环。如果存在环 ,则返回 true 。 否则,返回 false 。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环&#xf…

《涅朵奇卡:一个女人的一生》读后感

这周的计划是看完海明威的《丧钟为谁而鸣》,但是因为下班晚,而且书的体量大,所以只看了一半。本来以为这周的阅读计划完不成了,不料昨天加完班后拿起新到的《涅朵奇卡:一个女人的一生》,不自觉就陷进去了&a…

Cocos如何跟Android通信?

点击上方亿元程序员+关注和★星标 引言 Cocos如何跟Android通信 大家好,相信小伙伴们通过阅读笔者前几期的文章**《Cocos打安卓包打不出来?看看这个》,对Cocos**如何打安卓包有了一定的了解。 但是,除了把安卓包打出来,另外还有一个重要的就是要能够调用安卓提供的Java方…

时钟切换的代码

目录 描述 输入描述: 输出描述: 参考代码 描述 题目描述: 存在两个同步的倍频时钟clk0 clk1,已知clk0是clk1的二倍频,现在要设计一个切换电路,sel选择时候进行切换,要求没有毛刺。 信号示意图&…