I have a small web server:
# app.py
from typing import List
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
id: int
name: str
@app.post("/items")
async def items_list(items: List[Item]):
return items
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
and a python file that posts to the endpoint:
# req.py
import asyncio
from typing import List
import datetime as dt
import aiohttp
from app import Item
async def main():
data = [
Item(id=1, name='A').dict(),
Item(id=2, name='B').dict()
]
async with aiohttp.ClientSession() as session:
async with session.post(
'http://localhost:8000/items',
json=data
) as response:
print(f'response: {await response.json()}')
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
It works, I can get an output like:
response: [{'id': 1, 'name': 'A'}, {'id': 2, 'name': 'B'}]
If I set data as (no .dict()):
data = [
Item(id=1, name='A'),
Item(id=2, name='B')
]
it doesn't work because Item is not json serializable. My goal is to post list of items to the fastapi endpoint.
This working example doesn't work if I extend Item as this:
class Item(BaseModel):
id: int
name: str
created_at: dt.datetime
created_at is a datetime and even I em using Items(..).dict() it is not json serializable. Funny thing is that if I create an Item as:
Item(id=1, name='A',created_at=dt.datetime.utcnow()).json()
its json is perfect:
{"id": 1, "name": "A", "created_at": "2021-12-15T21:10:36.077435"}
but as aiohttp session.post(json...) uses non pydantic json encoder, Item is not json serializable.
I tried to create a new pydantic object:
class ItemsList(BaseModel):
data: List[Item]
end set it as:
data = [
Item(id=1, name='A', created_at=dt.datetime.utcnow()),
Item(id=2, name='B', created_at=dt.datetime.utcnow())
]
data_list = ItemsList(data=data)
Again, pydantic is clever enough to produce proper json:
data_list.json()
{"data": [{"id": 1, "name": "A", "created_at": "2021-12-15T21:17:34.368555"}, {"id": 2, "name": "B", "created_at": "2021-12-15T21:17:34.368555"}]}
but I am not sure how to send such json using aiohttp post.
My question is: How to by using aiohttp post a list of pydantic objects that contain datetime property to fastapi endpoint? I would be satisfied with sending/receiving list of itmes ([Item, Item, ... Item])