Library Overview
mongo-ops gives FastAPI/microservice teams a small, opinionated toolkit for talking to MongoDB asynchronously. This page builds the mental model: what the layers are, in what order they must be wired up, and which repository to reach for.
ποΈ Architecture
Text Only
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Application (FastAPI) β
β βββββββββββββββ¬ββββββββββββββββ¬ββββββββββββββββ¬ββββββββββ β
β β CachedBase β Populating β BaseRepositoryβ Raw β β
β β Repository β Repository β (CRUDMixin) β Motor β β
β ββββββββ¬βββββββ΄ββββββββ¬ββββββββ΄ββββββββ¬ββββββββ΄ββββββββββ β
β β β β β
β ββββββββ΄βββββββ ββββββ΄βββββββ βββββββ΄ββββββββββββββββββ β
β β Cache backendβ β Populationβ β TransactionManager β β
β β memory/redis β β Engine β β (session helpers) β β
β ββββββββ¬βββββββ ββββββ¬βββββββ βββββββββββ¬ββββββββββββββ β
β ββββββββ΄βββββββββββββββββββββββββββββββββββ΄ββββββββββββββ β
β β ModelRegistry (models, indexes, cache lifecycle) β β
β ββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββββββββ΄ββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β MongoConnectionManager (Motor client + database) β β
β ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββ
βΌ
MongoDB (Motor / PyMongo)
The layers build on each other:
- Connection β
MongoConnectionManagerowns the Motor client and active database. - Models β
BaseDocument(Pydantic v2) gives every documentid(aliased_id) pluscreated_at/updated_at. - CRUD β
CRUDMixin/BaseRepositoryimplement generic async CRUD against a collection. - Startup β
ModelRegistrycentralizes model + index registration and cache lifecycle for multi-collection services. - Advanced layers β caching and population compose around a repository:
CachedBaseRepositorywrapsBaseRepositorywith aCacheBackend.PopulatingRepositorywrapsBaseRepositorywith aPopulationEngine.- Transactions β
TransactionManagerruns a list of async operations atomically on a session.
π Lifecycle Rules
mongo-ops has a strict startup order. Violating it raises fast, loud exceptions:
| Step | Call | Why |
|---|---|---|
| 1 | await MongoConnectionManager.connect(uri, db_name) |
Without a connection, get_database()/get_client() raise RuntimeError("Database not connected..."). |
| 2 | await ModelRegistry.initialize_all() |
Create registered indexes (idempotent via create_index). |
| 3 | await ModelRegistry.set_cache_backend(...) then await ModelRegistry.initialize_cache() |
Must happen after connection, before any cache-backed operation. Raises RuntimeError("No cache backend registered...") if skipped. |
| 4 | Use repositories | Constructed repos resolve the collection from the live database. |
| 5 | await ModelRegistry.shutdown_cache() + await MongoConnectionManager.disconnect() |
On shutdown (in-memory TTL task cancelled; Redis pub/sub closed). |
The canonical wiring is the FastAPI lifespan context manager (see use case 01).
π§ Which Repository Should You Use?
| Repository | Use when | Adds |
|---|---|---|
BaseRepository[T] |
Plain CRUD β the default | nothing extra |
CachedBaseRepository[T] |
Readβheavy, lowβwrite fields (lookups by _id) |
cacheβfirst get_by_id, cache on create, invalidate on update/delete, warm_cache |
PopulatingRepository[T] |
You return related docs (FK references) denormalized | _populate on read, _depopulate on write, FKβguarded patch |
CRUDMixin |
Reusing CRUD inside an existing class | raw CRUD against a collection you already have |
There is no builtβin
CachedPopulatingRepository. Use case 10 shows how to compose caching + population in a small subclass.
β‘οΈ Read Next
- Core Components β the validated public API surface.
- Use case 01 β the minimal FastAPI app.
- Best Practices β team-wide conventions.