forked from boto/botocore
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathget-model-filename
More file actions
executable file
·152 lines (127 loc) · 5.38 KB
/
get-model-filename
File metadata and controls
executable file
·152 lines (127 loc) · 5.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/env python
"""Determine the filename for a JSON model.
This is a utility script that will parse a service's metadata
file and determine where this file should be placed. It
hides the details of botocore's internal file layout for JSON
models.
It its simplest usage you give it a path to a file and it
prints the location within botocore::
$ scripts/get-model-filename /tmp/myfile.json
/Users/foo/botocore/botocore/data/aws/cloudwatch/2010-08-01.normal.json
If you want, you can use the ``-c`` option to actually copy the file
to this location. When this option is specified, the parent directory
will be created if it does not exist.
$ scripts/get-model-filename -c /tmp/myfile.json
/Users/foo/botocore/data/aws/cloudwatch/2010-08-01.normal.json
Copied: /tmp/myfile.json -> /Users/foo/botocore/data/aws/cloudwatch/2010-08-01.normal.json
"""
# Note we're using optparse for 2.6 compat.
# We don't have particularly complicated command line
# parsing requirements so we'll deal with it.
import optparse
import unittest
import sys
import json
import shutil
import os
try:
from StringIO import StringIO
except ImportError:
# Python3 we need to import from the io module.
from io import StringIO
def determine_json_data_path(fileobj):
"""Determine the filepath for a JSON model.
This is a utility function that will introspect a JSON file and determine
where it should be placed in botocore/data/aws/.
"""
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']
# There's one single special case where we can't automatically
# figure out, and that's elasticloadbalancing -> elb so we have
# to hardcode this here.
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')
# The special casing of elasticloadbalancing -> elb.
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())