{ "info": { "author": "Garito", "author_email": "garito@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Plugins", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Topic :: Database" ], "description": "# yModel\nSchema is a [Marshmallow](https://marshmallow.readthedocs.io) subclass that saves the data and errors to private members (that you can access by using self.get_data() and self.get_errors())\n\nThe point is to not need a data class since, in an API context, all we need is json in json out\n\nIt highly uses decorators to avoid (because is automatic) the need of validation and post processing the response\n\nTree is the tree version with materialized paths and order in a object member (if needed)\n\nMongoSchema and yMongoTree are the MongoDB versions for CRUD plain schemas and tree structures\n\nIt is part of the yRest framework (which includes [ySanic](https://github.com/Garito/ySanic) and [yAuth](https://github.com/Garito/yAuth) by the moment and yOpenSanic in the future)\n\n## Example\n```python\nclass Person(Schema):\n name = fields.Str(required = True)\n age = fields.Int()\n\n @can_crash(Exception, ErrorSchema, 404)\n @can_crash(ValidationError, ErrorSchema)\n @produces(NameOnlyOkSchema, as_ = \"name\")\n @consumes(NameOnlyRequestSchema)\n async def set_name(self, request, schema):\n if schema.get_data()[\"name\"] == \"Exception\":\n raise Exception(\"It can crash from a regular Exception\")\n\n if schema.get_data()[\"name\"] == \"MakeItCrash\":\n raise ValidationError(\"Crash test\")\n\n self.get_data()[\"name\"] = schema.get_data()[\"name\"]\n return self.get_data[\"name\"]\n\n @deprecate(\"Reason to deprecate it\")\n async def to_deprecate(self, request):\n return True\n```\n\nAs you can see, the first part of the class is a regular marshmallow class with fields declaration\n\nThe interesting part is the ```set_name``` and ```to_deprecate``` members full of decorators\n\n```set_name``` consumes a ```NameOnlyRequestSchema``` (which is another yModel use for input validation) that will be filled with the request.json (by default)\n\nWith this decorator you will recieve an extra ```*args``` item with the model already validated\n\nThen it produces a ```NameOnlyOkSchema``` with the return value from the function. So in this case will be something like\n```json\n{\n \"ok\": true,\n \"result\": \"the name of the person\"\n}\n```\ncan_crash automates the error processing by returning a response like\n```json\n{\n \"ok\": false,\n \"message\": \"the raised error\"\n}\n```\nin the example two exception has been defined:\n\nIf the name passed is \"Exception\" will raise a regular python Exception which will be captured by the first ```can_crash``` returning and ```ErrorSchema``` and a 404 status\n\n```json\n{\n \"ok\": false,\n \"message\": \"It can crash from a regular Exception\"\n}\n```\n\nIf the name passed is \"MakeItCrash\" it will be captured by the second ```can_crash``` and will return an ```ErrorSchema``` too but with the status 400\n\n```json\n{\n \"ok\": false,\n \"message\": \"Crash test\"\n}\n```\n\nyModel defines some basic schemas for returning ok ```OkSchema``` and not ok ```ErrorSchema``` that you can subclass with your own needs (or even use a schema build by you from scratch. It only needs to be a subclass of yModel)\n\nThe ```deprecated``` decorator will be mostly useful with the yOpenSanic to mark an API endpoint as deprecated\n\nThis decorators will help later for introspection since the tree structures are tricky to instrospect\n\n## Installation\n```pip install yModel```\n\n## Tree structures\nAdd a ```path``` and ```name``` fields to build the materialized path or add a ```@pre_load``` function if you need a different source for the slug (it's using [python-slugify](https://github.com/un33k/python-slugify) but you can use any one else if you add your own ```@pre_load``` function)\n\nCheck out the tests for examples\n\n## MongoDB\nUse this class as a guide to create you own backend need (will be nice if you pull request it to this project if the backend is an open sourced one)\n\n## Help\nFeel free to help if you think something is weird or incomplete by submiting a pull request\n\nI've spend an indecent amount of time dealing with tree structures to know what's essential for that matter but will be no surprise if you have a nice idea to improve this code (at the end of the day I bet you are a smart person)\n\n### What is already needed\n- [] Elasticsearch module\n- [] Redis module\n- [] More testing\n- [] Continous integration\n- [] Better help & documentation\n\n### I'm not a technical person but still want to help\nYou can tip the project with cryptos too:\n\nBTC: 1GtKxwZGR65ar9V8xafxhMiniZyqXej2GC\n\nETH: 0x01bd478b8C07633D2f4E58AC553f72CE4E590d56\n\nLTC: LYUzrFX6ck5uMhw5VqcD9piQHnX7oeSLdh\n\nXMR: 49stcvbfjEkWLjb6mdG21zMJ3uRrLmN3bazGQ8cHjjsVHYYyY61N6P7emCXhpsvB2Vc8Uuz2FA1Qk6hkE8e4ADmJQQ64eyT\n\nADA: DdzFFzCqrhsoUF5UjGGAYUayV5uNCJZ17PJn9V8X9MTQ26m2wDVycme42gufKufPNWMazfJLg8RKHpc1iFvn6j8BTJjaozGtLPzCDx5t\n\nNEM: NDGYO6X3NTD6CX3V7MCCYKQPBIOYGZRXEKDLCDW2\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/Garito/yModel", "keywords": "data schema marshmallow trees materialized_paths mongodb", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "yModel", "package_url": "https://pypi.org/project/yModel/", "platform": "", "project_url": "https://pypi.org/project/yModel/", "project_urls": { "Homepage": "https://github.com/Garito/yModel" }, "release_url": "https://pypi.org/project/yModel/0.0.2/", "requires_dist": [ "marshmallow", "motor", "python-slugify" ], "requires_python": ">=3.6", "summary": "Marshmallow subclasses with extended features", "version": "0.0.2" }, "last_serial": 4627013, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "47578d6e54ad408427616ccf13e9f6c5", "sha256": "a0ef7d283d7771ad13026401ab9a03378df10d4badf834261649b59d57ab2057" }, "downloads": -1, "filename": "yModel-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "47578d6e54ad408427616ccf13e9f6c5", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 12822, "upload_time": "2018-11-12T16:07:36", "url": "https://files.pythonhosted.org/packages/f8/56/61132db8e3d827332ce99d2b7a1c4c19709202ede9a07d3d3a8239080468/yModel-0.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "475046a2d18152849fa13ea8fbd04b32", "sha256": "e0ce4468e17a473360eaa91cd3c835b93e166056ad96fccf4b5386b645464eb7" }, "downloads": -1, "filename": "yModel-0.0.1.tar.gz", "has_sig": false, "md5_digest": "475046a2d18152849fa13ea8fbd04b32", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 12206, "upload_time": "2018-11-12T16:07:37", "url": "https://files.pythonhosted.org/packages/05/80/fd3d03e850e593c8120c3b2aaa8f3b6c8772b5507ec051853f3e5f86e268/yModel-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "a3e263a8b56e462d58c8f497272b1a5f", "sha256": "c0f8e9336ebf6862c44a8814f2b1851d878c6af3f2f233a159dc55bf90b91ca9" }, "downloads": -1, "filename": "yModel-0.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "a3e263a8b56e462d58c8f497272b1a5f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 13102, "upload_time": "2018-12-22T02:06:23", "url": "https://files.pythonhosted.org/packages/ea/31/8a354c4e36e3513a57b5f331e3d74f80b0b2bae50a9860bf6b4dd9fe638c/yModel-0.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "40b77bb91b20d648eeaad6593478b967", "sha256": "cb2af3e34c47aa3c96df30ab0241acf04652fd4917ccd80ab54c2761e0df6443" }, "downloads": -1, "filename": "yModel-0.0.2.tar.gz", "has_sig": false, "md5_digest": "40b77bb91b20d648eeaad6593478b967", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 12486, "upload_time": "2018-12-22T02:06:25", "url": "https://files.pythonhosted.org/packages/ad/16/cf40b5e1e0eab07d69e5b646792c59e353c6d9a39ebc72290b7a095f993a/yModel-0.0.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "a3e263a8b56e462d58c8f497272b1a5f", "sha256": "c0f8e9336ebf6862c44a8814f2b1851d878c6af3f2f233a159dc55bf90b91ca9" }, "downloads": -1, "filename": "yModel-0.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "a3e263a8b56e462d58c8f497272b1a5f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6", "size": 13102, "upload_time": "2018-12-22T02:06:23", "url": "https://files.pythonhosted.org/packages/ea/31/8a354c4e36e3513a57b5f331e3d74f80b0b2bae50a9860bf6b4dd9fe638c/yModel-0.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "40b77bb91b20d648eeaad6593478b967", "sha256": "cb2af3e34c47aa3c96df30ab0241acf04652fd4917ccd80ab54c2761e0df6443" }, "downloads": -1, "filename": "yModel-0.0.2.tar.gz", "has_sig": false, "md5_digest": "40b77bb91b20d648eeaad6593478b967", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 12486, "upload_time": "2018-12-22T02:06:25", "url": "https://files.pythonhosted.org/packages/ad/16/cf40b5e1e0eab07d69e5b646792c59e353c6d9a39ebc72290b7a095f993a/yModel-0.0.2.tar.gz" } ] }