{ "info": { "author": "Omar Bohsali", "author_email": "me@omarish.com", "bugtrack_url": null, "classifiers": [], "description": "# Mutations\n\n[![pypi-version]][pypi]\n\nCompose your business logic into commands that sanitize and validate input.\n\n## Install\n\n```bash\n$ pip install mutations\n```\n\n## How it Works:\n\n1. Subclass `mutations.Mutation`\n2. Define your inputs.\n3. Define an `execute` method in your command.\n4. Run it, like this: `SimpleMutation.run(foo='bar')`\n\nTo learn more, see [this blog post](https://omarish.com/2018/02/17/mutations.html).\n\n## Example\n\n```python\nimport mutations\n\nclass UserSignup(mutations.Mutation):\n \"\"\"Define the inputs to your mutation here. \"\"\"\n email = mutations.fields.CharField(required=True)\n full_name = mutations.fields.CharField(required=True)\n send_welcome_email = mutations.fields.Boolean(required=False, default=True)\n\n def validate_email_address(self):\n \"\"\"Custom validation for a field.\n\n If you encounter any validation errors and want to raise, you should\n raise mutation.ValidationError or some sublcass thereof. Otherwise, it\n assumes there were no problems.\n\n Any function beginning with `validate_` is assumed to be a validator\n function and will be run before the mutation can execute.\n \"\"\"\n if not self.email.is_valid():\n raise mutations.ValidationError(\"email_not_valid\", \"Email is not valid.\")\n\n def execute(self):\n \"\"\"Executes the mutation.\n\n This method does the heavy lifting. You can call it by calling .run() on\n your mutation class.\n \"\"\"\n user = User.objects.create(email=self.email, name=self.full_name)\n if self.send_welcome_email:\n EmailServer.deliver(recipient = self.email)\n return user\n```\n\n## Calling Commands\n\n```python\n>>> result = UserSignup.run(email=email, full_name=\"Bob Boblob\")\n>>> result.success\nTrue\n>>> result.return_value\n\n>>> result.errors\n\nresult = ...\n\n```\n\n```python\n>>> result = UserSignup.run(email=None)\n>>> result.success\nFalse\n>>> result.errors\nmutations.ErrorDict({\n 'email': ['email_not_valid']\n})\n>>> result.value\nNone\n```\n\n## Only Run Validations\n\n```python\n>>> result = UserSignup.validate(email=email, full_name=\"Bob Boblob\")\n>>> result.is_valid\nTrue\n```\n\n## Testing\n\n```bash\n$ make tests\n```\n\nWhen you're ready to do a release, please make sure tests pass across both 2.7\nand 3.6 by running tox:\n\n```bash\n$ tox\n```\n\n# Versioning\n\nThis project uses [Semantic Versioning][semver].\n\n# Thanks\n\nThanks to Cypriss for the excellent Ruby [Mutations Gem][1]. I created this library because I was looking for something similar for Python.\n\n[1]: https://github.com/cypriss/mutations\n[semver]: https://semver.org/\n[pypi-version]: https://img.shields.io/pypi/v/mutations.svg\n[pypi]: https://pypi.org/project/mutations/", "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/omarish/mutations", "keywords": "business logic,django,fat models,thin models,input validation,commands,validation", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "mutations", "package_url": "https://pypi.org/project/mutations/", "platform": "", "project_url": "https://pypi.org/project/mutations/", "project_urls": { "Homepage": "http://github.com/omarish/mutations" }, "release_url": "https://pypi.org/project/mutations/0.4.0/", "requires_dist": null, "requires_python": "", "summary": "Encapsulate your business logic in command classes.", "version": "0.4.0" }, "last_serial": 4212334, "releases": { "0.2": [ { "comment_text": "", "digests": { "md5": "597d69a491cfe2d164e7440a8ffa2392", "sha256": "3f789829ad8e105b017a56d3db0e76f1a4f870a8a6dc3776103d19b933d2bcf6" }, "downloads": -1, "filename": "mutations-0.2.tar.gz", "has_sig": false, "md5_digest": "597d69a491cfe2d164e7440a8ffa2392", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2973, "upload_time": "2018-02-09T17:43:38", "url": "https://files.pythonhosted.org/packages/59/68/56f0f7cfd218f32a1249bbe89c172836c60665803df9a3e95bbc85531138/mutations-0.2.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "490e80715fedf54e545888461a31fcf1", "sha256": "46293fd66c1dd8410d79d8c8eb06b538de615573c79147a116f9e730627cb504" }, "downloads": -1, "filename": "mutations-0.2.1.tar.gz", "has_sig": false, "md5_digest": "490e80715fedf54e545888461a31fcf1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3001, "upload_time": "2018-02-09T17:50:17", "url": "https://files.pythonhosted.org/packages/dc/0c/810e1c2c1167291c12f49d1908d7e2b563cdc7d979803bdac50bfc0e9069/mutations-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "93b534a82e2f6dc103595abce539b77c", "sha256": "d47ae58b5c370107fa7ab75aaaf1d42ce9a8dc6bb3aa734c89a620f3be22d665" }, "downloads": -1, "filename": "mutations-0.2.2.tar.gz", "has_sig": false, "md5_digest": "93b534a82e2f6dc103595abce539b77c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2995, "upload_time": "2018-02-20T21:01:15", "url": "https://files.pythonhosted.org/packages/09/76/17501c7faf70a9fc1806f5f3b4e45a2c9ae559671bbd31ce88310d94223a/mutations-0.2.2.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "0a4adc2673c13f93dd3235e3f15d5f33", "sha256": "0c7bc91fdb5dc4605582e3c503ab2c71438c70fc2eba213351fdb6b6db534804" }, "downloads": -1, "filename": "mutations-0.3.0.tar.gz", "has_sig": false, "md5_digest": "0a4adc2673c13f93dd3235e3f15d5f33", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3648, "upload_time": "2018-05-30T19:46:36", "url": "https://files.pythonhosted.org/packages/4c/28/c7df43eb5d63724e30afb2ed8586aa2c3d32fcef051f742b640b854f760e/mutations-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "bbe06b558737d0853884679ae681977d", "sha256": "01d7066a5cfccf1b3e32f89b2feef0cb26120dfe258d50890f1c63255c0ef2c0" }, "downloads": -1, "filename": "mutations-0.3.1.tar.gz", "has_sig": false, "md5_digest": "bbe06b558737d0853884679ae681977d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5318, "upload_time": "2018-06-01T15:26:13", "url": "https://files.pythonhosted.org/packages/d8/c5/5f57c7d77982ebf6f4120511fc5c528ff4e26d3ba771e1e571b2f6ca2eaa/mutations-0.3.1.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "e05c3658f3c859d68824388152b06ba8", "sha256": "813d57b48adaeb643d0d8c66f4b0bb7f74a26452cdc4ceaca312daca92572a00" }, "downloads": -1, "filename": "mutations-0.4.0.tar.gz", "has_sig": false, "md5_digest": "e05c3658f3c859d68824388152b06ba8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5507, "upload_time": "2018-08-27T19:42:18", "url": "https://files.pythonhosted.org/packages/e9/2c/db7144437418ccd7137cb5075f808e10df9068773265bbf6544dfc93e66c/mutations-0.4.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e05c3658f3c859d68824388152b06ba8", "sha256": "813d57b48adaeb643d0d8c66f4b0bb7f74a26452cdc4ceaca312daca92572a00" }, "downloads": -1, "filename": "mutations-0.4.0.tar.gz", "has_sig": false, "md5_digest": "e05c3658f3c859d68824388152b06ba8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5507, "upload_time": "2018-08-27T19:42:18", "url": "https://files.pythonhosted.org/packages/e9/2c/db7144437418ccd7137cb5075f808e10df9068773265bbf6544dfc93e66c/mutations-0.4.0.tar.gz" } ] }