{ "info": { "author": "Josh Smeaton", "author_email": "josh.smeaton@gmail.com", "bugtrack_url": null, "classifiers": [ "Framework :: Django", "Framework :: Django :: 1.11", "Framework :: Django :: 2.0", "Framework :: Django :: 2.1", "Framework :: Django :: 2.2", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Natural Language :: English", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": "# django-subscriptions\n\nA django package for managing the status and terms of a subscription.\n\n[![PyPI version](https://badge.fury.io/py/django-subscriptions.svg)](https://badge.fury.io/py/django-subscriptions)\n[![CircleCI (all branches)](https://img.shields.io/circleci/project/github/kogan/django-subscriptions.svg)](https://circleci.com/gh/kogan/django-subscriptions)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n![PyPI - License](https://img.shields.io/pypi/l/django-subscriptions.svg?style=popout)\n\n## Compatibility\n\n- Django: 1.11 and 2.2 (LTS versions only)\n- Python: 2.7 and 3.6+\n\nOther Django or Python versions **may** work, but that is totally cooincidental\nand no effort is made to maintain compatibility with versions other than those\nlisted above.\n\n## Installation\n\n```bash\n$ pip install django-subscriptions\n```\n\nThen add the following packages to `INSTALLED_APPS` in your settings:\n\n```\nINSTALLED_APPS = [\n ...\n \"django_fsm_log\",\n \"subscriptions.apps.SubscriptionsConfig\",\n ...\n]\n```\n\nAnd of course, you'll need to run the migrations:\n\n```\n$ python manage.py migrate\n```\n\nYou'll also need to setup the triggers, which can be scheduled with celery or\nrun from a management task. See the [Triggers](#triggers) section below.\n\n## Design\n\nManages subscriptions in a single table. Pushes events (signals) so that\nconsumers can do the actual work required for that subscription, like billing.\n\nSubscriptions are built around a Finite State Machine model, where states and\nallowed transitions between states are well defined on the Model. To update from\none state to another, the user calls methods on the Subscription instance. This\nway, all side-effects and actions are contained within the state methods.\n\nSubscription State must not be modified directly.\n\nWhen a state change is triggered, the subscription will publish relevant signals\nso that interested parties can, themselves, react to the state changes.\n\n![State Diagram](subscriptions-state-diagram.png)\n\n## API\n\nThere are 3 major API components. State change methods, signals/events, and the\ntriggers used to begin the state changes.\n\n### State Methods\n\n\n| Method | Source States \t| Target State \t| Signal Emitted \t|\n|------------------------------------------------|---------------------------------\t|--------------\t|----------------------\t|\n| `cancel_autorenew()` | ACTIVE \t| EXPIRING \t| `autorenew_canceled` \t|\n| `enable_autorenew()` | EXPIRING \t| ACTIVE \t| `autorenew_enabled` \t|\n| `renew()` | ACTIVE,SUSPENDED \t| RENEWING \t| `subscription_due` \t|\n| `renewed(new_end, new_ref, description=None)` | ACTIVE,RENEWING,ERROR | ACTIVE \t| `subscription_renewed`|\n| `renewal_failed(description=None)`\t | RENEWING,ERROR \t| SUSPENDED \t| `renewal_failed` \t|\n| `end_subscription(description=None)` | ACTIVE,SUSPENDED,EXPIRING,ERROR \t| ENDED \t| `subscription_ended` \t|\n| `state_unknown(description=None)`\t | RENEWING \t| ERROR \t| `subscription_error` \t|\n\nExample:\n\n`subscription.renew()` may only be called if `subscription.state` is either `ACTIVE` or `SUSPENDED`,\nand will cause `subscription.state` to move into the `RENEWING` state.\n\nThe `description` argument is a string that can be used to persist the reason for a state\nchange in the `StateLog` table (and admin inlines).\n\n### Triggers\n\nThere are a bunch of triggers that are used to update subscriptions as they become\ndue or expire. Nothing is configured to run these triggers by default. You can\neither call them as part of your own process, or use `celery beat` to execute\nthe triggers using the tasks provided in `subscriptions.tasks`.\n\n\nCreate a new subscription:\n\n```\nSubscription.objects.add_subscription(start_date, end_date, reference) -> Subscription\n```\n\nTrigger subscriptions that are due for renewal:\n\n```\nSubscription.objects.trigger_renewals() -> int # number of renewals sent\n```\n\nTrigger subscriptions that are due to expire:\n\n```\nSubscription.objects.trigger_expiring() -> int # number of expirations\n```\n\nTrigger subscriptions that are suspended:\n\n```\nSubscription.objects.trigger_suspended() -> int # number of renewals\n```\n\nTrigger subscriptions that have been suspended for longer than `timeout_hours` to\nend (uses `subscription.end` date, not `subscription.last_updated`):\n\n```\nSubscription.objects.trigger_suspended_timeout(timeout_hours=48) -> int # number of suspensions\n```\n\nTrigger subscriptions that have been stuck in renewing state for longer than `timeout_hours`\nto be marked as an error (uses `subscription.last_updated` to determine the timeout):\n\n```\nSubscription.objects.trigger_stuck(timeout_hours=2) -> int # number of error subscriptions\n```\n\n\n### Tasks\n\nThe following tasks are defined but are not scheduled:\n\n```\nsubscriptions.tasks.trigger_renewals\nsubscriptions.tasks.trigger_expiring\nsubscriptions.tasks.trigger_suspended\nsubscriptions.tasks.trigger_suspended_timeout\nsubscriptions.tasks.trigger_stuck\n```\n\nIf you'd like to schedule the tasks, do so with a celery beat configuration like this:\n\n```\n# settings.py\n\nCELERYBEAT_SCHEDULE = {\n \"subscriptions_renewals\": {\n \"task\": \"subscriptions.tasks.trigger_renewals\",\n \"schedule\": crontab(hour=0, minute=10),\n },\n \"subscriptions_expiring\": {\n \"task\": \"subscriptions.tasks.trigger_expiring\",\n \"schedule\": crontab(hour=0, minute=15),\n },\n \"subscriptions_suspended\": {\n \"task\": \"subscriptions.tasks.trigger_suspended\",\n \"schedule\": crontab(hour=\"3,6,9\", minute=30),\n },\n \"subscriptions_suspended_timeout\": {\n \"task\": \"subscriptions.tasks.trigger_suspended_timeout\",\n \"schedule\": crontab(hour=0, minute=40),\n \"kwargs\": {\"hours\": 48},\n },\n \"subscriptions_stuck\": {\n \"task\": \"subscriptions.tasks.trigger_stuck\",\n \"schedule\": crontab(hour=\"*/2\", minute=50),\n \"kwargs\": {\"hours\": 2},\n },\n}\n```\n\n## Contributing\n\nWe use `pre-commit ` to enforce our code style rules\nlocally before you commit them into git. Once you install the pre-commit library\n(locally via pip is fine), just install the hooks::\n\n pre-commit install -f --install-hooks\n\nThe same checks are executed on the build server, so skipping the local linting\n(with `git commit --no-verify`) will only result in a failed test build.\n\nCurrent style checking tools:\n\n- flake8: python linting\n- isort: python import sorting\n- black: python code formatting\n\nNote:\n\n You must have python3.6 available on your path, as it is required for some\n of the hooks.\n\n\n## Generating Migrations\n\nAfter installing all dependencies, you can generate required migration files\nlike so:\n\n```bash\n$ poetry run ipython migrate.py \n```\n\n\n## Publishing a new version\n\n1. Bump the version number in pyproject.toml and src/subscriptions/init.py\n2. Commit and push to master\n3. From github, [create a new release](https://github.com/kogan/django-subscriptions/releases)\n4. Name the release \"v\" using the version number from step 1.\n5. Publish the release\n6. If the release successfully builds, circleci will publish the new package to pypi\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/kogan/", "keywords": "subscriptions,django", "license": "BSD-3-Clause", "maintainer": "Josh Smeaton", "maintainer_email": "josh.smeaton@gmail.com", "name": "django-subscriptions", "package_url": "https://pypi.org/project/django-subscriptions/", "platform": "", "project_url": "https://pypi.org/project/django-subscriptions/", "project_urls": { "Documentation": "http://github.com/kogan/django-subscriptions/", "Homepage": "http://github.com/kogan/", "Repository": "http://github.com/kogan/django-subscriptions/" }, "release_url": "https://pypi.org/project/django-subscriptions/1.1.0/", "requires_dist": [ "django-fsm (>=2.6,<3.0)", "django-fsm-log (>=1.6,<2.0)", "enum34 (>=1.1,<1.2); python_version >= \"2.7\" and python_version < \"2.8\"" ], "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "summary": "A django package for managing subscription states", "version": "1.1.0" }, "last_serial": 5928007, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "0614e1e435e7d6e864e629bac3d45391", "sha256": "08a191cc69e69d131a159da706363704f7475028ad26ffd6610bcb5bd390475a" }, "downloads": -1, "filename": "django_subscriptions-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "0614e1e435e7d6e864e629bac3d45391", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 2786, "upload_time": "2019-04-13T03:00:59", "url": "https://files.pythonhosted.org/packages/87/90/2f549637f1fe712bbe90cfd5d0211240a268f8d28e5213931f3ba4e5e70f/django_subscriptions-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c9163ae73322207f3ca2d6e0c8aee67a", "sha256": "47942b7c810293198531363a35f2f8400619c308d1ccd37909aed84391c3c0eb" }, "downloads": -1, "filename": "django-subscriptions-0.1.0.tar.gz", "has_sig": false, "md5_digest": "c9163ae73322207f3ca2d6e0c8aee67a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 3001, "upload_time": "2019-04-13T03:00:57", "url": "https://files.pythonhosted.org/packages/6f/76/0463228ed7ec50f7f80f51f33fc084c0f61624994cf78936bb181cd08ed4/django-subscriptions-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "0e60a627404cdcf58c97e763569213a0", "sha256": "b09076956847bf897d1b3b71bd11283f4c0c31f7523d047722a9205518e75029" }, "downloads": -1, "filename": "django_subscriptions-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "0e60a627404cdcf58c97e763569213a0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 11188, "upload_time": "2019-04-13T12:40:48", "url": "https://files.pythonhosted.org/packages/f8/f6/1d248e9821b3c3804d9ac2a20bd0ff8f48971c0ca8b3677ff6114f8360c7/django_subscriptions-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "726ebd8ac7a3e6152b7ef09e3654e17b", "sha256": "e002d6ce736e164f35c6fcf32be4f79f5b6d5c9cdf01c6c1c06f2639565f9bda" }, "downloads": -1, "filename": "django-subscriptions-0.2.0.tar.gz", "has_sig": false, "md5_digest": "726ebd8ac7a3e6152b7ef09e3654e17b", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 11269, "upload_time": "2019-04-13T12:40:47", "url": "https://files.pythonhosted.org/packages/c2/8f/35190d9a249960f81cdbe9c3ee69abfb44211260e6d6ba2d84f58ccfc3af/django-subscriptions-0.2.0.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "a6855fc726ec574e21a49182d029052c", "sha256": "c762a7b99fe95affe74ee6ae571d8cd814062232fd81885d14526cd20c6a8218" }, "downloads": -1, "filename": "django_subscriptions-0.3.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "a6855fc726ec574e21a49182d029052c", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "size": 12175, "upload_time": "2019-05-01T06:29:59", "url": "https://files.pythonhosted.org/packages/70/b9/3b9e9c03f806829a92247ccab59c78fd49a5d4c8ac7f33ddd37cb43221e9/django_subscriptions-0.3.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2de0acde9449d6a79e8d7e4e24c3f985", "sha256": "0a553b8e196e9209b725effa108e2c067da6be112319ad0ec3381c5b1b9d14b1" }, "downloads": -1, "filename": "django-subscriptions-0.3.0.tar.gz", "has_sig": false, "md5_digest": "2de0acde9449d6a79e8d7e4e24c3f985", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "size": 12220, "upload_time": "2019-05-01T06:29:57", "url": "https://files.pythonhosted.org/packages/3f/ec/eb7ac85cfaeaecfcf86f7e30f0db7a3994435ff26fb1fb7f10e3b92ed103/django-subscriptions-0.3.0.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "928aff1f0173fc566758ae93af558d40", "sha256": "893537bcc1f81155e6823756b4bd546a3610e4d8c987a99d5fe3d5b05cc4167c" }, "downloads": -1, "filename": "django_subscriptions-0.4.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "928aff1f0173fc566758ae93af558d40", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "size": 12364, "upload_time": "2019-05-07T00:56:50", "url": "https://files.pythonhosted.org/packages/4a/8b/dae9c2069e22c449461949f1d5db57e82ad0f5139997bcc3f82286cdd73b/django_subscriptions-0.4.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ce85ae477ddf6ae26f2d9fcd49282daa", "sha256": "90b12c15eb307f509bda78501661059d41b6a258636e46e6e6325f7bd565488a" }, "downloads": -1, "filename": "django-subscriptions-0.4.0.tar.gz", "has_sig": false, "md5_digest": "ce85ae477ddf6ae26f2d9fcd49282daa", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "size": 12512, "upload_time": "2019-05-07T00:56:49", "url": "https://files.pythonhosted.org/packages/34/d0/e3e7c077cf2c992c5c9a42abb628289fe42899ce8a630d5b889bb0b09c36/django-subscriptions-0.4.0.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "ac6bfc573d2b79f19d3a68b1ee466353", "sha256": "93749e6c500b7cbf5409337604e328421e794403d4e750b4abefe668d2aa400c" }, "downloads": -1, "filename": "django_subscriptions-0.5.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "ac6bfc573d2b79f19d3a68b1ee466353", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "size": 12375, "upload_time": "2019-06-04T05:44:20", "url": "https://files.pythonhosted.org/packages/45/35/bcaa5371f35a2eea28278050b9cd72cfffe0143a1ae05a071f13a23b8d37/django_subscriptions-0.5.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b0768791b24c7beb0a5b01faa029e879", "sha256": "923e34b599f71375acbc3d6fb83d8df35112d4f8b144a41f389463c5689b8b5e" }, "downloads": -1, "filename": "django-subscriptions-0.5.0.tar.gz", "has_sig": false, "md5_digest": "b0768791b24c7beb0a5b01faa029e879", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "size": 12528, "upload_time": "2019-06-04T05:44:18", "url": "https://files.pythonhosted.org/packages/c9/18/c5de4e3e8f26a3414afef10a3b803ebbf8e0dd60932b25f0e050032e51c4/django-subscriptions-0.5.0.tar.gz" } ], "0.5.1": [ { "comment_text": "", "digests": { "md5": "bb4f7f9e66b38eef066076e56fa8294f", "sha256": "3dd116c61ec26bb3085b93fd55743f485e39f63c4bcd7da8e180aaca6112c106" }, "downloads": -1, "filename": "django_subscriptions-0.5.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "bb4f7f9e66b38eef066076e56fa8294f", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "size": 12431, "upload_time": "2019-06-13T06:14:53", "url": "https://files.pythonhosted.org/packages/4d/a9/61a980e5ce29979199ef1c7699189e3e3d7b28f090ee59ad7f5d55b98eb4/django_subscriptions-0.5.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e19a64371636ace36eb1e3e6f8f30b69", "sha256": "619ef6dfc7a5a96c360705ae20aac8a69f326a474d5c88a7cd8e0c7a3b47c25e" }, "downloads": -1, "filename": "django-subscriptions-0.5.1.tar.gz", "has_sig": false, "md5_digest": "e19a64371636ace36eb1e3e6f8f30b69", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "size": 12578, "upload_time": "2019-06-13T06:14:51", "url": "https://files.pythonhosted.org/packages/80/cf/b3af591707717a04305a1c6c293b26d595264c149fa42a6f9e8842866e16/django-subscriptions-0.5.1.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "23ab92bb069bb3a83df7668eb45502ee", "sha256": "bef5944824c0035d9fd13da164a667fe8e4ad311da1413e0ed2367f05fad4200" }, "downloads": -1, "filename": "django_subscriptions-1.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "23ab92bb069bb3a83df7668eb45502ee", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "size": 12567, "upload_time": "2019-07-04T00:23:30", "url": "https://files.pythonhosted.org/packages/52/d2/6e2ef5840644450856676640085f5e665a96311c6c4ae63f97996ea88eb8/django_subscriptions-1.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ac904b4fa6d1226c721f38376002ceed", "sha256": "386766c4124ba96767e1cd919878b632a607e83de7e3b1edb50bd89eb21b5965" }, "downloads": -1, "filename": "django-subscriptions-1.0.0.tar.gz", "has_sig": false, "md5_digest": "ac904b4fa6d1226c721f38376002ceed", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "size": 12781, "upload_time": "2019-07-04T00:23:29", "url": "https://files.pythonhosted.org/packages/28/46/fd75c9b3e31ef5e0a8e23d3fbd750688af3ca9246f70de6630246d177e82/django-subscriptions-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "d2446932dc1426c057b9f38ed7b064b0", "sha256": "48426ac05b5e8500df6dd768ac7b06b2660b2ff2351b50b613543ed9d5f11692" }, "downloads": -1, "filename": "django_subscriptions-1.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "d2446932dc1426c057b9f38ed7b064b0", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "size": 13160, "upload_time": "2019-09-13T05:58:40", "url": "https://files.pythonhosted.org/packages/3f/a9/96b354d7ed626d93de3c01a2ed2068c4959555ed56798e0c83452b4d0316/django_subscriptions-1.0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5e93b3bf5c53b56b29056b58f42cea70", "sha256": "fff9e77c75e03b22ef5ee6e7e363f6626efcc8376657d93190f05e5d7c61b899" }, "downloads": -1, "filename": "django-subscriptions-1.0.1.tar.gz", "has_sig": false, "md5_digest": "5e93b3bf5c53b56b29056b58f42cea70", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "size": 12870, "upload_time": "2019-09-13T05:58:38", "url": "https://files.pythonhosted.org/packages/2f/06/72e49c967c135032aae66dde1df5b14824fe134abde6a565260be2d34c4f/django-subscriptions-1.0.1.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "673f87176089c7c33f9f720ef1ee6658", "sha256": "d4da418ba4b92ed8040949b36b40f49d253ea64299db11f53098be3b7364aa46" }, "downloads": -1, "filename": "django_subscriptions-1.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "673f87176089c7c33f9f720ef1ee6658", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "size": 13292, "upload_time": "2019-10-04T12:09:53", "url": "https://files.pythonhosted.org/packages/17/c2/052c83177183623052361af5709c25bd258c2544c915b13826378c379480/django_subscriptions-1.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "82a01899e04f5ae5b3eaa0428803488d", "sha256": "e9b83245a577579e08221f8f9a0df51c9e34638cd282b4d7c35f8aed90431a13" }, "downloads": -1, "filename": "django-subscriptions-1.1.0.tar.gz", "has_sig": false, "md5_digest": "82a01899e04f5ae5b3eaa0428803488d", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "size": 13098, "upload_time": "2019-10-04T12:09:52", "url": "https://files.pythonhosted.org/packages/1f/77/12117a841943a18f9b5490d7d0185d1e573b4889b6861f560d6222e64b2c/django-subscriptions-1.1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "673f87176089c7c33f9f720ef1ee6658", "sha256": "d4da418ba4b92ed8040949b36b40f49d253ea64299db11f53098be3b7364aa46" }, "downloads": -1, "filename": "django_subscriptions-1.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "673f87176089c7c33f9f720ef1ee6658", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "size": 13292, "upload_time": "2019-10-04T12:09:53", "url": "https://files.pythonhosted.org/packages/17/c2/052c83177183623052361af5709c25bd258c2544c915b13826378c379480/django_subscriptions-1.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "82a01899e04f5ae5b3eaa0428803488d", "sha256": "e9b83245a577579e08221f8f9a0df51c9e34638cd282b4d7c35f8aed90431a13" }, "downloads": -1, "filename": "django-subscriptions-1.1.0.tar.gz", "has_sig": false, "md5_digest": "82a01899e04f5ae5b3eaa0428803488d", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*", "size": 13098, "upload_time": "2019-10-04T12:09:52", "url": "https://files.pythonhosted.org/packages/1f/77/12117a841943a18f9b5490d7d0185d1e573b4889b6861f560d6222e64b2c/django-subscriptions-1.1.0.tar.gz" } ] }