Verified Commit 2443ec3a authored by Dan Jones's avatar Dan Jones
Browse files

refactor: load geojson defs from published schemas

parent b262672b
...@@ -184,20 +184,11 @@ platform_schema = { ...@@ -184,20 +184,11 @@ platform_schema = {
region_schema = { region_schema = {
"type": "object", "type": "object",
"properties": { "properties": {
"geometry_coordinates": { "geometry": {
"type": "array", "$ref": "https://geojson.org/schema/Polygon.json",
"example": [
[
[-4.1777839187560915, 50.34173405662855],
[-4.1777839187560915, 50.33820949229701],
[-4.143667777943875, 50.33820949229701],
[-4.143667777943875, 50.34173405662855],
[-4.1777839187560915, 50.34173405662855],
]
],
}, },
}, },
"description": "Using GEOJSON, exact 4-point region (rectangle shaped - 5 points)", "description": "GeoJSON Polygon",
} }
squad_metadata_schema = { squad_metadata_schema = {
......
...@@ -17,6 +17,8 @@ from flask import Flask ...@@ -17,6 +17,8 @@ from flask import Flask
import argparse import argparse
import json import json
import os import os
import re
import requests
# Enable running on domain sub-path # Enable running on domain sub-path
...@@ -112,6 +114,93 @@ swagger_config = { ...@@ -112,6 +114,93 @@ swagger_config = {
} }
def resolve_ref(ref):
"""
Get schema URL, parse JSON
Return None if either fails
"""
try:
res = requests.get(ref)
if res.status_code == 200:
return res.json()
else:
return None
except (json.JSONDecodeError, ValueError):
return None
def rename_ref(ref):
"""
Convert remote ref URL into a name that can
be used for a local ref in the schema
Remote the URL scheme and replace / with .
"""
# remove url scheme
deschemed = re.sub(r"^[htps]*\:*[/]{2}", "", ref)
# replace / with . since the name will be in a path
return re.sub(r"[/]", ".", deschemed)
def nested_replace(source, key, value, replace_with):
"""
Find all instances of a key value pair in a nested
dictionary and replace the value with replace_with
"""
for k,v in source.items():
if k == key and v == value:
source[k] = replace_with
elif type(v) is list:
for item in v:
if type(item) is dict:
nested_replace(item, key, value, replace_with)
if type(v) is dict:
nested_replace(v, key, value, replace_with)
def inject_schema(schema, remote_ref):
"""
Given a parent schema and a remote ref
1. get the remote ref schema
2. create a local reference name (without path separators)
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)
if (ref_schema is not None):
nested_replace(schema, "$ref", remote_ref, local_ref)
schema["components"]["schemas"][local_name] = ref_schema
return True
else:
return False
def import_remote_refs():
"""
inject the following remote refs into the schema
and replace the remote refs with local refs
returns True if all schemas resolved and injected
"""
ref_imports = [
"https://geojson.org/schema/Feature.json",
"https://geojson.org/schema/FeatureCollection.json",
"https://geojson.org/schema/LineString.json",
"https://geojson.org/schema/Point.json",
"https://geojson.org/schema/Polygon.json",
]
return all([
inject_schema(swagger_config, ref)
for ref in ref_imports
])
def configure_flask(swagger_config): def configure_flask(swagger_config):
""" """
Setup a flask app, load flasgger Setup a flask app, load flasgger
...@@ -223,6 +312,8 @@ def get_options(): ...@@ -223,6 +312,8 @@ def get_options():
if __name__ == "__main__": if __name__ == "__main__":
import_remote_refs()
# Parse script args # Parse script args
config = get_options() config = get_options()
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment