Skip to main content

🐫 Convert strings (and dictionary keys) between snake case, camel case and pascal case in Python. Inspired by Humps for Node

Project description

Humps logo

pypi pypi

Convert strings (and dictionary keys) between snake case, camel case and pascal case in Python. Inspired by Humps for Node.

Installation

To install humps, simply use pipenv (or pip, of course):

$ pipenv install pyhumps

Usage

Converting strings

import humps

humps.camelize('jack_in_the_box')  # jackInTheBox
humps.decamelize('rubyTuesdays')  # ruby_tuesdays
humps.pascalize('red_robin')  # RedRobin

Converting dictionary keys

import humps

array = [{'attrOne': 'foo'}, {'attrOne': 'bar'}]
humps.decamelize(array) # [{'attr_one': 'foo'}, {'attr_one': 'bar'}]

array = [{'attr_one': 'foo'}, {'attr_one': 'bar'}]
humps.camelize(array)  # [{'attrOne': 'foo'}, {'attrOne': 'bar'}]

array = [{'attr_one': 'foo'}, {'attr_one': 'bar'}]
humps.pascalize(array)  # [{'AttrOne': 'foo'}, {'AttrOne': 'bar'}]

Checking character casing

import humps

humps.is_camelcase('illWearYourGranddadsClothes')  # True
humps.is_pascalcase('ILookIncredible')  # True
humps.is_snakecase('im_in_this_big_ass_coat')  # True
humps.is_camelcase('from_that_thrift_shop')  # False
humps.is_snakecase('downTheRoad')  # False

# what about abbrevations, acronyms, and initialisms? No problem!
humps.decamelize('APIResponse')  # api_response

Humps Cookbook

Pythonic Boto3 API Wrapper

# aws.py
import humps
import boto3

def api(service, decamelize=True, *args, **kwargs):
    service, func = service.split(':')
    client = boto3.client(service)
    kwargs = humps.pascalize(kwargs)
    response = getattr(client, func)(*args, **kwargs)
    return (depascalize(response) if decamelize else response)

# usage
api('s3:download_file', bucket='bucket', key='hello.png', filename='hello.png')

Generic API Response Return Mangler

from functools import wraps
import enum

import humps


class Flags(enum.Enum):
    RAW = 1
    JSON = 2
    STATUS_CODE = 4
    OK = 8
    DECAMELIZE = 16


def returning(api_exception=Exception):
    def decorator(fn):
        @wraps(fn)
        def wrapper(*args, **kwargs):
            flags = []
            if 'returning' in kwargs:
                returning = kwargs.pop('returning')
                if isinstance(returning, Flags):
                    flags.append(returning)
                else:
                    flags.extend(returning)
            flags.extend([a for a in args if isinstance(a, Flags)])
            args = [a for a in args if not isinstance(a, Flags)]
            resp = fn(*args, **kwargs)
            is_json = resp.headers.get('Content-Type') == 'application/json'
            if not flags or Flags.RAW in flags:
                return resp
            if Flags.OK in flags:
                return resp.ok
            if Flags.STATUS_CODE in flags:
                return resp.status_code
            if Flags.JSON in flags:
                if not resp.ok:
                    raise api_exception(resp.json() if is_json else resp.text)
                if Flags.DECAMELIZE in flags:
                    return humps.decamelize(resp.json())
                else:
                    return resp.json()
        return wrapper
    return decorator

# usage
import requests

@returning()
def get_todo(todo_id):
  return requests.get('https://jsonplaceholder.typicode.com/posts/1')

get_todo(1) # <Response [200]> (true method return)

get_todo(1, Flags.JSON) # {'userId': 1, 'id': 1, 'title': '...'}

get_todo(1, Flags.JSON, Flags.DECAMELIZE) # {'user_id': 1, 'id': 1, 'title': '...'}

get_todo(1, Flags.OK) # True

get_todo(1, Flags.STATUS_CODE) # 200

Flask-RESTful Adaptive Responses

# I will post a code snippet for this soon. It's a decorator that checks if
# the request arguments were passed as camelcase or snake_case, it then
# rewrites the response to match the consumer's preferred casing style.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyhumps-1.3.0.tar.gz (7.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyhumps-1.3.0-py3-none-any.whl (6.0 kB view details)

Uploaded Python 3

File details

Details for the file pyhumps-1.3.0.tar.gz.

File metadata

  • Download URL: pyhumps-1.3.0.tar.gz
  • Upload date:
  • Size: 7.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.1.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.6.6

File hashes

Hashes for pyhumps-1.3.0.tar.gz
Algorithm Hash digest
SHA256 ee79a056c8d0972391c6ae595a2590250b1a84baf6a304c91edc8b5eddc7a88c
MD5 d8da6d4d4c5de00ff51ac57a70278c83
BLAKE2b-256 61eff41ec0640f54f8b0d492b36be768d4f676bbf4290fb43d15249e16b4aad7

See more details on using hashes here.

File details

Details for the file pyhumps-1.3.0-py3-none-any.whl.

File metadata

  • Download URL: pyhumps-1.3.0-py3-none-any.whl
  • Upload date:
  • Size: 6.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.1.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.6.6

File hashes

Hashes for pyhumps-1.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b80e07aecf625fec086cc2b0a81bb276e4be4ac1a738abd755ea48d225460191
MD5 6de6a4898fe5cdb158553e5d51b2356e
BLAKE2b-256 1670db3436a8b2c1b708521309780ef7e70a9e5b4b1bf5c39072913bdbfbccbe

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page