{ "info": { "author": "Timothy Edmund Crosley", "author_email": "timothy.crosley@gmail.com", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "[![preconvert - Supercharge Your Serializers](https://raw.github.com/timothycrosley/preconvert/master/art/logo_large.png)](https://timothycrosley.github.io/preconvert/)\n===================\n\n[![PyPI version](https://badge.fury.io/py/preconvert.svg)](http://badge.fury.io/py/preconvert)\n[![Build Status](https://travis-ci.org/timothycrosley/preconvert.svg?branch=master)](https://travis-ci.org/timothycrosley/preconvert)\n[![codecov](https://codecov.io/gh/timothycrosley/preconvert/branch/master/graph/badge.svg)](https://codecov.io/gh/timothycrosley/preconvert)\n[![Gitter](https://badges.gitter.im/preconvert/community.svg)](https://gitter.im/preconvert/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)\n[![License](https://img.shields.io/github/license/mashape/apistatus.svg)](https://pypi.python.org/pypi/hug/)\n[![Downloads](https://pepy.tech/badge/preconvert)](https://pepy.tech/project/preconvert)\n\n_________________\n\n[Read Latest Documentation](https://timothycrosley.github.io/preconvert/) - [Browse GitHub Code Repository](https://github.com/timothycrosley/preconvert/)\n_________________\n\nPreconvert is a library that extends existing serializiers (json, simplejson, bson, msgpack, ..) to be capable of converting *all* the types you use.\nIt accomplishes this by efficiently preconverting just the types the serializers aren't aware of (things like dataclasses and namedtuples) into basic built-in types that all\nserializers can understand. It then provides a mechanism for you to build custom preconverters, and preconvert_plugins that automatically take effect when installed via pip.\n\n## Quickstart\n\n1. Install preconvert using pip:\n\n pip3 install preconvert\n\n2. Replace existing json (or other serialization library) with preconvert equivalent:\n\n from preconvert.output import simplejson as json\n\n ...\n\n json.dumps(MY_COMPLEX_OBJECT_WITH_DATA_CLASSSES)\n\n4. Define preconverters for any custom types, even if they aren't under your control:\n\n import numpy\n from preconvert import json\n\n\n class Employee:\n\n def __init__(self, first_name, last_name):\n self.first_name = first_name\n self.last_name = last_name\n\n def __preconvert__(self):\n return {'name': {'first': self.first_name, 'last': self.last_name}}\n\n\n @preconvert.converter(numpy.integer)\n def numpy_integer_to_python_int(numpy_int):\n return int(numpy_int)\n\n\n json.dumps({\n 'employee': Employee('Timothy', 'Crosley'),\n 'height_inches': numpy.int_(73)\n })\n\n3. Enjoy a more comprehensive and configurable serializer!\n\n## Why?\n\nHave you ever tried to `json.dumps` a data structure, only to be surprised when your DataClass throws an exception, or your namedtuple outputs as a list?\nPreconvert was created to solve this problem across common serialization formats.\n\n\nBefore preconvert:\n\n```python\nimport sys\nimport json\nfrom dataclasses import dataclass\n\n\n@dataclass\nclass InventoryItem:\n \"\"\"Class for keeping track of an item in inventory.\"\"\"\n name: str\n unit_price: float\n quantity_on_hand: int = 0\n\n def total_cost(self) -> float:\n return self.unit_price * self.quantity_on_hand\n\n\nmy_store_inventory = [InventoryItem(\"beer\", unit_price=0.0, quantity_on_hand=sys.maxsize), InventoryItem(\"bacon\", unit_price=2.5, quantity_on_hand=3)]\njson.dumps(my_store_inventory)\n\noutput >>>\n\n 177\n 178\n--> 179 raise TypeError(f'Object of type {o.__class__.__name__} '\n 180 f'is not JSON serializable')\n 181\n\nTypeError: Object of type InventoryItem is not JSON serializable\n\nD:\n```\n\nAfter preconvert:\n\n```python\nimport sys\nimport json\nfrom preconvert.output import json\n\n\n@dataclass\nclass InventoryItem:\n \"\"\"Class for keeping track of an item in inventory.\"\"\"\n name: str\n unit_price: float\n quantity_on_hand: int = 0\n\n def total_cost(self) -> float:\n return self.unit_price * self.quantity_on_hand\n\n\nmy_store_inventory = [\n InventoryItem(\"beer\", unit_price=0.0, quantity_on_hand=sys.maxsize),\n InventoryItem(\"bacon\", unit_price=2.5, quantity_on_hand=3)\n]\njson.dumps(my_store_inventory)\n\n>>> [\n {\n \"name\": \"beer\",\n \"unit_price\": 0.0,\n \"quantity_on_hand\": 9223372036854775807\n },\n {\n \"name\": \"bacon\",\n \"unit_price\": 2.5,\n \"quantity_on_hand\": 3\n }\n ]\n\n:D\n```\n\n## Design goals:\n\n- Easy utilization from existing projects\n- Enable conversion from complex to simple types independant of desired output format\n- Provide built in conversion for common types that are not universally supported (dataclasses, namedtuple, etc...)\n- Provide a way to build custom preconverts or override built-in preconverts\n- Ability to build preconverts that are dependent on the destination format\n- Minimal overhead when utilized with common serialization formats\n\n## How do I use this?\n\nIf your project uses one of our built-in supported serializers (json, msgpak, bson)\nyou can simply replace your existing serializer import with a preconvert one:\n\n`from preconvert.outputs import json`\n\nOR\n\n`from preconvert.outputs import simplejson as json`\n\nOR\n\n`from preconvert.outputs import msgpack`\n\nOR\n\n`from preconvert.outputs import bson`\n\nIf not you can inject preconvert before usage of any other serializers, often by setting a `default` or `on_onknown` parameter:\n\n```\nimport preconvert\nimport my_serializer\n\nmy_serializer.dumps(default=preconvert.default_serializable)\n```\n\n## How do I extend this?\n\nWant to add preconversion to your own custom types? For OOP projects, one easy way to do this is to add a `__preconvert__` method to your object:\n\n```python\nclass MyCustomClass(object):\n def __init__(self, first_name, children=()):\n self.first_name = first_name\n self.children = children\n\n def __jsonifiable__(self)\n return {'first': self.first_name, 'children': children}\n```\n\nFor other entities, such as objects you do not control, you can register a new preconvert using the `preconvert.converter` decorator:\n\n```python\nimport preconvert\n\n\n@preconvert.converter(SomeFrameworkObject)\ndef convert_framework_object(instance):\n return {'name': instance.name}\n```\n\nYou can also, optionally, specify preconversions per an intended serialization format:\n\n```python\nimport preconvert\n\n\n@preconvert.json(SomeFrameworkObject)\ndef convert_framework_object(instance):\n return {'json': {'name': instance.name}}\n\n\n@preconvert.msgpack(SomeFrameworkObject)\ndef convert_framework_object(instance):\n return ['name', instance.name]\n```\n\nFinally, you can resister any modules that contain converters to package 'preconvert.converters' entrypoints, and they will take effect automatically as long as the package that contains them is installed.\nSee the [preconvert_numpy](https://github.com/timothycrosley/preconvert_numpy/blob/master/pyproject.toml#L28) for an example of how this works.\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/timothycrosley/preconvert", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "preconvert", "package_url": "https://pypi.org/project/preconvert/", "platform": "", "project_url": "https://pypi.org/project/preconvert/", "project_urls": { "Homepage": "https://github.com/timothycrosley/preconvert" }, "release_url": "https://pypi.org/project/preconvert/0.0.6/", "requires_dist": [ "pymongo; extra == \"bson\"", "msgpack; extra == \"msgpack\"", "simplejson; extra == \"simplejson\"" ], "requires_python": ">=3.5", "summary": "A Library to enable preconversion of any Python type into one that is easily serializable", "version": "0.0.6" }, "last_serial": 5696294, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "7b0e0f8a33c4c19f3283d5cf856be6cf", "sha256": "2607f8cb3c697f818074266ac12657546ed49f46c8282ba77c71eb52aea02a0d" }, "downloads": -1, "filename": "preconvert-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "7b0e0f8a33c4c19f3283d5cf856be6cf", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 14889, "upload_time": "2019-07-17T23:47:16", "url": "https://files.pythonhosted.org/packages/ca/b5/98c9da427f542677f24d26410b27873422e635e41b94d85b723ff8ab0b15/preconvert-0.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "493c2d81ae9f28ee2f1550c97bbf186d", "sha256": "a7b23acf9f65a97a1815ba75cc9fe0ae6b47448c560f38cb1e9baf30139784d9" }, "downloads": -1, "filename": "preconvert-0.0.1.tar.gz", "has_sig": false, "md5_digest": "493c2d81ae9f28ee2f1550c97bbf186d", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 13591, "upload_time": "2019-07-17T23:47:19", "url": "https://files.pythonhosted.org/packages/22/c5/dfd172f2033e7a50959b8a93abe232a600b8e1bc53df26efcd61b12d7898/preconvert-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "2d65776b78f665b6b00b77ba23a00c42", "sha256": "340d8eb3499aacc6780337af983ccd632d822a4ead74b2c090453fcc9b06aa3e" }, "downloads": -1, "filename": "preconvert-0.0.2-py3-none-any.whl", "has_sig": false, "md5_digest": "2d65776b78f665b6b00b77ba23a00c42", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 15370, "upload_time": "2019-07-18T00:52:40", "url": "https://files.pythonhosted.org/packages/7e/44/3875d8abd3ea24959381fe9aa52e8e7cc2bdbbf25d2c6125fa4999919e07/preconvert-0.0.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1051e13d0ce12a40f4a4d1e6f8b1c973", "sha256": "4bb30042827e9e2520661258f1d68ab6620d46ad93ae599643410b488dbed6d8" }, "downloads": -1, "filename": "preconvert-0.0.2.tar.gz", "has_sig": false, "md5_digest": "1051e13d0ce12a40f4a4d1e6f8b1c973", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 13997, "upload_time": "2019-07-18T00:52:41", "url": "https://files.pythonhosted.org/packages/a8/22/1692001488ba749e9fe53f491bfc2710dc0bb2405484a2f7e2d8ee751fc2/preconvert-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "6e16429dc7aee284cf2cb7a99b19d140", "sha256": "6726a8597507afc6a400c4e971d8ceca8afde0ab88e45aab298fd98ddcb3af74" }, "downloads": -1, "filename": "preconvert-0.0.3-py3-none-any.whl", "has_sig": false, "md5_digest": "6e16429dc7aee284cf2cb7a99b19d140", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 16338, "upload_time": "2019-07-29T05:16:10", "url": "https://files.pythonhosted.org/packages/ef/6e/316a7ac77b6c82eb896ed50d35f92262f5ff9d37957745b5b831ce04107c/preconvert-0.0.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f19c4ae5e7f27d9041dc82febc44007b", "sha256": "369a682b2a7e5a235ec4fb7156afdc66d7ffb9ae855c4252ff15ff654d993982" }, "downloads": -1, "filename": "preconvert-0.0.3.tar.gz", "has_sig": false, "md5_digest": "f19c4ae5e7f27d9041dc82febc44007b", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 14400, "upload_time": "2019-07-29T05:16:12", "url": "https://files.pythonhosted.org/packages/e2/57/b620cf861e8b1cdfda4eea423b5344382dccb1726e10586cde6b92563b36/preconvert-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "9c98b2ce2afc21c7fb1a12a606a0a0f6", "sha256": "59cdc38d0c1ee2f6b365b84da2b177b3667c73c71ba442e27d33b5faec440bb0" }, "downloads": -1, "filename": "preconvert-0.0.4-py3-none-any.whl", "has_sig": false, "md5_digest": "9c98b2ce2afc21c7fb1a12a606a0a0f6", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 17400, "upload_time": "2019-08-19T00:39:20", "url": "https://files.pythonhosted.org/packages/a5/7a/58b99c05db797b8bf11a31e5771c7d2f511577a0935704901852f506f86f/preconvert-0.0.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c0bfc675012bc8b942760e7f1005f9d9", "sha256": "09cd08ecd71be858ad69ca93f2cf86098b314efca8c19825bab111c74115f386" }, "downloads": -1, "filename": "preconvert-0.0.4.tar.gz", "has_sig": false, "md5_digest": "c0bfc675012bc8b942760e7f1005f9d9", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 124913, "upload_time": "2019-08-19T00:39:21", "url": "https://files.pythonhosted.org/packages/3d/71/8d9f2521aca6bca0a188daa7116419987c44db8c4789c85ee91cfe8210ab/preconvert-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "8ab8d1ad5eeda92d2337c45d974b17a0", "sha256": "834aef3d812d271c6c8ca712a52eeff7558f6c48b0bcd6fbc2a279055135f670" }, "downloads": -1, "filename": "preconvert-0.0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "8ab8d1ad5eeda92d2337c45d974b17a0", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 17338, "upload_time": "2019-08-19T00:47:07", "url": "https://files.pythonhosted.org/packages/b6/75/748cc2448cc839e80531e302ad546ab8a7dcdfa173e6f164aed438e9715f/preconvert-0.0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b5eb316126041d79456f3304c150d6b1", "sha256": "f4cbeb42a6d28dfb69dd51bce74c17a01c9bc4942b0d59487d1d1b252568d829" }, "downloads": -1, "filename": "preconvert-0.0.5.tar.gz", "has_sig": false, "md5_digest": "b5eb316126041d79456f3304c150d6b1", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 124893, "upload_time": "2019-08-19T00:47:08", "url": "https://files.pythonhosted.org/packages/0c/23/8b89e296c9b376a34e51b97380e463764190cc3c42b8bb1d6602b4e35414/preconvert-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "a0606d778334256d9cd7a3abe4d3a09e", "sha256": "4824251345c20e4af085b463623ed7825da070e900df683c0ef4e34431ff832e" }, "downloads": -1, "filename": "preconvert-0.0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "a0606d778334256d9cd7a3abe4d3a09e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 17338, "upload_time": "2019-08-19T01:18:21", "url": "https://files.pythonhosted.org/packages/55/fd/2835e0150bfd387aa1869f349b95d5103a1e79f76f67b1292f965a27a37e/preconvert-0.0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e6deb79e7236f5480462a6ec5bf5f851", "sha256": "ddc2c0b6cd8e02e9ed8ea9b983854a06c06ab4030f6e09836504157cde3b29c3" }, "downloads": -1, "filename": "preconvert-0.0.6.tar.gz", "has_sig": false, "md5_digest": "e6deb79e7236f5480462a6ec5bf5f851", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 128473, "upload_time": "2019-08-19T01:18:23", "url": "https://files.pythonhosted.org/packages/54/2c/29ec9f0103289160e991f4fc0f4fbd34e0d5b1f5739a7785337ef5d2faab/preconvert-0.0.6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "a0606d778334256d9cd7a3abe4d3a09e", "sha256": "4824251345c20e4af085b463623ed7825da070e900df683c0ef4e34431ff832e" }, "downloads": -1, "filename": "preconvert-0.0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "a0606d778334256d9cd7a3abe4d3a09e", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.5", "size": 17338, "upload_time": "2019-08-19T01:18:21", "url": "https://files.pythonhosted.org/packages/55/fd/2835e0150bfd387aa1869f349b95d5103a1e79f76f67b1292f965a27a37e/preconvert-0.0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e6deb79e7236f5480462a6ec5bf5f851", "sha256": "ddc2c0b6cd8e02e9ed8ea9b983854a06c06ab4030f6e09836504157cde3b29c3" }, "downloads": -1, "filename": "preconvert-0.0.6.tar.gz", "has_sig": false, "md5_digest": "e6deb79e7236f5480462a6ec5bf5f851", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.5", "size": 128473, "upload_time": "2019-08-19T01:18:23", "url": "https://files.pythonhosted.org/packages/54/2c/29ec9f0103289160e991f4fc0f4fbd34e0d5b1f5739a7785337ef5d2faab/preconvert-0.0.6.tar.gz" } ] }