Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More json schema #1

Merged
merged 18 commits into from
Sep 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions generate_schema/common.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
{
"$id": "https://raw.githubusercontent.com/ian-r-rose/mobility-data-specification/more-json-schema/provider/common.json",
"$schema": "http://json-schema.org/draft-06/schema#",
"title": "The MDS Provider Schema, common definitions",
"type": "object",
"definitions": {
"version": {
"$id": "#/definitions/version",
"type": "string",
"title": "The MDS Provider version this data represents",
"examples": [
"0.1.0"
],
"pattern": "^0\\.1\\.[0-9]+$"
},
"uuid": {
"$id": "#/definitions/uuid",
"type": "string",
"title": "A UUID 4 used to uniquely identifty an object",
"default": "",
"examples": [
"3c9604d6-b5ee-11e8-96f8-529269fb1459"
],
"format": "uri",
"pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$"
},
"propulsion_type": {
"$id": "#/definitions/propulsion_type",
"type": "array",
"description": "The type of propulsion; allows multiple values",
"items": {
"type": "string",
"enum": [
"combustion",
"electric",
"electric_assist",
"human"
]
},
"minItems": 1
},
"vehicle_type": {
"$id": "#/definitions/vehicle_type",
"type": "string",
"description": "The type of vehicle",
"enum": [
"bicycle",
"scooter"
]
},
"links": {
"$id": "#/definitions/links",
"type": "object",
"properties": {
"first": {
"$id": "#/definitions/links/first",
"type": "string",
"title": "The URL to the first page of data",
"examples": [
"https://data.provider.co/trips/first"
],
"format": "uri",
"pattern": "^(.*)$"
},
"last": {
"$id": "#/definitions/links/last",
"type": "string",
"title": "The URL to the last page of data",
"examples": [
"https://data.provider.co/trips/last"
],
"format": "uri",
"pattern": "^(.*)$"
},
"prev": {
"$id": "#/definitions/links/prev",
"type": "string",
"title": "The URL to the previous page of data",
"examples": [
"https://data.provider.co/trips/prev"
],
"format": "uri",
"pattern": "^(.*)$"
},
"next": {
"$id": "#/definitions/links/next",
"type": "string",
"title": "The URL to the next page of data",
"default": "",
"examples": [
"https://data.provider.co/trips/next"
],
"format": "uri",
"pattern": "^(.*)$"
}
},
"additionalProperties": false
}
}
}
102 changes: 102 additions & 0 deletions generate_schema/generate_provider_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
"""
generate_provider_schema.py

When run, makes standalone schemas for the MDS provider API.
"""

import json
import requests


def get_point_schema():
"""
Get the canonical schema for a GeoJSON point.
"""
p = requests.get("http://geojson.org/schema/Point.json")
point = p.json()
# Modify some metadata
point.pop("$schema")
point["$id"] = "#/definitions/Point"
return point

def get_feature_collection_schema():
"""
Get the canonical schema for a GeoJSON Feature Collection,
and make the following modifications to match the MDS spec:

1. Only allow GeoJSON Point features.
2. Those Point features *must* include a `timestamp` number property.
3. There must be *at least* two points in the FeatureCollection.
"""
# Get the canonical FeatureCollection schema
fc = requests.get("http://geojson.org/schema/FeatureCollection.json")
feature_collection = fc.json()
# Modify some metadata
feature_collection.pop("$schema")
feature_collection["$id"] = "#/definitions/FeatureCollectionMDS"
feature_collection["title"] = "GeoJSON FeatureCollection (MDS spin)"


# Only accept Points in the FeatureCollection
features = feature_collection["properties"]["features"]
geometry = features["items"]["properties"]["geometry"]
features["items"]["properties"]["geometry"] = { "$ref": "#/definitions/Point" }

# Force the FeatureCollection to at least have a start and an end.
feature_collection["properties"]["features"]["minItems"] = 2

# Add a required timestamp property
properties = features["items"]["properties"]["properties"]
properties["required"] = ["timestamp"]
properties["properties"] = {
"timestamp": {
"type": "number",
"minimum": 0.0
}
}
return feature_collection

def get_json_file(path):
"""
Load a JSON file from disk.
"""
with open(path) as f:
data = json.load(f)
return data


if __name__ == '__main__':
# Load common data
common = get_json_file('common.json')
point = get_point_schema()
feature_collection = get_feature_collection_schema()

# Create the standalone trips JSON schema by including the needed definitions
trips = get_json_file('provider/trips.json')
trips["definitions"] = {
"Point": point,
"FeatureCollectionMDS": feature_collection,
"links": common["definitions"]["links"],
"propulsion_type": common["definitions"]["propulsion_type"],
"vehicle_type": common["definitions"]["vehicle_type"],
"version": common["definitions"]["version"],
"uuid": common["definitions"]["uuid"],
}
# Write to the `provider` directory.
with open("../provider/trips.json", "w") as tripfile:
tripfile.write(json.dumps(trips, indent=2))


# Create the standalone status_changes JSON schema by including the needed definitions
status_changes = get_json_file('provider/status_changes.json')
status_changes["definitions"] = {
"Point": point,
"links": common["definitions"]["links"],
"propulsion_type": common["definitions"]["propulsion_type"],
"vehicle_type": common["definitions"]["vehicle_type"],
"version": common["definitions"]["version"],
"uuid": common["definitions"]["uuid"],
}
# Write to the `provider` directory.
with open("../provider/status_changes.json", "w") as statusfile:
statusfile.write(json.dumps(status_changes, indent=2))
157 changes: 157 additions & 0 deletions generate_schema/provider/status_changes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
{
"$id": "https://raw.githubusercontent.com/CityofLosAngeles/mobility-data-specification/master/provider/status_changes.json",
"$schema": "http://json-schema.org/draft-06/schema#",
"title": "The MDS Provider Schema, status_change payload",
"type": "object",
"definitions": {},
"required": [
"version",
"data"
],
"properties": {
"version": {
"$id": "#/properties/version",
"$ref": "#/definitions/version"
},
"data": {
"$id": "#/properties/data",
"type": "object",
"title": "The page of data",
"required": [
"status_changes"
],
"properties": {
"status_changes": {
"$id": "#/properties/data/properties/status_changes",
"type": "array",
"title": "The status_changes Schema",
"items": {
"$id": "#/properties/data/properties/status_changes/items",
"type": "object",
"title": "The Items Schema",
"required": [
"provider_name",
"provider_id",
"device_id",
"vehicle_id",
"vehicle_type",
"propulsion_type",
"event_type",
"event_type_reason",
"event_time",
"event_location"
],
"properties": {
"provider_name": {
"$id": "#/properties/data/properties/status_changes/items/properties/provider_name",
"type": "string",
"description": "The public-facing name of the Provider",
"examples": [
"Provider Name"
],
"pattern": "^(.*)$"
},
"provider_id": {
"$id": "#/properties/data/properties/status_changes/items/properties/provider_id",
"description": "The UUID for the Provider, unique within MDS",
"$ref": "#/definitions/uuid"
},
"device_id": {
"$id": "#/properties/data/properties/status_changes/items/properties/device_id",
"description": "A unique device ID in UUID format",
"$ref": "#/definitions/uuid"
},
"vehicle_id": {
"$id": "#/properties/data/properties/status_changes/items/properties/vehicle_id",
"type": "string",
"description": "The Vehicle Identification Number visible on the vehicle itself",
"default": "",
"examples": [
"ABC123"
],
"pattern": "^(.*)$"
},
"vehicle_type": {
"$id": "#/properties/data/properties/status_changes/items/properties/vehicle_type",
"$ref": "#/definitions/vehicle_type",
"description": "The type of vehicle"
},
"propulsion_type": {
"$id": "#/properties/data/properties/status_changes/items/properties/propulsion_type",
"description": "The type of propulsion; allows multiple values",
"$ref": "#/definitions/propulsion_type"
},
"event_type": {
"$id": "#/properties/data/properties/status_changes/items/properties/event_type",
"type": "string",
"description": "The type of the event",
"enum": [
"available",
"reserved",
"unavailable",
"removed"
]
},
"event_type_reason": {
"$id": "#/properties/data/properties/status_changes/items/properties/event_type_reason",
"type": "string",
"description": "The reason for the event",
"enum": [
"service_start",
"user_drop_off",
"rebalance_drop_off",
"maintenance_drop_off",
"user_pick_up",
"maintenance",
"low_battery",
"service_end",
"rebalance_pick_up",
"maintenance_pick_up"
]
},
"event_time": {
"$id": "#/properties/data/properties/status_changes/items/properties/event_time",
"type": "number",
"description": "The time the event occurred, expressed as a Unix Timestamp",
"default": 0.0,
"examples": [
1529968782.421409
]
},
"event_location": {
"$id": "#/properties/data/properties/status_changes/items/properties/event_location",
"description": "The GPS coordinates of where the event occurred",
"$ref": "#/definitions/Point"
},
"battery_pct": {
"$id": "#/properties/data/properties/status_changes/items/properties/battery_pct",
"type": "number",
"description": "Percent charge of device battery, expressed between 0 and 1",
"default": 0.0,
"examples": [
0.89
],
"minimum": 0,
"maximum": 1
},
"associated_trips": {
"$id": "#/properties/data/properties/status_changes/items/properties/associated_trips",
"type": "array",
"description": "For 'Reserved' event types, associated trip_ids",
"items": {
"$id": "#/properties/data/properties/status_changes/items/properties/associated_trips/items",
"$ref": "#/definitions/uuid"
}
}
}
}
}
}
},
"links": {
"$id": "#properties/links",
"$ref": "#/definitions/links"
}
},
"additionalProperties": false
}
Loading