需求:上传一个图片,保存到服务器,然后返回一个URL

# main.py
#Python3.8+
import hashlib

from anyio import Path
from fastapi import FastAPI, File, HTTPException, Request
from fastapi.staticfiles import StaticFiles

BASE_DIR = Path(__file__).parent
LIMIT_SIZE = 5 * 1024 * 1024  # 5M
MEDIA_URL = "/media"
MEDIA_ROOT = BASE_DIR / "media"
UPLOAD_ROOT = MEDIA_ROOT / "uploads"

if not UPLOAD_ROOT._path.exists():
    UPLOAD_ROOT._path.mkdir(parents=True)

app = FastAPI()
app.mount("/media", StaticFiles(directory=MEDIA_ROOT.name), name="media")


def get_host(req: Request) -> str:
    return getattr(req, "headers", {}).get("host") or "http://127.0.0.1:8000"


@app.post("/put-cert")
async def put_cert(request: Request, file: bytes = File(...)) -> str:
    """单文件上传(不能大于5M)"""
    if len(file) > LIMIT_SIZE:
        raise HTTPException(status_code=400, detail="每个文件都不能大于5M")
    # 使用md5作为文件名,以免同一个文件多次写入
    filename = hashlib.md5(file).hexdigest() + ".png"
    if not await (fpath := UPLOAD_ROOT / filename).exists():
        if not await fpath.parent.exists():
            await fpath.parent.mkdir(parents=True)
        await fpath.write_bytes(file)
    host = get_host(request)
    path = fpath.relative_to(MEDIA_ROOT).as_posix()
    return host + MEDIA_URL + "/" + path

使用:

# pip install fastapi uvicorn python-multipart
uvicorn main:app

请求示例:

curl localhost:8000/put-cert -F "file=@/path/to/file"

如果上传文件的同时,还需要提交其他参数,可参考官方文档,或是我写的Demo:
https://fastapi.tiangolo.com/tutorial/request-forms-and-files/?h=form#define-file-and-form-parameters
https://www.cnblogs.com/waketzheng/p/17785769.html

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐