Created
May 11, 2018 01:14
-
-
Save brmzkw/2eb4ab95e170b46108df640a96fa2078 to your computer and use it in GitHub Desktop.
JSON to shell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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