---
name: mongodb-fastapi
description: "Provisions a MongoDB database for a FastAPI app with `npx extraorbital add mongodb` (no signup, no card) and wires it into FastAPI with `pymongo`. Use when a FastAPI project needs MongoDB, Mongo, a document database, MONGODB_URI or PyMongo, or when MONGODB_URI is missing or unset in .env."
---

# MongoDB in FastAPI

<!-- Generated from ExtraOrbital's service registry by `pnpm skills:build` in platform/app. Edit the generator, not this file. -->

ExtraOrbital provisions a MongoDB database in one command and writes the credentials into the project's env file. For anything this recipe does not cover, use the `extraorbital` skill or https://extraorbital.dev/llms.txt.

## 1. Provision

```bash
npx extraorbital add mongodb
```

Run it from the project root. It is idempotent (a second run returns the same resource) and writes to `.env.local` if the project has one, otherwise `.env`, keeping that file out of git. Add `--json` to parse the result; credential values are redacted there, and you should never print them either.

| Variable | |
| --- | --- |
| `MONGODB_URI` | Carries the user, the password, TLS and the one database they reach |

Free on the Prototype plan: 512 MB, shared RAM and vCPU.

## 2. Install the client

```bash
pip install pydantic-settings pymongo
```

## 3. Connect

`pydantic-settings` reads `.env` and `.env.local` itself; if `app/config.py` already exists, add the fields to its `Settings`.

**`app/config.py`**

```python
from pydantic_settings import BaseSettings, SettingsConfigDict


class Settings(BaseSettings):
    # ExtraOrbital writes .env.local when the project has one, else .env; the later file wins.
    model_config = SettingsConfigDict(env_file=(".env", ".env.local"), extra="ignore")

    MONGODB_URI: str


settings = Settings()
```

**`app/mongodb.py`**

```python
from pymongo import AsyncMongoClient

from app.config import settings

mongo = AsyncMongoClient(settings.MONGODB_URI)
# The database named in the connection string: the only one the credentials reach.
mongo_db = mongo.get_default_database()
```

## 4. Use it

**`app/api/mongodb.py`**

```python
from fastapi import APIRouter

from app.mongodb import mongo_db

router = APIRouter()
# In app/main.py: from app.api import mongodb; app.include_router(mongodb.router)


@router.get("/api/mongodb")
async def check_mongodb():
    await mongo_db.events.insert_one({"type": "ping"})
    events = await mongo_db.events.count_documents({})
    return {"events": events}
```

## 5. Verify

```bash
npx extraorbital list        # the resource is listed as active
fastapi dev app/main.py
curl http://localhost:8000/api/mongodb
```

A JSON answer means the credentials, the client and the route all work. Delete the route afterwards if the app does not need it.

## Pitfalls

- Call `get_default_database()` with no name: the user in `MONGODB_URI` is scoped to the database in the string.
- Create the client once per process, as here; PyMongo pools connections inside it.
- A blocking client (`boto3`, `stripe`) belongs in a plain `def` route, which FastAPI runs in a threadpool; in `async def` it stalls every other request.
- With `uv`, `uv add` the same packages instead of `pip install`.
- Exit code 3 means the account is past its free allowance: show the human the link the command printed and wait. Do not retry or work around it.

Docs: https://extraorbital.dev/docs/resources/mongo.md
