import optparse
import unittest
import sys
import json
import shutil
import os
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
def determine_json_data_path(fileobj):
parsed = json.load(fileobj)
if 'metadata' in parsed:
return _determine_path_from_metadata(parsed)
else:
raise ValueError("Could not determine file path for JSON model, model "
"is missing required 'metadata' key.")
def _determine_path_from_metadata(parsed):
metadata = parsed['metadata']
if 'serviceAbbreviation' in metadata:
service_name = metadata['serviceAbbreviation'].lower().replace(' ', '')
if service_name.startswith('amazon'):
service_name = service_name[6:]
elif service_name.startswith('aws'):
service_name = service_name[3:]
else:
service_name = metadata['endpointPrefix']
if service_name == 'elasticloadbalancing':
service_name = 'elb'
api_version = metadata['apiVersion']
return os.path.join(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
'botocore', 'data', 'aws', service_name, api_version + '.normal.json')
class TestDeterminePath(unittest.TestCase):
def given_metadata(self, metadata):
self.metadata = {'metadata': metadata}
def assert_filename_is(self, filename):
source_file = StringIO(json.dumps(self.metadata))
actual = determine_json_data_path(source_file)
self.assertTrue(actual.endswith(filename))
def test_can_determine_path_from_metadata(self):
self.given_metadata(
{'apiVersion': '2015-01-01', 'endpointPrefix': 'foo'})
self.assert_filename_is('botocore/data/aws/foo/2015-01-01.normal.json')
self.given_metadata(
{'apiVersion': '2015-01-01', 'endpointPrefix': 'foo',
'serviceAbbreviation': 'Amazon Bar'})
self.assert_filename_is('botocore/data/aws/bar/2015-01-01.normal.json')
self.given_metadata(
{'apiVersion': '2015-01-01', 'endpointPrefix': 'foo',
'serviceAbbreviation': 'AWS Baz'})
self.assert_filename_is('botocore/data/aws/baz/2015-01-01.normal.json')
self.given_metadata(
{'apiVersion': '2015-01-01', 'endpointPrefix': 'foo',
'serviceAbbreviation': 'something else'})
self.assert_filename_is(
'botocore/data/aws/somethingelse/2015-01-01.normal.json')
self.given_metadata(
{'apiVersion': '2015-01-01',
'endpointPrefix': 'elasticloadbalancing'}),
self.assert_filename_is(
'botocore/data/aws/elb/2015-01-01.normal.json')
def main():
parser = optparse.OptionParser(usage=__doc__)
parser.add_option(
'-c', '--copy', action='store_true',
default=False, help='Copy the file to the appropriate location. ')
parser.add_option(
'-t', '--test', action='store_true',
default=False, help='Dev use only, run the unit tests.')
opts, args = parser.parse_args()
if opts.test:
sys.argv[:] = [sys.argv[0]]
unittest.main()
return 0
if len(args) != 1:
sys.stderr.write("Must provide the filename of the JSON model "
"as an argument.\n")
return 1
source_filename = args[0]
if not source_filename.endswith('.normal.json'):
sys.stderr.write("Only the *.normal.json files are supported.\n")
return 1
f = open(source_filename)
try:
filename = determine_json_data_path(f)
sys.stdout.write(filename)
sys.stdout.write("\n")
finally:
f.close()
if opts.copy:
if not os.path.isdir(os.path.dirname(filename)):
os.makedirs(os.path.dirname(filename))
shutil.copy(source_filename, filename)
sys.stdout.write("Copied: %s -> %s\n" % (source_filename, filename))
return 0
if __name__ == '__main__':
sys.exit(main())