Registry / database / bunnet

bunnet

JSON →
library1.3.0pypypi✓ verified 86d ago

Bunnet is a synchronous Python Object-Document Mapper (ODM) for MongoDB, built upon Pydantic for data modeling. It simplifies interaction with MongoDB collections by mapping Python classes to documents, reducing boilerplate code for common database operations like adding, updating, and deleting. Bunnet is a synchronous fork of the popular Beanie ODM, and its current version is 1.3.0 with active development and maintenance.

pip install bunnet
INSTALL
IMPORT
SIG · BUNNET
B
bunnet
databasepythonv1.3.0
Install
4.5s avg
Import
899ms
Disk
38MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.3.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.920 runs
installs and imports cleanly · install 0.0s · import 0.940s · 38MB
glibc
py 3.103.920 runs
installs and imports cleanly · install 4.5s · import 0.857s · 39MB
38MB installed
● package 38MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Document
from bunnet import Document
init_bunnet
from bunnet import init_bunnet
Indexed
from bunnet import Indexed
MongoClient
from pymongo import MongoClient
BaseModel
from pydantic import BaseModel
from bunnet import BaseModel
BaseModel should be imported from pydantic for nested models, not directly from bunnet.

This quickstart demonstrates how to connect to MongoDB, define a Bunnet Document, insert data, and perform basic queries and updates. It uses Pydantic for defining nested data structures and `pymongo.MongoClient` for the underlying database connection. Remember to replace `mongodb://localhost:27017` and `your_db_name` with your actual MongoDB connection string and database name.

from typing import Optional from pymongo import MongoClient from pydantic import BaseModel from bunnet import Document, Indexed, init_bunnet import os # Define a Pydantic model for a nested object class Category(BaseModel): name: str description: str # Define a Bunnet Document model class Product(Document): name: str description: Optional[str] = None price: Indexed(float) category: Category # Optional: Configure collection name and other settings class Settings: name = "products_collection" async def main(): # Connect to MongoDB (replace with your connection string) # Use os.environ.get for secure credentials in production MONGO_DETAILS = os.environ.get('MONGO_URI', 'mongodb://localhost:27017') client = MongoClient(MONGO_DETAILS) # Initialize Bunnet with the database and document models # Ensure 'your_db_name' exists or will be created upon first write init_bunnet(database=client.get_database('your_db_name'), document_models=[Product]) # Create a category instance chocolate_category = Category(name="Chocolate", description="A preparation of roasted and ground cacao seeds.") # Create a product instance tonybar = Product(name="Tony's Chocolonely", price=5.95, category=chocolate_category) # Insert the document into the database inserted_product = tonybar.insert() print(f"Inserted product: {inserted_product.name}") # Find a document using Pythonic syntax found_product = Product.find_one(Product.price < 10).run() if found_product: print(f"Found product: {found_product.name}") # Update a document updated_product = found_product.set({Product.name: "Gold Bar"}) print(f"Updated product to: {updated_product.name}") if __name__ == "__main__": # Bunnet is synchronous, so no asyncio.run() needed directly for document operations. # The main function is defined as async only for consistency if a project mixed sync/async components # For this quickstart, you would typically run the synchronous operations directly. # However, to simulate an async context often seen in examples for its counterpart (Beanie), # we wrap it here. For a purely synchronous application, you'd call main() directly and remove 'async/await'. main()
Debug
Known issues
gotchaBunnet is the synchronous version of Beanie ODM. Methods in Bunnet do not use `await` and attempts to call `async` methods (like `find_one_async`) will result in `AttributeError` or `TypeError`.
fix
Use synchronous methods provided by Bunnet (e.g., `find_one().run()`) and ensure your application context is synchronous. If an async context is required, consider using BeanieODM instead.
affects: All versions
breakingPydantic V2 introduced significant internal changes. While Bunnet aims for compatibility, developers migrating from Pydantic V1-based applications might encounter validation or serialization issues, especially with custom types or complex data structures.
fix
Refer to Pydantic's official migration guide. If issues persist, check Bunnet's GitHub discussions or issues for specific Pydantic V2 related workarounds or bug fixes.
affects: Bunnet versions built against Pydantic V2 (post-Pydantic V2 release)
gotchaThe `replace_one` method in Bunnet (and Beanie) does not natively support `upsert=True` as a direct parameter in the same way `update_one` does in PyMongo. Attempting to use it for an upsert might not behave as expected.
fix
For upsert functionality with `replace_one`, you might need to implement a check-then-insert/replace logic or use `save()` on a new or existing document instance. For more complex scenarios, consider using `update_one` with `upsert=True` or a custom bulk write operation. Raising a feature request/PR to the Bunnet maintainers might also be an option.
affects: All versions
gotchaInitialization with `init_bunnet` requires a PyMongo `database` object, not the client. Passing the client directly will raise an error or lead to incorrect behavior.
fix
Always pass the `database` object obtained from the client (e.g., `client.get_database('your_db_name')`) to `init_bunnet`.
affects: All versions
Errors
Common errors & fixes
AttributeError: 'Product' object has no attribute 'find_one_async'
Attempting to use an asynchronous method from BeanieODM (the async counterpart) on a Bunnet Document model.
fix
Bunnet is synchronous. Use `find_one().run()` instead of `find_one_async()`. All operations are synchronous and do not require `await`.
pymongo.errors.CollectionInvalid: collection name cannot be empty
The `init_bunnet` function was called without a valid `database` object or `document_models` list, preventing proper collection initialization.
fix
Ensure `init_bunnet(database=client.get_database('your_db_name'), document_models=[YourDocumentClass])` is called with both a valid `pymongo.database.Database` instance and a list of your Document classes.
TypeError: Document.save() missing 1 required positional argument: 'self'
Trying to call an instance method (`.save()`, `.insert()`, `.update()`) on the `Document` class itself, rather than on an instantiated document object.
fix
First create an instance of your document (e.g., `my_product = Product(...)`), then call the method on the instance (`my_product.save()`).
TypeError: 'Collection' object is not callable
Attempting to access a database collection property (e.g., `Product.Collection`) which was a pattern in older Beanie versions but is now deprecated or unsupported in Bunnet, replaced by `Settings`.
fix
Access collection-level settings via `Product.Settings` or define `class Settings:` within your `Document` class to configure collection options like `name`. Do not use `Document.Collection` directly.
Upgrade
Version history
1.3.0latest on PyPI · released Feb 28, 2024
Audit
Dependencies
pymongorequiredBunnet uses Pymongo client under the hood for MongoDB interaction.
pydanticrequiredData models in Bunnet are based on Pydantic models for validation and serialization.
Agent activity
17 hits · last 30 days
node
16
OpenAI (training)
1
Resources
bunnet — pip install bunnet · libregistry