adjango


Nameadjango JSON
Version 0.1.4 PyPI version JSON
download
home_pagehttps://github.com/Artasov/adjango
SummaryA library with many features for interacting with Django
upload_time2024-10-19 22:11:07
maintainerNone
docs_urlNone
authorxlartas
requires_python>=3.8
licenseNone
keywords adjango django utils funcs features async
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # ADjango 

> Sometimes I use this in different projects, so I decided to put it on pypi

`ADjango` — это удобная библиотека для упрощения работы с Django, которая предлагает различные полезные декораторы, утилиты для асинхронного программирования, планировщик задач для Celery, работу с транзакциями и многое другое.

## Installation
```bash
pip install adjango
```

## Settings

* ### Add the application to the project.
    ```python
    INSTALLED_APPS = [
        #...
        'adjango',
    ]
    ```
* ### In `settings.py` set the params
    ```python
    # adjango
    from adjango.decorators import _handling_function
    
    LOGIN_URL = '/login/'
    ADJANGO_BACKENDS_APPS = BASE_DIR / 'apps'
    ADJANGO_FRONTEND_APPS = BASE_DIR.parent / 'frontend' / 'src' / 'apps'
    ADJANGO_APPS_PREPATH = 'apps.'  # if apps in BASE_DIR/apps/app1,app2...
    # ADJANGO_APPS_PREPATH = None # if in BASE_DIR/app1,app2...
    # Override _handling_function so that unhandled exceptions are handled as you wish
    ADJANGO_UNCAUGHT_EXCEPTION_HANDLING_FUNCTION = _handling_function
    ADJANGO_CONTROLLERS_LOGGER_NAME = 'global'
    ADJANGO_CONTROLLERS_LOGGING = True
    ADJANGO_EMAIL_LOGGER_NAME = 'email'
    ```
    ```python
    MIDDLEWARE = [
        ...
        # add request.ip in views
        'adjango.middleware.IPAddressMiddleware',  
        ...
    ]
    ```
## Overview
Most functions, if available in asynchronous form, are also available in synchronous form.
* `aforce_data`

    Декоратор `aforce_data` объединяет данные из `GET`, `POST` и `JSON` тела 
    запроса в `request.data`. Это упрощает доступ ко всем данным запроса в одном месте.

* `aatomic`

    Асинхронный декоратор, который оборачивает 
    функцию в транзакционный контекст. Если происходит исключение, все изменения откатываются.

* `aatomic`

    Асинхронный декоратор, который оборачивает 
    функцию в транзакционный контекст. Если происходит исключение, все изменения откатываются.
    ```python
    from adjango.adecorators import acontroller

    @acontroller(name='MyView', logger='custom_logger', log_name=True, log_time=True)
    async def my_view(request):
        pass
  
    @acontroller('OneMoreView')
    async def my_view_one_more(request):
        pass
    ```
* `AsyncAtomicContextManager`

    Асинхронный контекст-менеджер для работы с транзакциями, который обеспечивает атомарность операций.
    ```python
    from adjango.utils.base import AsyncAtomicContextManager
    
    async def some_function():
        async with AsyncAtomicContextManager():
            ...  
    ```

* `Tasker`

    Класс Tasker предоставляет методы для планирования задач в `Celery` и `Celery Beat`.
    ```python
    from adjango.utils.tasks import Tasker
    
    task_id = Tasker.put(
        task=my_celery_task,
        param1='value1',
        param2='value2',
        countdown=60  # Задача выполнится через 60 секунд
    )
    ```
    ```python
    from adjango.utils.tasks import Tasker
    from datetime import datetime
    
    # Одноразовая задача через Celery Beat
    Tasker.beat(
        task=my_celery_task,
        name='one_time_task',
        schedule_time=datetime(2024, 10, 10, 14, 30),  # Запуск задачи 10 октября 2024 года в 14:30
        param1='value1',
        param2='value2'
    )
    
    # Периодическая задача через Celery Beat (каждый час)
    Tasker.beat(
        task=my_celery_task,
        name='hourly_task',
        interval=3600,  # Задача выполняется каждый час
        param1='value1',
        param2='value2'
    )
    ```

* `send_emails`

    Позволяет отправлять письма с использованием шаблонов и рендеринга контекста.
    ```python
    from adjango.utils.mail import send_emails
    
    send_emails(
        subject='Welcome!',
        emails=('user1@example.com', 'user2@example.com'),
        template='emails/welcome.html',
        context={'user': 'John Doe'}
    )
    ```
    ```python
    from adjango.tasks import send_emails_task
    from adjango.utils.tasks import Tasker
  
    send_emails_task.delay(
        subject='Hello!',
        emails=('user@example.com',),
        template='emails/hello.html',
        context={'message': 'Welcome to our service!'}
    )
    # or
    Tasker.put(
        task=send_emails_task,
        subject='Hello!',
        emails=('user@example.com',),
        template='emails/hello.html',
        context={'message': 'Welcome to our service!'},
        countdown=60  # Задача выполнится через 5 секунд
    )
    ```




            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Artasov/adjango",
    "name": "adjango",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "adjango django utils funcs features async",
    "author": "xlartas",
    "author_email": "ivanhvalevskey@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/53/fd/76ad1c36999e5a2feb8871b6d2a58a07343cd4b1ae83188f2e9e0f215d82/adjango-0.1.4.tar.gz",
    "platform": null,
    "description": "# ADjango \r\n\r\n> Sometimes I use this in different projects, so I decided to put it on pypi\r\n\r\n`ADjango` \u2014 \u044d\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Django, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440\u044b, \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0434\u043b\u044f \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u0437\u0430\u0434\u0430\u0447 \u0434\u043b\u044f Celery, \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438 \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435.\r\n\r\n## Installation\r\n```bash\r\npip install adjango\r\n```\r\n\r\n## Settings\r\n\r\n* ### Add the application to the project.\r\n    ```python\r\n    INSTALLED_APPS = [\r\n        #...\r\n        'adjango',\r\n    ]\r\n    ```\r\n* ### In `settings.py` set the params\r\n    ```python\r\n    # adjango\r\n    from adjango.decorators import _handling_function\r\n    \r\n    LOGIN_URL = '/login/'\r\n    ADJANGO_BACKENDS_APPS = BASE_DIR / 'apps'\r\n    ADJANGO_FRONTEND_APPS = BASE_DIR.parent / 'frontend' / 'src' / 'apps'\r\n    ADJANGO_APPS_PREPATH = 'apps.'  # if apps in BASE_DIR/apps/app1,app2...\r\n    # ADJANGO_APPS_PREPATH = None # if in BASE_DIR/app1,app2...\r\n    # Override _handling_function so that unhandled exceptions are handled as you wish\r\n    ADJANGO_UNCAUGHT_EXCEPTION_HANDLING_FUNCTION = _handling_function\r\n    ADJANGO_CONTROLLERS_LOGGER_NAME = 'global'\r\n    ADJANGO_CONTROLLERS_LOGGING = True\r\n    ADJANGO_EMAIL_LOGGER_NAME = 'email'\r\n    ```\r\n    ```python\r\n    MIDDLEWARE = [\r\n        ...\r\n        # add request.ip in views\r\n        'adjango.middleware.IPAddressMiddleware',  \r\n        ...\r\n    ]\r\n    ```\r\n## Overview\r\nMost functions, if available in asynchronous form, are also available in synchronous form.\r\n* `aforce_data`\r\n\r\n    \u0414\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440 `aforce_data` \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 `GET`, `POST` \u0438 `JSON` \u0442\u0435\u043b\u0430 \r\n    \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432 `request.data`. \u042d\u0442\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a\u043e \u0432\u0441\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432 \u043e\u0434\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435.\r\n\r\n* `aatomic`\r\n\r\n    \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \r\n    \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442. \u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0432\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f.\r\n\r\n* `aatomic`\r\n\r\n    \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \r\n    \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442. \u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0432\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f.\r\n    ```python\r\n    from adjango.adecorators import acontroller\r\n\r\n    @acontroller(name='MyView', logger='custom_logger', log_name=True, log_time=True)\r\n    async def my_view(request):\r\n        pass\r\n  \r\n    @acontroller('OneMoreView')\r\n    async def my_view_one_more(request):\r\n        pass\r\n    ```\r\n* `AsyncAtomicContextManager`\r\n\r\n    \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442-\u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0430\u0442\u043e\u043c\u0430\u0440\u043d\u043e\u0441\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439.\r\n    ```python\r\n    from adjango.utils.base import AsyncAtomicContextManager\r\n    \r\n    async def some_function():\r\n        async with AsyncAtomicContextManager():\r\n            ...  \r\n    ```\r\n\r\n* `Tasker`\r\n\r\n    \u041a\u043b\u0430\u0441\u0441 Tasker \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447 \u0432 `Celery` \u0438 `Celery Beat`.\r\n    ```python\r\n    from adjango.utils.tasks import Tasker\r\n    \r\n    task_id = Tasker.put(\r\n        task=my_celery_task,\r\n        param1='value1',\r\n        param2='value2',\r\n        countdown=60  # \u0417\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 60 \u0441\u0435\u043a\u0443\u043d\u0434\r\n    )\r\n    ```\r\n    ```python\r\n    from adjango.utils.tasks import Tasker\r\n    from datetime import datetime\r\n    \r\n    # \u041e\u0434\u043d\u043e\u0440\u0430\u0437\u043e\u0432\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0447\u0435\u0440\u0435\u0437 Celery Beat\r\n    Tasker.beat(\r\n        task=my_celery_task,\r\n        name='one_time_task',\r\n        schedule_time=datetime(2024, 10, 10, 14, 30),  # \u0417\u0430\u043f\u0443\u0441\u043a \u0437\u0430\u0434\u0430\u0447\u0438 10 \u043e\u043a\u0442\u044f\u0431\u0440\u044f 2024 \u0433\u043e\u0434\u0430 \u0432 14:30\r\n        param1='value1',\r\n        param2='value2'\r\n    )\r\n    \r\n    # \u041f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0447\u0435\u0440\u0435\u0437 Celery Beat (\u043a\u0430\u0436\u0434\u044b\u0439 \u0447\u0430\u0441)\r\n    Tasker.beat(\r\n        task=my_celery_task,\r\n        name='hourly_task',\r\n        interval=3600,  # \u0417\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u0436\u0434\u044b\u0439 \u0447\u0430\u0441\r\n        param1='value1',\r\n        param2='value2'\r\n    )\r\n    ```\r\n\r\n* `send_emails`\r\n\r\n    \u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u0438\u0441\u044c\u043c\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430.\r\n    ```python\r\n    from adjango.utils.mail import send_emails\r\n    \r\n    send_emails(\r\n        subject='Welcome!',\r\n        emails=('user1@example.com', 'user2@example.com'),\r\n        template='emails/welcome.html',\r\n        context={'user': 'John Doe'}\r\n    )\r\n    ```\r\n    ```python\r\n    from adjango.tasks import send_emails_task\r\n    from adjango.utils.tasks import Tasker\r\n  \r\n    send_emails_task.delay(\r\n        subject='Hello!',\r\n        emails=('user@example.com',),\r\n        template='emails/hello.html',\r\n        context={'message': 'Welcome to our service!'}\r\n    )\r\n    # or\r\n    Tasker.put(\r\n        task=send_emails_task,\r\n        subject='Hello!',\r\n        emails=('user@example.com',),\r\n        template='emails/hello.html',\r\n        context={'message': 'Welcome to our service!'},\r\n        countdown=60  # \u0417\u0430\u0434\u0430\u0447\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 5 \u0441\u0435\u043a\u0443\u043d\u0434\r\n    )\r\n    ```\r\n\r\n\r\n\r\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A library with many features for interacting with Django",
    "version": "0.1.4",
    "project_urls": {
        "Homepage": "https://github.com/Artasov/adjango",
        "Source": "https://github.com/Artasov/adjango",
        "Tracker": "https://github.com/Artasov/adjango/issues"
    },
    "split_keywords": [
        "adjango",
        "django",
        "utils",
        "funcs",
        "features",
        "async"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "49f6dcd3fcaca34d3f1451c62531d7ee32532ce47e531070665fabf41d747707",
                "md5": "01811518ed50204a8ef496907e3b9944",
                "sha256": "3df345124cd641cdd9bb7a03a65e4c933d3ee070d77fedcccd93c7cf1e844f44"
            },
            "downloads": -1,
            "filename": "adjango-0.1.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "01811518ed50204a8ef496907e3b9944",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 26268,
            "upload_time": "2024-10-19T22:11:06",
            "upload_time_iso_8601": "2024-10-19T22:11:06.256209Z",
            "url": "https://files.pythonhosted.org/packages/49/f6/dcd3fcaca34d3f1451c62531d7ee32532ce47e531070665fabf41d747707/adjango-0.1.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "53fd76ad1c36999e5a2feb8871b6d2a58a07343cd4b1ae83188f2e9e0f215d82",
                "md5": "a72dae18f2da973407da707b3849fe82",
                "sha256": "859905081231a15e43464d1bb6edb2a53fd8209ac8d0f91161cf1dc2ed472b80"
            },
            "downloads": -1,
            "filename": "adjango-0.1.4.tar.gz",
            "has_sig": false,
            "md5_digest": "a72dae18f2da973407da707b3849fe82",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 20897,
            "upload_time": "2024-10-19T22:11:07",
            "upload_time_iso_8601": "2024-10-19T22:11:07.421050Z",
            "url": "https://files.pythonhosted.org/packages/53/fd/76ad1c36999e5a2feb8871b6d2a58a07343cd4b1ae83188f2e9e0f215d82/adjango-0.1.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-10-19 22:11:07",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Artasov",
    "github_project": "adjango",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [],
    "lcname": "adjango"
}
        
Elapsed time: 0.36371s