Skip to content

Commit 992dcbd

Browse files
authored
Merge pull request #543 from thekaveman/organize-schema-gen
Organize schema generation
2 parents 7a97406 + f1605f2 commit 992dcbd

6 files changed

Lines changed: 692 additions & 646 deletions

File tree

schema/README.md

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,35 @@
22

33
This directory contains the templates and code that _generate_ the official JSON schemas for the Mobility Data Specification. However, the official schema documents live inside the `provider`, `agency` or appropriate folder.
44

5-
## Updating the Schemas
5+
## Regenerating the Schemas
66

7-
1. Edit the appropriate file(s) inside the the `templates` directory.
7+
At a command prompt within this `schema` directory run:
88

9-
1. At a command prompt within this `schema` directory run:
9+
```bash
10+
python generate_schemas.py [--agency] [--provider]
11+
```
1012

11-
```bash
12-
python generate_schemas.py [--agency] [--provider]
13-
```
13+
The optional flags `--agency` and `--provider` can be used to specify which
14+
set of schemas to generate. The default is to generate all schemas.
1415

15-
The optional flags `--agency` and `--provider` can be used to specify which
16-
set of schemas to generate. The default is to generate all schemas.
16+
## Updating Schemas
17+
18+
1. Edit the appropriate file(s) inside the the [`templates/`][templates] directory.
19+
20+
1. Run the command to regenerate the schema(s).
21+
22+
## Adding New Schemas
23+
24+
1. Create a new template in the appropriate folder inside [`templates/`][templates]. See the existing templates for ideas. Remember to reference shared definitions from [`templates/common.json`][common-template].
25+
26+
1. Edit the appropriate `.py` file to add a function that creates the new schema as a `dict`. See the existing functions for ideas. The [`common` module][common-module] defines some shared functionality.
27+
28+
1. Add your schema name and generator function to the collection in the `schema_generators()` function at the top of each `.py` file.
29+
30+
1. Run the command to regenerate the schema(s).
31+
32+
[agency]: ../agency
33+
[common-module]: common.py
34+
[common-template]: templates/common.json
35+
[provider]: ../provider
36+
[templates]: templates/

schema/__init__.py

Whitespace-only changes.

schema/agency.py

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
"""
2+
Schema generators for Agency endpoints.
3+
"""
4+
5+
import json
6+
7+
import common
8+
9+
10+
def get_stops_schema(common_definitions):
11+
"""
12+
Create the schema for the Agency GET /stops endpoint.
13+
"""
14+
# load schema template and insert definitions
15+
schema = common.load_json("./templates/agency/get_stops.json")
16+
stops = common.stop_definitions(common_definitions)
17+
schema["definitions"].update(stops)
18+
19+
# verify and return
20+
return common.check_schema(schema)
21+
22+
23+
def post_stops_schema(common_definitions):
24+
"""
25+
Create the schema for the Agency POST /stops endpoint.
26+
"""
27+
# load schema template and insert definitions
28+
schema = common.load_json("./templates/agency/post_stops.json")
29+
stops = common.stop_definitions(common_definitions)
30+
schema["definitions"].update(stops)
31+
32+
# verify and return
33+
return common.check_schema(schema)
34+
35+
36+
def put_stops_schema(common_definitions):
37+
"""
38+
Create the schema for the Agency POST /stops endpoint.
39+
"""
40+
# load schema template and insert definitions
41+
42+
# the PUT body allows a small subset of fields
43+
schema = common.load_json("./templates/agency/put_stops.json")
44+
45+
stop_defs = common.stop_definitions(common_definitions)
46+
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]
49+
50+
schema["definitions"].update(stop_defs)
51+
52+
# verify and return
53+
return common.check_schema(schema)
54+
55+
56+
def get_vehicle_schema(common_definitions):
57+
"""
58+
Create the schema for the Agency GET /vehicles endpoint.
59+
"""
60+
# load schema template and insert definitions
61+
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+
}
69+
70+
# merge the state machine definitions and transition combinations rule
71+
state_machine_defs, transitions = common.vehicle_state_machine(common_definitions, "state", "prev_events")
72+
schema["definitions"].update(state_machine_defs)
73+
schema["allOf"].append(transitions)
74+
75+
# merge common vehicle information, with Agency tweaks
76+
vehicle = common.vehicle_definition(common_definitions, provider_name=False)
77+
schema["required"] = vehicle["required"] + schema["required"]
78+
schema["properties"] = { **vehicle["properties"], **schema["properties"] }
79+
80+
# verify and return
81+
return common.check_schema(schema)
82+
83+
84+
def post_vehicle_schema(common_definitions):
85+
"""
86+
Create the schema for the Agency POST /vehicles endpoint.
87+
"""
88+
# load schema template and insert definitions
89+
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+
}
96+
97+
# merge common vehicle information, with Agency tweaks
98+
vehicle = common.vehicle_definition(common_definitions, provider_name=False)
99+
vehicle["required"].remove("provider_id")
100+
101+
schema["required"] = vehicle["required"] + schema["required"]
102+
schema["properties"] = { **vehicle["properties"], **schema["properties"] }
103+
104+
# verify and return
105+
return common.check_schema(schema)
106+
107+
108+
def post_vehicle_event_schema(common_definitions):
109+
"""
110+
Create the schema for the Agency POST /vehicles/:id/event endpoint.
111+
"""
112+
# load schema template and insert definitions
113+
schema = common.load_json("./templates/agency/post_vehicle_event.json")
114+
schema["definitions"] = {
115+
"telemetry": common_definitions["telemetry"],
116+
"timestamp": common_definitions["timestamp"],
117+
"uuid": common_definitions["uuid"]
118+
}
119+
120+
# merge the state machine definitions and transition combinations rule
121+
state_machine_defs, transitions = common.vehicle_state_machine(common_definitions, "vehicle_state", "event_types")
122+
schema["definitions"].update(state_machine_defs)
123+
schema["allOf"].append(transitions)
124+
125+
# add the conditionally-required trip_id rule
126+
trip_id_ref = common_definitions["trip_id_reference"]
127+
schema["allOf"].append(trip_id_ref)
128+
129+
# verify and return
130+
return common.check_schema(schema)
131+
132+
133+
def post_vehicle_telemetry_schema(common_definitions):
134+
"""
135+
Create the schema for the Agency POST /vehicles/telemetry endpoint.
136+
"""
137+
# load schema template and insert definitions
138+
schema = common.load_json("./templates/agency/post_vehicle_telemetry.json")
139+
schema["definitions"] = {
140+
"telemetry": common_definitions["telemetry"],
141+
"timestamp": common_definitions["timestamp"],
142+
"uuid": common_definitions["uuid"]
143+
}
144+
145+
# verify and return
146+
return common.check_schema(schema)
147+
148+
149+
def schema_generators():
150+
"""
151+
The dict of schema generators for Agency.
152+
153+
The key is the name of the schema file/template file.
154+
The value is the generator function, taking a dict of common definitions as an argument.
155+
The generator function should return the complete, validated schema document as a dict.
156+
"""
157+
return {
158+
"get_vehicle": get_vehicle_schema,
159+
"post_vehicle": post_vehicle_schema,
160+
"post_vehicle_event": post_vehicle_event_schema,
161+
"post_vehicle_telemetry": post_vehicle_telemetry_schema,
162+
"post_stops": post_stops_schema,
163+
"put_stops": put_stops_schema,
164+
"get_stops": get_stops_schema
165+
}
166+
167+
168+
def write_schema_files(common_definitions):
169+
"""
170+
Create each of the Agency endpoint schema files in the appropriate directory.
171+
"""
172+
print("\nStarting to generate Agency JSON Schemas...\n")
173+
174+
for name, generator in schema_generators().items():
175+
schema = generator(common_definitions)
176+
with open(f"../agency/{name}.json", "w") as schemafile:
177+
schemafile.write(json.dumps(schema, indent=2))
178+
print(f"Wrote {name}.json")
179+
180+
print("\nFinished generating Agency JSON Schemas")

0 commit comments

Comments
 (0)