Python WEB框架之FastAPI

news2024/11/24 15:18:30

Python WEB框架之FastAPI

今天想记录一下最近项目上一直在用的Python框架——FastAPI。

个人认为,FastAPI是我目前接触到的Python最好用的WEB框架,没有之一。

之前也使用过像Django、Flask等框架,但是Django就用起来太重了,各种功能都糅杂在一起;Flask 框架虽说简单,但又只是单线程需要自己改造才支持多并发。

FastAPI貌似结合弥补了Flask 框架的缺陷,如果你想要快速搭建一个WEB服务,用FastAPI准没错。

OK,开始今天的笔记。

一、安装FastAPI

pip install fastapi uvicorn python-multipart

二、示例代码

from fastapi import FastAPI
import uvicorn

app = FastAPI()


@app.get("/")
def index():
    return "Hello World"


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

运行起来之后,您应该会看到下面的画面:
在这里插入图片描述
浏览器访问你的ip地址加端口号,应该就能看到“Hello World”。
在这里插入图片描述

三、接受请求参数

1、直接通过参数名接受,参数名即传参的名称。
@app.get("/info")
def handle_info(name, age):
    return f"Hello World, {name}, {age}"

这种方式必须接受name和age参数,如果缺少参数则会看到以下错误:
在这里插入图片描述
适用于GET请求且参数固定的情况,并且可以省去自己验证必要参数的步骤。
正常传递后则不会发生错误:
在这里插入图片描述

2、使用Request对象传参

1)GET请求

from fastapi import FastAPI, Request

@app.get("/request")
def handle_info(params: Request):
    return params.query_params

从fastapi库导入Request对象,使用Request对象作为接受参数,Request对象会把所有的参数都收集到query_params属性当中。
在这里插入图片描述
2)POST请求

@app.post("/request")
async def handle_info(params: Request):
    form = dict(await params.form())
    return form

需要注意的是这里需要将使用asyncawait关键字,然后强转为 dict类型,就可以愉快的使用啦。
在这里插入图片描述
3)文件上传

# 图片批量上传
@app.post('/upload')
async def upload_file(params: Request, files: List[UploadFile] = File(...)):
    form = dict(await params.form())
    save_files = []
    for file in files:
        temp_arr = file.filename.split(".")
        suffix = temp_arr[len(temp_arr) - 1]
        file_name = f"img_{datetime.now().strftime('%Y%m%d%H%M%S%f')}.{suffix}"
        with open(file_name, "wb") as f:
            content = await file.read()  # 读取上传文件的内容
            f.write(content)  # 将内容写入文件
            save_files.append(file_name)
    return {
        "code": 200,
        "data": {
            "params": form,
            "save_files": save_files
        }
    }

实例为图片批量上传示例,使用Request对象进行接收,同时上传的文件也会被映射到files参数中。
可通过file.read() 读取文件内容,file.filename可拿到上传的文件名。
单文件上传,个人觉得可以沿用。

前端上传文件示例代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <input type="file" name="" id="file" multiple onchange="upload()">
    <div id="output"></div>
</body>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script type="text/javascript">
    let upload = () => {
        let el_file = document.querySelector("#file")
        let output = document.querySelector("#output")
        const form = new FormData();
        for (let i = 0; i < el_file.files.length; i++) {
            form.append('files', el_file.files[i]);
        }
        form.append("name", "zhangsan");
        form.append("age", 20);
        this.uploadStage = true;
        axios.post('http://127.0.0.1:8000/upload', form, {
            headers: { 'Content-Type': 'multipart/form-data' }
        }).then(res => {
            output.innerHTML = JSON.stringify(res.data)
        }).catch(err => {
            output.innerHTML = JSON.stringify(err)
        });
    }
</script>
</html>

示例结果:
在这里插入图片描述

四、跨域设定

from starlette.middleware.cors import CORSMiddleware
# 添加CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

*号部分可自由配置。

五、指定静态资源目录

from fastapi.staticfiles import StaticFiles
app.mount("/static", StaticFiles(directory="static"), name="static_resources")

static目录挂载为静态目录,当访问 /static时直接返回该文件内容。
把上述文件上传的示例文件index.html放到static文件夹下,则可直接通过 /static/index.html 访问。
在这里插入图片描述

六、返回文件

from starlette.responses import FileResponse

@app.get("/index")
def home():
    return FileResponse("static/index.html")

可通过FileResponse类返回指定文件的内容。用于做图片的预览、文件下载等功能。
现在也可以通过 /index 访问到 static/index.html 文件了。
在这里插入图片描述
以上,就是本次用到的fastapi 框架的相关内容。
相信以上知识已经足够解决日常的开发问题,希望看到的小伙伴不迷路。
欢迎大家留言探讨。

最后,奉上完整示例代码:

from datetime import datetime
from typing import List

from fastapi import FastAPI, Request, UploadFile, File
import uvicorn
from starlette.middleware.cors import CORSMiddleware
from starlette.responses import FileResponse
from starlette.staticfiles import StaticFiles

app = FastAPI()
# 添加CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

app.mount("/static", StaticFiles(directory="static"), name="static_resources")


@app.get("/")
def index():
    return "Hello World"


@app.get("/index")
def home():
    return FileResponse("static/index.html")


@app.get("/info")
def handle_info(name, age):
    return f"Hello World, {name}, {age}"


@app.post("/request")
def handle_info(params: Request):
    return params.query_params


@app.post("/request")
async def handle_info1(params: Request):
    form = dict(await params.form())
    return form


# 图片批量上传
@app.post('/upload')
async def upload_file(params: Request, files: List[UploadFile] = File(...)):
    form = dict(await params.form())
    save_files = []
    for file in files:
        temp_arr = file.filename.split(".")
        suffix = temp_arr[len(temp_arr) - 1]
        file_name = f"img_{datetime.now().strftime('%Y%m%d%H%M%S%f')}.{suffix}"
        with open(file_name, "wb") as f:
            content = await file.read()  # 读取上传文件的内容
            f.write(content)  # 将内容写入文件
            save_files.append(file_name)
    return {
        "code": 200,
        "data": {
            "params": form,
            "save_files": save_files
        }
    }


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

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

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

相关文章

remove elements in c++

https://www.youtube.com/watch?vq5OfB6ZXT6E&listPL5jc9xFGsL8E_BJAbOw_DH6nWDxKtzBPA&index4

AUTOSAR规范与ECU软件开发(实践篇)6.7 服务软件组件与应用层软件组件端口连接

在生成了BSW模块的代码后, 切换到ISOLAR-A系统级设计界面,会发现产生一些基础软件模块的服务软件组件: BswM、 ComM、 Det和EcuM等, 如图6.60所示。 图6.60 生成了BSW后的服务软件组件 此时, 如果涉及服务软件组件与应用层软件组件的交互, 就需要为应用层软件组…

PowerDesigner学习笔记

备注&#xff1a;文章主要对概念数据模型进行深入分析 1.对各种模型图初步认识 1.1.概念数据模型 (CDM) (Conceptual Data Model) 对数据和信息进行建模&#xff0c;利用实体-关系图&#xff08;E-R图&#xff09;的形式组织数据&#xff0c;检验数据设计的有效性和合理性。 …

【leetcode 力扣刷题】字符串翻转合集(全部反转///部分反转)

字符串翻转合集 344. 反转字符串541. 反转字符串Ⅱ151. 反转字符串中的单词剑指 Offer 58 - II. 左旋转字符串反转单词思路循环挪动子串和子串的拼接 344. 反转字符串 题目链接&#xff1a;344. 反转字符串 题目内容&#xff1a; 题目中重点强调了必须原地修改输入数组&#…

Java --- 异常处理

目录 一、什么是异常 二、异常抛出机制 三、如何对待异常 四、 Java异常体系 4.1、Throwable 4.2、Error 4.2、Exception 4.2.1、编译时异常 4.2.2、运行时期异常 五、异常处理 5.1、捕获异常&#xff08;try-catch&#xff09; 5.1.2、catch中异常处理方式 …

顺序表链表OJ题(1)——【LeetCode】

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; 前言&#xff1a; 今天我们来回顾一下顺序表与链表&#xff0c;针对这一块我们也有许多OJ题目供大家参考。当我们学习完顺序表链表后避免不了一些习题的练习&#xff0c;这样才能巩固我们学习的内容。 话不多说&#xf…

C++:常成员变量、常成员函数、常对象

常成员变量: 1.用const修饰&#xff0c;可位于类型前后&#xff0c;若是成员变量类型为指针则只可位于类型后。 即&#xff1a;int *const p&#xff1b; 2.只能通过构造函数的初始化表对常成员变量进行初始化。 3.常成员所在类中的所有构造函数都必须对常成员变量初始化…

06.sqlite3学习——DQL(数据查询)(全)

目录 SQLite——DQL&#xff08;数据查询&#xff09; 数据集 select语句 条件查询 比较 确定范围 确定集合 like 查询记录 查询不重复的记录 排序和限制 排序 限制 聚合 聚合函数 语法 SQLite Group By详解 语法 实例 SQLite Having 子句 语法 实例 多…

浪潮云海护航省联社金融上云,“一云多芯”赋能数字农业

农村金融是现代金融体系的重要组成部分&#xff0c;是农业农村发展的重要支撑力量&#xff0c;而统管全省农商行及农信社的省级农村信用社联合社&#xff08;以下简称&#xff1a;省联社&#xff09;在我国金融系统中占据着举足轻重的地位。省联社通常采用“大平台小法人”的发…

Leetcode 2651.计算列车到站时间

给你一个正整数 arrivalTime 表示列车正点到站的时间&#xff08;单位&#xff1a;小时&#xff09;&#xff0c;另给你一个正整数 delayedTime 表示列车延误的小时数。 返回列车实际到站的时间。 注意&#xff0c;该问题中的时间采用 24 小时制。 示例 1&#xff1a; 输入&…

计算机系统真题

计算机系统真题 考点计算机系统存储体系磁盘调度算法 考点 计算机系统 PC找到指令&#xff0c;存储到IR中 根据ID分析指令的操作&#xff0c;并执行指令,AR访问操作数 A pc存指令的地址 内存按照字节编址&#xff1a; 在统一单位&#xff0c;转换一下&#xff1a; 3x2的平方 …

飞腾E2000 UEFI使用设备树方式启动linux系统

以往我们使用uboot引导系统启动,是采用uboot引导设备树+内核+文件系统的方式。 那么使用UEFI如何通过设备树+内核+文件系统的方式进行引导呢?这篇文章主要就介绍了这种操作方法。 一、使用Buildroot交叉编译生成E2000 Linux系统 详细请参考嵌入式软件部提供的 E2000 Linux…

服务器部署前后端项目-SQL Father为例

hello~大家好哇&#xff0c;好久没更新博客了。现在来更新一波hhh 现在更新一下部署上的一些东西&#xff0c;因为其实有很多小伙伴跟我之前一样&#xff0c;很多时候只是开发了&#xff0c;本地前后端都能调通&#xff0c;也能用&#xff0c;但是没有部署到服务器试过&#x…

【FPGA零基础学习之旅#11】数码管动态扫描

&#x1f389;欢迎来到FPGA专栏~数码管动态扫描 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;FPGA学习之旅 文章作者技术和水平有限&#xff0c;如果文中出现错误&#xff0c;希望大家能指正…

React笔记(二)JSX

一、JSX JSX是javascript XML的简写&#xff0c;实际上是javascript的扩展&#xff0c;既有javascript的语法结构&#xff0c;又有XML的结构 1、JSX的规则要求 jsx必须要有一个根节点 如果不想产生无用的根标签&#xff0c;但是还要遵守JSX的语法的要求&#xff0c;可以使用…

Angular中使用drag and drop实现文件拖拽上传,及flask后端接收

效果&#xff1a;拖拽文件到组件上面时 边框变大变红 松手后发送到服务器(或者点击蓝字手动选择文件)并且把文件名显示在框内&#xff0c;美化还没做 html <div class"drapBox"><div id"drop" (dragenter)"dragenter($event)" (dragov…

AR界安卓在中国,Rokid引爆空间计算狂潮

击关注 文丨刘雨琦 你可能很难想象&#xff0c;在一个没有显示屏也没有鼠标的空间&#xff0c;仅凭一副AR眼镜和一台口袋主机&#xff0c;就能完成一篇5000字的文章。 没错&#xff0c;8月26日&#xff0c;在2023 Rokid Jungle 新品发布会现场&#xff0c;这样的场景正在真实…

前端如何走通后端接口

0 写在前面 现在基本都是前后端分离的项目了&#xff0c;那么前端小伙伴如何获取后端小伙伴接口呢&#xff1f; 1 条件 同一WiFi下&#xff0c;让后端小伙伴分享出自己的ip地址&#xff1a; 步骤1:winr调出运行界面 步骤2&#xff1a;cmd调出命令行窗口 步骤3&#xff1a;…

6. 激活层

6.1 非线性激活 ① inplace为原地替换&#xff0c;若为True&#xff0c;则变量的值被替换。若为False&#xff0c;则会创建一个新变量&#xff0c;将函数处理后的值赋值给新变量&#xff0c;原始变量的值没有修改。 import torch from torch import nn from torch.nn import …

第一次实验:Protocol Layers

第一次实验&#xff1a;Protocol Layers 捕获跟踪*Pick a URL and fetch it with* wget *or* curl*.* 检查跟踪数据包结构协议开销复用密钥*Which Ethernet header field is the demultiplexing key that tells it the next higher layer is IP?**Which IP header field is th…