From 9a412f5ee0f0a2e5ef9fef87460e196a2c22c7b5 Mon Sep 17 00:00:00 2001 From: Dan Jones <danjon@noc.ac.uk> Date: Fri, 30 Aug 2024 11:05:22 +0100 Subject: [PATCH] feat: downgrade geojson to 3.0.x compatible schema This allows us to include Feature and FeatureCollection We probably don't need FeatureCollection for now at least We do need Feature since the primitive list will contain a list of features of varied geometries --- generate_schema_config.py | 39 +- project/soar/swagger.json | 1020 +++++++++++++++++++++++++++++++++++++ 2 files changed, 1053 insertions(+), 6 deletions(-) diff --git a/generate_schema_config.py b/generate_schema_config.py index aca7647..cb3b238 100644 --- a/generate_schema_config.py +++ b/generate_schema_config.py @@ -162,6 +162,35 @@ def nested_replace(source, key, value, replace_with): nested_replace(v, key, value, replace_with) +def downgrade_schema_30x_compatible(schema): + """ + The published GeoJSON schemas are OpenAPI v3.1 + + Moving to v3.1 is not trivial + There isn't a CommonJS validator for v3.1 + There isn't a python source of the v3.0.x defs + + Remove $id and $schema + Remove oneOf: [{type:null}] + Iterate over oneOf and items child schemas + """ + if "$id" in schema: + del schema["$id"] + if "$schema" in schema: + del schema["$schema"] + if "properties" in schema: + for propConfig in schema["properties"].values(): + if "oneOf" in propConfig: + try: + propConfig["oneOf"].remove({"type": "null"}) + except ValueError: + pass + for child_schema in propConfig["oneOf"]: + downgrade_schema_30x_compatible(child_schema) + if "items" in propConfig: + downgrade_schema_30x_compatible(propConfig["items"]) + + def inject_schema(schema, remote_ref): """ Given a parent schema and a remote ref @@ -171,14 +200,12 @@ def inject_schema(schema, remote_ref): 3. insert into components.schemas 4. replace remote references with local references - returns True if resolved and injected """ local_name = rename_ref(remote_ref) local_ref = f"#/components/schemas/{local_name}" ref_schema = resolve_ref(remote_ref) - del ref_schema["$id"] - del ref_schema["$schema"] + downgrade_schema_30x_compatible(ref_schema) if ref_schema is not None: nested_replace(schema, "$ref", remote_ref, local_ref) schema["components"]["schemas"][local_name] = ref_schema @@ -198,8 +225,8 @@ def import_remote_refs(swagger_config): # makes the schema fail to validate ref_imports = [ - # "https://geojson.org/schema/Feature.json", - # "https://geojson.org/schema/FeatureCollection.json", + "https://geojson.org/schema/FeatureCollection.json", + "https://geojson.org/schema/Feature.json", "https://geojson.org/schema/LineString.json", "https://geojson.org/schema/MultiLineString.json", "https://geojson.org/schema/MultiPoint.json", @@ -316,7 +343,7 @@ def get_options(): args = parser.parse_args() config = vars(args) # If no flag is specified default to running the flask server - if not (config['run_flask'] or config['output_file']): + if not (config["run_flask"] or config["output_file"]): config["run_flask"] = True return config diff --git a/project/soar/swagger.json b/project/soar/swagger.json index e89b24f..e73d62e 100644 --- a/project/soar/swagger.json +++ b/project/soar/swagger.json @@ -111,6 +111,1026 @@ ], "type": "object" }, + "geojson.org.schema.Feature.json": { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "geometry": { + "oneOf": [ + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "type": { + "enum": [ + "Point" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON Point", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "minItems": 2, + "type": "array" + }, + "type": { + "enum": [ + "LineString" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON LineString", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "minItems": 4, + "type": "array" + }, + "type": "array" + }, + "type": { + "enum": [ + "Polygon" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON Polygon", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "type": "array" + }, + "type": { + "enum": [ + "MultiPoint" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON MultiPoint", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "minItems": 2, + "type": "array" + }, + "type": "array" + }, + "type": { + "enum": [ + "MultiLineString" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON MultiLineString", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "minItems": 4, + "type": "array" + }, + "type": "array" + }, + "type": "array" + }, + "type": { + "enum": [ + "MultiPolygon" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON MultiPolygon", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "geometries": { + "items": { + "oneOf": [ + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "type": { + "enum": [ + "Point" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON Point", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "minItems": 2, + "type": "array" + }, + "type": { + "enum": [ + "LineString" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON LineString", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "minItems": 4, + "type": "array" + }, + "type": "array" + }, + "type": { + "enum": [ + "Polygon" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON Polygon", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "type": "array" + }, + "type": { + "enum": [ + "MultiPoint" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON MultiPoint", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "minItems": 2, + "type": "array" + }, + "type": "array" + }, + "type": { + "enum": [ + "MultiLineString" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON MultiLineString", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "minItems": 4, + "type": "array" + }, + "type": "array" + }, + "type": "array" + }, + "type": { + "enum": [ + "MultiPolygon" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON MultiPolygon", + "type": "object" + } + ] + }, + "type": "array" + }, + "type": { + "enum": [ + "GeometryCollection" + ], + "type": "string" + } + }, + "required": [ + "type", + "geometries" + ], + "title": "GeoJSON GeometryCollection", + "type": "object" + } + ] + }, + "id": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ] + }, + "properties": { + "oneOf": [ + { + "type": "object" + } + ] + }, + "type": { + "enum": [ + "Feature" + ], + "type": "string" + } + }, + "required": [ + "type", + "properties", + "geometry" + ], + "title": "GeoJSON Feature", + "type": "object" + }, + "geojson.org.schema.FeatureCollection.json": { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "features": { + "items": { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "geometry": { + "oneOf": [ + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "type": { + "enum": [ + "Point" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON Point", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "minItems": 2, + "type": "array" + }, + "type": { + "enum": [ + "LineString" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON LineString", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "minItems": 4, + "type": "array" + }, + "type": "array" + }, + "type": { + "enum": [ + "Polygon" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON Polygon", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "type": "array" + }, + "type": { + "enum": [ + "MultiPoint" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON MultiPoint", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "minItems": 2, + "type": "array" + }, + "type": "array" + }, + "type": { + "enum": [ + "MultiLineString" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON MultiLineString", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "minItems": 4, + "type": "array" + }, + "type": "array" + }, + "type": "array" + }, + "type": { + "enum": [ + "MultiPolygon" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON MultiPolygon", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "geometries": { + "items": { + "oneOf": [ + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "type": { + "enum": [ + "Point" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON Point", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "minItems": 2, + "type": "array" + }, + "type": { + "enum": [ + "LineString" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON LineString", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "minItems": 4, + "type": "array" + }, + "type": "array" + }, + "type": { + "enum": [ + "Polygon" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON Polygon", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "type": "array" + }, + "type": { + "enum": [ + "MultiPoint" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON MultiPoint", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "minItems": 2, + "type": "array" + }, + "type": "array" + }, + "type": { + "enum": [ + "MultiLineString" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON MultiLineString", + "type": "object" + }, + { + "properties": { + "bbox": { + "items": { + "type": "number" + }, + "minItems": 4, + "type": "array" + }, + "coordinates": { + "items": { + "items": { + "items": { + "items": { + "type": "number" + }, + "minItems": 2, + "type": "array" + }, + "minItems": 4, + "type": "array" + }, + "type": "array" + }, + "type": "array" + }, + "type": { + "enum": [ + "MultiPolygon" + ], + "type": "string" + } + }, + "required": [ + "type", + "coordinates" + ], + "title": "GeoJSON MultiPolygon", + "type": "object" + } + ] + }, + "type": "array" + }, + "type": { + "enum": [ + "GeometryCollection" + ], + "type": "string" + } + }, + "required": [ + "type", + "geometries" + ], + "title": "GeoJSON GeometryCollection", + "type": "object" + } + ] + }, + "id": { + "oneOf": [ + { + "type": "number" + }, + { + "type": "string" + } + ] + }, + "properties": { + "oneOf": [ + { + "type": "object" + } + ] + }, + "type": { + "enum": [ + "Feature" + ], + "type": "string" + } + }, + "required": [ + "type", + "properties", + "geometry" + ], + "title": "GeoJSON Feature", + "type": "object" + }, + "type": "array" + }, + "type": { + "enum": [ + "FeatureCollection" + ], + "type": "string" + } + }, + "required": [ + "type", + "features" + ], + "title": "GeoJSON FeatureCollection", + "type": "object" + }, "geojson.org.schema.LineString.json": { "properties": { "bbox": { -- GitLab