API Reference
This page provides detailed documentation for all LightODM classes and functions.
Core Classes
MongoBaseModel
- class lightodm.MongoBaseModel(*, _id: str | None = <factory>, **extra_data: Any)[source]
Bases:
BaseModelBase class for MongoDB document models with ODM functionality.
Provides both synchronous and asynchronous methods for CRUD operations. Maps Pydantic ‘id’ field to MongoDB ‘_id’ field.
Subclasses must define an inner Settings class with ‘name’ attribute:
Example
- class User(MongoBaseModel):
- class Settings:
name = “users”
name: str email: str age: Optional[int] = None
# Sync usage user = User(name=”John”, email=”john@example.com”) user.save()
found_user = User.get(“some_id”) users = User.find({“age”: {“$gt”: 18}})
# Async usage await user.asave() found_user = await User.aget(“some_id”) users = await User.afind({“age”: {“$gt”: 18}})
Base class for MongoDB document models with ODM functionality.
Settings Class
Every model must define an inner
Settingsclass with the following attribute:Field Mapping
- id: str | None
Document ID that maps to MongoDB
_idfield. Auto-generated using ObjectId if not provided.
Synchronous CRUD Methods
- save(exclude_none: bool = False) str[source]
Save/upsert the document (synchronous).
- Parameters:
exclude_none – If True, exclude fields with None values from update
- Returns:
Document ID
- delete() bool[source]
Delete the document (synchronous).
- Returns:
True if document was deleted, False otherwise
- classmethod get(id: str) T | None[source]
Retrieve a document by ID (synchronous).
- Parameters:
id – Document ID
- Returns:
Model instance or None if not found
- classmethod find_one(filter: dict, **kwargs) T | None[source]
Find a single document (synchronous).
- Parameters:
filter – MongoDB filter dictionary
**kwargs – Additional arguments passed to find_one (e.g., sort, projection)
- Returns:
Model instance or None if not found
- classmethod find(filter: dict, **kwargs) List[T][source]
Find multiple documents (synchronous).
- Parameters:
filter – MongoDB filter dictionary
**kwargs – Additional arguments passed to find (e.g., sort, limit, skip, projection)
- Returns:
List of model instances
- classmethod find_iter(filter: dict, **kwargs) Iterator[T][source]
Find multiple documents with iterator (synchronous). Useful for large result sets to avoid loading all into memory.
- Parameters:
filter – MongoDB filter dictionary
**kwargs – Additional arguments passed to find
- Yields:
Model instances one at a time
- classmethod count(filter: dict = None) int[source]
Count documents matching filter (synchronous).
- Parameters:
filter – MongoDB filter dictionary (default: {} for all documents)
- Returns:
Number of matching documents
- classmethod update_one(filter: dict, update: dict, upsert: bool = False) bool[source]
Update a single document (synchronous).
- Parameters:
filter – MongoDB filter dictionary
update – MongoDB update dictionary (should include operators like $set)
upsert – If True, insert document if not found
- Returns:
True if document was modified, False otherwise
- classmethod update_many(filter: dict, update: dict) int[source]
Update multiple documents (synchronous).
- Parameters:
filter – MongoDB filter dictionary
update – MongoDB update dictionary (should include operators like $set)
- Returns:
Number of documents modified
- classmethod delete_one(filter: dict) bool[source]
Delete a single document (synchronous).
- Parameters:
filter – MongoDB filter dictionary
- Returns:
True if document was deleted, False otherwise
- classmethod delete_many(filter: dict) int[source]
Delete multiple documents (synchronous).
- Parameters:
filter – MongoDB filter dictionary
- Returns:
Number of documents deleted
- classmethod aggregate(pipeline: List[dict], **kwargs) List[dict][source]
Run aggregation pipeline (synchronous).
- Parameters:
pipeline – MongoDB aggregation pipeline
**kwargs – Additional arguments passed to aggregate
- Returns:
List of result documents
- classmethod insert_many(documents: List[T]) List[str][source]
Insert multiple documents (synchronous).
- Parameters:
documents – List of model instances
- Returns:
List of inserted document IDs
Asynchronous CRUD Methods
- async asave(exclude_none: bool = False) str[source]
Save/upsert the document (asynchronous).
- Parameters:
exclude_none – If True, exclude fields with None values from update
- Returns:
Document ID
- async adelete() bool[source]
Delete the document (asynchronous).
- Returns:
True if document was deleted, False otherwise
- async classmethod aget(id: str) T | None[source]
Retrieve a document by ID (asynchronous).
- Parameters:
id – Document ID
- Returns:
Model instance or None if not found
- async classmethod afind_one(filter: dict, **kwargs) T | None[source]
Find a single document (asynchronous).
- Parameters:
filter – MongoDB filter dictionary
**kwargs – Additional arguments passed to find_one (e.g., sort, projection)
- Returns:
Model instance or None if not found
- async classmethod afind(filter: dict, **kwargs) List[T][source]
Find multiple documents (asynchronous).
- Parameters:
filter – MongoDB filter dictionary
**kwargs – Additional arguments passed to find (e.g., sort, limit, skip, projection)
- Returns:
List of model instances
- classmethod afind_iter(filter: dict, **kwargs) AsyncIterator[T][source]
Find multiple documents with async iterator. Useful for large result sets to avoid loading all into memory.
- Parameters:
filter – MongoDB filter dictionary
**kwargs – Additional arguments passed to find
- Yields:
Model instances one at a time
- async classmethod acount(filter: dict = None) int[source]
Count documents matching filter (asynchronous).
- Parameters:
filter – MongoDB filter dictionary (default: {} for all documents)
- Returns:
Number of matching documents
- async classmethod aupdate_one(filter: dict, update: dict, upsert: bool = False) bool[source]
Update a single document (asynchronous).
- Parameters:
filter – MongoDB filter dictionary
update – MongoDB update dictionary (should include operators like $set)
upsert – If True, insert document if not found
- Returns:
True if document was modified, False otherwise
- async classmethod aupdate_many(filter: dict, update: dict) int[source]
Update multiple documents (asynchronous).
- Parameters:
filter – MongoDB filter dictionary
update – MongoDB update dictionary (should include operators like $set)
- Returns:
Number of documents modified
- async classmethod adelete_one(filter: dict) bool[source]
Delete a single document (asynchronous).
- Parameters:
filter – MongoDB filter dictionary
- Returns:
True if document was deleted, False otherwise
- async classmethod adelete_many(filter: dict) int[source]
Delete multiple documents (asynchronous).
- Parameters:
filter – MongoDB filter dictionary
- Returns:
Number of documents deleted
- async classmethod aaggregate(pipeline: List[dict], **kwargs) List[dict][source]
Run aggregation pipeline (asynchronous).
- Parameters:
pipeline – MongoDB aggregation pipeline
**kwargs – Additional arguments passed to aggregate
- Returns:
List of result documents
- async classmethod ainsert_many(documents: List[T]) List[str][source]
Insert multiple documents (asynchronous).
- Parameters:
documents – List of model instances
- Returns:
List of inserted document IDs
Collection Access Methods
- classmethod get_collection() Collection[source]
Get synchronous MongoDB collection.
Override this method to provide custom connection logic.
- Returns:
PyMongo Collection instance
- async classmethod get_async_collection() AsyncIOMotorCollection[source]
Get asynchronous MongoDB collection.
Override this method to provide custom connection logic.
- Returns:
Motor AsyncIOMotorCollection instance
Internal Methods
- _to_mongo_dict(exclude_none: bool = False) dict[source]
Convert model to dictionary for MongoDB, handling id -> _id mapping.
Only serializes Pydantic fields - class attributes like collection_name are automatically excluded.
- Parameters:
exclude_none – If True, exclude fields with None values
- Returns:
Dictionary suitable for MongoDB insertion/update
Connection Management
MongoConnection
- class lightodm.MongoConnection[source]
Bases:
objectSingleton MongoDB connection manager supporting both sync (pymongo) and async (motor) clients with thread-safety.
The connection is configured via environment variables: - MONGO_URL: MongoDB connection URL - MONGO_USER: MongoDB username - MONGO_PASSWORD: MongoDB password - MONGO_DB_NAME: Database name
Example
# Sync usage conn = MongoConnection() db = conn.database collection = conn.get_collection(“users”)
# Async usage conn = MongoConnection() client = await conn.get_async_client() db = await conn.get_async_database()
Singleton MongoDB connection manager supporting both sync and async clients.
Properties
- property client: MongoClient
Get the synchronous MongoDB client
- property database: Database
Get the synchronous MongoDB database
Methods
- get_collection(collection_name: str) Collection[source]
Get a synchronous collection.
- Parameters:
collection_name – Name of the collection
- Returns:
PyMongo Collection instance
- async get_async_client() AsyncIOMotorClient[source]
Get or create the AsyncIOMotorClient and verify connectivity asynchronously.
- Returns:
Motor AsyncIOMotorClient instance
Helper Functions
connect()
- lightodm.connect(url: str | None = None, username: str | None = None, password: str | None = None, db_name: str | None = None) Database[source]
Initialize MongoDB connection with optional explicit parameters.
If parameters are not provided, they will be read from environment variables:
MONGO_URL
MONGO_USER
MONGO_PASSWORD
MONGO_DB_NAME
- Parameters:
url – MongoDB connection URL (optional)
username – MongoDB username (optional)
password – MongoDB password (optional)
db_name – Database name (optional)
- Returns:
PyMongo Database instance
Example:
# Connect with explicit parameters db = connect( url="mongodb://localhost:27017", username="myuser", password="mypass", db_name="mydb" ) # Or use environment variables db = connect()
Convenience function to initialize MongoDB connection with the singleton pattern.
- Parameters:
- Returns:
MongoDB database instance
- Return type:
pymongo.database.Database
Environment Variables
If parameters are not provided, the function will attempt to read from environment variables:
MONGO_URL: MongoDB connection URLMONGO_USER: MongoDB usernameMONGO_PASSWORD: MongoDB passwordMONGO_DB_NAME: Default database name
Example
from lightodm import connect, MongoBaseModel # Connect explicitly connect( url="mongodb://localhost:27017", username="myuser", password="mypass", db_name="mydb" ) # Or using environment variables # MONGO_URL=mongodb://localhost:27017 # MONGO_USER=myuser # MONGO_PASSWORD=mypass # MONGO_DB_NAME=mydb connect()
generate_id()
- lightodm.generate_id() str[source]
Generate a new MongoDB ObjectId as a string.
- Returns:
String representation of a new ObjectId
Generate a unique ID for MongoDB documents.
- Parameters:
\**kwargs (dict) – Optional keyword arguments to generate deterministic hash-based ID
- Returns:
Unique ID string (ObjectId or MD5 hash)
- Return type:
Behavior
If called without arguments: Returns a new ObjectId string
If called with keyword arguments: Returns MD5 hash of sorted key-value pairs (deterministic)
Example
from lightodm import generate_id # Random ObjectId id1 = generate_id() # '507f1f77bcf86cd799439011' # Deterministic hash-based ID id2 = generate_id(user_id="123", type="profile") id3 = generate_id(type="profile", user_id="123") assert id2 == id3 # Same hash for same inputs
Type Definitions
Collection Types
LightODM uses the following collection types from PyMongo and Motor:
- class motor.motor_asyncio.AsyncIOMotorCollection
Asynchronous MongoDB collection (from Motor).
TypeVar
- lightodm.T: TypeVar
Type variable bound to
MongoBaseModelfor generic class methods.Used internally for type hinting to ensure methods return instances of the correct model class.
Configuration
Model Configuration
LightODM models use Pydantic v2’s model_config with the following settings:
from pydantic import ConfigDict
model_config = ConfigDict(
populate_by_name=True, # Allow field population by alias
extra='allow' # Allow extra fields beyond model definition
)
- populate_by_name
Enables using either the field name or alias (
_id/id) when creating models.- extra=’allow’
Allows storing arbitrary extra fields on the model. Extra fields are preserved when saving to MongoDB.
Environment Variables
The following environment variables are recognized by MongoConnection and connect():
- MONGO_URL
MongoDB connection URL.
Example:
mongodb://localhost:27017
- MONGO_USER
MongoDB username for authentication.
- MONGO_PASSWORD
MongoDB password for authentication.
- MONGO_DB_NAME
Default database name to use.
Exceptions
LightODM raises the following exceptions:
NotImplementedError
Raised when:
A model doesn’t define a
SettingsclassSettings.nameis not definedget_collection()orget_async_collection()is not implemented
ValueError
Raised when:
Attempting to save a document without an ID
MongoDB connection parameters are missing
PyMongo Exceptions
LightODM also propagates exceptions from PyMongo and Motor. Common ones include:
pymongo.errors.ConnectionFailure: Cannot connect to MongoDBpymongo.errors.OperationFailure: MongoDB operation failedpymongo.errors.DuplicateKeyError: Unique constraint violation
See PyMongo documentation for complete exception reference.
Usage Patterns
Bring Your Own Connection (BYOC)
For advanced use cases, override collection methods to use custom connection logic:
from lightodm import MongoBaseModel
from pymongo import MongoClient
from motor.motor_asyncio import AsyncIOMotorClient
# Global connection instances
sync_client = MongoClient("mongodb://localhost:27017")
async_client = AsyncIOMotorClient("mongodb://localhost:27017")
db_name = "myapp"
class User(MongoBaseModel):
class Settings:
name = "users"
name: str
email: str
@classmethod
def get_collection(cls):
return sync_client[db_name][cls.Settings.name]
@classmethod
async def get_async_collection(cls):
return async_client[db_name][cls.Settings.name]
Thread Safety
MongoConnection is thread-safe and uses a singleton pattern with locking:
from concurrent.futures import ThreadPoolExecutor
from lightodm import connect, MongoBaseModel
connect() # Initialize once
class User(MongoBaseModel):
class Settings:
name = "users"
name: str
def save_user(i):
user = User(name=f"User {i}")
user.save()
# Safe to use from multiple threads
with ThreadPoolExecutor(max_workers=10) as executor:
executor.map(save_user, range(100))
Async Context
Always use async methods in async contexts:
import asyncio
from lightodm import MongoBaseModel
class User(MongoBaseModel):
class Settings:
name = "users"
name: str
async def main():
# Use async methods
user = User(name="Async User")
await user.asave()
users = await User.afind({})
async for user in User.afind_iter({}):
print(user.name)
asyncio.run(main())