{ "info": { "author": "asduj", "author_email": "asduj@ya.ru", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": ".. highlight::python\n\nany_case\n========\n\nWhen developing a web application, you often have to choose the case format (snake_case/camelCase)\nwill be used for the input and the output json data. If the backend is written in Python,\nthe easiest option is to choose snake_case. On the one hand, this is good, because we have\nan obvious consistency, but on the other hand, the main consumers of the API (mobile and browser)\nprefer to use camelCase.\n\nIf we care about our consumers, we will change the case format to camelCase. And it's good if we think\nabout it in advance, before publishing API. But if this happens in an existing application,\nit becomes much more difficult to do so because there are consumers using the existing API.\nWe have two options here:\n\n- introduce a new version of the api\n- send data in two cases at once\n\nThe second option increases the size of the data, and the first option forces us to support two\nversions of the API without serious need. These options complicate the support and development of API.\n\nThings get a little more complicated when we have consumers who natively use snake_case,\nand using camelCase for them is not an option at all.\n\nAs you can see, the use of one notation does not improve, but may worsen the situation.\n\nBut why do we have to choose for the customer which case format they use?\nWhy customers do not send and not receive data in the format, which would be more convenient to them?\n\n\nThat's what this library is for. Consumers choose in what case they expect the data.\nIf they specified an incorrect case or made a request without specifying a case,\nthe data will be given as is.\n\nThis approach allows existing consumers to work without changes with existing API, and for those\nconsumers who want to use a single format, allows granular rewriting of the application.\n\nInstallation\n============\n::\n\n pip install any_case\n\nUsage\n=====\nFor converting dict or list use ``converts_keys`` function::\n\n >>> from any_case import converts_keys\n >>> data = {'camelCaseKey': 'value'}\n >>> converts_keys(data, case='snake')\n {'camel_case_key': 'value'}\n >>> data = {'snake_case': 'camelCase'}\n >>> converts_keys(data, case='camel')\n {'snakeCase': 'camelCase'}\n\nFor converting ``any_case`` uses compiled regex and stack for objects traversal instead of recursion.\n\nTo convert existing data without producing new one, use ``inplace`` param::\n\n >>> data = {'snake_case': 'camelCase'}\n >>> converts_keys(data, case='camel', inplace=True)\n {'snakeCase': 'camelCase'}\n >>> data\n {'snakeCase': 'camelCase'}\n\nSome tricky cases could happen when works with keys which contains numbers::\n\n >>> data = {'camelCase12': 'camelCase'}\n >>> converts_keys(data, case='snake')\n {'camel_case12': 'camelCase'}\n\nTo adjust this logic use `sep_numbers` params::\n\n >>> converts_keys(data, case='snake', sep_numbers=True)\n {'camel_case_12': 'camelCase'}\n\nTo convert text, use ``to_snake_case`` or ``to_camel_case``::\n\n >>> from any_case import to_snake_case, to_camel_case\n >>> to_snake_case('snakeCase')\n 'snake_case'\n >>> to_camel_case('snake_case')\n 'snakeCase'\n\nMore examples see at tests folder.\n\nIntegrations\n============\n\nDjango\n------\n\nFor integration with the Django framework, you need to add ``any_case`` middleware::\n\n MIDDLEWARE = [\n 'django.contrib.sessions.middleware.SessionMiddleware',\n ...\n 'any_case.contrib.django.middleware.KeysConverterMiddleware'\n ]\n\n\nWhen the input data is converted, it is saved in the ``json`` field of request object.\nThat is, you can access to the converted data in the view as follows::\n\n def view(request):\n data = request.json\n ...\n\nrest_framework\n--------------\n\nFor integration with rest_framework, replace default json parser and renderer::\n\n REST_FRAMEWORK = {\n 'DEFAULT_RENDERER_CLASSES': (\n 'any_case.contrib.rest_framework.AnyCaseJSONParser',\n ...\n ),\n 'DEFAULT_PARSER_CLASSES': (\n 'any_case.contrib.rest_framework.AnyCaseJSONRenderer',\n ...\n )\n }\n\n\nSettings\n--------\n``any_case`` has the next default settings::\n\n ANY_CASE = {\n 'HEADER_KEY': 'Accept-Json-Case',\n 'QUERY_KEY': None,\n 'BODY_KEY': None,\n 'CONVERT_INPUT_JSON': True,\n 'SEP_NUMBERS_TO_CAMEL': False,\n 'SEP_NUMBERS_TO_SNAKE': False,\n }\n\nSettings are specified in django ``settings.py``.\n\n``any_case`` can be used for converting:\n\n- input json data to snake_case\n- output json to snake_case or camelCase\n\nOr only one of the above independently.\n\nYou can specify the case format in the header, in the query parameters, or in the json body.\nThe preferred way is the header, because specifying in the query or in the body\nis not always possible. Specifying case format in the body also forces to parse json data that\nmay not be needed at all.\n\n\nDisable converting output data\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n::\n\n ANY_CASE = {\n 'HEADER_KEY': None,\n 'QUERY_KEY': None,\n 'BODY_KEY': None,\n }\n\nDisable converting input data\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n::\n\n ANY_CASE = {\n 'CONVERT_INPUT_JSON': False\n }\n", "description_content_type": "text/x-rst", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/asduj/any_case", "keywords": "snake-case,django,rest_framework,camel-case", "license": "MIT", "maintainer": "asduj", "maintainer_email": "asduj@ya.ru", "name": "any-case", "package_url": "https://pypi.org/project/any-case/", "platform": "", "project_url": "https://pypi.org/project/any-case/", "project_urls": { "Homepage": "https://github.com/asduj/any_case", "Repository": "https://github.com/asduj/any_case" }, "release_url": "https://pypi.org/project/any-case/0.1.6/", "requires_dist": null, "requires_python": ">=3.6,<4.0", "summary": "Snake/Camel case converter with Django and Djnago REST framework integration", "version": "0.1.6", "yanked": false, "yanked_reason": null }, "last_serial": 6122407, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "4ea3adb1cbdc25714951879388ca08de", "sha256": "b861bb153885ac65f158e8368f87829e7e1ba1af60354d2caf1c806a263087cc" }, "downloads": -1, "filename": "any_case-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "4ea3adb1cbdc25714951879388ca08de", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 6200, "upload_time": "2019-04-21T14:00:07", "upload_time_iso_8601": "2019-04-21T14:00:07.108372Z", "url": "https://files.pythonhosted.org/packages/1b/18/6669ba70d8e889f1662025476137073271f12f7373437b7144b72fe29432/any_case-0.1.0-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "16b0ed4c13b756658b527c771c742628", "sha256": "127a4ee482475b25357df0744ca20e8c9aa16e2ebde3d7f9323ed539dd16ab83" }, "downloads": -1, "filename": "any_case-0.1.0.tar.gz", "has_sig": false, "md5_digest": "16b0ed4c13b756658b527c771c742628", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 3893, "upload_time": "2019-04-21T14:00:09", "upload_time_iso_8601": "2019-04-21T14:00:09.093674Z", "url": "https://files.pythonhosted.org/packages/9e/16/01ac89e04c8d2ca08f3a280184f59c0de6b4c519229cf3d89e7f4f699467/any_case-0.1.0.tar.gz", "yanked": false, "yanked_reason": null } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "b3565ffcb39781c40c3c5a85ddf6204f", "sha256": "c6ed38d6e0d9eb686c7109bc4336df45c827862c265d0efb7fea2ffd2ad91f34" }, "downloads": -1, "filename": "any_case-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "b3565ffcb39781c40c3c5a85ddf6204f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 8064, "upload_time": "2019-04-21T14:06:55", "upload_time_iso_8601": "2019-04-21T14:06:55.029811Z", "url": "https://files.pythonhosted.org/packages/e2/4b/6b1d54384a170b52060e0f39e641b8a31b8868e4dff3829e8eb9e45d80cf/any_case-0.1.1-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "6d9f8c2c035c591133e6ac459be8ccde", "sha256": "60bca74345fb7e0b54ca30401e048a7dc7dfd32430aa51d3dac45a7830e02f13" }, "downloads": -1, "filename": "any_case-0.1.1.tar.gz", "has_sig": false, "md5_digest": "6d9f8c2c035c591133e6ac459be8ccde", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 7794, "upload_time": "2019-04-21T14:06:56", "upload_time_iso_8601": "2019-04-21T14:06:56.227626Z", "url": "https://files.pythonhosted.org/packages/ff/b6/bee569140fa95a36889e73fafa65f2b3b34e4fc41a63cee2a9a22e0833a7/any_case-0.1.1.tar.gz", "yanked": false, "yanked_reason": null } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "9dafb91472855b46cc4280d990c8c0cb", "sha256": "837b57c2b2e1d69ec640f4a9033e29308b9d0f9b3cab30ccccd1d3877fe47f1d" }, "downloads": -1, "filename": "any_case-0.1.2-py3-none-any.whl", "has_sig": false, "md5_digest": "9dafb91472855b46cc4280d990c8c0cb", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 8072, "upload_time": "2019-04-21T14:14:40", "upload_time_iso_8601": "2019-04-21T14:14:40.050073Z", "url": "https://files.pythonhosted.org/packages/6e/26/8baab69ee39ce420ac943ced56a80c51554457142f7c13107689ff7ef4a6/any_case-0.1.2-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "8268c982cfbfccf6158d8ab4a665b6b5", "sha256": "71f0e277014e947a0445a0db2ee04fecba7a026a7767139a2e69850ae404e553" }, "downloads": -1, "filename": "any_case-0.1.2.tar.gz", "has_sig": false, "md5_digest": "8268c982cfbfccf6158d8ab4a665b6b5", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 7807, "upload_time": "2019-04-21T14:14:41", "upload_time_iso_8601": "2019-04-21T14:14:41.516706Z", "url": "https://files.pythonhosted.org/packages/f7/57/cd38c713361267b0e199332a92f17a441412f7f688aba9b555efc5bdbdfd/any_case-0.1.2.tar.gz", "yanked": false, "yanked_reason": null } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "2f2b02db8baf903a68390a69986d2bb7", "sha256": "6153a8b2ad195cdb654c44b98a387ed17e6326cdf94c6d7145711c5b0e3b6c71" }, "downloads": -1, "filename": "any_case-0.1.3-py3-none-any.whl", "has_sig": false, "md5_digest": "2f2b02db8baf903a68390a69986d2bb7", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 8138, "upload_time": "2019-04-21T16:18:38", "upload_time_iso_8601": "2019-04-21T16:18:38.095997Z", "url": "https://files.pythonhosted.org/packages/68/0a/303d8b7db14cf23cb763bc885037a93f1c0ed502155dfe5c6f4efb3bb2aa/any_case-0.1.3-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "577bc4babda10986afb2b471cf2f88a1", "sha256": "273ed64626a65c9eb0bb07ab10955aa02a7e68ec3ac078bd4f01c71c68104adc" }, "downloads": -1, "filename": "any_case-0.1.3.tar.gz", "has_sig": false, "md5_digest": "577bc4babda10986afb2b471cf2f88a1", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 7917, "upload_time": "2019-04-21T16:18:39", "upload_time_iso_8601": "2019-04-21T16:18:39.650082Z", "url": "https://files.pythonhosted.org/packages/6f/68/083cfb7f96b2d5c9cbb0f7c9ea43fae4da6ef45604112791769cb4b7d2c1/any_case-0.1.3.tar.gz", "yanked": false, "yanked_reason": null } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "fa210398c9299868ca34822a37019d5f", "sha256": "9f1c05d287264106d232ef1389529986e42db85310ef2679dfcddb6235d194f9" }, "downloads": -1, "filename": "any_case-0.1.4-py3-none-any.whl", "has_sig": false, "md5_digest": "fa210398c9299868ca34822a37019d5f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 8409, "upload_time": "2019-04-27T20:11:44", "upload_time_iso_8601": "2019-04-27T20:11:44.074876Z", "url": "https://files.pythonhosted.org/packages/20/20/6b09d3cb81fd5f39579b94940a7dfb9bd128e5dc3aaf2f51aabbcb61d10d/any_case-0.1.4-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "23655060677c39dc9a5af0805b95ca7d", "sha256": "dbdb5d46b0c2200622cfcb9b0c508ac1fc70029c500160193d0d08a865ff2d9a" }, "downloads": -1, "filename": "any_case-0.1.4.tar.gz", "has_sig": false, "md5_digest": "23655060677c39dc9a5af0805b95ca7d", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 8184, "upload_time": "2019-04-27T20:11:46", "upload_time_iso_8601": "2019-04-27T20:11:46.726780Z", "url": "https://files.pythonhosted.org/packages/eb/0b/a342c4927c6b44c59e6aa57fded7c3974fca8dbaf15cb012a23aedcd98f0/any_case-0.1.4.tar.gz", "yanked": false, "yanked_reason": null } ], "0.1.5": [ { "comment_text": "", "digests": { "md5": "1aa9e3a0a388d383be03ce95caa3d25a", "sha256": "0af6ab4393c3b255c92feb61ee1dfc09fa1a0286477a2b7821f59f876a1f433d" }, "downloads": -1, "filename": "any_case-0.1.5-py3-none-any.whl", "has_sig": false, "md5_digest": "1aa9e3a0a388d383be03ce95caa3d25a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 8946, "upload_time": "2019-10-30T13:51:32", "upload_time_iso_8601": "2019-10-30T13:51:32.329487Z", "url": "https://files.pythonhosted.org/packages/1e/29/acd00e70675590aabe2182c66e06d2ea2c2ee207a21b80e6ff7a0953224e/any_case-0.1.5-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "f92e1c10ad2b94ce827a2812e91d0d71", "sha256": "5e3402fb21984d927331a1b31baa401b894a8c22f46ccc9ddc7f766e2b64d42d" }, "downloads": -1, "filename": "any_case-0.1.5.tar.gz", "has_sig": false, "md5_digest": "f92e1c10ad2b94ce827a2812e91d0d71", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 8811, "upload_time": "2019-10-30T13:51:34", "upload_time_iso_8601": "2019-10-30T13:51:34.002547Z", "url": "https://files.pythonhosted.org/packages/b9/ee/fc65a7148884b8d7eb637bf9b5f05b6a2e6df1aa6a2d8187cd208c8896a0/any_case-0.1.5.tar.gz", "yanked": false, "yanked_reason": null } ], "0.1.6": [ { "comment_text": "", "digests": { "md5": "c5ebe0a231e917563c247f7d68f9728f", "sha256": "22b097591beb2bb35b88a3eef138cc2b90caae421c033e2dacc7c2020ee47bc2" }, "downloads": -1, "filename": "any_case-0.1.6-py3-none-any.whl", "has_sig": false, "md5_digest": "c5ebe0a231e917563c247f7d68f9728f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 9793, "upload_time": "2019-11-12T09:30:16", "upload_time_iso_8601": "2019-11-12T09:30:16.224224Z", "url": "https://files.pythonhosted.org/packages/1e/7f/84d38f67dee3135045ab2f001eab067bec5c2e1527d8a07c5bf96eea7f87/any_case-0.1.6-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "a4640d58739e33528388396af32ab4e6", "sha256": "51cdb5bf12518653c223f08c3347adc2d07a5c4fd64704fccdb3e0ffed9b4c62" }, "downloads": -1, "filename": "any_case-0.1.6.tar.gz", "has_sig": false, "md5_digest": "a4640d58739e33528388396af32ab4e6", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 9513, "upload_time": "2019-11-12T09:30:17", "upload_time_iso_8601": "2019-11-12T09:30:17.540034Z", "url": "https://files.pythonhosted.org/packages/3b/5b/41d060ecf49f57c4558fdd2699ff018285525d98bbed359d8d07e32995d9/any_case-0.1.6.tar.gz", "yanked": false, "yanked_reason": null } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c5ebe0a231e917563c247f7d68f9728f", "sha256": "22b097591beb2bb35b88a3eef138cc2b90caae421c033e2dacc7c2020ee47bc2" }, "downloads": -1, "filename": "any_case-0.1.6-py3-none-any.whl", "has_sig": false, "md5_digest": "c5ebe0a231e917563c247f7d68f9728f", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": ">=3.6,<4.0", "size": 9793, "upload_time": "2019-11-12T09:30:16", "upload_time_iso_8601": "2019-11-12T09:30:16.224224Z", "url": "https://files.pythonhosted.org/packages/1e/7f/84d38f67dee3135045ab2f001eab067bec5c2e1527d8a07c5bf96eea7f87/any_case-0.1.6-py3-none-any.whl", "yanked": false, "yanked_reason": null }, { "comment_text": "", "digests": { "md5": "a4640d58739e33528388396af32ab4e6", "sha256": "51cdb5bf12518653c223f08c3347adc2d07a5c4fd64704fccdb3e0ffed9b4c62" }, "downloads": -1, "filename": "any_case-0.1.6.tar.gz", "has_sig": false, "md5_digest": "a4640d58739e33528388396af32ab4e6", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6,<4.0", "size": 9513, "upload_time": "2019-11-12T09:30:17", "upload_time_iso_8601": "2019-11-12T09:30:17.540034Z", "url": "https://files.pythonhosted.org/packages/3b/5b/41d060ecf49f57c4558fdd2699ff018285525d98bbed359d8d07e32995d9/any_case-0.1.6.tar.gz", "yanked": false, "yanked_reason": null } ], "vulnerabilities": [] }