friend package

friend.collections module

friend.collections.select_dict(coll, key, value)[source]

Given an iterable of dictionaries, return the dictionaries where the values at a given key match the given value. If the value is an iterable of objects, the function will consider any to be a match.

This is especially useful when calling REST APIs which return arrays of JSON objects. When such a response is converted to a Python list of dictionaries, it may be easily filtered using this function.

Parameters:
  • coll (iter) – An iterable containing dictionaries
  • key (obj) – A key to search in each dictionary
  • value (obj or iter) – A value or iterable of values to match
Returns:

A list of dictionaries matching the query

Return type:

list

Example:
>>> dicts = [
...    {'hi': 'bye'},
...    {10: 2, 30: 4},
...    {'hi': 'hello', 'bye': 'goodbye'},
... ]
>>> select_dict(dicts, 'hi', 'bye')
[{'hi': 'bye'}]
>>> select_dict(dicts, 'hi', ('bye', 'hello'))
[{'hi': 'bye'}, {'hi': 'hello', 'bye': 'goodbye'}]

friend.net module

friend.net.random_ipv4(cidr='10.0.0.0/8')[source]

Return a random IPv4 address from the given CIDR block.

Key str cidr:CIDR block
Returns:An IPv4 address from the given CIDR block
Return type:ipaddress.IPv4Address

friend.strings module

Utility functions related to strings.

friend.strings.camel_to_kebab(stringue)[source]

Convert a “camel case” string to a “kebab case” string.

Parameters:stringue (str) – The string to convert
Returns:A kebab case string
Return type:str
Example:
>>> camel_to_kebab('camelCaseString')
'camel-case-string'
friend.strings.camel_to_kebab_obj(obj)[source]

Take a dictionary with string keys and recursively convert all keys from “camel case” to “kebab case”.

The dictionary may contain lists as values, and any nested dictionaries within those lists will also be converted.

Parameters:obj (object) – The object to convert
Returns:A new object with keys converted
Return type:object
Example:
>>> obj = {
...     'dictList': [
...         {'oneKey': 123, 'twoKey': 456},
...         {'threeKey': 789, 'fourKey': 456},
...     ],
...     'someOtherKey': 'someUnconvertedValue'
... }
>>> camel_to_kebab_obj(obj)
{
    'dict-list': [
        {'one-key': 123, 'two-key': 456},
        {'four-key': 456, 'three-key': 789}
    ],
    'some-other-key': 'someUnconvertedValue'
}
friend.strings.camel_to_snake(stringue)[source]

Convert a “camel case” string to a “snake case” string.

Parameters:stringue (str) – The string to convert
Returns:A snake case string
Return type:str
Example:
>>> camel_to_snake('camelCaseString')
'camel_case_string'
friend.strings.camel_to_snake_obj(obj)[source]

Take a dictionary with string keys and recursively convert all keys from “camel case” to “snake case”.

The dictionary may contain lists as values, and any nested dictionaries within those lists will also be converted.

Parameters:obj (object) – The object to convert
Returns:A new object with keys converted
Return type:object
Example:
>>> obj = {
...     'dictList': [
...         {'oneKey': 123, 'twoKey': 456},
...         {'threeKey': 789, 'fourKey': 456},
...     ],
...     'someOtherKey': 'someUnconvertedValue'
... }
>>> camel_to_snake_obj(obj)
{
    'dict_list': [
        {'one_key': 123, 'two_key': 456},
        {'four_key': 456, 'three_key': 789}
    ],
    'some_other_key': 'someUnconvertedValue'
}
friend.strings.format_obj_keys(obj, formatter)[source]

Take a dictionary with string keys and recursively convert all keys from one form to another using the formatting function.

The dictionary may contain lists as values, and any nested dictionaries within those lists will also be converted.

Parameters:
  • obj (object) – The object to convert
  • formatter (function) – The formatting function for keys, which takes and returns a string
Returns:

A new object with keys converted

Return type:

object

Example:
>>> obj = {
...     'dict-list': [
...         {'one-key': 123, 'two-key': 456},
...         {'threeKey': 789, 'four-key': 456},
...     ],
...     'some-other-key': 'some-unconverted-value'
... }
>>> format_obj_keys(obj, lambda s: s.upper())
{
    'DICT-LIST': [
        {'ONE-KEY': 123, 'TWO-KEY': 456},
        {'FOUR-KEY': 456, 'THREE-KEY': 789}
    ],
    'SOME-OTHER-KEY': 'some-unconverted-value'
}
friend.strings.kebab_to_camel(stringue)[source]

Convert a “kebab case” string to a “camel case” string.

Parameters:stringue (str) – The string to convert
Returns:A camel case string
Return type:str
Example:
>>> kebab_to_camel('kebab-to-camel')
'kebabToCamel'
friend.strings.kebab_to_camel_obj(obj)[source]

Take a dictionary with string keys and recursively convert all keys from “kebab case” to “camel case”.

The dictionary may contain lists as values, and any nested dictionaries within those lists will also be converted.

Parameters:obj (object) – The object to convert
Returns:A new object with keys converted
Return type:object
Example:
>>> obj = {
...     'dict-list': [
...         {'one-key': 123, 'two-key': 456},
...         {'three-key': 789, 'four-key': 456},
...     ],
...     'some-other-key': 'some-unconverted-value',
... }
>>> kebab_to_camel_obj(obj)
{
    'dictList': [
        {'oneKey': 123, 'twoKey': 456},
        {'fourKey': 456, 'threeKey': 789}
    ],
    'someOtherKey': 'some-unconverted-value'
}
friend.strings.kebab_to_pascal(stringue)[source]

Convert a “kebab case” string to a “pascal case” string.

Parameters:stringue (str) – The string to convert
Returns:A pascal case string
Return type:str
Example:
>>> kebab_to_pascal('kebab-to-pascal')
'KebabToPascal'
friend.strings.kebab_to_pascal_obj(obj)[source]

Take a dictionary with string keys and recursively convert all keys from “kebab case” to “pascal case”.

The dictionary may contain lists as values, and any nested dictionaries within those lists will also be converted.

Parameters:obj (object) – The object to convert
Returns:A new object with keys converted
Return type:object
Example:
>>> obj = {
...     'dict-list': [
...         {'one-key': 123, 'two-key': 456},
...         {'three-key': 789, 'four-key': 456},
...     ],
...     'some-other-key': 'some-unconverted-value',
... }
>>> kebab_to_pascal_obj(obj)
{
    'DictList': [
        {'OneKey': 123, 'TwoKey': 456},
        {'FourKey': 456, 'ThreeKey': 789}
    ],
    'SomeOtherKey': 'some-unconverted-value'
}
friend.strings.random_alphanum(length)[source]

Return a random string of ASCII letters and digits.

Parameters:length (int) – The length of string to return
Returns:A random string
Return type:str
friend.strings.random_hex(length)[source]

Return a random hex string.

Parameters:length (int) – The length of string to return
Returns:A random string
Return type:str
friend.strings.random_string(length, charset)[source]

Return a random string of the given length from the given character set.

Parameters:
  • length (int) – The length of string to return
  • charset (str) – A string of characters to choose from
Returns:

A random string

Return type:

str

friend.strings.snake_to_camel(stringue)[source]

Convert a “snake case” string to a “camel case” string.

Parameters:stringue (str) – The string to convert
Returns:A camel case string
Return type:str
Example:
>>> snake_to_camel('snake_to_camel')
'snakeToCamel'
friend.strings.snake_to_camel_obj(obj)[source]

Take a dictionary with string keys and recursively convert all keys from “snake case” to “camel case”.

The dictionary may contain lists as values, and any nested dictionaries within those lists will also be converted.

Parameters:obj (object) – The object to convert
Returns:A new object with keys converted
Return type:object
Example:
>>> obj = {
...     'dict_list': [
...         {'one_key': 123, 'two_key': 456},
...         {'three_key': 789, 'four_key': 456},
...     ],
...     'some_other_key': 'some_unconverted_value',
... }
>>> snake_to_camel_obj(obj)
{
    'dictList': [
        {'onekey': 123, 'twoKey': 456},
        {'fourKey': 456, 'threeKey': 789}
    ],
    'someOtherKey': 'some_unconverted_value'
}
friend.strings.snake_to_pascal(stringue)[source]

Convert a “snake case” string to a “pascal case” string.

Parameters:stringue (str) – The string to convert
Returns:A pascal case string
Return type:str
Example:
>>> snake_to_pascal('snake_to_pascal')
'SnakeToPascal'
friend.strings.snake_to_pascal_obj(obj)[source]

Take a dictionary with string keys and recursively convert all keys from “snake case” to “pascal case”.

The dictionary may contain lists as values, and any nested dictionaries within those lists will also be converted.

Parameters:obj (object) – The object to convert
Returns:A new object with keys converted
Return type:object
Example:
>>> obj = {
...     'dict_list': [
...         {'one_key': 123, 'two_key': 456},
...         {'three_key': 789, 'four_key': 456},
...     ],
...     'some_other_key': 'some_value'
... }
>>> snake_to_pascal_obj(obj)
{
    'DictList': [
        {'OneKey': 123, 'TwoKey': 456},
        {'FourKey': 456, 'ThreeKey': 789}
    ],
    'SomeOtherKey': 'some_value'
}

friend.utils module

exception friend.utils.IncompleteEnvironment(message, variables)[source]

Bases: exceptions.RuntimeError

An exception which is used to indicate when environment variables are unset.

friend.utils.cached(func)[source]

A decorator function to cache values. It uses the decorated function’s arguments as the keys to determine if the function has been called previously.

friend.utils.ensure_environment(variables)[source]

Check os.environ to ensure that a given collection of variables has been set.

Parameters:variables – A collection of environment variable names
Returns:os.environ
Raises:IncompleteEnvironment – if any variables are not set, with the exception’s variables attribute populated with the missing variables
friend.utils.retry_bool(callback, times=3, cap=120000)[source]

Retry a callback function if it returns False.

Parameters:
  • callback (function) – The function to call
  • times (int) – Number of times to retry on initial failure
  • cap (int) – Maximum wait time in milliseconds
Returns:

The return value of the callback

Return type:

bool

friend.utils.retry_ex(callback, times=3, cap=120000)[source]

Retry a callback function if any exception is raised.

Parameters:
  • callback (function) – The function to call
  • times (int) – Number of times to retry on initial failure
  • cap (int) – Maximum wait time in milliseconds
Returns:

The return value of the callback

Raises:

Exception – If the callback raises an exception after exhausting all retries

friend.utils.retry_wait_time(attempt, cap)[source]

Determine a retry wait time based on the number of the retry attempt and a cap on the wait time. The wait time uses an exponential backoff with a random jitter. The algorithm used is explained at https://www.awsarchitectureblog.com/2015/03/backoff.html.

Parameters:
  • attempt (int) – The number of the attempt
  • cap (int) – A cap on the wait time in milliseconds
Returns:

The number of milliseconds to wait

Return type:

int

friend.utils.retryable(retryer=<function retry_ex>, times=3, cap=120000)[source]

A decorator to make a function retry. By default the retry occurs when an exception is thrown, but this may be changed by modifying the retryer argument.

See also retry_ex() and retry_bool(). By default retry_ex() is used as the retry function.

Note that the decorator must be called even if not given keyword arguments.

Parameters:
  • retryer (function) – A function to handle retries
  • times (int) – Number of times to retry on initial failure
  • cap (int) – Maximum wait time in milliseconds
Example:
@retryable()
def can_fail():
    ....

@retryable(retryer=retry_bool, times=10)
def can_fail_bool():
    ....