Skip to content

Instantly share code, notes, and snippets.

@benkehoe
Last active August 26, 2020 15:25
Show Gist options
  • Save benkehoe/7b6df9613d2a0bb5d434 to your computer and use it in GitHub Desktop.
Save benkehoe/7b6df9613d2a0bb5d434 to your computer and use it in GitHub Desktop.
JSON <--> YAML conversion scripts

JSON <--> YAML conversion scripts

JSON is very standard. YAML, a superset of JSON, is very readable. Got something that needs JSON, and want to write the input in YAML? Use yaml2json. Have JSON and want to view it in a more readable format? Use json2yaml.

Use with files or stdin/stdout. Pretty-print the JSON if you want.

Requires pyyaml (via pip or easy_install), aka the python-yaml Ubuntu package.

A version of these files is available at tinyurl/json2yaml and tinyurl.com/yaml2json for you to wget or curl -L

#!/usr/bin/env python
# The MIT License (MIT)
# Copyright (c) 2015 Ben Kehoe
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# Updates at https://gist.github.com/benkehoe/7b6df9613d2a0bb5d434
import sys
import yaml
import yaml.constructor as yamlc
import json
import optparse
usage = """Usage: %prog INPUT_FILE [OUTPUT_FILE]
%prog [--input INPUT_FILE] [--output OUTPUT_FILE]
Convert JSON into YAML. With positional arguments, an input filename must
be given. If no output file is given, the YAML will be sent to stdout.
With named arguments, if --input is not given, the JSON will be read from
stdin, and if --output is not given, the YAML will be written to stdout.
Since JSON is valid YAML, and is already in the most compact YAML style,
this program is meant to output YAML in the block style for readability and
inspection purposes."""
parser = optparse.OptionParser(usage=usage)
parser.add_option('-i', '--input', metavar='FILE')
parser.add_option('-o', '--output', metavar='FILE')
options, args = parser.parse_args()
if len(args) >= 3:
parser.exit(1, 'Too many inputs!\n')
if args and (options.input or options.output):
parser.exit(1, "Can't specify both args and options\n")
def open_file(name, mode):
try:
return open(name, mode, 1)
except:
parser.exit(2, "Could not open file %s\n" % name)
if options.input:
input = open_file(options.input,'r')
elif len(args) >= 1:
input = open_file(args[0],'r')
else:
input = sys.stdin
if options.output:
out = open_file(options.output,'w')
elif len(args) == 2:
out = open_file(args[1],'w')
else:
out = sys.stdout
indent = 2
with input, out:
try:
value = json.load(input)
yaml.safe_dump(value, out, indent=indent, default_style=None, default_flow_style=False)
out.write('\n')
except:
import traceback
traceback.print_exception(*sys.exc_info())
sys.exit(3)
sys.exit(0)
#!/usr/bin/env python
# The MIT License (MIT)
# Copyright (c) 2015 Ben Kehoe
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# Updates at https://gist.github.com/benkehoe/7b6df9613d2a0bb5d434
import sys
import yaml
import yaml.constructor as yamlc
import json
import optparse
yamlc.SafeConstructor.add_constructor(u'tag:yaml.org,2002:timestamp', yamlc.SafeConstructor.construct_yaml_str)
def construct_yaml_set(self, node):
data = []
yield data
value = self.construct_mapping(node)
data.extend(value.keys())
yamlc.SafeConstructor.add_constructor(u'tag:yaml.org,2002:set', construct_yaml_set)
usage = """Usage: %prog [--pretty] INPUT_FILE [OUTPUT_FILE]
%prog [--pretty] [--input INPUT_FILE] [--output OUTPUT_FILE]
Convert YAML into JSON. With positional arguments, an input filename must
be given. If no output file is given, the JSON will be sent to stdout.
With named arguments, if --input is not given, the YAML will be read from
stdin, and if --output is not given, the JSON will be written to stdout.
The two standard YAML types not directly representable in JSON are timestamp
and set. The exact string given in the YAML for a timestamp is stored in the
JSON. Sets are converted to lists."""
parser = optparse.OptionParser(usage=usage)
parser.add_option('-i', '--input', metavar='FILE')
parser.add_option('-o', '--output', metavar='FILE')
parser.add_option('-p', '--pretty', action='store_true', default=False, help='Pretty-print JSON for easier readability')
options, args = parser.parse_args()
if len(args) >= 3:
parser.exit(1, 'Too many inputs!\n')
if args and (options.input or options.output):
parser.exit(1, "Can't specify both args and options\n")
def open_file(name, mode):
try:
return open(name, mode, 1)
except:
parser.exit(2, "Could not open file %s\n" % name)
if options.input:
input = open_file(options.input,'r')
elif len(args) >= 1:
input = open_file(args[0],'r')
else:
input = sys.stdin
if options.output:
out = open_file(options.output,'w')
elif len(args) == 2:
out = open_file(args[1],'w')
else:
out = sys.stdout
indent = 2 if options.pretty else None
with input, out:
try:
value = yaml.safe_load(input)
json.dump(value, out, indent=indent)
out.write('\n')
except:
import traceback
traceback.print_exception(*sys.exc_info())
sys.exit(3)
sys.exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment