{ "info": { "author": "Alex Hayes", "author_email": "alex@alution.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Framework :: Django", "Framework :: Django :: 1.7", "Framework :: Django :: 1.8", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: MacOS :: MacOS X", "Operating System :: Microsoft :: Windows", "Operating System :: OS Independent", "Operating System :: POSIX", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Object Brokering", "Topic :: System :: Distributed Computing" ], "description": "=============\ndjango-cereal\n=============\n\nEfficient serialization of `Django`_ `Models`_ for use in `Celery`_ that ensure\nthe state of the world.\n\nIt supports Django 1.7, 1.8 and 1.9 for Python versions 2.7, 3.3, 3.4, 3.5 and\npypy (where Django supports the Python version).\n\n.. _`Django`: https://www.djangoproject.com/\n.. _`Models`: https://docs.djangoproject.com/en/stable/topics/db/models/\n.. _`Celery`: http://www.celeryproject.org/\n\nScenario\n========\n\nIf you're using `Django`_ and `Celery`_ you're most likely passing instances\nof `models`_ back and forth between tasks or, as the Celery `docs suggest`_,\nyou're passing just the primary key to a task and then retrieving the the model\ninstance with the primary key.\n\nIf you're doing the former, it's potentially inefficient and certainly dangerous\nas by the time the task executes the models data could be changed!\n\nIf you're using the later, you're probably wondering to yourself, surely there \nis a better way?! While it's efficient and certainly readable it's not exactly\nmuch fun continually fetching the model at the start of each task...\n\nYou may also be using model methods as tasks, but unless you're using something\nsimilar to `this refresh decorator`_, you'll potentially have stale model data.\n\ndjango-cereal to the rescue...\n\n.. _`Django`: https://www.djangoproject.com/\n.. _`Celery`: http://www.celeryproject.org/\n.. _`models`: https://docs.djangoproject.com/en/stable/topics/db/models/\n.. _`docs suggest`: http://docs.celeryproject.org/en/latest/userguide/tasks.html?highlight=model#state\n.. _`this refresh decorator`: https://bitbucket.org/alexhayes/django-toolkit/src/93d23b254bb1edcf31ff5b0f91673fc439f26438/django_toolkit/models/decorators.py?at=master#cl-3\n\n\nHow It Works\n============\n\ndjango-cereal works by using an alternative serializer before the task is sent\nto the message bus and then retrieves a fresh instance of the model during\ndeserialization. Currently only `pickle`_ is supported (feel free to fork and\nimplement for JSON or YAML).\n\nEssentially when the model is serialized only the primary key and the model's \nclass are pickled. This is obviously not quite as efficient as pickling just the\nmodels primary key, but it's certainly better than serializing the entire model!\n\nWhen the task is picked up by a Celery worker and deserialized an instance of\nthe model is retrieved using :code:`YourModel.objects.get(pk=xxx)` and thus this\napproach is also safe as you're not using stale model data in your task.\n\nThe serializer is `registered with kombu`_ and safely patches\n:code:`django.db.Model.__reduce__` - it only operates inside the scope of kombu\nand thus doesn't mess with a model's pickling outside of kombu.\n\n.. _`pickle`: https://docs.python.org/2/library/pickle.html\n.. _`registered with kombu`: http://kombu.readthedocs.org/en/latest/userguide/serialization.html#creating-extensions-using-setuptools-entry-points\n\n\nInstallation\n============\n\nYou can install django-cereal either via the Python Package Index (PyPI)\nor from github.\n\nTo install using pip;\n\n.. code-block:: bash\n\n $ pip install django-cereal\n\nFrom github;\n\n.. code-block:: bash\n\n $ pip install git+https://github.com/alexhayes/django-cereal.git\n\n\nUsage\n=====\n\nAll that is required is that you specify the kwarg :code:`serializer` when\ndefining a task.\n\n.. code-block:: python\n\n from django_cereal.pickle import DJANGO_CEREAL_PICKLE\n\n @app.task(serializer=DJANGO_CEREAL_PICKLE)\n def my_task(my_model):\n ...\n\nThere is also a helper task that you can use which defines the serializer if\nit's not set.\n\n.. code-block:: python\n\n from django_cereal.pickle import task\n\n @task\n def my_task(my_model):\n ...\n\nAnother approach is to set :code:`CELERY_TASK_SERIALIZER` to\n:code:`django-cereal-pickle`.\n\n\nModel Task Methods\n==================\n\nYou can also use task methods on your Django models, so you don't have to define\nthem in a tasks.py. For example;\n\n.. code-block:: python\n\n from celery.contrib.methods import task_method\n from django_cereal.pickle import DJANGO_CEREAL_PICKLE\n from yourproject.celery import app\n\n\n task_method_kwargs = dict(filter=task_method,\n serializer=DJANGO_CEREAL_PICKLE)\n\n\n class MyModel(models.Model):\n\n @app.task(name='MyModel.foo', **task_method_kwargs)\n def foo(self):\n # self is an instance of MyModel\n\n\nThen, you can call your task as follows;\n\n.. code-block:: python\n\n bar = MyModel.objects.get(...)\n bar.foo.delay()\n\n\nJust like your would a normal task but you can stop defining tasks that simply\norchestrate calls on a model and just call the model directly.\n\n\nChaining Task Methods\n=====================\n\nWhile not directly related to serialization of Django models, if you are using\nDjango Model methods as tasks, or any class methods as tasks for that matter,\nand you are chaining these tasks you may be interested in the\n`@ensure_self decorator`_ (see `Celery issue #2137`_ for more details).\n\n.. _`@ensure_self decorator`: https://github.com/alexhayes/django-toolkit/blob/master/django_toolkit/celery/decorators.py#L3\n.. _`Celery issue #2137`: https://github.com/celery/celery/issues/2137\n\n\nDatabase Connections\n====================\n\nNote that if you use the :code:`--maxtasksperworker` flag in Celery, or under\nother similar situations, the connection to a database in Django could become\nunusable, with errors such as the following thrown;\n\n.. code-block:: python\n\n OperationalError(2006, 'MySQL server has gone away')\n\nThis is now handled by the unpickling by closing down the database connection\nwhich forces a new connection to be created.\n\nPerhaps in the future there may be a nicer way of handling this, for instance,\na new connection is created each time a worker is created, but for now the fix\nin place works, even if it's not ideal.\n\n\nLicense\n=======\n\nThis software is licensed under the `MIT License`. See the ``LICENSE``\nfile in the top distribution directory for the full license text.\n\n\nAuthor\n======\n\nAlex Hayes ", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/alexhayes/django-cereal", "keywords": null, "license": "MIT", "maintainer": null, "maintainer_email": null, "name": "django-cereal", "package_url": "https://pypi.org/project/django-cereal/", "platform": "any", "project_url": "https://pypi.org/project/django-cereal/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/alexhayes/django-cereal" }, "release_url": "https://pypi.org/project/django-cereal/0.2.1/", "requires_dist": null, "requires_python": null, "summary": "Efficient serialization of Django Models for use in Celery that ensure the state of the world.", "version": "0.2.1" }, "last_serial": 1860702, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "5a1882676652ae002acdda5335c1a4b1", "sha256": "22fb224a00ee2e879743b78027e2640ac1ebec31b1b333857182de4a2d751902" }, "downloads": -1, "filename": "django-cereal-0.1.0.tar.gz", "has_sig": false, "md5_digest": "5a1882676652ae002acdda5335c1a4b1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8197, "upload_time": "2015-06-19T02:27:54", "url": "https://files.pythonhosted.org/packages/d0/11/5114c0d2be5328f8b3e105a67686c0ecbe9a934efd60b530620fa0bf7d6d/django-cereal-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "2c40431969a1d088da06def90d89180e", "sha256": "89e2206d21ec269a6bfa339be1aacebd50263b17b82c6a2dd96138c22b993273" }, "downloads": -1, "filename": "django-cereal-0.1.1.tar.gz", "has_sig": false, "md5_digest": "2c40431969a1d088da06def90d89180e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8203, "upload_time": "2015-06-19T04:53:04", "url": "https://files.pythonhosted.org/packages/65/1e/82c8ad97be4d68278a323bb7a745ee0c0872e0573f8ed341a92b1c4f729c/django-cereal-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "399a599813e388816d2e277bcc7923b0", "sha256": "f023d57ce8adb432e45246c066b2a942098d075c99b335d64b838ec4ec50fbb9" }, "downloads": -1, "filename": "django-cereal-0.1.2.tar.gz", "has_sig": false, "md5_digest": "399a599813e388816d2e277bcc7923b0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9086, "upload_time": "2015-07-01T01:57:02", "url": "https://files.pythonhosted.org/packages/e5/c3/956a53ada7df05a89217172e4e73a5d2adf6e24271d9169dea33ffa4b9b0/django-cereal-0.1.2.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "af50d4f0bf4c0abd38a1f3e1c1e9714b", "sha256": "c72556a7921b2c5e47220f0fad5316e9fe3be9d71f0f2e190fb4a3783a1ec1b2" }, "downloads": -1, "filename": "django-cereal-0.2.1.tar.gz", "has_sig": false, "md5_digest": "af50d4f0bf4c0abd38a1f3e1c1e9714b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8813, "upload_time": "2015-12-14T01:28:46", "url": "https://files.pythonhosted.org/packages/46/c3/3a0ed4f72d9effc9d3c8976d2bdbf21f42dbecc6d2997cbe0949f8ed4e91/django-cereal-0.2.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "af50d4f0bf4c0abd38a1f3e1c1e9714b", "sha256": "c72556a7921b2c5e47220f0fad5316e9fe3be9d71f0f2e190fb4a3783a1ec1b2" }, "downloads": -1, "filename": "django-cereal-0.2.1.tar.gz", "has_sig": false, "md5_digest": "af50d4f0bf4c0abd38a1f3e1c1e9714b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8813, "upload_time": "2015-12-14T01:28:46", "url": "https://files.pythonhosted.org/packages/46/c3/3a0ed4f72d9effc9d3c8976d2bdbf21f42dbecc6d2997cbe0949f8ed4e91/django-cereal-0.2.1.tar.gz" } ] }