Skip to content

๐Ÿ“จ ๐Ÿ“

๐Ÿ‘† ๐Ÿ’ช ๐Ÿ”ฌ ๐Ÿ“ ๐Ÿ“‚ ๐Ÿ‘ฉโ€๐Ÿ’ป โš™๏ธ File.

Info

๐Ÿ“จ ๐Ÿ“‚ ๐Ÿ“, ๐Ÿฅ‡ โŽ python-multipart.

๐Ÿคถ โ“‚. pip install python-multipart.

๐Ÿ‘‰ โ†ฉ๏ธ ๐Ÿ“‚ ๐Ÿ“ ๐Ÿ“จ "๐Ÿ“จ ๐Ÿ’ฝ".

๐Ÿ—„ File

๐Ÿ—„ File & UploadFile โšช๏ธโžก๏ธ fastapi:

from fastapi import FastAPI, File, UploadFile

app = FastAPI()


@app.post("/files/")
async def create_file(file: bytes = File()):
    return {"file_size": len(file)}


@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
    return {"filename": file.filename}

๐Ÿ”ฌ File ๐Ÿ”ข

โœ ๐Ÿ“ ๐Ÿ”ข ๐ŸŽ ๐ŸŒŒ ๐Ÿ‘† ๐Ÿ”œ Body โš–๏ธ Form:

from fastapi import FastAPI, File, UploadFile

app = FastAPI()


@app.post("/files/")
async def create_file(file: bytes = File()):
    return {"file_size": len(file)}


@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
    return {"filename": file.filename}

Info

File ๐ŸŽ“ ๐Ÿ‘ˆ ๐Ÿ˜– ๐Ÿ”— โšช๏ธโžก๏ธ Form.

โœ‹๏ธ ๐Ÿ’ญ ๐Ÿ‘ˆ ๐Ÿ•โ” ๐Ÿ‘† ๐Ÿ—„ Query, Path, File & ๐ŸŽ โšช๏ธโžก๏ธ fastapi, ๐Ÿ‘ˆ ๐Ÿค™ ๐Ÿ”ข ๐Ÿ‘ˆ ๐Ÿ“จ ๐ŸŽ ๐ŸŽ“.

Tip

๐Ÿ“ฃ ๐Ÿ“ ๐Ÿ’ช, ๐Ÿ‘† ๐Ÿ’ช โš™๏ธ File, โ†ฉ๏ธ โช ๐Ÿ”ข ๐Ÿ”œ ๐Ÿ”ฌ ๐Ÿ”ข ๐Ÿ”ข โš–๏ธ ๐Ÿ’ช (๐ŸŽป) ๐Ÿ”ข.

๐Ÿ“ ๐Ÿ”œ ๐Ÿ“‚ "๐Ÿ“จ ๐Ÿ’ฝ".

๐Ÿšฅ ๐Ÿ‘† ๐Ÿ“ฃ ๐Ÿ†Ž ๐Ÿ‘† โžก ๐Ÿ› ๏ธ ๐Ÿ”ข ๐Ÿ”ข bytes, FastAPI ๐Ÿ”œ โœ ๐Ÿ“ ๐Ÿ‘† & ๐Ÿ‘† ๐Ÿ”œ ๐Ÿ“จ ๐ŸŽš bytes.

โœ”๏ธ ๐Ÿคฏ ๐Ÿ‘ˆ ๐Ÿ‘‰ โ›“ ๐Ÿ‘ˆ ๐ŸŽ‚ ๐ŸŽš ๐Ÿ”œ ๐Ÿช ๐Ÿ’พ. ๐Ÿ‘‰ ๐Ÿ”œ ๐Ÿ‘ท ๐Ÿ‘ ๐Ÿคช ๐Ÿ“.

โœ‹๏ธ ๐Ÿ“ค ๐Ÿ“š ๐Ÿ’ผ โ” ๐Ÿ‘† ๐Ÿ’ช ๐Ÿ’ฐ โšช๏ธโžก๏ธ โš™๏ธ UploadFile.

๐Ÿ“ ๐Ÿ”ข โฎ๏ธ UploadFile

๐Ÿ”ฌ ๐Ÿ“ ๐Ÿ”ข โฎ๏ธ ๐Ÿ†Ž UploadFile:

from fastapi import FastAPI, File, UploadFile

app = FastAPI()


@app.post("/files/")
async def create_file(file: bytes = File()):
    return {"file_size": len(file)}


@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
    return {"filename": file.filename}

โš™๏ธ UploadFile โœ”๏ธ ๐Ÿ“š ๐Ÿ“ˆ ๐Ÿคญ bytes:

  • ๐Ÿ‘† ๐Ÿšซ โœ”๏ธ โš™๏ธ File() ๐Ÿ”ข ๐Ÿ’ฒ ๐Ÿ”ข.
  • โšซ๏ธ โš™๏ธ "๐Ÿงต" ๐Ÿ“:
    • ๐Ÿ“ ๐Ÿช ๐Ÿ’พ ๐Ÿ†™ ๐Ÿ”† ๐Ÿ“ ๐Ÿ“‰, & โฎ๏ธ ๐Ÿšถโ€โ™€๏ธ ๐Ÿ‘‰ ๐Ÿ“‰ โšซ๏ธ ๐Ÿ”œ ๐Ÿช ๐Ÿ’พ.
  • ๐Ÿ‘‰ โ›“ ๐Ÿ‘ˆ โšซ๏ธ ๐Ÿ”œ ๐Ÿ‘ท ๐Ÿ‘ โญ• ๐Ÿ“ ๐Ÿ’– ๐Ÿ–ผ, ๐Ÿ“น, โญ• ๐Ÿ’ฑ, โ™’๏ธ. ๐Ÿต ๐Ÿ˜ฉ ๐ŸŒ ๐Ÿ’พ.
  • ๐Ÿ‘† ๐Ÿ’ช ๐Ÿคš ๐Ÿ—ƒ โšช๏ธโžก๏ธ ๐Ÿ“‚ ๐Ÿ“.
  • โšซ๏ธ โœ”๏ธ ๐Ÿ“-๐Ÿ’– async ๐Ÿ”ข.
  • โšซ๏ธ ๐ŸŽฆ โ˜‘ ๐Ÿ SpooledTemporaryFile ๐ŸŽš ๐Ÿ‘ˆ ๐Ÿ‘† ๐Ÿ’ช ๐Ÿšถโ€โ™€๏ธ ๐Ÿ”— ๐ŸŽ ๐Ÿ—ƒ ๐Ÿ‘ˆ โŒ› ๐Ÿ“-๐Ÿ’– ๐ŸŽš.

UploadFile

UploadFile โœ”๏ธ ๐Ÿ“„ ๐Ÿ”ข:

  • filename: str โฎ๏ธ โฎ๏ธ ๐Ÿ“ ๐Ÿ“› ๐Ÿ‘ˆ ๐Ÿ“‚ (โœ… myimage.jpg).
  • content_type: str โฎ๏ธ ๐ŸŽš ๐Ÿ†Ž (๐Ÿ“ ๐Ÿ†Ž / ๐Ÿ“ป ๐Ÿ†Ž) (โœ… image/jpeg).
  • file: SpooledTemporaryFile ( ๐Ÿ“-๐Ÿ’– ๐ŸŽš). ๐Ÿ‘‰ โ˜‘ ๐Ÿ ๐Ÿ“ ๐Ÿ‘ˆ ๐Ÿ‘† ๐Ÿ’ช ๐Ÿšถโ€โ™€๏ธ ๐Ÿ”— ๐ŸŽ ๐Ÿ”ข โš–๏ธ ๐Ÿ—ƒ ๐Ÿ‘ˆ โŒ› "๐Ÿ“-๐Ÿ’–" ๐ŸŽš.

UploadFile โœ”๏ธ ๐Ÿ“„ async ๐Ÿ‘ฉโ€๐Ÿ”ฌ. ๐Ÿ‘ซ ๐ŸŒ ๐Ÿค™ ๐Ÿ”— ๐Ÿ“ ๐Ÿ‘ฉโ€๐Ÿ”ฌ ๐Ÿ”˜ (โš™๏ธ ๐Ÿ”— SpooledTemporaryFile).

  • write(data): โœ data (str โš–๏ธ bytes) ๐Ÿ“.
  • read(size): โœ size (int) ๐Ÿ”ข/๐Ÿฆน ๐Ÿ“.
  • seek(offset): ๐Ÿšถ ๐Ÿ”ข ๐Ÿง˜ offset (int) ๐Ÿ“.
    • ๐Ÿคถ โ“‚., await myfile.seek(0) ๐Ÿ”œ ๐Ÿšถ โ–ถ๏ธ ๐Ÿ“.
    • ๐Ÿ‘‰ โœด๏ธ โš  ๐Ÿšฅ ๐Ÿ‘† ๐Ÿƒ await myfile.read() ๐Ÿ• & โคด๏ธ ๐Ÿ’ช โœ ๐ŸŽš ๐Ÿ”„.
  • close(): ๐Ÿ” ๐Ÿ“.

๐ŸŒ ๐Ÿ‘ซ ๐Ÿ‘ฉโ€๐Ÿ”ฌ async ๐Ÿ‘ฉโ€๐Ÿ”ฌ, ๐Ÿ‘† ๐Ÿ’ช "โŒ›" ๐Ÿ‘ซ.

๐Ÿ–ผ, ๐Ÿ”˜ async โžก ๐Ÿ› ๏ธ ๐Ÿ”ข ๐Ÿ‘† ๐Ÿ’ช ๐Ÿคš ๐ŸŽš โฎ๏ธ:

contents = await myfile.read()

๐Ÿšฅ ๐Ÿ‘† ๐Ÿ”˜ ๐Ÿ˜ def โžก ๐Ÿ› ๏ธ ๐Ÿ”ข, ๐Ÿ‘† ๐Ÿ’ช ๐Ÿ” UploadFile.file ๐Ÿ”—, ๐Ÿ–ผ:

contents = myfile.file.read()

async ๐Ÿ“ก โ„น

๐Ÿ•โ” ๐Ÿ‘† โš™๏ธ async ๐Ÿ‘ฉโ€๐Ÿ”ฌ, FastAPI ๐Ÿƒ ๐Ÿ“ ๐Ÿ‘ฉโ€๐Ÿ”ฌ ๐Ÿงต & โŒ› ๐Ÿ‘ซ.

๐Ÿ’ƒ ๐Ÿ“ก โ„น

FastAPI'โ“‚ UploadFile ๐Ÿ˜– ๐Ÿ”— โšช๏ธโžก๏ธ ๐Ÿ’ƒ'โ“‚ UploadFile, โœ‹๏ธ ๐Ÿšฎ ๐Ÿ’ช ๐Ÿ• โš’ โšซ๏ธ ๐Ÿ”— โฎ๏ธ Pydantic & ๐ŸŽ ๐Ÿ• FastAPI.

โšซ๏ธโ” "๐Ÿ“จ ๐Ÿ’ฝ"

๐ŸŒŒ ๐Ÿ•ธ ๐Ÿ“จ (<form></form>) ๐Ÿ“จ ๐Ÿ’ฝ ๐Ÿ’ฝ ๐Ÿ›Ž โš™๏ธ "๐ŸŽ" ๐Ÿ”ข ๐Ÿ‘ˆ ๐Ÿ“Š, โšซ๏ธ ๐ŸŽ โšช๏ธโžก๏ธ ๐ŸŽป.

FastAPI ๐Ÿ”œ โš’ ๐Ÿ’ญ โœ ๐Ÿ‘ˆ ๐Ÿ“Š โšช๏ธโžก๏ธ โ–ถ๏ธ๏ธ ๐Ÿฅ‰ โ†ฉ๏ธ ๐ŸŽป.

๐Ÿ“ก โ„น

๐Ÿ“Š โšช๏ธโžก๏ธ ๐Ÿ“จ ๐Ÿ›Ž ๐Ÿ—œ โš™๏ธ "๐Ÿ“ป ๐Ÿ†Ž" application/x-www-form-urlencoded ๐Ÿ•โ” โšซ๏ธ ๐Ÿšซ ๐Ÿ”Œ ๐Ÿ“.

โœ‹๏ธ ๐Ÿ•โ” ๐Ÿ“จ ๐Ÿ”Œ ๐Ÿ“, โšซ๏ธ ๐Ÿ—œ multipart/form-data. ๐Ÿšฅ ๐Ÿ‘† โš™๏ธ File, FastAPI ๐Ÿ”œ ๐Ÿ’ญ โšซ๏ธ โœ”๏ธ ๐Ÿคš ๐Ÿ“ โšช๏ธโžก๏ธ โ˜‘ ๐Ÿ• ๐Ÿ’ช.

๐Ÿšฅ ๐Ÿ‘† ๐Ÿ’š โœ ๐ŸŒ– ๐Ÿ”ƒ ๐Ÿ‘‰ ๐Ÿ”ข & ๐Ÿ“จ ๐Ÿ‘, ๐Ÿ‘ณ ๐Ÿ‡ ๐Ÿ•ธ ๐Ÿฉบ POST.

Warning

๐Ÿ‘† ๐Ÿ’ช ๐Ÿ“ฃ ๐Ÿ’— File & Form ๐Ÿ”ข โžก ๐Ÿ› ๏ธ, โœ‹๏ธ ๐Ÿ‘† ๐Ÿ’ช ๐Ÿšซ ๐Ÿ“ฃ Body ๐Ÿ‘ ๐Ÿ‘ˆ ๐Ÿ‘† โŒ› ๐Ÿ“จ ๐ŸŽป, ๐Ÿ“จ ๐Ÿ”œ โœ”๏ธ ๐Ÿ’ช ๐Ÿ—œ โš™๏ธ multipart/form-data โ†ฉ๏ธ application/json.

๐Ÿ‘‰ ๐Ÿšซ ๐Ÿšซ FastAPI, โšซ๏ธ ๐Ÿ• ๐Ÿ‡บ๐Ÿ‡ธ๐Ÿ” ๐Ÿ› ๏ธ.

๐Ÿ“ฆ ๐Ÿ“ ๐Ÿ“‚

๐Ÿ‘† ๐Ÿ’ช โš’ ๐Ÿ“ ๐Ÿ“ฆ โš™๏ธ ๐Ÿฉ ๐Ÿ†Ž โœ & โš’ ๐Ÿ”ข ๐Ÿ’ฒ None:

from typing import Union

from fastapi import FastAPI, File, UploadFile

app = FastAPI()


@app.post("/files/")
async def create_file(file: Union[bytes, None] = File(default=None)):
    if not file:
        return {"message": "No file sent"}
    else:
        return {"file_size": len(file)}


@app.post("/uploadfile/")
async def create_upload_file(file: Union[UploadFile, None] = None):
    if not file:
        return {"message": "No upload file sent"}
    else:
        return {"filename": file.filename}
from fastapi import FastAPI, File, UploadFile

app = FastAPI()


@app.post("/files/")
async def create_file(file: bytes | None = File(default=None)):
    if not file:
        return {"message": "No file sent"}
    else:
        return {"file_size": len(file)}


@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile | None = None):
    if not file:
        return {"message": "No upload file sent"}
    else:
        return {"filename": file.filename}

UploadFile โฎ๏ธ ๐ŸŒ– ๐Ÿ—ƒ

๐Ÿ‘† ๐Ÿ’ช โš™๏ธ File() โฎ๏ธ UploadFile, ๐Ÿ–ผ, โš’ ๐ŸŒ– ๐Ÿ—ƒ:

from fastapi import FastAPI, File, UploadFile

app = FastAPI()


@app.post("/files/")
async def create_file(file: bytes = File(description="A file read as bytes")):
    return {"file_size": len(file)}


@app.post("/uploadfile/")
async def create_upload_file(
    file: UploadFile = File(description="A file read as UploadFile"),
):
    return {"filename": file.filename}

๐Ÿ’— ๐Ÿ“ ๐Ÿ“‚

โšซ๏ธ ๐Ÿ’ช ๐Ÿ“‚ ๐Ÿ“š ๐Ÿ“ ๐ŸŽ ๐Ÿ•ฐ.

๐Ÿ‘ซ ๐Ÿ”œ ๐Ÿ‘จโ€๐Ÿ’ผ ๐ŸŽ "๐Ÿ“จ ๐Ÿ‘" ๐Ÿ“จ โš™๏ธ "๐Ÿ“จ ๐Ÿ’ฝ".

โš™๏ธ ๐Ÿ‘ˆ, ๐Ÿ“ฃ ๐Ÿ“‡ bytes โš–๏ธ UploadFile:

from typing import List

from fastapi import FastAPI, File, UploadFile
from fastapi.responses import HTMLResponse

app = FastAPI()


@app.post("/files/")
async def create_files(files: List[bytes] = File()):
    return {"file_sizes": [len(file) for file in files]}


@app.post("/uploadfiles/")
async def create_upload_files(files: List[UploadFile]):
    return {"filenames": [file.filename for file in files]}


@app.get("/")
async def main():
    content = """
<body>
<form action="/files/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
<form action="/uploadfiles/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
</body>
    """
    return HTMLResponse(content=content)
from fastapi import FastAPI, File, UploadFile
from fastapi.responses import HTMLResponse

app = FastAPI()


@app.post("/files/")
async def create_files(files: list[bytes] = File()):
    return {"file_sizes": [len(file) for file in files]}


@app.post("/uploadfiles/")
async def create_upload_files(files: list[UploadFile]):
    return {"filenames": [file.filename for file in files]}


@app.get("/")
async def main():
    content = """
<body>
<form action="/files/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
<form action="/uploadfiles/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
</body>
    """
    return HTMLResponse(content=content)

๐Ÿ‘† ๐Ÿ”œ ๐Ÿ“จ, ๐Ÿ“ฃ, list bytes โš–๏ธ UploadFileโ“‚.

๐Ÿ“ก โ„น

๐Ÿ‘† ๐Ÿ’ช โš™๏ธ from starlette.responses import HTMLResponse.

FastAPI ๐Ÿšš ๐ŸŽ starlette.responses fastapi.responses ๐Ÿช ๐Ÿ‘†, ๐Ÿ‘ฉโ€๐Ÿ’ป. โœ‹๏ธ ๐ŸŒ… ๐Ÿ’ช ๐Ÿ“จ ๐Ÿ‘Ÿ ๐Ÿ”— โšช๏ธโžก๏ธ ๐Ÿ’ƒ.

๐Ÿ’— ๐Ÿ“ ๐Ÿ“‚ โฎ๏ธ ๐ŸŒ– ๐Ÿ—ƒ

& ๐ŸŽ ๐ŸŒŒ โญ, ๐Ÿ‘† ๐Ÿ’ช โš™๏ธ File() โš’ ๐ŸŒ– ๐Ÿ”ข, UploadFile:

from typing import List

from fastapi import FastAPI, File, UploadFile
from fastapi.responses import HTMLResponse

app = FastAPI()


@app.post("/files/")
async def create_files(
    files: List[bytes] = File(description="Multiple files as bytes"),
):
    return {"file_sizes": [len(file) for file in files]}


@app.post("/uploadfiles/")
async def create_upload_files(
    files: List[UploadFile] = File(description="Multiple files as UploadFile"),
):
    return {"filenames": [file.filename for file in files]}


@app.get("/")
async def main():
    content = """
<body>
<form action="/files/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
<form action="/uploadfiles/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
</body>
    """
    return HTMLResponse(content=content)
from fastapi import FastAPI, File, UploadFile
from fastapi.responses import HTMLResponse

app = FastAPI()


@app.post("/files/")
async def create_files(
    files: list[bytes] = File(description="Multiple files as bytes"),
):
    return {"file_sizes": [len(file) for file in files]}


@app.post("/uploadfiles/")
async def create_upload_files(
    files: list[UploadFile] = File(description="Multiple files as UploadFile"),
):
    return {"filenames": [file.filename for file in files]}


@app.get("/")
async def main():
    content = """
<body>
<form action="/files/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
<form action="/uploadfiles/" enctype="multipart/form-data" method="post">
<input name="files" type="file" multiple>
<input type="submit">
</form>
</body>
    """
    return HTMLResponse(content=content)

๐ŸŒƒ

โš™๏ธ File, bytes, & UploadFile ๐Ÿ“ฃ ๐Ÿ“ ๐Ÿ“‚ ๐Ÿ“จ, ๐Ÿ“จ ๐Ÿ“จ ๐Ÿ’ฝ.