### Install pydantic-mongo Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/quickstart.md Installs the pydantic-mongo library using pip. This is the first step to using the library in your Python project. ```bash pip install pydantic-mongo ``` -------------------------------- ### Async Repository Setup and Usage in Python Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/examples/async_support.md Demonstrates setting up an asynchronous repository with pydantic-mongo to interact with MongoDB. It includes defining a Pydantic model, initializing an AsyncMongoClient, creating a repository instance, and asynchronous examples for saving and finding user data. Dependencies include pymongo and pydantic-mongo. ```python from pymongo import AsyncMongoClient from pydantic import BaseModel from pydantic_mongo import AsyncAbstractRepository class User(BaseModel): id: str name: str email: str class UserRepository(AsyncAbstractRepository[User]): class Meta: collection_name = 'users' # Initialize database connection client = AsyncMongoClient('mongodb://localhost:27017') database = client["mydb"] # Create repository instance user_repo = UserRepository(database) # Example usage async def create_user(): user = User(name='John Doe', email='john@example.com') await user_repo.save(user) async def find_user(user_id: str): user = await user_repo.find_one_by_id(user_id) return user ``` -------------------------------- ### Paginate Query Results with Pydantic-Mongo Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/quickstart.md Illustrates how to implement pagination for MongoDB queries using pydantic-mongo. Allows fetching data in batches and navigating through pages using cursors. ```python # Get first page edges = repo.paginate({"status": "active"}, limit=10) # Get next page using the last cursor next_edges = repo.paginate( {"status": "active"}, limit=10, after=list(edges)[-1].cursor ) ``` -------------------------------- ### Delete Documents with Pydantic-Mongo Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/quickstart.md Demonstrates methods for removing documents from a MongoDB collection using pydantic-mongo. Supports deletion by model instance and by document ID. ```python # Delete by model instance repo.delete(user) # Delete by ID repo.delete_by_id(ObjectId("...")) ``` -------------------------------- ### Query Documents with Pydantic-Mongo Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/quickstart.md Shows how to retrieve documents from a MongoDB collection using pydantic-mongo. Supports finding documents by their unique ObjectId and by custom query filters. ```python # Find by ID user = repo.find_one_by_id(ObjectId("...")) # Find by query active_users = repo.find_by({"status": "active"}) ``` -------------------------------- ### Create and Save User Document with Pydantic-Mongo Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/quickstart.md Demonstrates how to define a Pydantic model for a user and save it to a MongoDB collection using pydantic-mongo's AbstractRepository. The 'id' field is automatically populated with an ObjectId upon saving. ```python from bson import ObjectId from pydantic import BaseModel from pydantic_mongo import AbstractRepository, PydanticObjectId class User(BaseModel): id: PydanticObjectId = None name: str email: str class UserRepository(AbstractRepository[User]): class Meta: collection_name = 'users' # Create a new user user = User(name="John Doe", email="john@example.com") repo.save(user) # user.id is now set to an ObjectId ``` -------------------------------- ### Define Async Repository with Pydantic Model Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/async_abstract_repository.md Example of defining a custom asynchronous repository for a Pydantic model. It requires specifying the collection name in an inner Meta class and takes an AsyncDatabase instance for operations. ```python from pydantic_mongo import AsyncAbstractRepository from pymongo.asynchronous.database import AsyncDatabase from pydantic import BaseModel class User(BaseModel): id: int name: str class UserRepository(AsyncAbstractRepository[User]): class Meta: collection_name = 'users' # Usage: # database: AsyncDatabase = ... # Initialize your async database connection # repo = UserRepository(database) # user = await repo.find_one_by_id(user_id) ``` -------------------------------- ### Delete MongoDB Documents with Pydantic Mongo (Python) Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/README.md Provides examples of deleting documents from MongoDB using Pydantic Mongo. It covers deleting a document by passing the Pydantic model instance and deleting a document by its ObjectId. ```python # Delete a document repo.delete(spam) # Delete by ID repo.delete_by_id(ObjectId("...")) ``` -------------------------------- ### Get MongoDB Collection (Python) Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/abstract_repository.md Provides direct access to the underlying PyMongo Collection object associated with the repository. This allows for more advanced or custom operations that might not be covered by the repository's higher-level methods. ```python collection = repo.get_collection() ``` -------------------------------- ### Get Collection Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/async_abstract_repository.md Retrieves the underlying asynchronous MongoDB collection object associated with the repository. ```APIDOC ## get_collection ### Description Get the MongoDB collection associated with this repository. ### Method GET ### Endpoint /collection (example endpoint, actual endpoint depends on repository setup) ### Response #### Success Response (200) - **AsyncCollection** (object) - PyMongo AsyncCollection instance #### Response Example ```json { "name": "users", "database": "mydatabase" } ``` ``` -------------------------------- ### AbstractRepository Methods Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/abstract_repository.md This section details the core methods of the AbstractRepository for interacting with MongoDB. ```APIDOC ## AbstractRepository ### Description A synchronous repository implementation for MongoDB using Pydantic models. This class provides a high-level interface for performing CRUD operations on MongoDB collections using Pydantic models for type safety and data validation. **Generic type T must be a Pydantic model with an ‘id’ field.** ### Methods #### delete(model: T) **Description:** Delete a model instance from the database. **Method:** POST (assumed, as it modifies data) **Endpoint:** `/repository/{collection_name}` (inferred, requires model instance) **Parameters:** #### Request Body - **model** (T) - Required - The model instance to delete #### Response Success Response (200) - **result** (DeleteResult) - The result of the delete operation #### delete_by_id(_id: Any) **Description:** Delete a model instance from the database by its ID. **Method:** DELETE (assumed) **Endpoint:** `/repository/{collection_name}/{_id}` **Parameters:** #### Path Parameters - **_id** (Any) - Required - The ID of the model instance to delete #### Response Success Response (200) - **result** (DeleteResult) - The result of the delete operation #### find_by(query: dict, skip: int | None = None, limit: int | None = None, sort: Sequence[Tuple[str, int]] | None = None, projection: Dict[str, int] | None = None) → Iterable[T] **Description:** Find multiple model instances by a MongoDB query. **Method:** GET (assumed) **Endpoint:** `/repository/{collection_name}/find` **Parameters:** #### Query Parameters - **query** (dict) - Required - MongoDB query dictionary - **skip** (int | None) - Optional - Number of documents to skip - **limit** (int | None) - Optional - Maximum number of documents to return - **sort** (Sequence[Tuple[str, int]] | None) - Optional - List of (field, direction) tuples for sorting - **projection** (Dict[str, int] | None) - Optional - MongoDB projection dictionary #### Response Success Response (200) - **documents** (Iterable[T]) - Iterator of model instances #### find_by_with_output_type(output_type: Type[OutputT], query: dict, skip: int | None = None, limit: int | None = None, sort: Sequence[Tuple[str, int]] | None = None, projection: Dict[str, int] | None = None) → Iterable[OutputT] **Description:** Find multiple model instances with custom output type. This method allows querying with a different output model than the repository’s base model type, useful for projections and transformations. **Method:** GET (assumed) **Endpoint:** `/repository/{collection_name}/find_with_output` **Parameters:** #### Query Parameters - **output_type** (Type[OutputT]) - Required - The Pydantic model class for the output - **query** (dict) - Required - MongoDB query dictionary - **skip** (int | None) - Optional - Number of documents to skip - **limit** (int | None) - Optional - Maximum number of documents to return - **sort** (Sequence[Tuple[str, int]] | None) - Optional - List of (field, direction) tuples for sorting - **projection** (Dict[str, int] | None) - Optional - MongoDB projection dictionary #### Response Success Response (200) - **documents** (Iterable[OutputT]) - Iterator of model instances of the specified output type ### Inner Class: Meta #### collection_name *: str **Description:** Specifies the name of the MongoDB collection to use for this repository. ``` -------------------------------- ### Define Pydantic Mongo Repository in Python Source: https://context7.com/jefersondaniel/pydantic-mongo/llms.txt Demonstrates how to define a custom repository by subclassing AbstractRepository and defining a Meta class with the collection name. It includes Pydantic model definitions and repository initialization. ```python from bson import ObjectId from pydantic import BaseModel from pydantic_mongo import AbstractRepository, PydanticObjectId from pymongo import MongoClient from typing import Optional, List # Define your Pydantic models class Foo(BaseModel): count: int size: float = None class Bar(BaseModel): apple: str = 'x' banana: str = 'y' class Spam(BaseModel): id: Optional[PydanticObjectId] = None foo: Foo bars: List[Bar] # Create a repository class class SpamRepository(AbstractRepository[Spam]): class Meta: collection_name = 'spams' # Initialize database connection and repository client = MongoClient("mongodb://localhost:27017") database = client["example_db"] repo = SpamRepository(database) ``` -------------------------------- ### Paginate Model Instances (Python) Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/abstract_repository.md Implements cursor-based pagination to iterate through model instances. This method is efficient for large datasets and supports fetching pages forward or backward using cursors. It requires a query, a limit, and optionally 'after' or 'before' cursors, and sorting parameters. ```python edges = repo.paginate({"status": "active"}, limit=10) next_edges = repo.paginate( {"status": "active"}, limit=10, after=list(edges)[-1].cursor ) ``` -------------------------------- ### Get MongoDB AsyncCollection Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/async_abstract_repository.md Retrieves the PyMongo AsyncCollection instance associated with the repository. This provides direct access to the underlying asynchronous MongoDB collection for advanced operations not covered by the repository's high-level methods. ```python def get_collection(self) -> AsyncCollection: """Get the MongoDB collection associated with this repository. Returns: PyMongo AsyncCollection instance """ # Implementation details omitted for brevity pass ``` -------------------------------- ### Create and Save MongoDB Documents with Pydantic Mongo (Python) Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/README.md Demonstrates how to create Pydantic model instances (Spam) and save them to MongoDB using the Pydantic Mongo repository. It covers saving a single document and multiple documents, including one with a predefined ObjectId. ```python # Create a new document spam = Spam(foo=Foo(count=1, size=1.0), bars=[Bar()]) # Create a document with predefined ID spam_with_predefined_id = Spam( id=ObjectId("611827f2878b88b49ebb69fc"), foo=Foo(count=2, size=2.0), bars=[Bar()] ) # Save a single document repo.save(spam) # spam.id is now set to an ObjectId # Save multiple documents repo.save_many([spam, spam_with_predefined_id]) ``` -------------------------------- ### Asynchronous MongoDB Operations with Pydantic Mongo (Python) Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/README.md Demonstrates the asynchronous capabilities of Pydantic Mongo using `AsyncAbstractRepository`. It shows how to define an asynchronous repository, connect to MongoDB asynchronously, and perform basic CRUD operations like saving and finding documents using async/await. ```python from pymongo import AsyncMongoClient from pydantic import BaseModel from pydantic_mongo import AsyncAbstractRepository class User(BaseModel): id: str name: str email: str class UserRepository(AsyncAbstractRepository[User]): class Meta: collection_name = 'users' # Initialize database connection client = AsyncMongoClient('mongodb://localhost:27017') database = client["mydb"] # Create repository instance user_repo = UserRepository(database) # Example usage user = User(name='John Doe', email='john@example.com') await user_repo.save(user) user = await user_repo.find_one_by_id(user_id) ``` -------------------------------- ### Repository Definition Source: https://context7.com/jefersondaniel/pydantic-mongo/llms.txt This section demonstrates how to define a custom repository by subclassing AbstractRepository and setting up the Meta class with the collection name. It also shows how to define Pydantic models for your data. ```APIDOC ## Defining a Repository Create a custom repository by subclassing AbstractRepository and defining a Meta class with the collection name. ### Example ```python from bson import ObjectId from pydantic import BaseModel from pydantic_mongo import AbstractRepository, PydanticObjectId from pymongo import MongoClient from typing import Optional, List # Define your Pydantic models class Foo(BaseModel): count: int size: float = None class Bar(BaseModel): apple: str = 'x' banana: str = 'y' class Spam(BaseModel): id: Optional[PydanticObjectId] = None foo: Foo bars: List[Bar] # Create a repository class class SpamRepository(AbstractRepository[Spam]): class Meta: collection_name = 'spams' # Initialize database connection and repository client = MongoClient("mongodb://localhost:27017") database = client["example_db"] repo = SpamRepository(database) ``` ``` -------------------------------- ### Paginate Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/async_abstract_repository.md Asynchronously paginate through model instances using cursor-based pagination for efficient data retrieval. ```APIDOC ## async paginate ### Description Asynchronously paginate through model instances using cursor-based pagination. This method implements cursor-based pagination which is more reliable than offset-based pagination for large datasets. ### Method POST (assumed, as it retrieves paginated data based on query and cursors) ### Endpoint /items/paginate (example endpoint, actual endpoint depends on repository setup) ### Parameters #### Query Parameters - **query** (dict) - Required - MongoDB query dictionary - **limit** (int) - Required - Maximum number of documents per page - **after** (str | None) - Optional - Cursor string for fetching next page - **before** (str | None) - Optional - Cursor string for fetching previous page - **sort** (Sequence[Tuple[str, int]] | None) - Optional - List of (field, direction) tuples for sorting - **projection** (Dict[str, int] | None) - Optional - MongoDB projection dictionary ### Request Example ```json { "query": {"status": "active"}, "limit": 10, "after": "some_cursor_string" } ``` ### Response #### Success Response (200) - **Iterable[Edge[T]]** (array) - Iterator of Edge objects containing model instances and pagination cursors #### Response Example ```json [ { "node": { "_id": "60f7b3b3b3b3b3b3b3b3b3b3", "name": "Alice", "status": "active" }, "cursor": "cursor_for_alice" }, { "node": { "_id": "60f7b3b3b3b3b3b3b3b3b3b4", "name": "Bob", "status": "active" }, "cursor": "cursor_for_bob" } ] ``` ``` -------------------------------- ### Paginate MongoDB documents with pydantic-mongo Source: https://context7.com/jefersondaniel/pydantic-mongo/llms.txt Demonstrates how to paginate through MongoDB documents using cursor-based pagination with 'after' and 'before' parameters. It also shows how to perform complex queries for pagination. Requires a configured repository and collection. ```python from pydantic_mongo import ASCENDING # Get next page using the last cursor if edges_list: last_cursor = edges_list[-1].cursor next_edges = post_repo.paginate( {"author": "john_doe"}, limit=10, after=last_cursor, sort=[("published_at", ASCENDING)] ) print("\nSecond page:") for edge in next_edges: print(f"Post: {edge.node.title}") # Paginate with complex query popular_posts = post_repo.paginate( {"views": {"$gte": 1000}}, limit=5, sort=[("views", -1), ("_id", 1)] ) # Get previous page using before cursor if edges_list and len(edges_list) > 1: first_cursor = edges_list[0].cursor previous_edges = post_repo.paginate( {"author": "john_doe"}, limit=10, before=first_cursor, sort=[("published_at", ASCENDING)] ) ``` -------------------------------- ### Query with Custom Output Model using Pydantic Mongo Source: https://context7.com/jefersondaniel/pydantic-mongo/llms.txt Illustrates querying MongoDB with a custom Pydantic model for projections using AbstractRepository. Useful for selecting specific fields and transforming data. Requires pymongo and pydantic-mongo. ```python from pydantic import BaseModel from pydantic_mongo import AbstractRepository, PydanticObjectId from pymongo import MongoClient from typing import Optional class User(BaseModel): id: Optional[PydanticObjectId] = None username: str email: str password_hash: str full_name: str age: int address: str class UserSummary(BaseModel): id: Optional[PydanticObjectId] = None username: str email: str class UserRepository(AbstractRepository[User]): class Meta: collection_name = 'users' client = MongoClient("mongodb://localhost:27017") database = client["app_db"] user_repo = UserRepository(database) # Query with custom output type and projection user_summaries = user_repo.find_by_with_output_type( output_type=UserSummary, query={"age": {"$gte": 18}}, projection={"username": 1, "email": 1}, limit=10 ) for summary in user_summaries: print(f"User: {summary.username}, Email: {summary.email}") # Note: password_hash, full_name, age, address are not included # Use with sorting sorted_summaries = user_repo.find_by_with_output_type( output_type=UserSummary, query={"age": {"$lt": 30}}, projection={"username": 1, "email": 1}, sort=[("username", 1)], skip=0, limit=50 ) ``` -------------------------------- ### Implement Pagination with Pydantic Mongo (Python) Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/README.md Shows how to implement cursor-based pagination for MongoDB queries using Pydantic Mongo. It demonstrates fetching the first page of results and then fetching subsequent pages using the cursor from the last item of the previous page. ```python # Get first page edges = repo.paginate({'foo.count': {'$gte': 1}}, limit=10) # Get next page using the last cursor more_edges = repo.paginate( {'foo.count': {'$gte': 1}}, limit=10, after=list(edges)[-1].cursor ) ``` -------------------------------- ### Asynchronously paginate model instances Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/async_abstract_repository.md Asynchronously paginates through Pydantic model instances using cursor-based pagination, which is robust for large datasets. It accepts a query, limit, and optional cursor parameters (after, before) for navigating pages. Sorting and projection are also supported. ```python async def paginate( self, query: dict, limit: int, after: str | None = None, before: str | None = None, sort: Sequence[Tuple[str, int]] | None = None, projection: Dict[str, int] | None = None ) -> Iterable[Edge[T]]: """Asynchronously paginate through model instances using cursor-based pagination. This method implements cursor-based pagination which is more reliable than offset-based pagination for large datasets. Parameters: query: MongoDB query dictionary limit: Maximum number of documents per page after: Cursor string for fetching next page before: Cursor string for fetching previous page sort: List of (field, direction) tuples for sorting projection: MongoDB projection dictionary Returns: Iterator of Edge objects containing model instances and pagination cursors """ # Implementation details omitted for brevity pass ``` -------------------------------- ### Python: AbstractRepository CRUD Operations Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/abstract_repository.md Demonstrates the usage of AbstractRepository for MongoDB operations. Requires a Pydantic model with an 'id' field and a pymongo Database instance. Supports finding, deleting, and custom output types. ```python from pymongo import MongoClient from pymongo.database import Database from typing import Type, Dict, Any, Iterable, Sequence, Tuple from pydantic import BaseModel # Assume Database and DeleteResult are defined elsewhere or imported class Database: pass # Placeholder for pymongo.database.Database class DeleteResult: pass # Placeholder for pymongo.results.DeleteResult class BaseAbstractRepository: pass # Placeholder for Generic type T T = TypeVar('T') OutputT = TypeVar('OutputT') class AbstractRepository(BaseAbstractRepository): def __init__(self, database: Database): self.database = database class Meta: collection_name: str = "" def delete(self, model: T) -> DeleteResult: # Implementation omitted for brevity pass def delete_by_id(self, _id: Any) -> DeleteResult: # Implementation omitted for brevity pass def find_by(self, query: dict, skip: int | None = None, limit: int | None = None, sort: Sequence[Tuple[str, int]] | None = None, projection: Dict[str, int] | None = None) -> Iterable[T]: # Implementation omitted for brevity pass def find_by_with_output_type(self, output_type: Type[OutputT], query: dict, skip: int | None = None, limit: int | None = None, sort: Sequence[Tuple[str, int]] | None = None, projection: Dict[str, int] | None = None) -> Iterable[OutputT]: # Implementation omitted for brevity pass # Example Usage: class User(BaseModel): id: str name: str class UserRepository(AbstractRepository[User]): class Meta: collection_name = 'users' # Assuming 'database' is an instance of pymongo.database.Database # repo = UserRepository(database) # user_id = "some_id" # user = repo.find_one_by_id(user_id) # find_one_by_id is likely a method in the base or an extension ``` -------------------------------- ### Query MongoDB Documents using Pydantic Mongo (Python) Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/README.md Illustrates various methods for querying documents from MongoDB using Pydantic Mongo. This includes finding a document by its ID (both PydanticObjectId and string representations), finding a single document by a custom query, and finding multiple documents based on query criteria. ```python # Find by ID result = repo.find_one_by_id(spam.id) # Find by ID using string result = repo.find_one_by_id(ObjectId('611827f2878b88b49ebb69fc')) assert result.foo.count == 2 # Find one by custom query result = repo.find_one_by({'foo.count': 1}) # Find multiple documents by query results = repo.find_by({'foo.count': {'$gte': 1}}) ``` -------------------------------- ### paginate Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/abstract_repository.md Performs cursor-based pagination through model instances in the MongoDB collection. ```APIDOC ## POST /paginate ### Description Paginate through model instances using cursor-based pagination. This method implements cursor-based pagination which is more reliable than offset-based pagination for large datasets. ### Method POST ### Endpoint /paginate ### Parameters #### Request Body - **query** (dict) - Required - MongoDB query dictionary - **limit** (int) - Required - Maximum number of documents per page - **after** (str | None) - Optional - Cursor string for fetching next page - **before** (str | None) - Optional - Cursor string for fetching previous page - **sort** (Sequence[Tuple[str, int]] | None) - Optional - List of (field, direction) tuples for sorting - **projection** (Dict[str, int] | None) - Optional - MongoDB projection dictionary ### Request Example ```json { "query": {"status": "active"}, "limit": 10 } ``` ### Response #### Success Response (200) - **Iterable[Edge[TypeVar]]** - Iterator of Edge objects containing model instances and pagination cursors #### Response Example ```json [ { "node": { "_id": "60f7a2b3c4d5e6f7a8b9c0d1", "name": "User 1", "status": "active" }, "cursor": "cursor_string_1" }, { "node": { "_id": "60f7a2b3c4d5e6f7a8b9c0d2", "name": "User 2", "status": "active" }, "cursor": "cursor_string_2" } ] ``` ``` -------------------------------- ### Define Pydantic Models and MongoDB Repository (Python) Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/README.md Defines Pydantic models for data structures (Foo, Bar, Spam) and a Pydantic Mongo repository (SpamRepository) for interacting with a MongoDB collection named 'spams'. It shows how to connect to MongoDB and instantiate the repository. ```python from bson import ObjectId from pydantic import BaseModel from pydantic_mongo import AbstractRepository, PydanticObjectId from pymongo import MongoClient from typing import Optional, List # Define your models class Foo(BaseModel): count: int size: float = None class Bar(BaseModel): apple: str = 'x' banana: str = 'y' class Spam(BaseModel): # PydanticObjectId is an alias to Annotated[ObjectId, ObjectIdAnnotation] id: Optional[PydanticObjectId] = None foo: Foo bars: List[Bar] # Create a repository class SpamRepository(AbstractRepository[Spam]): class Meta: collection_name = 'spams' # Connect to database client = MongoClient("mongodb://localhost:27017") database = client["example"] repo = SpamRepository(database) ``` -------------------------------- ### Python: Custom MongoDB Operations with Pydantic-Mongo Repository Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/examples/custom_methods.md This Python code defines a custom repository class `UserRepository` that inherits from `AbstractRepository`. It demonstrates how to implement custom methods for finding users by domain using regex, performing bulk updates on user statuses, fetching users with raw PyMongo queries and converting them to Pydantic models, and retrieving specific user profile data using custom projections and model conversion. It leverages `get_collection()` for raw operations and `to_model()`/`to_model_custom()` for data transformation. ```python from typing import Iterable, Optional from bson import ObjectId # Assuming AbstractRepository, User, UserProfile, and database are defined elsewhere class UserRepository(AbstractRepository[User]): class Meta: collection_name = 'users' def find_users_by_domain(self, domain: str) -> Iterable[User]: """Custom method to find users by email domain.""" return self.find_by({"email": {"$regex": f"@{domain}$"}}) def bulk_update_status(self, status: str, user_ids: list): """Custom method to update status for multiple users.""" collection = self.get_collection() collection.update_many( {"_id": {"$in": user_ids}}, {"$set": {"status": status}} ) def get_user_by_raw_query(self, user_id: str) -> Optional[User]: """Custom method to fetch a user with raw PyMongo query and convert to model.""" collection = self.get_collection() raw_data = collection.find_one({"_id": ObjectId(user_id)}) return self.to_model(raw_data) if raw_data else None def get_custom_user_view(self, user_id: str) -> Optional[UserProfile]: """Custom method to fetch a user with raw PyMongo query and convert to a custom model.""" collection = self.get_collection() raw_data = collection.find_one( {"_id": ObjectId(user_id)}, projection={"name": 1, "age": 1, "_id": 0} ) return self.to_model_custom(UserProfile, raw_data) if raw_data else None # Example usage: # repo = UserRepository(database) # domain_users = repo.find_users_by_domain("example.com") # repo.bulk_update_status("active", user_ids) # user = repo.get_user_by_raw_query("valid-object-id") # user_profile = repo.get_custom_user_view("valid-object-id") ``` -------------------------------- ### Paginate with Output Type Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/async_abstract_repository.md Asynchronously paginate through model instances with a specified output type, supporting cursor-based pagination for reliable results on large datasets. ```APIDOC ## async paginate_with_output_type ### Description Paginate through model instances with custom output type. This method implements cursor-based pagination which is more reliable than offset-based pagination for large datasets. ### Method ASYNC GET (or equivalent) ### Endpoint `/collection/{collection_name}/paginate` (Assumed endpoint based on functionality) ### Parameters #### Query Parameters - **output_type** (Type) - Required - The Pydantic model class for the output. - **query** (dict) - Required - MongoDB query dictionary. - **limit** (int) - Required - Maximum number of documents per page. - **after** (str | None) - Optional - Cursor string for fetching next page. - **before** (str | None) - Optional - Cursor string for fetching previous page. - **sort** (Sequence[Tuple[str, int]] | None) - Optional - List of (field, direction) tuples for sorting. - **projection** (Dict[str, int] | None) - Optional - MongoDB projection dictionary. ### Response #### Success Response (200) - **results** (Iterable[Edge[OutputT]]) - Iterator of Edge objects containing model instances and pagination cursors. #### Response Example ```json { "results": [ { "node": { /* Model instance */ }, "cursor": "some_cursor_string" } ] } ``` ``` -------------------------------- ### Async Repository Operations with Pydantic Mongo Source: https://context7.com/jefersondaniel/pydantic-mongo/llms.txt Demonstrates asynchronous CRUD operations using AsyncAbstractRepository for Pydantic models. Requires motor and pydantic-mongo. Handles saving, finding by ID, finding multiple documents, paginating, updating, and deleting users asynchronously. ```python import asyncio from pydantic import BaseModel from pydantic_mongo import AsyncAbstractRepository, PydanticObjectId from motor.motor_asyncio import AsyncIOMotorClient from typing import Optional class User(BaseModel): id: Optional[PydanticObjectId] = None username: str email: str is_active: bool class UserRepository(AsyncAbstractRepository[User]): class Meta: collection_name = 'users' async def main(): # Initialize async database connection client = AsyncIOMotorClient('mongodb://localhost:27017') database = client["async_db"] user_repo = UserRepository(database) # Create and save user user = User(username="alice", email="alice@example.com", is_active=True) await user_repo.save(user) print(f"Saved user with ID: {user.id}") # Find user by ID found_user = await user_repo.find_one_by_id(user.id) if found_user: print(f"Found user: {found_user.username}") # Find multiple users active_users = await user_repo.find_by({"is_active": True}) for active_user in active_users: print(f"Active user: {active_user.username}") # Pagination edges = await user_repo.paginate( {"is_active": True}, limit=10, sort=[("username", 1)] ) edges_list = list(edges) if edges_list: # Get next page next_edges = await user_repo.paginate( {"is_active": True}, limit=10, after=edges_list[-1].cursor, sort=[("username", 1)] ) # Update user user.email = "alice_new@example.com" await user_repo.save(user) # Delete user await user_repo.delete(user) print("User deleted") # Close connection client.close() # Run the async function asyncio.run(main()) ``` -------------------------------- ### Perform Aggregation with PyMongo and Pydantic-Mongo Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/examples/aggregations.md This Python code snippet demonstrates how to use PyMongo's aggregation framework with Pydantic-Mongo. It defines a custom Pydantic model for the aggregation results and a repository method to execute the aggregation pipeline. The method accesses the raw PyMongo collection, runs the pipeline, and maps the results to the custom model. ```python from pydantic import BaseModel from pydantic_mongo import AbstractRepository # Custom model for aggregation results class UserStats(BaseModel): role: str average_age: float total_count: int class UserRepository(AbstractRepository[User]): class Meta: collection_name = 'users' def get_user_stats(self) -> list[UserStats]: """Get statistics about users grouped by role.""" pipeline = [ {"$group": { "_id": "$role", "average_age": {"$avg": "$age"}, "total_count": {"$sum": 1} }}, {"$project": { "role": "$_id", "average_age": 1, "total_count": 1, "_id": 0 }} ] collection = self.get_collection() results = collection.aggregate(pipeline) return [UserStats(**doc) for doc in results] # Use the custom method # Assuming 'database' is an initialized Pymongo database object # repo = UserRepository(database) # stats = repo.get_user_stats() # for stat in stats: # print(f"Role: {stat.role}, Avg Age: {stat.average_age}, Count: {stat.total_count}") ``` -------------------------------- ### save Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/abstract_repository.md Save a model instance to the database. Inserts the model if it has no ID, otherwise updates it. ```APIDOC ## save ### Description Save a model instance to the database. This method will insert the model if it doesn’t have an ID, or update it if it already has an ID. ### Method POST (or PUT, depending on implementation details) ### Endpoint `/save` (This is a conceptual endpoint, actual implementation might be a method call within the library) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **model** (T) - Required - The Pydantic model instance to save. ### Request Example ```json { "model": { "field1": "value1", "field2": "value2" } } ``` ### Response #### Success Response (200) - **InsertOneResult | UpdateResult** - The result of the save operation (either an insert or update result from PyMongo). #### Response Example ```json { "insertedId": "your_document_id" } ``` (Or an update result structure depending on the operation) ``` -------------------------------- ### Annotating MongoDB ObjectIds with Pydantic-Mongo Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/object_id_annotation.md Demonstrates how to use ObjectIdAnnotation to define ObjectId fields in Pydantic models. It shows direct annotation and the use of the PydanticObjectId type alias. This annotation handles string-to-ObjectId conversion and validation automatically during model loading and ObjectId-to-string conversion during serialization. ```python from typing_extensions import Annotated from bson import ObjectId from pydantic import BaseModel from pydantic_mongo import ObjectIdAnnotation, PydanticObjectId class User(BaseModel): # Using the annotation directly id: Annotated[ObjectId, ObjectIdAnnotation] # Or using the provided type alias id: PydanticObjectId # equivalent to above ``` -------------------------------- ### paginate_with_output_type Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/abstract_repository.md Paginate through model instances with a specified output type. This method uses cursor-based pagination for reliable results on large datasets. ```APIDOC ## paginate_with_output_type ### Description Paginate through model instances with a custom output type. This method implements cursor-based pagination, which is more reliable than offset-based pagination for large datasets. ### Method GET (or custom method depending on library implementation) ### Endpoint `/paginate_with_output_type` (This is a conceptual endpoint, actual implementation might be a method call within the library) ### Parameters #### Path Parameters None #### Query Parameters - **output_type** (Type) - Required - The Pydantic model class for the output. - **query** (dict) - Required - MongoDB query dictionary. - **limit** (int) - Required - Maximum number of documents per page. - **after** (str | None) - Optional - Cursor string for fetching the next page. - **before** (str | None) - Optional - Cursor string for fetching the previous page. - **sort** (Sequence[Tuple[str, int]] | None) - Optional - List of (field, direction) tuples for sorting. - **projection** (Dict[str, int] | None) - Optional - MongoDB projection dictionary. ### Request Example ```json { "output_type": "YourPydanticModel", "query": {"field": "value"}, "limit": 10, "after": "cursor_string_if_any" } ``` ### Response #### Success Response (200) - **Iterable[Edge[OutputT]]** - An iterator of Edge objects containing model instances and pagination cursors. #### Response Example ```json [ { "node": { "field1": "value1", "field2": "value2" }, "cursor": "next_cursor_string" } ] ``` ``` -------------------------------- ### Paginate Datasets with Pydantic-Mongo Cursor Pagination Source: https://context7.com/jefersondaniel/pydantic-mongo/llms.txt Implements cursor-based pagination for large datasets, returning Edge objects containing the model and a cursor for the next page. Requires `pydantic-mongo` and `pymongo`. Input includes query, limit, and sort parameters; output is an iterable of Edge objects. ```python from pydantic import BaseModel from pydantic_mongo import AbstractRepository, PydanticObjectId from pymongo import MongoClient, ASCENDING from typing import Optional class Post(BaseModel): id: Optional[PydanticObjectId] = None title: str content: str author: str views: int published_at: str class PostRepository(AbstractRepository[Post]): class Meta: collection_name = 'posts' client = MongoClient("mongodb://localhost:27017") database = client["content_db"] post_repo = PostRepository(database) # Get first page edges = post_repo.paginate( {"author": "john_doe"}, limit=10, sort=[("published_at", ASCENDING)] ) edges_list = list(edges) print(f"First page: {len(edges_list)} posts") for edge in edges_list: post = edge.node print(f"Post: {post.title}, Views: {post.views}") print(f"Cursor: {edge.cursor}") ``` -------------------------------- ### Pydantic-Mongo EnumAnnotation for BSON Serialization Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/examples/working_with_enum_fields.md Shows how to use pydantic-mongo's `EnumAnnotation` with regular Python Enum classes. This approach ensures proper BSON serialization for Enum fields in Pydantic models when saving to MongoDB. ```python from enum import Enum from typing_extensions import Annotated from pydantic import BaseModel from pydantic_mongo import EnumAnnotation class OrderStatus(Enum): # Regular Enum, no str inheritance needed PENDING = "pending" PROCESSING = "processing" COMPLETED = "completed" class Order(BaseModel): status: Annotated[OrderStatus, EnumAnnotation[OrderStatus]] # Usage order = Order(status=OrderStatus.PENDING) # Will serialize correctly to BSON # The value will be stored as "pending" in MongoDB # You can also create from string values order = Order(status="pending") # Will be converted to OrderStatus.PENDING ``` -------------------------------- ### Asynchronous Find by Query Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/async_abstract_repository.md Implement asynchronous retrieval of multiple documents from MongoDB based on a query. Supports pagination (skip, limit), sorting, and projection, returning an iterable of model instances. ```python from pydantic_mongo import AsyncAbstractRepository from pydantic import BaseModel from typing import Sequence, Tuple, Dict, Any class Item(BaseModel): id: int category: str price: float class ItemRepo(AsyncAbstractRepository[Item]): class Meta: collection_name = 'items' # Assuming 'repo' is an instance of ItemRepo # results = await repo.find_by(query={'category': 'electronics'}, limit=10, sort=[('price', -1)]) # for item in results: # print(item) ``` -------------------------------- ### Save Multiple Model Instances Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/async_abstract_repository.md Asynchronously save multiple Pydantic model instances to the database in a single bulk operation, optimizing for performance by grouping inserts and updates. ```APIDOC ## async save_many ### Description Asynchronously save multiple model instances to the database in bulk. This method optimizes bulk operations by grouping models into insert and update operations and performing bulk inserts and updates. ### Method ASYNC POST (for bulk operation) ### Endpoint `/collection/{collection_name}/save_many` (Assumed endpoint based on functionality) ### Parameters #### Request Body - **models** (Iterable[T]) - Required - Iterable of model instances to save. ### Request Example ```json { "models": [ { "field1": "value1" }, { "_id": "existing_id", "field1": "updated_value" } ] } ``` ### Response #### Success Response (200) - **results** (BulkWriteResult) - The result of the bulk save operation. #### Response Example ```json { "results": { "inserted_count": 1, "modified_count": 1 } } ``` ``` -------------------------------- ### Find Multiple Documents with Pydantic-Mongo Source: https://context7.com/jefersondaniel/pydantic-mongo/llms.txt Retrieves an iterable of Pydantic model instances that match a given query. Supports optional sorting, limiting, skipping (for pagination), and field projection. Requires `pydantic-mongo` and `pymongo`. Input is a query dictionary and optional pagination/sorting parameters; output is an iterable of Pydantic models. ```python from pydantic import BaseModel from pydantic_mongo import AbstractRepository, PydanticObjectId from pymongo import MongoClient, ASCENDING, DESCENDING from typing import Optional class Order(BaseModel): id: Optional[PydanticObjectId] = None customer_id: str total: float status: str created_at: str class OrderRepository(AbstractRepository[Order]): class Meta: collection_name = 'orders' client = MongoClient("mongodb://localhost:27017") database = client["shop_db"] order_repo = OrderRepository(database) # Find all pending orders pending_orders = order_repo.find_by({"status": "pending"}) for order in pending_orders: print(f"Order {order.id}: ${order.total}") # Find with sorting and limit recent_orders = order_repo.find_by( {"status": "completed"}, sort=[("created_at", DESCENDING)], limit=10 ) # Find with skip and limit (pagination) page_2_orders = order_repo.find_by( {"customer_id": "cust_123"}, skip=20, limit=10, sort=[("total", DESCENDING)] ) # Find with projection (only specific fields) order_summaries = order_repo.find_by( {"status": "pending"}, projection={"total": 1, "status": 1} ) # Complex query with operators high_value_orders = order_repo.find_by({ "total": {"$gte": 100.0}, "status": {"$in": ["pending", "processing"]} }) ``` -------------------------------- ### Find One By Query Source: https://github.com/jefersondaniel/pydantic-mongo/blob/main/docs/api/async_abstract_repository.md Asynchronously find a single model instance based on a provided MongoDB query. ```APIDOC ## async find_one_by ### Description Asynchronously find a single model instance by a MongoDB query. ### Method POST (assumed, as it modifies/retrieves based on query) ### Endpoint /items (example endpoint, actual endpoint depends on repository setup) ### Parameters #### Query Parameters - **query** (dict) - Required - MongoDB query dictionary ### Request Example ```json { "query": {"email": "user@example.com"} } ``` ### Response #### Success Response (200) - **T** (object) - The found model instance - **None** (null) - If no instance is found #### Response Example ```json { "_id": "60f7b3b3b3b3b3b3b3b3b3b3", "email": "user@example.com", "name": "John Doe" } ``` ``` -------------------------------- ### Bulk Save Multiple Documents using Pydantic Mongo Repository in Python Source: https://context7.com/jefersondaniel/pydantic-mongo/llms.txt Shows how to perform bulk operations by saving multiple Pydantic model instances to MongoDB. The `save_many` method groups operations into inserts and updates, optimizing database round trips. IDs are automatically assigned to newly inserted models. ```python from bson import ObjectId from pydantic import BaseModel from pydantic_mongo import AbstractRepository, PydanticObjectId from pymongo import MongoClient from typing import Optional, List class Product(BaseModel): id: Optional[PydanticObjectId] = None name: str price: float stock: int class ProductRepository(AbstractRepository[Product]): class Meta: collection_name = 'products' client = MongoClient("mongodb://localhost:27017") database = client["store_db"] product_repo = ProductRepository(database) # Create multiple products products = [ Product(name="Laptop", price=999.99, stock=50), Product(name="Mouse", price=29.99, stock=200), Product(id=ObjectId("611827f2878b88b49ebb69fc"), name="Keyboard", price=79.99, stock=100) ] # Save all products in bulk product_repo.save_many(products) # All products now have IDs for product in products: print(f"Product {product.name} - ID: {product.id}") ```