django-post-deploy


Namedjango-post-deploy JSON
Version 2.3.1 PyPI version JSON
download
home_pagehttps://github.com/erlendgit/django_post_deploy
SummaryA generic way to have post-deploy actions done.
upload_time2023-01-12 14:26:53
maintainer
docs_urlNone
authorErlend ter Maat
requires_python
licensecc-by-4.0
keywords django deployment management cli
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            Django Post Deploy
===

This module adds a way automate release-specific post-deploy/post-migrate actions to your Django project.

### Features

* Allow actions to be scheduled with the deployment automation
    * But also give the oppurtunity to keep special actions out of the automation and have those executed manually.
* Schedule the actions to be executed in Celery.
    * The task scheduler is configurable, so you can write your own.
* Support for django_tenants.

### Alternatives

Alternative to this module you can use:

* Management tasks. Used once and in the future confuse developers "Must we also maintain this code?"
* "Empty" migrations. That
    * may or may not activate all custom expected code for it...
    * may or may not depend on other migrations being completed.

### Why use this module?

This module is of use for your application if you:

* want to keep management commands clean of one-time-used code.
* want to have release finishing tasks executed in a certain and known state of the application.

## Example

```python
# Inside a custom django module's post_deploy.py
from post_deploy import post_deploy_action


@post_deploy_action
def make_non_code_changes_to_complete_the_next_release():
    pass


@post_deploy_action(auto=False)
def this_action_must_be_triggered_manually():
    pass
```

```shell
# This line may be added to your deployment automation script
python manage.py deploy --auto
```

```shell
# This line is executed when the time is right for specific actions
$ ./manage.py deploy --one core.post_deploy.this_action_must_be_triggered_manually

# Or like this: both auto and manual actions are scheduled:
$ ./manage.py deploy --all

# Print actions that are running, have errors and are completed.
$ ./manage.py deploy --status

# Print actions that completed with errors, or did not run yet. The tasks with errors may need
# to be scheduled with the --once option.
$ ./manage.py deploy --todo

# Print uuids of the tasks that have run before; for debugging purposes.
$ ./manage.py deploy --uuids

# This is an example of running a custom action
$ ./manage.py deploy --one core.a_custom_repository_of_functions.a_custom_function_to_be_executed

# This is an example of running an action only if it has not started before, or when it completed with errors
$ ./manage.py deploy --once core.post_deploy.failed_before_or_did_not_run_yet

# In this example a non-processed task will be marked complete
$ ./manage.py deploy --skip core.post_deploy.aint_no_run_no_more

# In this example a processed task will become ready to schedule (again)
$ ./manage.py deploy --reset core.post_deploy.run_again_at_all_or_auto

```

## Configuration

The module is to be installed as an app in the django settings.

```python
# inside your projects settings.py file:

INSTALLED_APPS = [
    ...,
    'post_deploy',
]
```

### Celery

Out of the box the deploy management command runs the actions serially. However, if you use Celery you have to add this to your settings:

```python
# inside your projects settings.py file:

POST_DEPLOY_CELERY_APP = 'module.path.to.your.projects.celery.app'
POST_DEPLOY_SCHEDULER_MANAGER = 'post_deploy.plugins.scheduler.celery.CeleryScheduler'
```

### Custom scheduler manager

Below is a partial copy of othe Celery scheduler manager as an example on how to write one for your alternative task scheduler:

**NOTICE: remember to configure your custom scheduler manager in your project settings.**

```python
from celery import Celery
from celery.result import AsyncResult

from post_deploy.plugins.scheduler import DefaultScheduler


class CeleryScheduler(DefaultScheduler):
    ...

    def task_ready(self, id):
        return AsyncResult(id=id, app=...).ready()

    def schedule(self, action_ids, context_kwargs):
        from post_deploy.tasks import deploy_task
        result = deploy_task.delay(action_ids, context_kwargs)
        return result.id

    ...
```

### Django tenants

This module supports the django_tenants module. In order to make the post deploy actions tenant aware two things are different from normal operation. You have
to (1) configure a context manager, and (2) the management command is a little different.

**BE AWARE!!!** Make sure that you install the post_deploy app in the SHARED_APPS section. Not doing this may lead to unexpected results.

```python
# inside your projects settings.py file, two additions:

SHARED_APPS = [
    ...,
    'post_deploy',
]

TENANT_APPS = [
    ...,
    'post_deploy',
]

...

POST_DEPLOY_CONTEXT_MANAGER = 'post_deploy.plugins.context.tenant.TenantContext'
```

```shell
# The tenant schema is transported to the celery task runner when the management
# command is executed in the given schema aware management commands. For example:

# all_tenants_command example:
$ ./manage.py all_tenants_command deploy --all

# tenant_command example:
$ ./manage.py tenant_command deploy --report --schema=public
```

Example on how to have actions behave different based on the selected schema:

```python
# Inside a module's post_deploy.py
from django_tenants.utils import parse_tenant_config_path
from post_deploy import post_deploy_action


@post_deploy_action
def example_on_how_alter_operation_based_on_schema():
    if parse_tenant_config_path("") == 'public':
        # Do 'public' specific operations.
        pass

    # else, proceed as required.
    ...
```

## Technical details

* This module provides a model, and therefore require a common relational database to be installed. There are however no relations between multiple models in
  this module, so it may be possible that it works with a non-relational database too. But it is not tested in non-relational database configurations.

## License information

django_post_deploy (c) by Erlend ter Maat

django_post_deploy is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

You should have received a copy of the license along with this work. If not, see <http://creativecommons.org/licenses/by-sa/4.0/>.



            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/erlendgit/django_post_deploy",
    "name": "django-post-deploy",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "Django,Deployment,Management,CLI",
    "author": "Erlend ter Maat",
    "author_email": "erwitema@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/32/0b/da2b6a06606ed6fa144bf9d0606194b35a5377a16230ae65fca7325c40e0/django_post_deploy-2.3.1.tar.gz",
    "platform": null,
    "description": "Django Post Deploy\n===\n\nThis module adds a way automate release-specific post-deploy/post-migrate actions to your Django project.\n\n### Features\n\n* Allow actions to be scheduled with the deployment automation\n    * But also give the oppurtunity to keep special actions out of the automation and have those executed manually.\n* Schedule the actions to be executed in Celery.\n    * The task scheduler is configurable, so you can write your own.\n* Support for django_tenants.\n\n### Alternatives\n\nAlternative to this module you can use:\n\n* Management tasks. Used once and in the future confuse developers \"Must we also maintain this code?\"\n* \"Empty\" migrations. That\n    * may or may not activate all custom expected code for it...\n    * may or may not depend on other migrations being completed.\n\n### Why use this module?\n\nThis module is of use for your application if you:\n\n* want to keep management commands clean of one-time-used code.\n* want to have release finishing tasks executed in a certain and known state of the application.\n\n## Example\n\n```python\n# Inside a custom django module's post_deploy.py\nfrom post_deploy import post_deploy_action\n\n\n@post_deploy_action\ndef make_non_code_changes_to_complete_the_next_release():\n    pass\n\n\n@post_deploy_action(auto=False)\ndef this_action_must_be_triggered_manually():\n    pass\n```\n\n```shell\n# This line may be added to your deployment automation script\npython manage.py deploy --auto\n```\n\n```shell\n# This line is executed when the time is right for specific actions\n$ ./manage.py deploy --one core.post_deploy.this_action_must_be_triggered_manually\n\n# Or like this: both auto and manual actions are scheduled:\n$ ./manage.py deploy --all\n\n# Print actions that are running, have errors and are completed.\n$ ./manage.py deploy --status\n\n# Print actions that completed with errors, or did not run yet. The tasks with errors may need\n# to be scheduled with the --once option.\n$ ./manage.py deploy --todo\n\n# Print uuids of the tasks that have run before; for debugging purposes.\n$ ./manage.py deploy --uuids\n\n# This is an example of running a custom action\n$ ./manage.py deploy --one core.a_custom_repository_of_functions.a_custom_function_to_be_executed\n\n# This is an example of running an action only if it has not started before, or when it completed with errors\n$ ./manage.py deploy --once core.post_deploy.failed_before_or_did_not_run_yet\n\n# In this example a non-processed task will be marked complete\n$ ./manage.py deploy --skip core.post_deploy.aint_no_run_no_more\n\n# In this example a processed task will become ready to schedule (again)\n$ ./manage.py deploy --reset core.post_deploy.run_again_at_all_or_auto\n\n```\n\n## Configuration\n\nThe module is to be installed as an app in the django settings.\n\n```python\n# inside your projects settings.py file:\n\nINSTALLED_APPS = [\n    ...,\n    'post_deploy',\n]\n```\n\n### Celery\n\nOut of the box the deploy management command runs the actions serially. However, if you use Celery you have to add this to your settings:\n\n```python\n# inside your projects settings.py file:\n\nPOST_DEPLOY_CELERY_APP = 'module.path.to.your.projects.celery.app'\nPOST_DEPLOY_SCHEDULER_MANAGER = 'post_deploy.plugins.scheduler.celery.CeleryScheduler'\n```\n\n### Custom scheduler manager\n\nBelow is a partial copy of othe Celery scheduler manager as an example on how to write one for your alternative task scheduler:\n\n**NOTICE: remember to configure your custom scheduler manager in your project settings.**\n\n```python\nfrom celery import Celery\nfrom celery.result import AsyncResult\n\nfrom post_deploy.plugins.scheduler import DefaultScheduler\n\n\nclass CeleryScheduler(DefaultScheduler):\n    ...\n\n    def task_ready(self, id):\n        return AsyncResult(id=id, app=...).ready()\n\n    def schedule(self, action_ids, context_kwargs):\n        from post_deploy.tasks import deploy_task\n        result = deploy_task.delay(action_ids, context_kwargs)\n        return result.id\n\n    ...\n```\n\n### Django tenants\n\nThis module supports the django_tenants module. In order to make the post deploy actions tenant aware two things are different from normal operation. You have\nto (1) configure a context manager, and (2) the management command is a little different.\n\n**BE AWARE!!!** Make sure that you install the post_deploy app in the SHARED_APPS section. Not doing this may lead to unexpected results.\n\n```python\n# inside your projects settings.py file, two additions:\n\nSHARED_APPS = [\n    ...,\n    'post_deploy',\n]\n\nTENANT_APPS = [\n    ...,\n    'post_deploy',\n]\n\n...\n\nPOST_DEPLOY_CONTEXT_MANAGER = 'post_deploy.plugins.context.tenant.TenantContext'\n```\n\n```shell\n# The tenant schema is transported to the celery task runner when the management\n# command is executed in the given schema aware management commands. For example:\n\n# all_tenants_command example:\n$ ./manage.py all_tenants_command deploy --all\n\n# tenant_command example:\n$ ./manage.py tenant_command deploy --report --schema=public\n```\n\nExample on how to have actions behave different based on the selected schema:\n\n```python\n# Inside a module's post_deploy.py\nfrom django_tenants.utils import parse_tenant_config_path\nfrom post_deploy import post_deploy_action\n\n\n@post_deploy_action\ndef example_on_how_alter_operation_based_on_schema():\n    if parse_tenant_config_path(\"\") == 'public':\n        # Do 'public' specific operations.\n        pass\n\n    # else, proceed as required.\n    ...\n```\n\n## Technical details\n\n* This module provides a model, and therefore require a common relational database to be installed. There are however no relations between multiple models in\n  this module, so it may be possible that it works with a non-relational database too. But it is not tested in non-relational database configurations.\n\n## License information\n\ndjango_post_deploy (c) by Erlend ter Maat\n\ndjango_post_deploy is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.\n\nYou should have received a copy of the license along with this work. If not, see <http://creativecommons.org/licenses/by-sa/4.0/>.\n\n\n",
    "bugtrack_url": null,
    "license": "cc-by-4.0",
    "summary": "A generic way to have post-deploy actions done.",
    "version": "2.3.1",
    "split_keywords": [
        "django",
        "deployment",
        "management",
        "cli"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "320bda2b6a06606ed6fa144bf9d0606194b35a5377a16230ae65fca7325c40e0",
                "md5": "c8099a5df33e462a0d99f6afec3320ab",
                "sha256": "1c9818090489c77092880b268d4c1680a22f6e1f94115ed21e80ec9b6e1d1941"
            },
            "downloads": -1,
            "filename": "django_post_deploy-2.3.1.tar.gz",
            "has_sig": false,
            "md5_digest": "c8099a5df33e462a0d99f6afec3320ab",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 18393,
            "upload_time": "2023-01-12T14:26:53",
            "upload_time_iso_8601": "2023-01-12T14:26:53.537317Z",
            "url": "https://files.pythonhosted.org/packages/32/0b/da2b6a06606ed6fa144bf9d0606194b35a5377a16230ae65fca7325c40e0/django_post_deploy-2.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-01-12 14:26:53",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "erlendgit",
    "github_project": "django_post_deploy",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "django-post-deploy"
}
        
Elapsed time: 0.02948s