An API with Python and FastAPI
TeselaDB
TeselaDB team
25 minBeginner
Build an orders API with FastAPI and PyMongo that validates each order and saves it in TeselaDB.
A Python API uses TeselaDB with PyMongo, the official MongoDB driver. Here you write with FastAPI the same orders API as in the Express guide, which creates an order and reads it.
What you will build
A FastAPI server on port 8000 with POST /orders, which validates the order with Pydantic and saves it, and
GET /orders/{order_id}, which returns it or answers 404.
Requirements
- Python 3.9 or later.
- A TeselaDB cluster and a user with
readWriteon theshopdatabase. - The connection string with TLS in the
TESELADB_URIenvironment variable, as in Python.
1. Create the environment
python3 -m venv .venv
. .venv/bin/activate
pip install fastapi uvicorn pymongo2. Write the API
Save it as main.py. The endpoint functions are synchronous, so FastAPI runs them in its thread pool and the PyMongo
client shares its connections between them:
import os
from datetime import datetime, timezone
from bson import ObjectId
from bson.errors import InvalidId
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from pymongo import MongoClient
client = MongoClient(os.environ["TESELADB_URI"])
orders = client.shop.orders
app = FastAPI()
class NewOrder(BaseModel):
customer: str
total: float = Field(ge=0)
@app.post("/orders", status_code=201)
def create_order(order: NewOrder):
result = orders.insert_one({**order.model_dump(), "createdAt": datetime.now(timezone.utc)})
return {"id": str(result.inserted_id)}
@app.get("/orders/{order_id}")
def read_order(order_id: str):
try:
order = orders.find_one({"_id": ObjectId(order_id)})
except InvalidId:
order = None
if order is None:
raise HTTPException(status_code=404)
order["_id"] = str(order["_id"])
return orderTry it
Start the server with uvicorn main:app. Then, in another terminal, create an order for Ana with a total of 30 and read it
back with the id that the first request returns, which goes in place of <id> in the second command:
curl -s -X POST localhost:8000/orders -H "content-type: application/json" -d '{"customer":"Ana","total":30}'
curl -s localhost:8000/orders/<id>The first command returns {"id":"…"} and the second, the order with its creation date. An order with a negative
total answers 422 with the validation error.
Clean up
Stop the server with Ctrl+C and delete the test orders from mongosh:
db.getSiblingDB("shop").orders.deleteMany({ customer: "Ana" });Next steps
- An API with Node.js and Express, the same API in JavaScript.
- Query documents, with the filters you can pass to
find.