ramifice
ORM-pseudo-like API MongoDB for Python language.
Ramifice is built around PyMongo.
For simulate relationship Many-to-One and Many-to-Many,
a simplified alternative (Types of selective fields with dynamic addition of elements) is used.
The project is more concentrated for web development or for applications with a graphic interface.
Supports MongoDB 3.6, 4.0, 4.2, 4.4, 5.0, 6.0, 7.0, and 8.0.
For more information see PyMongo.
Installation
# Fedora:
sudo dnf install gettext
# Ubuntu:
sudo apt install gettext
# MacOS
brew install gettext
brew link gettext --force
# Windows:
https://mlocati.github.io/articles/gettext-iconv-windows.html
- Install Ramifice in your project:
uv add ramifice
-
Add
configandpublicdirectories in root of your project:
Download config directory
Download public directory -
Run
# Run Development:
uv run python main.py
# Run Production:
uv run python -OOP main.py
Usage
import re
import asyncio
from pprint import pprint as pp
from pymongo import AsyncMongoClient
from ramifice import (
Migration,
Model,
NamedTuple,
Translator,
fields,
meta,
to_human_size,
)
_ = Translator.STUB_TRANSLATOR_FOR_ATTRIBUTES_OF_FIELD
@meta(service_name="Accounts")
class User(Model):
"""User Model."""
avatar = fields.ImageField(
label=_("Avatar"),
default="public/media/default/no-photo.png",
# Directory for images inside media directory.
target_dir="users/avatars",
# Available 4 sizes from lg to xs or None.
# Hint: Default = None
thumbnails={"lg": 512, "md": 256, "sm": 128, "xs": 64},
# The maximum size of the original image in bytes.
# Hint: Default = 2 MB
max_size=524288, # 0.5 MB = 512 KB = 524288 Bytes (in binary)
warning=[
_("Maximum size: {}").format(to_human_size(524288)),
],
)
username = fields.TextField(
label=_("Username"),
max_length=150,
is_require=True,
is_unique=True,
warning=[
_("Allowed characters: {}").format("a-z A-Z 0-9 _"),
_("Maximum length: {}").format(150),
],
)
password = fields.PasswordField(
label=_("Password"),
warning=[
_("Maximum length: {}").format(256), # this is an immutable size
_("Minimum length: {}").format(8), # this is an immutable size
],
)
сonfirm_password = fields.PasswordField(
label=_("Confirm password"),
# If true, the value of this field is not saved in the database.
is_ignore=True,
)
# Optional method
async def add_validation(self) -> NamedTuple:
"""Additional validation of fields."""
_ = self._CUSTOM_TRANSLATOR.gettext
err_map = self.get_error_map()
_id = self.id
password = self.password
сonfirm_password = self.сonfirm_password
username = self.username
# Check password
if _id is None and password != сonfirm_password:
err_map.update("password", _("Passwords do not match!"))
# Check username
if username is not None and re.match(r"^[a-zA-Z0-9_]+$", username) is None:
err_map.update("username", _("Allowed characters: {}").format("a-z A-Z 0-9 _"))
return err_map
async def main():
client = AsyncMongoClient()
await Migration(
database_name="test_db",
mongo_client=client,
).migrate()
# Create User
user = User("ru")
# user.avatar__core.from_path("public/media/default/no-photo.png")
# user.avatar__core.from_base64("base64-string")
user.username = "pythondev"
user.password = "12345678"
user.сonfirm_password = "12345678"
# Save User
if not await user.save():
# Convenient to use during development
user.print_err()
# Update User
user.username = "pythondev_123"
if not await user.save():
user.print_err()
print("User details:")
user_details: dict | None = await User.find_one_to_model_dict(filter={"_id": user.id})
if user_details is not None:
pp(user_details)
else:
print("No User!")
# Close connection
await client.close()
if __name__ == "__main__":
asyncio.run(main())
Model Parameters
( only service_name is a required parameter )
| Parameter | Default | Description |
|---|---|---|
| service_name | no | Examples: Accounts | Smartphones | Washing machines | etc ... |
| fixture_name | None |
The name of the fixture in the config/fixtures directory (without extension).
Examples: SiteSettings | AppSettings | etc ... |
| db_query_docs_limit | 100 | Limiting the number of request results. |
| is_create_doc | True |
Can a Model create new documents in a collection? Set to False if you only need one document in the collection and the Model is using a fixture. |
| is_update_doc | True | Can a Model update documents in a collection? |
| is_delete_doc | True | Can a Model remove documents from a collection? |
Example:
from ramifice import (
Model,
fields,
meta,
)
@meta(
service_name="ServiceName",
fixture_name="FixtureName",
db_query_docs_limit=100,
is_create_doc = True,
is_update_doc = True,
is_delete_doc = True,
)
class User(Model):
username = fields.TextField(
label="Username",
is_require=True,
is_unique=True,
)
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
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 ramifice-2.0.2-py3-none-any.whl.
File metadata
- Download URL: ramifice-2.0.2-py3-none-any.whl
- Upload date:
- Size: 130.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Fedora Linux","version":"44","id":"","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e2563ce56c5a529ed4063eb3fefb21cf7c7dfc81dfe0372f30ae4bd306b3c7e6
|
|
| MD5 |
6883e715e5f1726de02823d0dcf783f6
|
|
| BLAKE2b-256 |
7ca8d3eaa83174b8e4465d7010a46645542b531a25c226e8209bad5c9b4fc048
|