So, I am trying to build a simple TODO app using FastApi and MongoDB. All the routes work fine, except for the POST route. When I try to post a "title" and and "description" using the SwaggerUI, it gives me an error. Surprsingly, if I modify the file and save again (the app reloads), the entry magically pops up in the DB. This is the error:
> INFO: 127.0.0.1:35516 - "POST /api/todo HTTP/1.1" 500 Internal Server Error
> ERROR: Exception in ASGI application
> Traceback (most recent call last):
> File "/home/eeshaan/.local/share/virtualenvs/backend-plIook9\_/lib/python3.10/site-packages/uvicorn/protocols/http/h11_impl.py", line 369, in run_asgi
> result = await app(self.scope, self.receive, self.send)
> File "/home/eeshaan/.local/share/virtualenvs/backend-plIook9\_/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 59, in __call__
> return await self.app(scope, receive, send)
> File "/home/eeshaan/.local/share/virtualenvs/backend-plIook9\_/lib/python3.10/site-packages/fastapi/applications.py", line 199, in __call__
> await super().__call__(scope, receive, send)
> File "/home/eeshaan/.local/share/virtualenvs/backend-plIook9\_/lib/python3.10/site-packages/starlette/applications.py", line 112, in __call__
> await self.middleware_stack(scope, receive, send)
> File "/home/eeshaan/.local/share/virtualenvs/backend-plIook9\_/lib/python3.10/site-packages/starlette/middleware/errors.py", line 181, in __call__
> raise exc from None
> File "/home/eeshaan/.local/share/virtualenvs/backend-plIook9\_/lib/python3.10/site-packages/starlette/middleware/errors.py", line 159, in __call__
> await self.app(scope, receive, _send)
> File "/home/eeshaan/.local/share/virtualenvs/backend-plIook9_/lib/python3.10/site-packages/starlette/middleware/cors.py", line 86, in __call__
> await self.simple_response(scope, receive, send, request_headers=headers)
> File "/home/eeshaan/.local/share/virtualenvs/backend-plIook9\_/lib/python3.10/site-packages/starlette/middleware/cors.py", line 142, in simple_response
> await self.app(scope, receive, send)
> File "/home/eeshaan/.local/share/virtualenvs/backend-plIook9\_/lib/python3.10/site-packages/starlette/exceptions.py", line 82, in __call__
> raise exc from None
> File "/home/eeshaan/.local/share/virtualenvs/backend-plIook9\_/lib/python3.10/site-packages/starlette/exceptions.py", line 71, in __call__
> await self.app(scope, receive, sender)
> File "/home/eeshaan/.local/share/virtualenvs/backend-plIook9\_/lib/python3.10/site-packages/starlette/routing.py", line 580, in __call__
> await route.handle(scope, receive, send)
> File "/home/eeshaan/.local/share/virtualenvs/backend-plIook9\_/lib/python3.10/site-packages/starlette/routing.py", line 241, in handle
> await self.app(scope, receive, send)
> File "/home/eeshaan/.local/share/virtualenvs/backend-plIook9\_/lib/python3.10/site-packages/starlette/routing.py", line 52, in app
> response = await func(request)
> File "/home/eeshaan/.local/share/virtualenvs/backend-plIook9\_/lib/python3.10/site-packages/fastapi/routing.py", line 209, in app
> response_data = await serialize_response(
> File "/home/eeshaan/.local/share/virtualenvs/backend-plIook9\_/lib/python3.10/site-packages/fastapi/routing.py", line 137, in serialize_response
> return jsonable_encoder(response_content)
> File "/home/eeshaan/.local/share/virtualenvs/backend-plIook9\_/lib/python3.10/site-packages/fastapi/encoders.py", line 141, in jsonable_encoder
> raise ValueError(errors)
> ValueError: \[TypeError("'InsertOneResult' object is not iterable"), TypeError('vars() argument must have __dict__ attribute')\]
Following are the code files: main.py
@app.post("/api/todo", response_model = Todo)
async def post_todo(todo: Todo):
response = await create_todo(todo.dict())
if response:
return response
else:
raise HTTPException(400, "Something went wrong. Try again.")
database.py
#mongoDB driver
import asyncio
from motor.motor_asyncio import AsyncIOMotorClient
#setup the connection to the database
client = AsyncIOMotorClient("mongodb://127.0.0.1:27017/")
async def create_todo(todo):
# take the the todo var in a dictionary form of key value pairs, and directly add them to the documents.
document = todo
result = await collection.insert_one(document)
return result
model.py
#this file helps us define a model on how our data from the databsse should look like
from pydantic import BaseModel
#specify the model for the todo. A title and a description
class Todo(BaseModel):
title : str
description : str