赞
踩
今天想记录一下最近项目上一直在用的Python框架——FastAPI。
个人认为,FastAPI是我目前接触到的Python最好用的WEB框架,没有之一。
之前也使用过像Django、Flask等框架,但是Django就用起来太重了,各种功能都糅杂在一起;Flask 框架虽说简单,但又只是单线程需要自己改造才支持多并发。
FastAPI貌似结合弥补了Flask 框架的缺陷,如果你想要快速搭建一个WEB服务,用FastAPI准没错。
OK,开始今天的笔记。
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”。
@app.get("/info")
def handle_info(name, age):
return f"Hello World, {name}, {age}"
这种方式必须接受name和age参数,如果缺少参数则会看到以下错误:
适用于GET请求且参数固定的情况,并且可以省去自己验证必要参数的步骤。
正常传递后则不会发生错误:
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
需要注意的是这里需要将使用async
和await
关键字,然后强转为 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
访问。
※ fastapi已经做了循环挂载,所以static下的子文件夹也会被一起挂载成静态资源。
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)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。