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,
)
Metadata
Release files for ramifice 2.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ramifice-2.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Release files / ramifice-2.0.3-py3-none-any.whl
| Download URL | ramifice-2.0.3-py3-none-any.whl |
|---|---|
| Size | 130.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4e0c3a4ab8b42a258fa405cf6aa3bfdccd5558f3d4ac8733ae28b33dbb02e1c5
|
|
BLAKE2b-256 checksum How to use checksums |
ea2143dd1421baf941de83791447c872bc0feb4e18486d9dfd8e78ee14b765cb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","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}
|