विषय पर बढ़ें

Input और Output के लिए अलग OpenAPI Schemas या नहीं

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

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

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

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

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

जबसे Pydantic v2 रिलीज़ हुआ है, generated OpenAPI पहले की तुलना में थोड़ा अधिक सटीक और सही है। 😎

वास्तव में, कुछ मामलों में, एक ही Pydantic model के लिए OpenAPI में दो JSON Schemas भी होंगे, input और output के लिए, इस पर निर्भर करते हुए कि उनमें default values हैं या नहीं।

आइए देखते हैं कि यह कैसे काम करता है और अगर आपको ज़रूरत हो तो इसे कैसे बदलना है।

Input और Output के लिए Pydantic Models

मान लीजिए आपके पास default values वाला एक Pydantic model है, जैसे यह:

from fastapi import FastAPI
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: str | None = None

# Code below omitted 👇
👀 Full file preview
from fastapi import FastAPI
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: str | None = None


app = FastAPI()


@app.post("/items/")
def create_item(item: Item):
    return item


@app.get("/items/")
def read_items() -> list[Item]:
    return [
        Item(
            name="Portal Gun",
            description="Device to travel through the multi-rick-verse",
        ),
        Item(name="Plumbus"),
    ]

Input के लिए Model

अगर आप इस model को यहाँ की तरह input के रूप में उपयोग करते हैं:

from fastapi import FastAPI
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: str | None = None


app = FastAPI()


@app.post("/items/")
def create_item(item: Item):
    return item

# Code below omitted 👇
👀 Full file preview
from fastapi import FastAPI
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: str | None = None


app = FastAPI()


@app.post("/items/")
def create_item(item: Item):
    return item


@app.get("/items/")
def read_items() -> list[Item]:
    return [
        Item(
            name="Portal Gun",
            description="Device to travel through the multi-rick-verse",
        ),
        Item(name="Plumbus"),
    ]

...तो description field required नहीं होगा। क्योंकि इसका default value None है।

Docs में Input Model

आप docs में इसकी पुष्टि कर सकते हैं, description field के पास लाल asterisk नहीं है, इसे required के रूप में mark नहीं किया गया है:

Output के लिए Model

लेकिन अगर आप उसी model को output के रूप में उपयोग करते हैं, जैसे यहाँ:

from fastapi import FastAPI
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: str | None = None


app = FastAPI()


@app.post("/items/")
def create_item(item: Item):
    return item


@app.get("/items/")
def read_items() -> list[Item]:
    return [
        Item(
            name="Portal Gun",
            description="Device to travel through the multi-rick-verse",
        ),
        Item(name="Plumbus"),
    ]

...तो क्योंकि description का default value है, अगर आप उस field के लिए कुछ भी return नहीं करते, तब भी इसका वही default value रहेगा।

Output Response Data के लिए Model

अगर आप docs के साथ interact करते हैं और response जाँचते हैं, तो भले ही code ने description fields में से किसी एक में कुछ भी add नहीं किया, JSON response में default value (null) शामिल होता है:

इसका मतलब है कि इसमें हमेशा एक value होगा, बस कभी-कभी value None हो सकता है (या JSON में null)।

इसका मतलब है कि आपकी API का उपयोग करने वाले clients को यह जाँचने की ज़रूरत नहीं है कि value मौजूद है या नहीं, वे मान सकते हैं कि field हमेशा मौजूद रहेगा, बस कुछ मामलों में इसका default value None होगा।

OpenAPI में इसे describe करने का तरीका है कि उस field को required के रूप में mark किया जाए, क्योंकि वह हमेशा मौजूद रहेगा।

इस वजह से, किसी model के लिए JSON Schema अलग हो सकता है, यह इस पर निर्भर करता है कि उसे input या output के लिए उपयोग किया गया है:

  • input के लिए description required नहीं होगा
  • output के लिए यह required होगा (और संभवतः None, या JSON terms में, null)

Docs में Output के लिए Model

आप docs में output model भी देख सकते हैं, दोनों name और description को लाल asterisk के साथ required के रूप में mark किया गया है:

Docs में Input और Output के लिए Model

और अगर आप OpenAPI में उपलब्ध सभी Schemas (JSON Schemas) जाँचते हैं, तो आप देखेंगे कि दो हैं, एक Item-Input और एक Item-Output

Item-Input के लिए, description required नहीं है, इसमें लाल asterisk नहीं है।

लेकिन Item-Output के लिए, description required है, इसमें लाल asterisk है।

Pydantic v2 की इस feature के साथ, आपकी API documentation अधिक precise होती है, और अगर आपके पास autogenerated clients और SDKs हैं, तो वे भी अधिक precise होंगे, बेहतर developer experience और consistency के साथ। 🎉

Schemas को अलग न करें

अब, कुछ मामले ऐसे हैं जहाँ आप input और output के लिए same schema रखना चाह सकते हैं।

शायद इसका मुख्य use case यह है कि अगर आपके पास पहले से कुछ autogenerated client code/SDKs हैं और आप अभी सभी autogenerated client code/SDKs को update नहीं करना चाहते, तो शायद आप इसे किसी समय करना चाहेंगे, लेकिन शायद अभी नहीं।

उस स्थिति में, आप FastAPI में इस feature को parameter separate_input_output_schemas=False के साथ disable कर सकते हैं।

नोट

separate_input_output_schemas के लिए support FastAPI 0.102.0 में add किया गया था। 🤓

from fastapi import FastAPI
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: str | None = None


app = FastAPI(separate_input_output_schemas=False)


@app.post("/items/")
def create_item(item: Item):
    return item


@app.get("/items/")
def read_items() -> list[Item]:
    return [
        Item(
            name="Portal Gun",
            description="Device to travel through the multi-rick-verse",
        ),
        Item(name="Plumbus"),
    ]

Docs में Input और Output Models के लिए Same Schema

और अब model के लिए input और output के लिए केवल एक single schema होगा, सिर्फ Item, और इसमें description required नहीं होगा: