{ "info": { "author": "Michael Lasevich", "author_email": "mlasevich+quick@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3" ], "description": "[![Build Status](https://travis-ci.org/mlasevich/QuickScheme.svg?branch=master)](https://travis-ci.org/mlasevich/QuickScheme)\n[![Coverage Status](https://coveralls.io/repos/github/mlasevich/QuickScheme/badge.svg?branch=master)](https://coveralls.io/github/mlasevich/QuickScheme?branch=master)\n[![PyPI version](https://badge.fury.io/py/QuickScheme.svg)](https://badge.fury.io/py/QuickScheme)\n\n# QuickScheme - Quick Way To Define Data Schema and Mapping Data To Objects\n\n| ***\u26a0\ufe0fWARNING*** : This is currently a _Work in Progress_ and is not ready for general use yet |\n| :---: |\n\n## QuickScheme Release Notes\n* 0.2.0\n * Add before/instead/after field set hooks\n* 0.1.1\n * Add Validators\n* 0.1.0\n * Initial version\n\n## Quick Intro to QuickScheme\n\nQuickScheme is a quick and easy to map arbitrary data in any python dict to an object without\nforcing markup of the data file.\n\nThis allows easy data definition in YAML or JSON files including references, defaults, etc\n\n\n## Features\n\n* Easily load standard python data (from python dict, or json or yaml)\n* Allow use of the data directly in Python code\n* Produce \"inflated\" data with default values and references populated\n* Do all of this without relying on custom markup in the source data\n\n## Usage\n\n### Basic Example Walkthrough\n\n| NOTE: This example exists in examples directory as \"basic.py\" |\n| :---: |\n\nTo get the most out of QuickScheme you need to define the objects your schema consists of.\n\nfor example if we want to process a yaml file like this:\n\n version: 1\n updates:\n # this is our update log to demonstrate lists \n - 2019-08-14: initial version\n - 2019-08-15: added user3\n - 2019-08-15: added project2\n users:\n user1:\n first_name: User\n last_name: One\n user2:\n first_name: Another\n last_name: User\n email: another.user@mydomain.com\n desc: Another User\n user3:\n first_name: Another\n last_name: User\n email: another.user@mydomain.com\n desc: Another User\n\n groups:\n users:\n desc: Regular Users\n admins: Admins\n\n projects:\n project1:\n desc: My First Project\n users:\n - user1\n groups:\n - admins\n project2:\n desc: My Other Project\n groups:\n - users\n\nSo, what we have here is a version of the file, a list of users and groups and list of projects. \nA few interesting things:\n\n* **admin** group is defined by a string instead of a mapping\n* Users contain references to groups by a key\n* Similarly projects contain references to both users and groups\n\nSo, to be easily this we define our objects that represent the entities:\n\nLet us define Group first:\n\n class Group(SchemeNode):\n FIELDS = [\n Field('groupname', identity=True),\n Field('desc', brief=True, default='No Description')\n ]\n\nWhat is happening here:\n* We define an object called Group which extends our SchemeNode(a field defined mapping) with two \n fields:\n * _groupname_ - which is an identity field, meaning it is populated from the id of the field.\n If this object is in a mapping, this would be populated from the item's key, if it is in a\n sequence, it will be populated with sequence index number\n * _desc_ - our description. We specify a default value. We also mark it as our **brief** field,\n meaning if the item is specified as a string instead of a mapping, we will populate this field\n\nThis takes care of how we defined **admin** group and allows us to know the groupname if we are\nworking with this object directly in python.\n\nNext lets define User\n\n class User(SchemeNode):\n FIELDS = [\n Field('username', identity=True),\n Filed('userid', ftype=int, required=True),\n Field('first_name', default=\"\", required=True),\n Field('last_name', default=\"\", required=True),\n Field('email', default=\"\", required=False),\n Field('desc', default=\"No Description\", required=False),\n Field('groups', ftype=ListOfReferences(Group, \".groups\", False),\n default=[], required=False),\n ]\n\nWhat is happening here:\n* Similar to `Group` object we extended `SchemeNode` to create a field based mapping in which:\n * We defined identity field `username`\n * We defined an integer field `userid` - and made it a required field\n * We added two more required fields `first_name` and `last_name` - which are both strings because\n **ftype** is omitted\n * We added optional `email` and `desc` fields - with latter having a default value\n * And we added a `groups` field, wich is a list of references to Group objects which are to be\n resolved against 'groups' subkey of the root document.\n\nLastly We need a Project object:\n\n\n class Project(SchemeNode):\n FIELDS = [\n Field('projectname', identity=True),\n Field('order', ftype=int, required=True),\n Field('users', ftype=ListOfReferences(User, \".users\"),\n default=\"\", required=True),\n Field('groups', ftype=ListOfReferences(Group, \".groups\"),\n default=[], required=False),\n ]\n\nThis is similar to previous objects\n\nNow to put it all together, we create a root Object that represents the document:\n\n class Data(SchemeNode):\n FIELDS = [\n Field('version', ftype=str, default='1'),\n Field('updates', ftype=ListOfNodes(str)),\n Field('groups', ftype=KeyBasedList(Group)),\n Field('users', ftype=KeyBasedList(User)),\n Field('projects', ftype=KeyBasedList(Project))\n ]\n\n PRESERVE_ORDER = True\n ALLOW_UNDEFINED = True\n\nHere we have the same thing describing the root document:\n\n* `version` field is a simple string\n* `updates` field is a List of Nodes - where each node is a simple string. \n* `groups`, `users`, and `projects` field are each _KeyBasedList_ - or list of objects mapped by \n their identity. The difference between _KeyBasedList_ and _SchemeNode_ is that all child nodes\n are of the same type and all keys are identities of those nodes.\n* In addition, we define a few more properties for this node:\n * `PRESERVE_ORDER` suggests to attempt to preserve the order of the keys in this object\n * `ALLOW_UNDEFINED` tells the parser that if it encounters a key that in not a defined field,\n store it as a plain value. If not set to _True_, QuickScheme will throw an exception\n\n\n### Usage Reference\n\n\n#### Node Types\n\nCurrently implemented Node Types:\n\n* ***SchemaNode*** - A basic mapping with pre-defined fields.\n * ***Options***\n * `FIELDS` - a list of Fields (see Fields bellow)\n * `ALLOW_UNDEFINED`(Default: False) - if true, store fields that are not defined\n * `MAP_CLASS` (Default: None) if set, force use of this _dict_ subclass.\n * `PRESERVE_ORDER` (Default: False) if set to true, attempt to preserve order of fields\n * `BRIEF_OUT` (Default: False) - if set to true, attempt to use brief format if brief\n field exists and is the only field that is set\n\n* ***KeyBasedListNode*** - A list of nodes presented as a mapping, where all nodes are of the same\n type, and the key in the mapping is the identity field for each node.\n * ***Options***\n * `TYPE` - type of nodes contained in this list\n * ***Helper Functions***\n * ***KeyBasedList(item_type)*** generates a ***KeyBasedListNode*** class with TYPE set to \n `item_type`. For example, to create a list of ***Group*** nodes keyed by their id, use \n `KeyBasedList(Group)`\n\n* ***ListOfNodesNode*** - Basic sequence of items (list or array) where each of the items is of same\n type\n * ***Options***\n * `TYPE` - type of nodes contained in this List\n * ***Helper Functions***\n * ***ListOfNodes(item_type)*** generates a ListOfNodesNode with TYPE set to `item_type`.\n For example, to create a list of ***Group*** nodes use `ListOfNodes(Group)`\n\n* ***ReferenceNode*** - A Node that stores an ID that references another node stored in \n ***KeyBasedListNode*** object somewhere in document\n * ***Options***\n * `PATH` - Path to the ***KeyBasedListNode*** in the document. Path uses '.' as separator.\n * `DEREFERENCE` - (Default: True) If set to true, dereference the item on conversion to\n data. If False, then when converting to data, return only the id field.\n * ***Helper Functions***\n * ***ListOfNodes(item_type)*** generates a ListOfNodesNode with TYPE set to `item_type`.\n For example, to create a list of ***Group*** nodes use `ListOfNodes(Group)`\n\n#### Fields\n\nDefinitions of key-based fields\n\n* ***Field(name, [options])*** Basic field definition\n * Options:\n * `name` - (_string_) name of the field key in the parent\n * `ftype` - (_Class_) - Field Type. Default is string May be any class that can be\n initialized with the data or a derivative of `SchemeBaseNode`\n * `required` - (_bool_) - If true, this field must be specified explicitly.)\n * `default` - (_string_ or _callable_) - If specified, value to use if field is not\n specified. If value is a callable, it is executed with the object as argument \n * `identity` - (_bool_) - if true, this fields is set when identity is set. By default, only\n one identity field is allowed to be present.\n * `brief` - (_bool_) - if True, this field is set when \"brief\" format (i.e. specifying\n value) as a value instead of a mapping) - By default only one brief field is allowed. If\n more complicated processing is required, do not set this field and instead implement\n `_brief_set(data)` method in your class deriving from `SchemeNode`\n * `always` - (_bool_) - If _true_(default) show this field when asking for data even if\n not set. If _false_ only show if explicitly set\n * `validator` - (_callable_) - If provided, called to validate this field. Must take \n `FieldValue` object as first parameter\n\n## TODOS:\n\nThings that may be documented but not yet implemented or are in works:\n\n(right now this is a very open list, many things are not yet done)\n\n* `Node` specifications\n * ???\n\n* `Field` specifications\n * ???\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://mlasevich.github.io/QuickScheme/", "keywords": "", "license": "Apache 2.0", "maintainer": "", "maintainer_email": "", "name": "QuickScheme", "package_url": "https://pypi.org/project/QuickScheme/", "platform": "", "project_url": "https://pypi.org/project/QuickScheme/", "project_urls": { "Homepage": "https://mlasevich.github.io/QuickScheme/" }, "release_url": "https://pypi.org/project/QuickScheme/0.2.0/", "requires_dist": [ "PyYaml", "future" ], "requires_python": "", "summary": "Quick Way To Define Data Schema and Mapping Data To Objects", "version": "0.2.0" }, "last_serial": 5713163, "releases": { "0.1.0rc0": [ { "comment_text": "", "digests": { "md5": "ff8c6179bfa11491d44ac43806d7e03d", "sha256": "3c51935c39e3574feb57f8359dbf8850ff53f3613ae96dfc4aba110fc49a3665" }, "downloads": -1, "filename": "QuickScheme-0.1.0rc0-py2-none-any.whl", "has_sig": false, "md5_digest": "ff8c6179bfa11491d44ac43806d7e03d", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 21930, "upload_time": "2019-08-19T18:56:56", "url": "https://files.pythonhosted.org/packages/05/7c/adf662e8c9ee38c2f4bc6492e48e936def44fe2bb6be13c04a7727353c9c/QuickScheme-0.1.0rc0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a357844212219160d1db3a9de7da4d7d", "sha256": "d8ed33779cb25bc6ad135b26fa30148df43d777dcbd91f7c8d626d60269a546f" }, "downloads": -1, "filename": "QuickScheme-0.1.0rc0-py3-none-any.whl", "has_sig": false, "md5_digest": "a357844212219160d1db3a9de7da4d7d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 21930, "upload_time": "2019-08-19T18:58:54", "url": "https://files.pythonhosted.org/packages/15/52/9cc77ef9ab925917627b31925118ff4b6ade606259f14ace78fd4749a57a/QuickScheme-0.1.0rc0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "d46330a79751c6da1089127b6003fe5e", "sha256": "fe3dae0e1647525d69b71c98f66e57439522f5ec1e76d0eb2390cebcc0a8dd99" }, "downloads": -1, "filename": "QuickScheme-0.1.0rc0.tar.gz", "has_sig": false, "md5_digest": "d46330a79751c6da1089127b6003fe5e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16881, "upload_time": "2019-08-19T18:56:58", "url": "https://files.pythonhosted.org/packages/05/4a/1302978c7a55a4bd7bb903da781a371b3a72ae29e896d71f41d7d9c134b6/QuickScheme-0.1.0rc0.tar.gz" } ], "0.1.1rc0": [ { "comment_text": "", "digests": { "md5": "dde20aecd2c69ab18dc643a174aa499b", "sha256": "2a37d327a874d7142e7ac484e185e088807edeecac146f6252630376e95b57c1" }, "downloads": -1, "filename": "QuickScheme-0.1.1rc0-py2-none-any.whl", "has_sig": false, "md5_digest": "dde20aecd2c69ab18dc643a174aa499b", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 27709, "upload_time": "2019-08-20T18:05:09", "url": "https://files.pythonhosted.org/packages/ed/a0/c002b65e2f778f85aa0403dd08e7f62a4d7276a2a976b03827a42f76d9e4/QuickScheme-0.1.1rc0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9abf20812b7cc8101062dd8b3cd4c0b6", "sha256": "84a5913b156ac9621c0dbf913ae1245d5d2a3ea85a9a1fe18cdc8a0bc9ba4cc2" }, "downloads": -1, "filename": "QuickScheme-0.1.1rc0-py3-none-any.whl", "has_sig": false, "md5_digest": "9abf20812b7cc8101062dd8b3cd4c0b6", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 27694, "upload_time": "2019-08-20T05:49:38", "url": "https://files.pythonhosted.org/packages/68/ec/915e86540adc5e7ab9cfce01b3be8f5b298db66e20c473cbfcd645ac8c69/QuickScheme-0.1.1rc0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2855a911728e8839f2389343614e7aa7", "sha256": "b5fe17a9373c62f58ce9e74876fe36a123df2762628f41e0112c164875e87fba" }, "downloads": -1, "filename": "QuickScheme-0.1.1rc0.tar.gz", "has_sig": false, "md5_digest": "2855a911728e8839f2389343614e7aa7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20042, "upload_time": "2019-08-20T05:49:39", "url": "https://files.pythonhosted.org/packages/76/6e/4801318a96bc26a8a8a882ac29a3ba6cb3f02092fa1099c752d5fa6abbd4/QuickScheme-0.1.1rc0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "d1d210f1af0ae0d50e7a39b868f46e48", "sha256": "220a0297a2a4aa24299994de5d9b7881b540839a83bf4d85e3d879dca35a4d01" }, "downloads": -1, "filename": "QuickScheme-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "d1d210f1af0ae0d50e7a39b868f46e48", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 28854, "upload_time": "2019-08-22T04:50:26", "url": "https://files.pythonhosted.org/packages/ee/a5/0d5417f5ca1ee8c11255725fb20db4307dc952b1cecf13cb5375d133f70b/QuickScheme-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b835724e0eafd40111ef67e73bff0ab0", "sha256": "ab7a4862702587e37b870df0edda59bd684729a4b8154151e0eb430e0dd6f04c" }, "downloads": -1, "filename": "QuickScheme-0.2.0.tar.gz", "has_sig": false, "md5_digest": "b835724e0eafd40111ef67e73bff0ab0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20885, "upload_time": "2019-08-22T04:50:27", "url": "https://files.pythonhosted.org/packages/a7/f1/94151705de94b7b80c9429f28a1ad723ad0ea0fa7367f6f611bc0fd62e01/QuickScheme-0.2.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d1d210f1af0ae0d50e7a39b868f46e48", "sha256": "220a0297a2a4aa24299994de5d9b7881b540839a83bf4d85e3d879dca35a4d01" }, "downloads": -1, "filename": "QuickScheme-0.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "d1d210f1af0ae0d50e7a39b868f46e48", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 28854, "upload_time": "2019-08-22T04:50:26", "url": "https://files.pythonhosted.org/packages/ee/a5/0d5417f5ca1ee8c11255725fb20db4307dc952b1cecf13cb5375d133f70b/QuickScheme-0.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b835724e0eafd40111ef67e73bff0ab0", "sha256": "ab7a4862702587e37b870df0edda59bd684729a4b8154151e0eb430e0dd6f04c" }, "downloads": -1, "filename": "QuickScheme-0.2.0.tar.gz", "has_sig": false, "md5_digest": "b835724e0eafd40111ef67e73bff0ab0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20885, "upload_time": "2019-08-22T04:50:27", "url": "https://files.pythonhosted.org/packages/a7/f1/94151705de94b7b80c9429f28a1ad723ad0ea0fa7367f6f611bc0fd62e01/QuickScheme-0.2.0.tar.gz" } ] }