Skip to main content

ORM-like API MongoDB for Python language.

Project description

Logo

ramifice

ORM-like API MongoDB for Python language.

Build Status Docs PyPI pyversions PyPI status PyPI version fury.io
GitHub issues PyPI Downloads GitHub license GitHub repository

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.

Project Status



Attention

For version `0.3.6`, do not forget to update `config` and `public` directories in root of your project:

Download config directory
Download public directory

Documentation

Online browsable documentation is available at https://kebasyaty.github.io/ramifice/.

Requirements

View the list of requirements.

Installation

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

  2. Run:

# Fedora:
sudo dnf install gettext
gettext --version
# Ubuntu:
sudo apt install gettext
gettext --version
# Windows:
https://mlocati.github.io/articles/gettext-iconv-windows.html
gettext --version

cd project_name
poetry add ramifice
  1. Add config and public directories in root of your project:
    Download config directory
    Download public directory

Usage

It is recommended to look at examples here.

import asyncio
import pprint
from datetime import datetime

from pymongo import AsyncMongoClient
from ramifice import model, translations
from ramifice.fields import DateField, EmailField, ImageField, PasswordField, TextField
from ramifice.migration import Monitor


@model(service_name="Accounts")
class User:
    def fields(self, gettext):
        # ngettext = translations.ngettext
        self.avatar = ImageField(
            label=gettext("Avatar"),
            default="public/media/default/no-photo.png",
            # Available 4 sizes from lg to xs or None.
            thumbnails={"lg": 480, "md": 240, "sm": 120, "xs": 60},
            # True is high quality and low performance.
            is_high_quality=True,
        )
        self.username = TextField(
            label=gettext("Username"),
            required=True,
            unique=True,
        )
        self.first_name = TextField(label=gettext("First name"), required=True)
        self.last_name = TextField(
            label=gettext("Last name"),
            required=True,
        )
        self.email = EmailField(
            label=gettext("Email"),
            required=True,
            unique=True,
        )
        self.birthday = DateField(label=gettext("Birthday"))
        self.password = PasswordField(label=gettext("Password"))
        self.сonfirm_password = PasswordField(
            label=gettext("Confirm password"),
            # If true, the value of this field is not saved in the database.
            ignored=True,
        )

    async def add_validation(self) -> dict[str, str]:
        """For additional validation of fields."""
        error_map: dict[str, str] = {}
        if self.password != self.сonfirm_password:
            error_map["password"] = "Passwords do not match!"
        return error_map


async def main():
    client = AsyncMongoClient()

    await Monitor(
        database_name="test_db",
        mongo_client=client,
    ).migrat()

    # If you need to change the language of translation.
    # translations.change_locale("ru")

    user = User()
    user.username.value = "pythondev"
    user.avatar.from_path("public/media/default/no-photo.png")
    user.first_name.value = "John"
    user.last_name.value = "Smith"
    user.email.value = "John_Smith@gmail.com"
    user.birthday.value = datetime(2000, 1, 25)
    user.password.value = "12345678"
    user.сonfirm_password.value = "12345678"

    if not await user.save():
        # Convenient to use during development.
        user.print_err()

    doc_count = await User.estimated_document_count()
    print(f"Document count: {doc_count}")  # => 1

    print("User details:")
    user_details = await User.find_one_to_raw_doc({"_id": user._id.value})
    pprint.pprint(user_details)

    # await user.delete()
    # doc_count = await User.estimated_document_count()
    # print(f"Document count: {doc_count}")  # => 0

    await client.close()


if __name__ == "__main__":
    asyncio.run(main())

For create custom translations

from ramifice import translations

translations.DEFAULT_LOCALE = "en"  # By default in Ramifice = "en"
translations.LANGUAGES = ["en", "ru"]  # By default in Ramifice = ["en", "ru"]
cd project_name
# Add your custom translations:
poetry run pybabel extract -o config/translations/custom.pot src
poetry run pybabel init -i config/translations/custom.pot -d config/translations/custom -l en
poetry run pybabel init -i config/translations/custom.pot -d config/translations/custom -l ru
...
poetry run pybabel compile -d config/translations/custom
# Update your custom translations:
poetry run pybabel extract -o config/translations/custom.pot src
poetry run pybabel update -i config/translations/custom.pot -d config/translations/custom
poetry run pybabel compile -d config/translations/custom
#
# Add new languages ​​to Ramifice:
# Example:
poetry run pybabel init -i config/translations/ramifice.pot -d config/translations/ramifice -l de
poetry run pybabel init -i config/translations/ramifice.pot -d config/translations/ramifice -l de_ch
...
poetry run pybabel compile -d config/translations/ramifice
# Update translations to Ramifice:
poetry run pybabel extract -o config/translations/ramifice.pot ramifice
poetry run pybabel update -i config/translations/ramifice.pot -d config/translations/ramifice
poetry run pybabel compile -d config/translations/ramifice

See more examples here.

Model Parameters

See the documentation here.

( only service_name is a required parameter )
Parameter Default Description
service_name no Examples: Accounts | Smartphones | Washing machines | etc ...
fixture_name no The name of the fixture in the config/fixtures directory (without extension).
Examples: SiteSettings | AppSettings | etc ...
db_query_docs_limit 1000 limiting query results.
is_migrat_model True Set to False if you do not need to migrate the Model to the database.
This can be use to validate a web forms - Search form, Contact form, etc.
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:

@model(
    service_name="ServiceName",
    fixture_name="FixtureName",
    db_query_docs_limit=1000,
    is_migrat_model=True,
    is_create_doc = True,
    is_update_doc = True,
    is_delete_doc = True,
)
class User:
    def fields(self, gettext):
        self.username = TextField(
            label=gettext("Username"),
            required=True,
            unique=True,
        )

Contributing

  1. Fork it (https://github.com/kebasyaty/ramifice/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Install for development of Ramifice

# Fedora:
sudo dnf install gettext
gettext --version
# Ubuntu:
sudo apt install gettext
gettext --version
# Windows:
https://mlocati.github.io/articles/gettext-iconv-windows.html
gettext --version

cd project_name
poetry install --with dev,docs

Contributors

  • kebasyaty Gennady Kostyunin - creator and maintainer

Changelog

View the change history.

License

This project is licensed under the MIT.

Project details


Release history Release notifications | RSS feed

This version

0.3.6

Download files

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

Source Distribution

ramifice-0.3.6.tar.gz (35.1 kB view details)

Uploaded Source

Built Distribution

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

ramifice-0.3.6-py3-none-any.whl (76.9 kB view details)

Uploaded Python 3

File details

Details for the file ramifice-0.3.6.tar.gz.

File metadata

  • Download URL: ramifice-0.3.6.tar.gz
  • Upload date:
  • Size: 35.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.2 CPython/3.13.3 Windows/10

File hashes

Hashes for ramifice-0.3.6.tar.gz
Algorithm Hash digest
SHA256 f553665fa4c8862cfe3bf5074e88d9f80b4a50d0eb9a5c85a92936294be427eb
MD5 842d1c23a5063c894fe27248074ff9e1
BLAKE2b-256 ebed73d7fd18e7d877eb1bc1f4bc3bdada9ed05e4d6950014db8d93d56937f10

See more details on using hashes here.

File details

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

File metadata

  • Download URL: ramifice-0.3.6-py3-none-any.whl
  • Upload date:
  • Size: 76.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.2 CPython/3.13.3 Windows/10

File hashes

Hashes for ramifice-0.3.6-py3-none-any.whl
Algorithm Hash digest
SHA256 a3c2d13ed4b7f14f36c05c0614d767c8e0c88a6990e6f826c0b5812924490de8
MD5 f755116343f2c40dc46135cabe9e87f4
BLAKE2b-256 9e48b5456bc855c4ff5e287b04401cf0cf1efefdb08a1fb933edfa5acb4fa83c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page