Request Dosyaları¶
🌐 Yapay Zekâ ve İnsanlar Tarafından Çeviri
Bu çeviri, insanlar tarafından yönlendirilen bir yapay zekâ ile oluşturuldu. 🤝
Orijinal anlamın yanlış anlaşılması ya da kulağa doğal gelmeme gibi hatalar içerebilir. 🤖
Yapay zekâyı daha iyi yönlendirmemize yardımcı olarak bu çeviriyi iyileştirebilirsiniz.
İstemcinin upload edeceği dosyaları File kullanarak tanımlayabilirsiniz.
Bilgi
Upload edilen dosyaları alabilmek için önce python-multipart yükleyin.
Bir virtual environment oluşturduğunuzdan, aktive ettiğinizden ve ardından paketi yüklediğinizden emin olun. Örneğin:
$ pip install python-multipart
Bunun nedeni, upload edilen dosyaların "form data" olarak gönderilmesidir.
File Import Edin¶
fastapi içinden File ve UploadFile import edin:
from typing import Annotated
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
@app.post("/files/")
async def create_file(file: Annotated[bytes, File()]):
return {"file_size": len(file)}
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
return {"filename": file.filename}
🤓 Other versions and variants
Tip
Prefer to use the Annotated version if possible.
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 Parametrelerini Tanımlayın¶
Body veya Form için yaptığınız gibi dosya parametreleri oluşturun:
from typing import Annotated
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
@app.post("/files/")
async def create_file(file: Annotated[bytes, File()]):
return {"file_size": len(file)}
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
return {"filename": file.filename}
🤓 Other versions and variants
Tip
Prefer to use the Annotated version if possible.
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}
Bilgi
File, doğrudan Form’dan türeyen bir sınıftır.
Ancak unutmayın: fastapi içinden Query, Path, File ve diğerlerini import ettiğinizde, bunlar aslında özel sınıflar döndüren fonksiyonlardır.
İpucu
File body’leri tanımlamak için File kullanmanız gerekir; aksi halde parametreler query parametreleri veya body (JSON) parametreleri olarak yorumlanır.
Dosyalar "form data" olarak upload edilir.
path operation function parametrenizin tipini bytes olarak tanımlarsanız, FastAPI dosyayı sizin için okur ve içeriği bytes olarak alırsınız.
Bunun, dosyanın tüm içeriğinin bellekte tutulacağı anlamına geldiğini unutmayın. Küçük dosyalar için iyi çalışır.
Ancak bazı durumlarda UploadFile kullanmak size fayda sağlayabilir.
UploadFile ile Dosya Parametreleri¶
Tipi UploadFile olan bir dosya parametresi tanımlayın:
from typing import Annotated
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
@app.post("/files/")
async def create_file(file: Annotated[bytes, File()]):
return {"file_size": len(file)}
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
return {"filename": file.filename}
🤓 Other versions and variants
Tip
Prefer to use the Annotated version if possible.
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 kullanmanın bytes’a göre birkaç avantajı vardır:
- Parametrenin varsayılan değerinde
File()kullanmak zorunda değilsiniz. - "Spooled" bir dosya kullanır:
- Belirli bir maksimum boyuta kadar bellekte tutulan, bu limiti aşınca diske yazılan bir dosya.
- Bu sayede görüntüler, videolar, büyük binary’ler vb. gibi büyük dosyalarda tüm belleği tüketmeden iyi çalışır.
- Upload edilen dosyadan metadata alabilirsiniz.
- file-like bir
asyncarayüze sahiptir. SpooledTemporaryFilenesnesini dışa açar; bunu, file-like nesne bekleyen diğer library’lere doğrudan geçebilirsiniz.
UploadFile¶
UploadFile şu attribute’lara sahiptir:
filename: Upload edilen orijinal dosya adını içeren birstr(örn.myimage.jpg).content_type: Content type’ı (MIME type / media type) içeren birstr(örn.image/jpeg).file: BirSpooledTemporaryFile(bir file-like nesne). Bu, "file-like" nesne bekleyen diğer fonksiyonlara veya library’lere doğrudan verebileceğiniz gerçek Python file nesnesidir.
UploadFile şu async method’lara sahiptir. Bunların hepsi altta ilgili dosya method’larını çağırır (dahili SpooledTemporaryFile kullanarak).
write(data): Dosyayadata(strveyabytes) yazar.read(size): Dosyadansize(int) kadar byte/karakter okur.seek(offset): Dosyadaoffset(int) byte pozisyonuna gider.- Örn.
await myfile.seek(0)dosyanın başına gider. - Bu, özellikle bir kez
await myfile.read()çalıştırdıysanız ve sonra içeriği yeniden okumaya ihtiyaç duyuyorsanız faydalıdır.
- Örn.
close(): Dosyayı kapatır.
Bu method’ların hepsi async olduğundan, bunları "await" etmeniz gerekir.
Örneğin, bir async path operation function içinde içeriği şöyle alabilirsiniz:
contents = await myfile.read()
Normal bir def path operation function içindeyseniz UploadFile.file’a doğrudan erişebilirsiniz, örneğin:
contents = myfile.file.read()
async Teknik Detaylar
async method’ları kullandığınızda, FastAPI dosya method’larını bir threadpool içinde çalıştırır ve bunları await eder.
Starlette Teknik Detaylar
FastAPI’nin UploadFile’ı doğrudan Starlette’in UploadFile’ından türetilmiştir; ancak Pydantic ve FastAPI’nin diğer parçalarıyla uyumlu olması için bazı gerekli eklemeler yapar.
"Form Data" Nedir¶
HTML formları (<form></form>) veriyi server’a gönderirken normalde JSON’dan farklı, veri için "özel" bir encoding kullanır.
FastAPI, JSON yerine bu veriyi doğru yerden okuyacağından emin olur.
Teknik Detaylar
Formlardan gelen veri, dosya içermiyorsa normalde "media type" olarak application/x-www-form-urlencoded ile encode edilir.
Ancak form dosya içeriyorsa multipart/form-data olarak encode edilir. File kullanırsanız, FastAPI dosyaları body’nin doğru kısmından alması gerektiğini bilir.
Bu encoding’ler ve form alanları hakkında daha fazla okumak isterseniz MDN web dokümanlarındaki POST sayfasına bakın.
Uyarı
Bir path operation içinde birden fazla File ve Form parametresi tanımlayabilirsiniz, ancak JSON olarak almayı beklediğiniz Body alanlarını ayrıca tanımlayamazsınız; çünkü request body application/json yerine multipart/form-data ile encode edilmiş olur.
Bu, FastAPI’nin bir kısıtı değildir; HTTP protocol’ünün bir parçasıdır.
Opsiyonel Dosya Upload¶
Standart type annotation’ları kullanıp varsayılan değeri None yaparak bir dosyayı opsiyonel hale getirebilirsiniz:
from typing import Annotated
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
@app.post("/files/")
async def create_file(file: Annotated[bytes | None, File()] = 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}
🤓 Other versions and variants
from typing import Annotated, Union
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
@app.post("/files/")
async def create_file(file: Annotated[Union[bytes, None], File()] = 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}
Tip
Prefer to use the Annotated version if possible.
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}
Tip
Prefer to use the Annotated version if possible.
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}
Ek Metadata ile UploadFile¶
Ek metadata ayarlamak için UploadFile ile birlikte File() da kullanabilirsiniz. Örneğin:
from typing import Annotated
from fastapi import FastAPI, File, UploadFile
app = FastAPI()
@app.post("/files/")
async def create_file(file: Annotated[bytes, File(description="A file read as bytes")]):
return {"file_size": len(file)}
@app.post("/uploadfile/")
async def create_upload_file(
file: Annotated[UploadFile, File(description="A file read as UploadFile")],
):
return {"filename": file.filename}
🤓 Other versions and variants
Tip
Prefer to use the Annotated version if possible.
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}
Birden Fazla Dosya Upload¶
Aynı anda birden fazla dosya upload etmek mümkündür.
Bu dosyalar, "form data" ile gönderilen aynı "form field" ile ilişkilendirilir.
Bunu kullanmak için bytes veya UploadFile listesini tanımlayın:
from typing import Annotated
from fastapi import FastAPI, File, UploadFile
from fastapi.responses import HTMLResponse
app = FastAPI()
@app.post("/files/")
async def create_files(files: Annotated[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)
🤓 Other versions and variants
Tip
Prefer to use the Annotated version if possible.
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)
Tanımladığınız gibi, bytes veya UploadFile’lardan oluşan bir list alırsınız.
Teknik Detaylar
from starlette.responses import HTMLResponse da kullanabilirsiniz.
FastAPI, geliştiriciye kolaylık olsun diye starlette.responses modülünü fastapi.responses olarak da sağlar. Ancak mevcut response’ların çoğu doğrudan Starlette’ten gelir.
Ek Metadata ile Birden Fazla Dosya Upload¶
Daha önce olduğu gibi, UploadFile için bile ek parametreler ayarlamak amacıyla File() kullanabilirsiniz:
from typing import Annotated
from fastapi import FastAPI, File, UploadFile
from fastapi.responses import HTMLResponse
app = FastAPI()
@app.post("/files/")
async def create_files(
files: Annotated[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: Annotated[
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)
🤓 Other versions and variants
Tip
Prefer to use the Annotated version if possible.
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)
Özet¶
Request’te (form data olarak gönderilen) upload edilecek dosyaları tanımlamak için File, bytes ve UploadFile kullanın.