I would like my script to receive these mutually exclusive input options:
- an input file containing a JSON (
script.py -i input.json
); - a string containing a JSON (
script.py '{"a":1}'
); - a JSON from stdin (
echo '{"a":1}' | script.py
orcat input.json | script.py
).
and these mutually exclusive output options:
- an output file containing a JSON;
- a JSON in stdout.
So I tried with this code
import json,sys,argparse
parser = argparse.ArgumentParser(description='Template for python script managing JSON as input/output format')
group = parser.add_mutually_exclusive_group()
group.add_argument('--input-file', '-i', type=str, help='Input file name containing a valid JSON.', default=sys.stdin)
group.add_argument('json', nargs='?', type=str, help='Input string containing a valid JSON.' , default=sys.stdin)
parser.add_argument('--output-file', '-o',type=str, help='Output file name.')
args = parser.parse_args()
if not sys.stdin.isatty():
data = sys.stdin.read()
else:
# args = parser.parse_args()
if args.input_file :
data=open(args.input_file).read()
elif args.json :
data=args.json
datain=json.loads(data)
dataout=json.dumps(datain, indent=2)
if args.output_file :
output_file=open(args.output_file, 'w')
output_file.write(dataout+'\n')
output_file.close()
else:
print (dataout)
But it does not work with stdin as it requires at least one of the two group
options.
How can I add stdin in the list of input options?
Adding the default=sys.stdin
argument works if I call it like that
echo '{}' | ./script.py -
but not like that:
echo '{}' | ./script.py
With:
You could test
Or may be better:
A tricky thing with
stdin
is that you don't want to close it after use like you would with a regular file name. And you can't use it in awith
.Similarly with
stdout
.Some code sets a flag when it opens a file, as opposed to receiving an already open one, so it can remember to close the file at the end.
would set
arg.input_file
tostdin
when given-i
without an argument. But I think looking for a plain-
string is a better idea.I would take advantage of
argparse.FileType
with a default value ofsys.stdin
.