Body - İç İçe Modeller¶
🌐 Translation by AI and humans
This translation was made by AI guided by humans. 🤝
It could have mistakes of misunderstanding the original meaning, or looking unnatural, etc. 🤖
You can improve this translation by helping us guide the AI LLM better.
FastAPI ile (Pydantic sayesinde) istediğiniz kadar derin iç içe geçmiş modelleri tanımlayabilir, doğrulayabilir, dokümante edebilir ve kullanabilirsiniz.
List alanları¶
Bir attribute’u bir alt tipe sahip olacak şekilde tanımlayabilirsiniz. Örneğin, bir Python list:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: list = []
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
tags: list = []
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
Bu, tags’in bir list olmasını sağlar; ancak list’in elemanlarının tipini belirtmez.
Tip parametresi olan list alanları¶
Ancak Python’da, iç tipleri olan list’leri (ya da "type parameter" içeren tipleri) tanımlamanın belirli bir yolu vardır:
Tip parametresiyle bir list tanımlayın¶
list, dict, tuple gibi type parameter (iç tip) alan tipleri tanımlamak için, iç tipi(leri) köşeli parantezlerle "type parameter" olarak verin: [ ve ]
my_list: list[str]
Bu, tip tanımları için standart Python sözdizimidir.
İç tipleri olan model attribute’ları için de aynı standart sözdizimini kullanın.
Dolayısıyla örneğimizde, tags’i özel olarak bir "string list’i" yapabiliriz:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: list[str] = []
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
tags: list[str] = []
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
Set tipleri¶
Sonra bunu düşününce, tag’lerin tekrar etmemesi gerektiğini fark ederiz; büyük ihtimalle benzersiz string’ler olmalıdır.
Python’da benzersiz öğelerden oluşan kümeler için özel bir veri tipi vardır: set.
O zaman tags’i string’lerden oluşan bir set olarak tanımlayabiliriz:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
tags: set[str] = set()
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
Böylece duplicate veri içeren bir request alsanız bile, bu veri benzersiz öğelerden oluşan bir set’e dönüştürülür.
Ve bu veriyi ne zaman output etseniz, kaynakta duplicate olsa bile, benzersiz öğelerden oluşan bir set olarak output edilir.
Ayrıca buna göre annotate / dokümante edilir.
İç İçe Modeller¶
Bir Pydantic modelinin her attribute’unun bir tipi vardır.
Ancak bu tip, kendi başına başka bir Pydantic modeli de olabilir.
Yani belirli attribute adları, tipleri ve validation kurallarıyla derin iç içe JSON "object"leri tanımlayabilirsiniz.
Hem de istediğiniz kadar iç içe.
Bir alt model tanımlayın¶
Örneğin bir Image modeli tanımlayabiliriz:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Image(BaseModel):
url: str
name: str
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
image: Image | None = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Image(BaseModel):
url: str
name: str
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
tags: set[str] = set()
image: Union[Image, None] = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
Alt modeli tip olarak kullanın¶
Ardından bunu bir attribute’un tipi olarak kullanabiliriz:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Image(BaseModel):
url: str
name: str
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
image: Image | None = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Image(BaseModel):
url: str
name: str
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
tags: set[str] = set()
image: Union[Image, None] = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
Bu da FastAPI’nin aşağıdakine benzer bir body bekleyeceği anlamına gelir:
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2,
"tags": ["rock", "metal", "bar"],
"image": {
"url": "http://example.com/baz.jpg",
"name": "The Foo live"
}
}
Yine, sadece bu tanımı yaparak FastAPI ile şunları elde edersiniz:
- Editör desteği (tamamlama vb.), iç içe modeller için bile
- Veri dönüştürme
- Veri doğrulama (validation)
- Otomatik dokümantasyon
Özel tipler ve doğrulama¶
str, int, float vb. normal tekil tiplerin yanında, str’den türeyen daha karmaşık tekil tipleri de kullanabilirsiniz.
Tüm seçenekleri görmek için Pydantic Type Overview sayfasına göz atın. Sonraki bölümde bazı örnekleri göreceksiniz.
Örneğin Image modelinde bir url alanımız olduğuna göre, bunu str yerine Pydantic’in HttpUrl tipinden bir instance olacak şekilde tanımlayabiliriz:
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
image: Image | None = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
tags: set[str] = set()
image: Union[Image, None] = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
String’in geçerli bir URL olup olmadığı kontrol edilir ve JSON Schema / OpenAPI’de de buna göre dokümante edilir.
Alt modellerden oluşan list’lere sahip attribute’lar¶
Pydantic modellerini list, set vb. tiplerin alt tipi olarak da kullanabilirsiniz:
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
images: list[Image] | None = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
tags: set[str] = set()
images: Union[list[Image], None] = None
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
results = {"item_id": item_id, "item": item}
return results
Bu, aşağıdaki gibi bir JSON body bekler (dönüştürür, doğrular, dokümante eder vb.):
{
"name": "Foo",
"description": "The pretender",
"price": 42.0,
"tax": 3.2,
"tags": [
"rock",
"metal",
"bar"
],
"images": [
{
"url": "http://example.com/baz.jpg",
"name": "The Foo live"
},
{
"url": "http://example.com/dave.jpg",
"name": "The Baz"
}
]
}
Bilgi
images key’inin artık image object’lerinden oluşan bir list içerdiğine dikkat edin.
Çok derin iç içe modeller¶
İstediğiniz kadar derin iç içe modeller tanımlayabilirsiniz:
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
tags: set[str] = set()
images: list[Image] | None = None
class Offer(BaseModel):
name: str
description: str | None = None
price: float
items: list[Item]
@app.post("/offers/")
async def create_offer(offer: Offer):
return offer
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
tags: set[str] = set()
images: Union[list[Image], None] = None
class Offer(BaseModel):
name: str
description: Union[str, None] = None
price: float
items: list[Item]
@app.post("/offers/")
async def create_offer(offer: Offer):
return offer
Bilgi
Offer’ın bir Item list’i olduğuna, Item’ların da opsiyonel bir Image list’ine sahip olduğuna dikkat edin.
Sadece list olan body’ler¶
Beklediğiniz JSON body’nin en üst seviye değeri bir JSON array (Python’da list) ise, tipi Pydantic modellerinde olduğu gibi fonksiyonun parametresinde tanımlayabilirsiniz:
images: list[Image]
şu örnekte olduğu gibi:
from fastapi import FastAPI
from pydantic import BaseModel, HttpUrl
app = FastAPI()
class Image(BaseModel):
url: HttpUrl
name: str
@app.post("/images/multiple/")
async def create_multiple_images(images: list[Image]):
return images
Her yerde editör desteği¶
Ve her yerde editör desteği alırsınız.
List içindeki öğeler için bile:

Pydantic modelleri yerine doğrudan dict ile çalışsaydınız bu tür bir editör desteğini alamazdınız.
Ancak bunlarla uğraşmanız da gerekmez; gelen dict’ler otomatik olarak dönüştürülür ve output’unuz da otomatik olarak JSON’a çevrilir.
Rastgele dict body’leri¶
Body’yi, key’leri bir tipte ve value’ları başka bir tipte olan bir dict olarak da tanımlayabilirsiniz.
Bu şekilde (Pydantic modellerinde olduğu gibi) geçerli field/attribute adlarının önceden ne olduğunu bilmeniz gerekmez.
Bu, önceden bilmediğiniz key’leri almak istediğiniz durumlarda faydalıdır.
Bir diğer faydalı durum da key’lerin başka bir tipte olmasını istediğiniz zamandır (ör. int).
Burada göreceğimiz şey de bu.
Bu durumda, int key’lere ve float value’lara sahip olduğu sürece herhangi bir dict kabul edersiniz:
from fastapi import FastAPI
app = FastAPI()
@app.post("/index-weights/")
async def create_index_weights(weights: dict[int, float]):
return weights
İpucu
JSON key olarak yalnızca str destekler, bunu unutmayın.
Ancak Pydantic otomatik veri dönüştürme yapar.
Yani API client’larınız key’leri sadece string olarak gönderebilse bile, bu string’ler saf tamsayı içeriyorsa Pydantic bunları dönüştürür ve doğrular.
Ve weights olarak aldığınız dict, gerçekte int key’lere ve float value’lara sahip olur.
Özet¶
FastAPI ile Pydantic modellerinin sağladığı en yüksek esnekliği elde ederken, kodunuzu da basit, kısa ve şık tutarsınız.
Üstelik tüm avantajlarla birlikte:
- Editör desteği (her yerde tamamlama!)
- Veri dönüştürme (diğer adıyla parsing / serialization)
- Veri doğrulama (validation)
- Schema dokümantasyonu
- Otomatik dokümanlar