๐จ ๐¶
๐ ๐ช ๐ฌ ๐ ๐ ๐ฉโ๐ป โ๏ธ 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 ๐ฃ ๐ ๐ ๐จ, ๐จ ๐จ ๐ฝ.