विषय पर बढ़ें

Request Files

🌐 एआई और मनुष्यों द्वारा किया गया अनुवाद

यह अनुवाद मनुष्यों के मार्गदर्शन में एआई द्वारा किया गया है। 🤝

इसमें मूल अर्थ को गलत समझने या अप्राकृतिक लगने आदि जैसी गलतियाँ हो सकती हैं। 🤖

आप हमें एआई LLM को बेहतर मार्गदर्शन करने में मदद करके इस अनुवाद को बेहतर बना सकते हैं।

अंग्रेज़ी संस्करण

आप client द्वारा अपलोड की जाने वाली files को File का उपयोग करके परिभाषित कर सकते हैं।

नोट

अपलोड की गई files प्राप्त करने के लिए, पहले python-multipart install करें।

सुनिश्चित करें कि आप एक virtual environment बनाते हैं, उसे activate करते हैं, और फिर इसे install करते हैं, उदाहरण के लिए:

$ pip install python-multipart

ऐसा इसलिए है क्योंकि अपलोड की गई files "form data" के रूप में भेजी जाती हैं।

File Import करें

fastapi से File और UploadFile import करें:

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 Parameters परिभाषित करें

file parameters उसी तरह बनाएं जैसे आप Body या Form के लिए बनाते हैं:

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 एक class है जो सीधे Form से inherit करती है।

लेकिन याद रखें कि जब आप fastapi से Query, Path, File और अन्य import करते हैं, तो वे वास्तव में functions होते हैं जो विशेष classes return करते हैं।

सुझाव

File bodies घोषित करने के लिए, आपको File का उपयोग करना होगा, क्योंकि अन्यथा parameters को query parameters या body (JSON) parameters के रूप में समझा जाएगा।

files "form data" के रूप में अपलोड की जाएंगी।

यदि आप अपने path operation function parameter का type bytes के रूप में घोषित करते हैं, तो FastAPI आपके लिए file पढ़ेगा और आपको सामग्री bytes के रूप में प्राप्त होगी।

ध्यान रखें कि इसका मतलब है कि पूरी सामग्री memory में संग्रहीत होगी। यह छोटी files के लिए अच्छी तरह काम करेगा।

लेकिन कई मामलों में आपको UploadFile का उपयोग करने से लाभ हो सकता है।

UploadFile के साथ File Parameters

UploadFile type के साथ file parameter परिभाषित करें:

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}

bytes की तुलना में UploadFile का उपयोग करने के कई फायदे हैं:

  • आपको parameter के default value में File() का उपयोग नहीं करना पड़ता।
  • यह एक "spooled" file का उपयोग करता है:
    • एक file जो अधिकतम size limit तक memory में संग्रहीत होती है, और इस limit को पार करने के बाद disk पर संग्रहीत होती है।
  • इसका मतलब है कि यह images, videos, बड़े binaries आदि जैसी बड़ी files के लिए सारी memory का उपयोग किए बिना अच्छी तरह काम करेगा।
  • आप अपलोड की गई file से metadata प्राप्त कर सकते हैं।
  • इसमें file-like async interface है।
  • यह एक वास्तविक Python SpooledTemporaryFile object expose करता है जिसे आप सीधे अन्य libraries को पास कर सकते हैं जो file-like object की अपेक्षा करती हैं।

UploadFile

UploadFile में निम्नलिखित attributes होते हैं:

  • filename: मूल file name के साथ एक str जो अपलोड किया गया था (जैसे myimage.jpg)।
  • content_type: content type (MIME type / media type) के साथ एक str (जैसे image/jpeg)।
  • file: एक SpooledTemporaryFile (एक file-like object)। यह वास्तविक Python file object है जिसे आप सीधे अन्य functions या libraries को पास कर सकते हैं जो "file-like" object की अपेक्षा करती हैं।

UploadFile में निम्नलिखित async methods होते हैं। ये सभी अंदर से संबंधित file methods को call करते हैं (internal SpooledTemporaryFile का उपयोग करके)।

  • write(data): data (str या bytes) को file में लिखता है।
  • read(size): file के size (int) bytes/characters पढ़ता है।
  • seek(offset): file में byte position offset (int) पर जाता है।
    • उदाहरण के लिए, await myfile.seek(0) file की शुरुआत पर जाएगा।
    • यह विशेष रूप से तब उपयोगी है जब आप एक बार await myfile.read() चलाते हैं और फिर सामग्री को दोबारा पढ़ने की आवश्यकता होती है।
  • close(): file को बंद करता है।

क्योंकि ये सभी methods async methods हैं, आपको उन्हें "await" करना होगा।

उदाहरण के लिए, एक async path operation function के अंदर आप सामग्री इस तरह प्राप्त कर सकते हैं:

contents = await myfile.read()

यदि आप एक सामान्य def path operation function के अंदर हैं, तो आप सीधे UploadFile.file access कर सकते हैं, उदाहरण के लिए:

contents = myfile.file.read()

async तकनीकी विवरण

जब आप async methods का उपयोग करते हैं, तो FastAPI file methods को threadpool में चलाता है और उनके लिए await करता है।

Starlette तकनीकी विवरण

FastAPI का UploadFile सीधे Starlette के UploadFile से inherit करता है, लेकिन Pydantic और FastAPI के अन्य भागों के साथ इसे compatible बनाने के लिए कुछ आवश्यक हिस्से जोड़ता है।

"Form Data" क्या है

HTML forms (<form></form>) सामान्यतः data को server पर भेजने के लिए उस data के लिए एक "special" encoding का उपयोग करते हैं, यह JSON से अलग होता है।

FastAPI यह सुनिश्चित करेगा कि उस data को JSON के बजाय सही जगह से पढ़ा जाए।

तकनीकी विवरण

forms से data सामान्यतः "media type" application/x-www-form-urlencoded का उपयोग करके encoded होता है जब इसमें files शामिल नहीं होतीं।

लेकिन जब form में files शामिल होती हैं, तो यह multipart/form-data के रूप में encoded होता है। यदि आप File का उपयोग करते हैं, तो FastAPI जान जाएगा कि उसे body के सही भाग से files प्राप्त करनी हैं।

यदि आप इन encodings और form fields के बारे में अधिक पढ़ना चाहते हैं, तो POST के लिए MDN web docs पर जाएं।

चेतावनी

आप एक path operation में कई File और Form parameters घोषित कर सकते हैं, लेकिन आप ऐसे Body fields भी घोषित नहीं कर सकते जिन्हें आप JSON के रूप में प्राप्त करने की अपेक्षा करते हैं, क्योंकि request में body application/json के बजाय multipart/form-data का उपयोग करके encoded होगी।

यह FastAPI की limitation नहीं है, यह HTTP protocol का हिस्सा है।

Optional File Upload

आप standard type annotations का उपयोग करके और default value None set करके file को optional बना सकते हैं:

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

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}

अतिरिक्त Metadata के साथ UploadFile

आप UploadFile के साथ File() का भी उपयोग कर सकते हैं, उदाहरण के लिए, अतिरिक्त metadata set करने के लिए:

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}

Multiple File Uploads

एक ही समय में कई files अपलोड करना संभव है।

वे "form data" का उपयोग करके भेजे गए उसी "form field" से संबंधित होंगी।

इसका उपयोग करने के लिए, bytes या UploadFile की list घोषित करें:

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)

आपको, जैसा घोषित किया गया है, bytes या UploadFiles की एक list प्राप्त होगी।

तकनीकी विवरण

आप from starlette.responses import HTMLResponse का भी उपयोग कर सकते हैं।

FastAPI आपकी सुविधा के लिए, developer के रूप में, वही starlette.responses को fastapi.responses के रूप में प्रदान करता है। लेकिन उपलब्ध अधिकांश responses सीधे Starlette से आते हैं।

अतिरिक्त Metadata के साथ Multiple File Uploads

और पहले की तरह ही, आप अतिरिक्त parameters set करने के लिए File() का उपयोग कर सकते हैं, यहां तक कि UploadFile के लिए भी:

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)

Recap

request में अपलोड की जाने वाली files घोषित करने के लिए File, bytes, और UploadFile का उपयोग करें, जिन्हें form data के रूप में भेजा जाता है।