Skip to main content

Logo

ramifice

ORM-pseudo-like API MongoDB for Python language.

Build Status Docs PyPI pyversions PyPI status PyPI version fury.io
Types: Pyrefly Code style: Ruff Format PyPI Downloads GitHub license

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.


MongoDB
Supports MongoDB 3.6, 4.0, 4.2, 4.4, 5.0, 6.0, 7.0, and 8.0.
For more information see PyMongo.


Documentation

Requirements

Installation

  1. Install MongoDB (if not installed):
    Fedora Ubuntu Windows

  2. Install system dependencies:

# 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
  1. Install Ramifice in your project:
uv add ramifice
  1. Add config and public directories in root of your project:
    Download config directory
    Download public directory

  2. Run

# Run Development:
uv run python main.py
# Run Production:
uv run python -OOP main.py

Usage

Examples

import re
import asyncio
from pprint import pprint as pp

from pymongo import AsyncMongoClient

from ramifice import (
    Migration,
    Model,
    Translator,
    fields,
    meta,
    to_human_size,
)

_ = Translator.STUB_TRANSLATOR_FOR_ATTRIBUTES_OF_FIELD


@model(service_name="Accounts")
class User:
    """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) -> dict[str, Any]:
        """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,
  )

Changelog

MIT

APACHE-2.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ramifice-2.0.0-py3-none-any.whl (130.2 kB view details)

Uploaded Python 3

File details

Details for the file ramifice-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: ramifice-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 130.2 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

Hashes for ramifice-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4e0eb0673eff596b89f33e49e740f1de07a7a912c9a785c090ba81250f4d6135
MD5 eeea6c6883fb07fc69f5751d23bc74a1
BLAKE2b-256 6cc4562b6a76f934267c8213056dcba97b166a49e1c0b56950f6556b2854d7ea

See more details on using hashes here.

Release history Release notifications | RSS feed

2.0.2

1 file

2.0.1

1 file

This release

2.0.0 This release

1 file

1.0.1

1 file

1.0.0

1 file

0.10.0

1 file

0.9.19

1 file

0.9.18

1 file

0.9.17

1 file

0.9.16

1 file

0.9.15

1 file

0.9.14

1 file

0.9.13

1 file

0.9.12

1 file

0.9.11

1 file

0.9.10

1 file

0.9.9

1 file

0.9.8

1 file

0.9.7

1 file

0.9.6

1 file

0.9.5

1 file

0.9.3

1 file

0.9.2

1 file

0.9.1

1 file

0.9.0

1 file

0.8.48

1 file

0.8.47

1 file

0.8.46

1 file

0.8.45

1 file

0.8.44

1 file

0.8.43

1 file

0.8.42

1 file

0.8.41

1 file

0.8.40

1 file

0.8.39

1 file

0.8.38

1 file

0.8.37

1 file

0.8.35

1 file

0.8.34

1 file

0.8.33

1 file

0.8.32

1 file

0.8.31

1 file

0.8.30

1 file

0.8.29

1 file

0.8.28

1 file

0.8.27

1 file

0.8.26

1 file

0.8.25

1 file

0.8.22

1 file

0.8.21

1 file

0.8.20

1 file

0.8.19

1 file

0.8.18

1 file

0.8.17

1 file

0.8.16

1 file

0.8.15

1 file

0.8.14

1 file

0.8.13

1 file

0.8.12

1 file

0.8.11

1 file

0.8.10

1 file

0.8.9

1 file

0.8.8

1 file

0.8.7

1 file

0.8.6

1 file

0.8.5

1 file

0.8.4

1 file

0.8.3

1 file

0.8.2

1 file

0.8.1

1 file

0.8.0

1 file

0.7.0

1 file

0.6.1

1 file

0.6.0

1 file

0.5.12

1 file

0.5.11

1 file

0.5.10

1 file

0.5.9

1 file

0.5.8

1 file

0.5.7

1 file

0.5.6

1 file

0.5.5

1 file

0.5.4

1 file

0.5.3

1 file

0.5.2

1 file

0.5.1

1 file

0.5.0

1 file

0.4.12

1 file

0.4.11

1 file

0.4.10

1 file

0.4.9

1 file

0.4.8

1 file

0.4.7

1 file

0.4.6

1 file

0.4.5

1 file

0.4.4

1 file

0.4.3

1 file

0.4.2

1 file

0.4.1

1 file

0.4.0

1 file

0.3.34

1 file

0.3.32

1 file

0.3.30

1 file

0.3.29

1 file

0.3.28

1 file

0.3.27

1 file

0.3.26

1 file

0.3.25

1 file

0.3.24

1 file

0.3.23

1 file

0.3.22

1 file

0.3.21

1 file

0.3.20

1 file

0.3.19

1 file

0.3.18

1 file

0.3.17

1 file

0.3.16

1 file

0.3.15

1 file

0.3.14

1 file

0.3.13

1 file

0.3.12

1 file

0.3.11

1 file

0.3.10

1 file

0.3.9

1 file

0.3.8

1 file

0.3.7

2 files

0.3.6

2 files

0.3.5

2 files

0.3.4

2 files

0.3.3

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.19

2 files

0.2.18

2 files

0.2.17

2 files

0.2.16

2 files

0.2.15

2 files

0.2.14

2 files

0.2.13

2 files

0.2.12

2 files

0.2.11

2 files

0.2.10

2 files

0.2.9

2 files

0.2.8

2 files

0.2.7

2 files

0.2.6

2 files

0.2.5

2 files

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page