Skip to content

Instantly share code, notes, and snippets.

@brmzkw
Created May 11, 2018 01:14
Show Gist options
  • Save brmzkw/2eb4ab95e170b46108df640a96fa2078 to your computer and use it in GitHub Desktop.
Save brmzkw/2eb4ab95e170b46108df640a96fa2078 to your computer and use it in GitHub Desktop.
JSON to shell
import json
import pipes
def shell(json_input):
""" Flattens a JSON-dict as a list of key-value pairs.
For each key/value of the dictionary:
- "Simple" elements (strings, bools, integers) are represented as a string
"KEY=value". pipes.quote is used to handle escaping.
- Lists are represented as a string "KEY=n" where n is the number of
elements in the list, then with one line per element "KEY_n=value" where
n is the index of the element.
- Dictionaries are represented as a string "KEY=a b c" where a, b, c are
the keys of the dictionary, then with one line per element "KEY_X=value"
where X is the dictionary key.
Example:
>>> shell({
... 'hello': 'world',
... 'complex': 'value with spaces',
... 'list': ['one', 'two'],
... 'dict': {
... 'first': 'value',
... 'second': 'value with spaces',
... 'third': ['x', 'xx', 'xxx']
... }
... })
HELLO=world
COMPLEX='value with spaces'
LIST=2
LIST_0=one
LIST_1=two
DICT='FIRST SECOND THIRD'
DICT_FIRST=value
DICT_SECOND='value with spaces'
DICT_THIRD=3
DICT_THIRD_0=x
DICT_THIRD_1=xx
DICT_THIRD_0=x
DICT_THIRD_1=xx
DICT_THIRD_2=xxx
"""
def _transform_line(key, value):
""" Transforms a single line (simple type, list or dict).
"""
def make_key(key):
""" Makes keys uppercase. """
return key.upper()
if isinstance(value, dict):
# KEY=a b c
out = '%s=%s\n' % (
make_key(key),
pipes.quote(' '.join(make_key(key) for key in value.keys()))
)
for elem_key, elem_value in value.items():
out += _transform_line(
make_key('%s_%s' % (key, elem_key)),
elem_value
)
return out
elif isinstance(value, list):
# KEY=n
out = '%s=%s\n' % (make_key(key), len(value))
for idx, elem in enumerate(value):
out += _transform_line(make_key('%s_%s' % (key, idx)), elem)
return out
elif value is None:
# KEY=
return '%s=\n' % make_key(key)
# pipes.quote doesn't accept integers or bools.
value = str(value)
return '%s=%s\n' % (make_key(key), pipes.quote(value))
json_input = ''.join(
_transform_line(key, value)
for key, value in json.loads(json_input).items()
)
return json_input
print(shell(json.dumps({
'key': ['one', 'two', {'three': 'x', 'three_bis': 3}]
})))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment