Skip to content

Commit 756c169

Browse files
committed
refactor common definitions access
* cache the read file in a global dict * provide filtering overloads for common use cases * remove duplicated code and unnecessary params
1 parent 6a22885 commit 756c169

6 files changed

Lines changed: 151 additions & 139 deletions

File tree

agency/get_vehicle.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@
3131
],
3232
"pattern": "^(.*)$"
3333
},
34+
"timestamp": {
35+
"$id": "#/definitions/timestamp",
36+
"type": "number",
37+
"description": "Integer milliseconds since Unix epoch",
38+
"multipleOf": 1.0,
39+
"minimum": 0
40+
},
3441
"vehicle_type": {
3542
"$id": "#/definitions/vehicle_type",
3643
"type": "string",
@@ -43,13 +50,6 @@
4350
"other"
4451
]
4552
},
46-
"timestamp": {
47-
"$id": "#/definitions/timestamp",
48-
"type": "number",
49-
"description": "Integer milliseconds since Unix epoch",
50-
"multipleOf": 1.0,
51-
"minimum": 0
52-
},
5353
"uuid": {
5454
"$id": "#/definitions/uuid",
5555
"type": "string",

schema/agency.py

Lines changed: 47 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,33 @@
77
import common
88

99

10-
def get_stops_schema(common_definitions):
10+
def get_stops_schema():
1111
"""
1212
Create the schema for the Agency GET /stops endpoint.
1313
"""
1414
# load schema template and insert definitions
1515
schema = common.load_json("./templates/agency/get_stops.json")
16-
stops = common.stop_definitions(common_definitions)
16+
stops = common.stop_definitions()
1717
schema["definitions"].update(stops)
1818

1919
# verify and return
2020
return common.check_schema(schema)
2121

2222

23-
def post_stops_schema(common_definitions):
23+
def post_stops_schema():
2424
"""
2525
Create the schema for the Agency POST /stops endpoint.
2626
"""
2727
# load schema template and insert definitions
2828
schema = common.load_json("./templates/agency/post_stops.json")
29-
stops = common.stop_definitions(common_definitions)
29+
stops = common.stop_definitions()
3030
schema["definitions"].update(stops)
3131

3232
# verify and return
3333
return common.check_schema(schema)
3434

3535

36-
def put_stops_schema(common_definitions):
36+
def put_stops_schema():
3737
"""
3838
Create the schema for the Agency POST /stops endpoint.
3939
"""
@@ -42,60 +42,62 @@ def put_stops_schema(common_definitions):
4242
# the PUT body allows a small subset of fields
4343
schema = common.load_json("./templates/agency/put_stops.json")
4444

45-
stop_defs = common.stop_definitions(common_definitions)
45+
stops = common.stop_definitions()
4646
needed_defs = ["stop_status", "uuid", "vehicle_type_counts"]
47-
for key in [k for k in stop_defs.keys() if k not in needed_defs]:
48-
del stop_defs[key]
47+
for key in [k for k in stops.keys() if k not in needed_defs]:
48+
del stops[key]
4949

50-
schema["definitions"].update(stop_defs)
50+
schema["definitions"].update(stops)
5151

5252
# verify and return
5353
return common.check_schema(schema)
5454

5555

56-
def get_vehicle_schema(common_definitions):
56+
def get_vehicle_schema():
5757
"""
5858
Create the schema for the Agency GET /vehicles endpoint.
5959
"""
6060
# load schema template and insert definitions
6161
schema = common.load_json("./templates/agency/get_vehicle.json")
62-
schema["definitions"] = {
63-
"propulsion_types": common_definitions["propulsion_types"],
64-
"string": common_definitions["string"],
65-
"vehicle_type": common_definitions["vehicle_type"],
66-
"timestamp": common_definitions["timestamp"],
67-
"uuid": common_definitions["uuid"]
68-
}
62+
definitions = common.load_definitions(
63+
"propulsion_types",
64+
"string",
65+
"timestamp",
66+
"vehicle_type",
67+
"uuid"
68+
)
69+
schema["definitions"].update(definitions)
6970

7071
# merge the state machine definitions and transition combinations rule
71-
state_machine_defs, transitions = common.vehicle_state_machine(common_definitions, "state", "prev_events")
72+
state_machine_defs, transitions = common.vehicle_state_machine("state", "prev_events")
7273
schema["definitions"].update(state_machine_defs)
7374
schema["allOf"].append(transitions)
7475

7576
# merge common vehicle information, with Agency tweaks
76-
vehicle = common.vehicle_definition(common_definitions, provider_name=False)
77+
vehicle = common.vehicle_definition(provider_name=False)
7778
schema["required"] = vehicle["required"] + schema["required"]
7879
schema["properties"] = { **vehicle["properties"], **schema["properties"] }
7980

8081
# verify and return
8182
return common.check_schema(schema)
8283

8384

84-
def post_vehicle_schema(common_definitions):
85+
def post_vehicle_schema():
8586
"""
8687
Create the schema for the Agency POST /vehicles endpoint.
8788
"""
8889
# load schema template and insert definitions
8990
schema = common.load_json("./templates/agency/post_vehicle.json")
90-
schema["definitions"] = {
91-
"propulsion_types": common_definitions["propulsion_types"],
92-
"string": common_definitions["string"],
93-
"vehicle_type": common_definitions["vehicle_type"],
94-
"uuid": common_definitions["uuid"]
95-
}
91+
definitions = common.load_definitions(
92+
"propulsion_types",
93+
"string",
94+
"vehicle_type",
95+
"uuid"
96+
)
97+
schema["definitions"].update(definitions)
9698

9799
# merge common vehicle information, with Agency tweaks
98-
vehicle = common.vehicle_definition(common_definitions, provider_name=False, provider_id=False)
100+
vehicle = common.vehicle_definition(provider_name=False, provider_id=False)
99101

100102
schema["required"] = vehicle["required"] + schema["required"]
101103
schema["properties"] = { **vehicle["properties"], **schema["properties"] }
@@ -104,42 +106,44 @@ def post_vehicle_schema(common_definitions):
104106
return common.check_schema(schema)
105107

106108

107-
def post_vehicle_event_schema(common_definitions):
109+
def post_vehicle_event_schema():
108110
"""
109111
Create the schema for the Agency POST /vehicles/:id/event endpoint.
110112
"""
111113
# load schema template and insert definitions
112114
schema = common.load_json("./templates/agency/post_vehicle_event.json")
113-
schema["definitions"] = {
114-
"telemetry": common_definitions["telemetry"],
115-
"timestamp": common_definitions["timestamp"],
116-
"uuid": common_definitions["uuid"]
117-
}
115+
definitions = common.load_definitions(
116+
"telemetry",
117+
"timestamp",
118+
"uuid"
119+
)
120+
schema["definitions"].update(definitions)
118121

119122
# merge the state machine definitions and transition combinations rule
120-
state_machine_defs, transitions = common.vehicle_state_machine(common_definitions, "vehicle_state", "event_types")
123+
state_machine_defs, transitions = common.vehicle_state_machine("vehicle_state", "event_types")
121124
schema["definitions"].update(state_machine_defs)
122125
schema["allOf"].append(transitions)
123126

124127
# add the conditionally-required trip_id rule
125-
trip_id_ref = common_definitions["trip_id_reference"]
128+
trip_id_ref = common.load_definitions("trip_id_reference")
126129
schema["allOf"].append(trip_id_ref)
127130

128131
# verify and return
129132
return common.check_schema(schema)
130133

131134

132-
def post_vehicle_telemetry_schema(common_definitions):
135+
def post_vehicle_telemetry_schema():
133136
"""
134137
Create the schema for the Agency POST /vehicles/telemetry endpoint.
135138
"""
136139
# load schema template and insert definitions
137140
schema = common.load_json("./templates/agency/post_vehicle_telemetry.json")
138-
schema["definitions"] = {
139-
"telemetry": common_definitions["telemetry"],
140-
"timestamp": common_definitions["timestamp"],
141-
"uuid": common_definitions["uuid"]
142-
}
141+
definitions = common.load_definitions(
142+
"telemetry",
143+
"timestamp",
144+
"uuid"
145+
)
146+
schema["definitions"].update(definitions)
143147

144148
# verify and return
145149
return common.check_schema(schema)
@@ -164,14 +168,14 @@ def schema_generators():
164168
}
165169

166170

167-
def write_schema_files(common_definitions):
171+
def write_schema_files():
168172
"""
169173
Create each of the Agency endpoint schema files in the appropriate directory.
170174
"""
171175
print("\nStarting to generate Agency JSON Schemas...\n")
172176

173177
for name, generator in schema_generators().items():
174-
schema = generator(common_definitions)
178+
schema = generator()
175179
with open(f"../agency/{name}.json", "w") as schemafile:
176180
schemafile.write(json.dumps(schema, indent=2))
177181
print(f"Wrote {name}.json")

schema/common.py

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
import requests
99

1010

11+
COMMON_DEFINITIONS = {}
12+
13+
1114
def load_json(path):
1215
"""
1316
Load a JSON file from disk.
@@ -24,11 +27,11 @@ def definition_id(id):
2427
return f"#/definitions/{id}"
2528

2629

27-
def vehicle_definition(common_definitions, provider_name=True, provider_id=True):
30+
def vehicle_definition(provider_name=True, provider_id=True):
2831
"""
2932
Extract a deep-copy of the common vehicle model definition to allow for customization.
3033
"""
31-
vehicle = copy.deepcopy(common_definitions["vehicle"])
34+
vehicle = copy.deepcopy(load_definitions("vehicle"))
3235

3336
if not provider_name:
3437
vehicle["required"].remove("provider_name")
@@ -41,7 +44,7 @@ def vehicle_definition(common_definitions, provider_name=True, provider_id=True)
4144
return vehicle
4245

4346

44-
def vehicle_state_machine(common_definitions, vehicle_state=None, vehicle_events=None):
47+
def vehicle_state_machine(vehicle_state=None, vehicle_events=None):
4548
"""
4649
Return a tuple (definitions, transitions) with the common vehicle state schema.
4750
* defitions is the common definitions for vehicle state fields
@@ -50,13 +53,8 @@ def vehicle_state_machine(common_definitions, vehicle_state=None, vehicle_events
5053
Optionally pass field names for the vehicle_state and vehicle_events schemas
5154
to override those in transitions.
5255
"""
53-
state_machine_defs = {
54-
"vehicle_state": common_definitions["vehicle_state"],
55-
"vehicle_event": common_definitions["vehicle_event"],
56-
"vehicle_events": common_definitions["vehicle_events"],
57-
}
58-
59-
transitions = copy.deepcopy(common_definitions["vehicle_state_transitions"])
56+
state_machine_defs = load_definitions("vehicle_state", "vehicle_event", "vehicle_events")
57+
transitions = copy.deepcopy(load_definitions("vehicle_state_transitions"))
6058

6159
if vehicle_state:
6260
for option in transitions["oneOf"]:
@@ -73,14 +71,14 @@ def vehicle_state_machine(common_definitions, vehicle_state=None, vehicle_events
7371
return (state_machine_defs, transitions)
7472

7573

76-
def vehicle_type_counts_definition(common_definitions):
74+
def vehicle_type_counts_definition(definitions=None):
7775
"""
7876
Generate a definition for a dict of vehicle_type: int.
7977
"""
8078
vehicle_type_counts = {}
8179
def_name = "vehicle_type_counts"
8280
def_id = definition_id(def_name)
83-
vehicle_types = common_definitions["vehicle_type"]
81+
vehicle_types = definitions["vehicle_type"] if definitions else load_definitions("vehicle_type")
8482

8583
for vehicle_type in vehicle_types["enum"]:
8684
vehicle_type_counts[vehicle_type] = {
@@ -191,52 +189,67 @@ def mds_feature_point_definition():
191189
}
192190

193191

194-
def stop_definitions(common_definitions):
192+
def stop_definitions():
195193
"""
196194
Return a dict of definitions needed for stops.
197195
"""
198-
defs = {
199-
"stop": common_definitions["stop"],
200-
"stop_status": common_definitions["stop_status"],
201-
"string": common_definitions["string"],
202-
"timestamp": common_definitions["timestamp"],
203-
"uuid": common_definitions["uuid"],
204-
"vehicle_type_counts": common_definitions["vehicle_type_counts"]
205-
}
206-
defs.update(mds_feature_point_definition())
196+
definitions = load_definitions(
197+
"stop",
198+
"stop_status",
199+
"string",
200+
"timestamp",
201+
"uuid",
202+
"vehicle_type_counts"
203+
)
204+
definitions.update(mds_feature_point_definition())
207205

208-
return defs
206+
return definitions
209207

210208

211-
def property_definition(id, common_definitions, ref=""):
209+
def property_definition(property_id, ref=""):
212210
"""
213211
Return a tuple (property, definition) of schema elements for the given id.
214212
"""
215213
# property ref definition
216-
definition = { id: common_definitions.get(id) }
214+
definition = { property_id: load_definitions(property_id) }
217215
# the property
218-
ref = ref or definition_id(id)
219-
prop = { id: { "$id": f"#/properties/{id}", "$ref": ref } }
216+
ref = ref or definition_id(property_id)
217+
prop = { property_id: { "$id": f"#/properties/{property_id}", "$ref": ref } }
220218

221219
return prop, definition
222220

223221

224-
def load_definitions():
222+
def load_definitions(*args):
225223
"""
226224
Load the common.json definitions file, with some generated additions.
225+
226+
If args are provided, filter to a dictionary of definitions using the args as keys.
227+
228+
With only a single arg, return just the definition with that key directly.
227229
"""
228-
common = load_json("./templates/common.json")
229-
common_definitions = common["definitions"]
230+
global COMMON_DEFINITIONS
231+
232+
if COMMON_DEFINITIONS == {}:
233+
common = load_json("./templates/common.json")
234+
definitions = common["definitions"]
235+
236+
# MDS specific geography definition
237+
mds_feature = mds_feature_point_definition()
238+
definitions.update(mds_feature)
230239

231-
# MDS specific geography definition
232-
mds_feature = mds_feature_point_definition()
233-
common_definitions.update(mds_feature)
240+
# vehicle_type -> count definition
241+
veh_type_counts = vehicle_type_counts_definition(definitions)
242+
definitions.update(veh_type_counts)
234243

235-
# vehicle_type -> count definition
236-
veh_type_counts = vehicle_type_counts_definition(common_definitions)
237-
common_definitions.update(veh_type_counts)
244+
COMMON_DEFINITIONS = definitions
238245

239-
return common_definitions
246+
if args and len(args) > 0:
247+
if len(args) == 1:
248+
return COMMON_DEFINITIONS.get(args[0])
249+
else:
250+
return { key: COMMON_DEFINITIONS.get(key) for key in args }
251+
else:
252+
return COMMON_DEFINITIONS
240253

241254

242255
def check_schema(schema):

0 commit comments

Comments
 (0)