Skip to main content

any_case

When developing a web application, you often have to choose the case format (snake_case/camelCase) will be used for the input and the output json data. If the backend is written in Python, the easiest option is to choose snake_case. On the one hand, this is good, because we have an obvious consistency, but on the other hand, the main consumers of the API (mobile and browser) prefer to use camelCase.

If we care about our consumers, we will change the case format to camelCase. And it’s good if we think about it in advance, before publishing API. But if this happens in an existing application, it becomes much more difficult to do so because there are consumers using the existing API. We have two options here:

  • introduce a new version of the api

  • send data in two cases at once

The second option increases the size of the data, and the first option forces us to support two versions of the API without serious need. These options complicate the support and development of API.

Things get a little more complicated when we have consumers who natively use snake_case, and using camelCase for them is not an option at all.

As you can see, the use of one notation does not improve, but may worsen the situation.

But why do we have to choose for the customer which case format they use? Why customers do not send and not receive data in the format, which would be more convenient to them?

That’s what this library is for. Consumers choose in what case they expect the data. If they specified an incorrect case or made a request without specifying a case, the data will be given as is.

This approach allows existing consumers to work without changes with existing API, and for those consumers who want to use a single format, allows granular rewriting of the application.

Installation

pip install any_case

Usage

For converting dict or list use converts_keys function:

>>> from any_case import converts_keys
>>> data = {'camelCaseKey': 'value'}
>>> converts_keys(data, case='snake')
{'camel_case_key': 'value'}
>>> data = {'snake_case': 'camelCase'}
>>> converts_keys(data, case='camel')
{'snakeCase': 'camelCase'}

For converting any_case uses compiled regex and stack for objects traversal instead of recursion.

To convert existing data without producing new one, use inplace param:

>>> data = {'snake_case': 'camelCase'}
>>> converts_keys(data, case='camel', inplace=True)
{'snakeCase': 'camelCase'}
>>> data
{'snakeCase': 'camelCase'}

Some tricky cases could happen when works with keys which contains numbers:

>>> data = {'camelCase12': 'camelCase'}
>>> converts_keys(data, case='snake')
{'camel_case12': 'camelCase'}

To adjust this logic use sep_numbers params:

>>> converts_keys(data, case='snake', sep_numbers=True)
{'camel_case_12': 'camelCase'}

To convert text, use to_snake_case or to_camel_case:

>>> from any_case import to_snake_case, to_camel_case
>>> to_snake_case('snakeCase')
'snake_case'
>>> to_camel_case('snake_case')
'snakeCase'

More examples see at tests folder.

Integrations

Django

For integration with the Django framework, you need to add any_case middleware:

MIDDLEWARE = [
    'django.contrib.sessions.middleware.SessionMiddleware',
    ...
    'any_case.contrib.django.middleware.KeysConverterMiddleware'
]

When the input data is converted, it is saved in the json field of request object. That is, you can access to the converted data in the view as follows:

def view(request):
    data = request.json
    ...

rest_framework

For integration with rest_framework, replace default json parser and renderer:

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'any_case.contrib.rest_framework.AnyCaseJSONParser',
        ...
    ),
    'DEFAULT_PARSER_CLASSES': (
        'any_case.contrib.rest_framework.AnyCaseJSONRenderer',
        ...
    )
}

Settings

any_case has the next default settings:

ANY_CASE = {
    'HEADER_KEY': 'Accept-Json-Case',
    'QUERY_KEY': None,
    'BODY_KEY': None,
    'CONVERT_INPUT_JSON': True,
    'SEP_NUMBERS_TO_CAMEL': False,
    'SEP_NUMBERS_TO_SNAKE': False,
}

Settings are specified in django settings.py.

any_case can be used for converting:

  • input json data to snake_case

  • output json to snake_case or camelCase

Or only one of the above independently.

You can specify the case format in the header, in the query parameters, or in the json body. The preferred way is the header, because specifying in the query or in the body is not always possible. Specifying case format in the body also forces to parse json data that may not be needed at all.

Disable converting output data

ANY_CASE = {
    'HEADER_KEY': None,
    'QUERY_KEY': None,
    'BODY_KEY': None,
}

Disable converting input data

ANY_CASE = {
    'CONVERT_INPUT_JSON': False
}

Metadata

Release files for any-case 0.1.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for any-case 0.1.6
File Size Uploaded
any_case-0.1.6.tar.gz 9.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for any-case 0.1.6
File Interpreter ABI Platform
any_case-0.1.6-py3-none-any.whl Python 3 none any Details

Total release size: 19.3 kB

Release files / any_case-0.1.6.tar.gz

Download URL any_case-0.1.6.tar.gz
Size 9.5 kB
Tags Source
SHA-256 checksum
How to use checksums
51cdb5bf12518653c223f08c3347adc2d07a5c4fd64704fccdb3e0ffed9b4c62
BLAKE2b-256 checksum
How to use checksums
3b5b41d060ecf49f57c4558fdd2699ff018285525d98bbed359d8d07e32995d9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/0.12.12 CPython/3.6.7 Darwin/19.0.0

Release files / any_case-0.1.6-py3-none-any.whl

Download URL any_case-0.1.6-py3-none-any.whl
Size 9.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
22b097591beb2bb35b88a3eef138cc2b90caae421c033e2dacc7c2020ee47bc2
BLAKE2b-256 checksum
How to use checksums
1e7f84d38f67dee3135045ab2f001eab067bec5c2e1527d8a07c5bf96eea7f87
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/0.12.12 CPython/3.6.7 Darwin/19.0.0

Release history Release notifications | RSS feed

This release

0.1.6 This release

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page