{ "info": { "author": "drowse314-dev-ymat", "author_email": "drowse314@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries", "Topic :: Utilities" ], "description": "Froshki\n=======\n\nFroshki is a simple and poor object data mapper library.\n\nLooking quite similar to `WTForms\n`_,\nrather intended to focus on data input/output abstraction,\nseparating validation or conversion functions as APIs & extensions.\n\nInstead of integrating with web forms etc., designed to achieve more flexible attribute sourcing.\n\nFeatures\n........\n\n* Define data schema as class definition.\n* Supply data inputs by keyword arguments, dict, or both.\n* Convert and validate data inputs with user defined methods or built-in integration with 3rd party libraries.\n* Access validated data as attributes / mapping.\n* Easy to hook your functions on validation.\n\nSimple usage\n------------\n\nPrimitive demo:: \n\n >>> from froshki import Froshki, Attribute\n >>>\n >>> class ResourceId(Attribute):\n ... @classmethod\n ... def transform(klass, input_value):\n ... return int(input_value)\n ... @classmethod\n ... def validate(klass, input_value):\n ... if input_value in (1,5,7,9):\n ... return True, input_value\n ... else:\n ... return False, 'resource id not found'\n >>>\n >>> class Filetype(Attribute):\n ... @classmethod\n ... def transform(klass, input_value):\n ... return input_value.lower()\n ... @classmethod\n ... def validate(klass, input_value):\n ... if input_value in ('pdf', 'txt', 'mobi'):\n ... return True, input_value\n ... else:\n ... return False, 'filetype unavailable'\n >>>\n >>> class Download(Froshki):\n ... resource_id = ResourceId()\n ... filetype = Filetype()\n >>>\n >>> download = Download(resource_id='9', filetype='PDF')\n >>> download.validate()\n True\n >>> download.resource_id\n 9\n >>> download.filetype\n 'pdf'\n \nTo use any functions of Froshki, extend ``froshki.Froshki`` to define data model schema.\nAttributes are represented by attaching ``froshki.Attribute`` subclasses onto the model.\n\nYou can add any data conversion (``Attribute.transform``) or validation (``Attribute.validate``) methods for attributes.\n``Froshki.validate`` converts and validates all attributes as defined.\nBut it's a bit bothersome, and you can use a built-in extension supporting attribute definition.\n\nUsing trafaret extension\n------------------------\n\nYou need to pre-install `trafaret\n`_ to use the extension.\nUsage::\n\n >>> from froshki import Froshki\n >>> import trafaret\n >>> from froshki.ext import trafaret_attr\n >>>\n >>> class SendInquiry(Froshki):\n ... user_name = trafaret_attr(trafaret.String())()\n ... user_contact = trafaret_attr(trafaret.Email())()\n ... message = trafaret_attr(trafaret.String(regex=r'\\w{10,400}'))()\n >>>\n >>> send_inquiry = SendInquiry(\n ... user_name='yu mat', user_contact='drowse314@gmail.com',\n ... message='cannot post messages to my group'\n ... )\n >>> send_inquiry.validate()\n True\n\nIf you prefer other validation libraries,\nyou will find it so easy to extend ``froshki.Attribute.validate``.\nOr some more libraries are built-in supported:\n\n* `voluptuous `_\n\nSee ``froshki/ext/*_attr.py`` for documentation or details of extension wrinting.\n\nOther features\n--------------\n\nData as mappings\n................\n\nSome utility properties are available for accessing validated data::\n\n (...)\n >>> send_inquiry.data\n {'user_name': 'yu mat', 'user_contact': 'drowse314@gmail.com', 'message': 'cannot post messages to my group'}\n >>> send_inquiry.errors # error messages are registered if validation failed\n {}\n\nFurther, you can initialize ``froshki.Froshki`` with mappings::\n\n (...)\n >>> data = {'user_name': 'ymat', 'user_contact': 'drowse314.gmail.com', 'message': 'cannot post messages to my group'}\n >>> another_inquiry = SendInquiry(source=data)\n >>> another_inquiry.validate()\n False\n\nSource attributes with alias names\n..................................\n\nYou can use the names differring from the class attribute names for sourcing attributes::\n\n >>> class ResourceAccess(Froshki):\n ... resource_id = Attribute()\n ... user_id = Attribute()\n ... resource_key = Attribute(key_alias='password')\n >>> access = ResourceAccess(resource_id='1276', user_id='ymat', password='VXFPF93')\n >>> access.resource_key\n 'VXFPF93'\n\nExtra validation\n................\n\nYou can add attribute dependent extra validator methods for attribute relations etc., using ``validation_hook`` decorator::\n\n >>> from froshki import Froshki, Attribute, validation_hook\n >>>\n >>> class SendInquiry(Froshki):\n ... user_name = Attribute()\n ... user_contact = Attribute()\n ... user_contact_confirmation = Attribute()\n ... message = Attribute()\n ... @validation_hook\n ... def confirm_email(self):\n ... return self.user_contact == self.user_contact_confirmation\n >>>\n >>> send_inquiry = SendInquiry(\n ... user_name='yu mat', user_contact='drowse314@gmail.com', user_contact_confirmation='drose@gmail.com',\n ... message='cannot post messages to my group'\n ... )\n >>> send_inquiry.validate()\n False\n\nIf you need error information with these extra validators, extend the decorator as following::\n\n (...)\n >>> class SendInquiryExt(SendInquiry):\n ... @validation_hook.extend(error='inconsistent email inputs')\n ... def confirm_email(self):\n ... return self.user_contact == self.user_contact_confirmation\n >>>\n >>> send_inquiry = SendInquiry(\n ... user_name='yu mat', user_contact='drowse314@gmail.com', user_contact_confirmation='drose@gmail.com',\n ... message='cannot post messages to my group'\n ... )\n >>> send_inquiry.validate()\n False\n >>> send_inquiry.errors\n {'confirm_email': 'inconsistent email inputs'}\n\nSubclassing and attribute mixin\n...............................\n\n``froshki.Froshki`` subclasses are usable as base classes::\n\n (...)\n >>> class Resource(Froshki):\n ... resource_id = ResourceId()\n >>>\n >>> class Download(Resource):\n ... filetype = Filetype()\n >>>\n >>> download = Download(resource_id='9', filetype='pdf')\n >>> download.validate()\n True\n\nMixins are useful if you want to share some attribute definitions between schemas::\n\n (...)\n >>> class UserMixin(object):\n ... user = Attribute()\n >>>\n >>> class DownloadAsUser(Download, UserMixin):\n ... pass\n >>>\n >>> download_as_someone = DownloadAsUser(\n ... resource_id='5', filetype='mobi',\n ... user='ymat',\n ... )\n >>> download_as_someone.validate()\n True\n >>> download_as_someone.user\n 'ymat'\n\nYou can use any classes as attribute mixins by attaching ``froshki.Attribute`` instances,\nwith the exception of ``froshki.Froshki`` subclass which causes MRO issue.\n\nOther options\n.............\n\n``froshki.Froshki`` class has some useful options.\n\n* ``Froshki.default_values``: provide attribute defaults as dict.\n* ``Froshki.ignore_unkown_keys``: control if ``source`` argument accepts names that are not defined as attributes, or not (True/False).\n\nAlso some options for ``froshki.Attribute``.\n\n* (As argument) ``Attribute(nullable=)``: allows ``None`` in validation (with any validation methods set).", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/drowse314-dev-ymat/froshki", "keywords": "form forms object data mapper schema validation", "license": "BSD", "maintainer": null, "maintainer_email": null, "name": "froshki", "package_url": "https://pypi.org/project/froshki/", "platform": "any", "project_url": "https://pypi.org/project/froshki/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/drowse314-dev-ymat/froshki" }, "release_url": "https://pypi.org/project/froshki/0.4.3/", "requires_dist": null, "requires_python": null, "summary": "simple and poor object data mapper library", "version": "0.4.3" }, "last_serial": 838965, "releases": { "0.2": [ { "comment_text": "", "digests": { "md5": "07355761de25708c339bd04d7c375842", "sha256": "a5b1aedbc7bd4208d98c567055b9413129630503db3878c0a83df35ec44e3dcd" }, "downloads": -1, "filename": "froshki-0.2.zip", "has_sig": false, "md5_digest": "07355761de25708c339bd04d7c375842", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13033, "upload_time": "2013-04-22T16:55:54", "url": "https://files.pythonhosted.org/packages/7f/63/64807c738b601e60f5da3c2cd2f49d3a3721aa0012d055f7b20d15ada039/froshki-0.2.zip" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "2263e69445c2fe0040ad84b3737c799e", "sha256": "b24dfdea89d29b07b1dccba65b88281843bb4ff47b60b696aa1682a61b921e70" }, "downloads": -1, "filename": "froshki-0.3.zip", "has_sig": false, "md5_digest": "2263e69445c2fe0040ad84b3737c799e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14456, "upload_time": "2013-04-23T14:59:21", "url": "https://files.pythonhosted.org/packages/4a/56/67c53c98c1d774f99971a5943d31fe652cd65b7295593450c20e57e85477/froshki-0.3.zip" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "975b4516b776d70798bebc630db1f0be", "sha256": "623f362e0029e0c6858e0ddfc9e8f447336d7cadec047f7f339ca27090abcc02" }, "downloads": -1, "filename": "froshki-0.4.zip", "has_sig": false, "md5_digest": "975b4516b776d70798bebc630db1f0be", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14645, "upload_time": "2013-05-15T12:42:40", "url": "https://files.pythonhosted.org/packages/de/96/120b75b4bf41b90159af706b96ac3f4a9abbc1ce0f7ed06219dc7cbdcc29/froshki-0.4.zip" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "552056b760be856138a742913dc0dbf1", "sha256": "28272957b5ac2d333ea548204e8462712a2d9b862416c762b419519b49a5f8b2" }, "downloads": -1, "filename": "froshki-0.4.1.tar.gz", "has_sig": false, "md5_digest": "552056b760be856138a742913dc0dbf1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8052, "upload_time": "2013-07-05T16:56:02", "url": "https://files.pythonhosted.org/packages/cf/42/ef28d288005ab2784f5e3fc0752f3f9b2ce19065a48626ac9800be2346c2/froshki-0.4.1.tar.gz" } ], "0.4.2": [ { "comment_text": "", "digests": { "md5": "41c81529c2cf10774c89f745ed4590c1", "sha256": "7d87ae5fb1682338691e5ee8e52817e5d7e1241cafca75b29cd86f6acf9e1b77" }, "downloads": -1, "filename": "froshki-0.4.2.tar.gz", "has_sig": false, "md5_digest": "41c81529c2cf10774c89f745ed4590c1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8590, "upload_time": "2013-07-12T08:26:14", "url": "https://files.pythonhosted.org/packages/bc/36/935d8cc645920af80f94c9a21e89b6f180dca0a35603d67309df84f393da/froshki-0.4.2.tar.gz" } ], "0.4.3": [ { "comment_text": "", "digests": { "md5": "7b2c39b32241473905b73384bee8a814", "sha256": "be32dc5d3689940f34767192ed134f7edc0be3977c283537ec7c29dec1d6cbf9" }, "downloads": -1, "filename": "froshki-0.4.3.tar.gz", "has_sig": false, "md5_digest": "7b2c39b32241473905b73384bee8a814", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8172, "upload_time": "2013-08-13T13:20:35", "url": "https://files.pythonhosted.org/packages/01/0e/41ef67afe52114379654566f4911099ab2b3c1848f496cae97f55f4f462d/froshki-0.4.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "7b2c39b32241473905b73384bee8a814", "sha256": "be32dc5d3689940f34767192ed134f7edc0be3977c283537ec7c29dec1d6cbf9" }, "downloads": -1, "filename": "froshki-0.4.3.tar.gz", "has_sig": false, "md5_digest": "7b2c39b32241473905b73384bee8a814", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8172, "upload_time": "2013-08-13T13:20:35", "url": "https://files.pythonhosted.org/packages/01/0e/41ef67afe52114379654566f4911099ab2b3c1848f496cae97f55f4f462d/froshki-0.4.3.tar.gz" } ] }