OpenFrame Microservice Suite — MongoDB document store adapter.
Project description
openframe-adapters-db-mongo
MongoDB document store adapter for the OpenFrame Microservice Suite.
Part of the openframe-adapters monorepo. Implements BaseRepository[T] and
HealthCheck from openframe-core using motor (AsyncIOMotorClient).
Installation
pip install openframe-adapters-db-mongo
Required env vars:
MONGO_URL=mongodb://user:password@host:27017
MONGO_DATABASE=mydb
Atlas SRV URIs work too:
MONGO_URL=mongodb+srv://user:password@cluster.mongodb.net
Quick start
Raw dict mode
from openframe.adapters.db.mongo import MongoSettings, MongoRepository
settings = MongoSettings() # reads MONGO_URL and MONGO_DATABASE from env
repo = MongoRepository(settings, collection="artifacts")
doc = await repo.get("507f1f77bcf86cd799439011") # dict | None
docs, total = await repo.list(10, 0) # ([dict, ...], int)
created = await repo.create({"title": "paper"})
updated = await repo.update({"_id": "...", "title": "updated"})
deleted = await repo.delete("507f1f77bcf86cd799439011") # bool
Typed domain mode
from dataclasses import dataclass
from openframe.adapters.db.mongo import MongoSettings, MongoRepository
@dataclass
class Artifact:
id: str
title: str
artifact_type: str
class ArtifactRepository(MongoRepository[Artifact]):
_collection = "artifacts"
def _doc_to_entity(self, doc: dict) -> Artifact:
return Artifact(
id=doc["_id"],
title=doc["title"],
artifact_type=doc["artifact_type"],
)
def _entity_to_doc(self, entity: Artifact) -> dict:
return {
"_id": entity.id,
"title": entity.title,
"artifact_type": entity.artifact_type,
}
settings = MongoSettings()
repo = ArtifactRepository(settings)
artifact: Artifact | None = await repo.get("507f1f77bcf86cd799439011")
_id handling
MongoDB uses _id as the document identifier; BaseRepository uses
entity_id: str. The adapter bridges this transparently:
- Reading:
_idis always returned asstr—ObjectIdis never exposed to callers. A convenienceidkey is also added mirroring_id. - Writing: If an entity dict has an
idkey but no_idkey, the adapter mapsid→_idbefore insertion. - Filtering: String entity IDs that are valid 24-char hex are parsed
as
ObjectIdfor indexed lookups; other strings are used as plain string_idvalues.
Configuration
All settings are read from environment variables.
| Env var | Type | Default | Description |
|---|---|---|---|
MONGO_URL |
str |
required | Motor/pymongo connection string |
MONGO_DATABASE |
str |
required | Database name |
MONGO_MIN_POOL_SIZE |
int |
5 |
Minimum pool connections |
MONGO_MAX_POOL_SIZE |
int |
20 |
Maximum pool connections |
MONGO_SERVER_SELECTION_TIMEOUT_MS |
int |
5000 |
Server selection timeout (ms) |
MONGO_TLS |
bool |
False |
Enable TLS/SSL |
MONGO_TLS_ALLOW_INVALID_CERTS |
bool |
False |
Skip cert validation (dev only) |
CONNECTION_TIMEOUT |
float |
30.0 |
Pool creation timeout (s) |
OPERATION_TIMEOUT |
float |
10.0 |
Per-operation timeout (s) |
MAX_RETRIES |
int |
3 |
Max retry attempts |
Timeout strategy
Two layers of timeout on every operation:
asyncio.timeout(settings.operation_timeout)— cancels the Python coroutine.max_time_ms=int(settings.operation_timeout * 1000)passed to motor query methods — instructs the MongoDB server to abort the query.
Health checks
MongoRepository implements the HealthCheck protocol from openframe-core.
alive = await repo.ping() # admin.command("ping") — fast liveness check
ready = await repo.is_ready() # list_collection_names() — full readiness check
Both methods return False on any failure and never raise.
Exception hierarchy
All exceptions are AdapterError subclasses from openframe.core.exceptions.
Raw motor/pymongo exceptions never escape the adapter.
| Situation | Exception |
|---|---|
| Cannot connect to MongoDB | AdapterConnectionError |
Invalid MONGO_URL syntax |
AdapterConfigurationError |
| Query failed (constraint, auth, etc.) | AdapterQueryError |
| Operation exceeded timeout | AdapterTimeoutError |
Development
# from the package directory
pip install -e ".[dev]"
pytest tests/ -v
Protocol conformance
from openframe.core.ports import BaseRepository
from openframe.core.health import HealthCheck
repo = MongoRepository(settings, collection="artifacts")
assert isinstance(repo, BaseRepository) # True — structural check
assert isinstance(repo, HealthCheck) # True — structural check
No inheritance from either Protocol is required or used.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openframe_adapters_db_mongo-1.0.0.tar.gz.
File metadata
- Download URL: openframe_adapters_db_mongo-1.0.0.tar.gz
- Upload date:
- Size: 14.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
deacbb679b7fec3218b883644b42d000882d8a40af6c4ad5c5de8d3f2c692124
|
|
| MD5 |
8150eb48fbddb1bcb8d2d1120584516f
|
|
| BLAKE2b-256 |
c423c9c31fcc87c4d024e7d36e6b9f7cb1c7179268ede6fe2e97369a8de99985
|
File details
Details for the file openframe_adapters_db_mongo-1.0.0-py3-none-any.whl.
File metadata
- Download URL: openframe_adapters_db_mongo-1.0.0-py3-none-any.whl
- Upload date:
- Size: 11.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ddf5e2341be6409c915ed17522fa3bf800fac5827da677c60bdb046bb376b6d3
|
|
| MD5 |
ca34b0a53532616275eb8351beb94422
|
|
| BLAKE2b-256 |
cc0b8d8b9467a3972c8e1f5a545960d6504c99906200dda728585539de465876
|