From e113878bbc215405ec9d919962c1d107dd93f5ce Mon Sep 17 00:00:00 2001
From: Trishna Saeharaseelan <trishna.saeharaseelan@noc.ac.uk>
Date: Tue, 3 Jan 2023 22:10:15 +0800
Subject: [PATCH] refactor: all messages from flask model to json schema
 definitions

---
 README.md                         |   2 +-
 __init__.py                       |   1 -
 docs/__init__.py                  |   8 -
 docs/generate_swagger.py          | 183 -----------
 examples/all/observation.json     |   2 +-
 formats/__init__.py               | 190 ++++++------
 formats/acknowledgement.py        |  59 ++--
 formats/message_wrapper.py        |  58 ++++
 formats/mission_plan.py           | 212 ++++++++-----
 formats/observation.py            | 106 ++++---
 formats/planning_configuration.py | 308 ++++++++++++------
 formats/platform_status.py        | 497 ++++++++++++++++++++----------
 generate_swagger.py               | 134 ++++++++
 13 files changed, 1086 insertions(+), 674 deletions(-)
 delete mode 100644 docs/__init__.py
 delete mode 100644 docs/generate_swagger.py
 create mode 100644 formats/message_wrapper.py
 create mode 100644 generate_swagger.py

diff --git a/README.md b/README.md
index 04df03d..56bbe31 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@ This project repository is a collaborative workspace. It consists of all message
 
 
 # Message Types
-Each message below will be treated as the `payload` that are wrapped in a `full_message_format` that includes a `message_header`:
+Each message below will be wrapped in a `message_wrapper`:
 * `mission_plan`: these would be two message types, i. encoded (platform-specific serialized message) and ii. parsed, human-readable message.
 * `platform_status`: these would be two message types, i. encoded (platform-specific serialized message) and ii. parsed, human-readable message.
 * `observation`: this would be desired scientific data sent by the platform
diff --git a/__init__.py b/__init__.py
index 7a18f10..1aa4a33 100644
--- a/__init__.py
+++ b/__init__.py
@@ -11,4 +11,3 @@ __all__ = [
 ]
 app = Flask(__name__)
 api = Api(app)
-# api = Marshmallow(app)
diff --git a/docs/__init__.py b/docs/__init__.py
deleted file mode 100644
index 2253a07..0000000
--- a/docs/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-import os
-
-
-__all__ = [
-    os.path.splitext(os.path.basename(x))[0]
-    for x in os.listdir(os.path.dirname(__file__))
-    if x.endswith(".py") and x != "__init__.py"
-]
diff --git a/docs/generate_swagger.py b/docs/generate_swagger.py
deleted file mode 100644
index f5ae472..0000000
--- a/docs/generate_swagger.py
+++ /dev/null
@@ -1,183 +0,0 @@
-from flask import Flask
-from flasgger import Swagger
-
-app = Flask(__name__)
-
-swagger_config = {
-    "headers": [],
-    "openapi": "3.0.2",
-    "swagger_ui": True,
-    "specs_route": "/soardocs/",
-    "info": {
-        "title": "Backbone Message Formats",
-        "version": "0.1",
-        "description": "SoAR message schemas (i.e. formats)",
-    },
-    "specs": [
-        {
-            "endpoint": "swagger",
-            "route": "/swagger.json",
-            "rule_filter": lambda rule: True,
-            "model_filter": lambda tag: True,
-        }
-    ],
-    "components": {
-        "schemas": {
-            "Message": {
-                "type": "object",
-                "required": ["message_type"],
-                "properties": {
-                    "message_type": {
-                        "type": "string",
-                    },
-                    "source": {
-                        "type": "string",
-                        "description": "The sender.",
-                        "example": "autonomy-engine",
-                    },
-                    "destination": {
-                        "type": "string",
-                        "description": "Publisher topic.",
-                        "example": "soar.noc.autosub.ah1.status",
-                    },
-                    "delivery_type": {
-                        "type": "string",
-                        "description": "Published or broadcast",
-                        "enum": ["broadcast", "publish"],
-                        "example": "2.0.0",
-                    },
-                    "message_ID": {
-                        "type": "string",
-                        "description": "An identifier for the type of "
-                        + "message received.",
-                        "example": "PlatformStatus",
-                    },
-                },
-                "discriminator": {
-                    "propertyName": "message_type",
-                },
-            },
-            "Coordinate": {
-                "allOf": [{"$ref": "#/components/schemas/Message"}],
-                "type": "object",
-                "properties": {
-                    "latitude": {
-                        "type": "integer",
-                        "description": "Latitude in decimal degrees.",
-                        "example": 54.234,
-                    },
-                    "longitude": {
-                        "type": "integer",
-                        "description": "Longitude in decimal degrees.",
-                        "example": -1.432,
-                    },
-                    "depth": {
-                        "type": "integer",
-                        "description": "Target depth",
-                        "default": 0,
-                        "example": 50,
-                    },
-                    "projection": {
-                        "type": "integer",
-                        "description": "EPSG Projection Code",
-                        "example": 4326,
-                        "default": 4326,
-                    },
-                },
-            },
-            "PlatformStatus": {
-                "allOf": [
-                    {"$ref": "#/components/schemas/Message"},
-                ],
-                "type": "object",
-                "properties": {
-                    "partner_ID": {
-                        "type": "string",
-                        "description": "An identifier for the partner "
-                        + "owning/operating the platform.",
-                        "example": "noc",
-                    },
-                    "platform_ID": {
-                        "type": "string",
-                        "description": "An identifier for the platform.",
-                        "example": "noc_ah1",
-                    },
-                    "state": {
-                        "type": "string",
-                        "description": "Status of platform.",
-                        "example": "idle",
-                    },
-                },
-            },
-        },
-    },
-    "paths": {
-        "/messages": {
-            "get": {
-                "description": "Returns all messages from the system.",
-                "responses": {
-                    "200": {
-                        "description": "A list of messages.",
-                        "content": {
-                            "application/json": {
-                                "schema": {
-                                    "oneOf": [
-                                        {
-                                            "$ref": "#/components/"
-                                            + "schemas/Coordinate"
-                                        },
-                                        {
-                                            "$ref": "#/components/"
-                                            + "schemas/PlatformStatus"
-                                        },
-                                    ],
-                                    "discriminator": {
-                                        "propertyName": "message_type",
-                                    },
-                                }
-                            }
-                        },
-                    }
-                },
-            }
-        },
-        "/platformstatus": {
-            "get": {
-                "description": "Returns platform status message",
-                "responses": {
-                    "200": {
-                        "description": "Platform status message.",
-                        "content": {
-                            "application/json": {
-                                "schema": {
-                                    "allOf": [
-                                        {
-                                            "$ref": "#/components/schemas"
-                                            + "/PlatformStatus"
-                                        },
-                                    ],
-                                    "discriminator": {
-                                        "propertyName": "message_type",
-                                    },
-                                }
-                            }
-                        },
-                    }
-                },
-            }
-        },
-    },
-    "produces": ["application/json"],
-    "consumes": ["application/json"],
-}
-
-swag = Swagger(app, config=swagger_config, merge=True)
-
-# app.add_url_rule(
-#     '/coordinates',
-#     view_func=Coordinates.as_view('coordinates'),
-#     methods=['GET']
-# )
-
-if __name__ == "__main__":
-    app.run(debug=True)
diff --git a/examples/all/observation.json b/examples/all/observation.json
index a4a8574..65049a9 100644
--- a/examples/all/observation.json
+++ b/examples/all/observation.json
@@ -5,7 +5,7 @@
     "source": "ecosub_c2",
     "destination": "autonomy_engine",
     "encoded": false,
-    "type": "platform_status",
+    "type": "observation",
     "payload": {
         "platform_serial":"ecosub-3",
         "points_of_interest": [],
diff --git a/formats/__init__.py b/formats/__init__.py
index fda3a30..446108f 100644
--- a/formats/__init__.py
+++ b/formats/__init__.py
@@ -1,5 +1,5 @@
-from flask_restx import fields
-from . import api
+# from flask_restx import fields
+# from . import api
 import os
 
 
@@ -11,99 +11,99 @@ __all__ = [
 
 # TODO: Define units for all schemas
 
-message_types = [
-    "platform_status",
-    "mission_plan_ecosub",
-    "mission_plan_reav",
-    "mission_plan_autosub",
-]  # TODO: Add full range of message types once scoped out
+# message_types = [
+#     "platform_status",
+#     "mission_plan_ecosub",
+#     "mission_plan_reav",
+#     "mission_plan_autosub",
+# ]  # TODO: Add full range of message types once scoped out
 
-full_message_schema = api.model(
-    "FullMessageSchema",
-    {
-        "message_ID": fields.String(
-            required=True,
-            description="UUID assigned to this message",
-            example="b427003c-7bc8-11ed-a1eb-0242ac120002",
-        ),
-        "timestamp": fields.DateTime(
-            required=True,
-            description="Timestamp of message",
-            example="2022-11-16T00:00:00Z",
-        ),
-        "version": fields.Float(
-            required=True,
-            description="Version of comms bacbone messaging format protocol",
-            example=2.0,
-        ),
-        "source": fields.String(
-            required=True,
-            description="Where is this message from",
-            example="autonomy_engine",
-        ),
-        "destination": fields.String(
-            required=True,
-            description="What is the destination of this message",
-            example="ah-1",
-        ),
-        "encoded": fields.Boolean(
-            required=True,
-            description="Indicate that message raw (encoded) or decoded. "
-            + "Options: encoded=True, decoded=False",
-            example=False,
-        ),
-        "type": fields.String(
-            required=True,
-            description="Type of message",
-            example="platform_status",
-        ),
-        "payload": fields.Raw(
-            required=True,
-            description="Content of Message",
-            # example="{}",
-        ),
-    },
-)
+# full_message_schema = api.model(
+#     "FullMessageSchema",
+#     {
+#         "message_ID": fields.String(
+#             required=True,
+#             description="UUID assigned to this message",
+#             example="b427003c-7bc8-11ed-a1eb-0242ac120002",
+#         ),
+#         "timestamp": fields.DateTime(
+#             required=True,
+#             description="Timestamp of message",
+#             example="2022-11-16T00:00:00Z",
+#         ),
+#         "version": fields.Float(
+#             required=True,
+#             description="Version of comms bacbone messaging format protocol",
+#             example=2.0,
+#         ),
+#         "source": fields.String(
+#             required=True,
+#             description="Where is this message from",
+#             example="autonomy_engine",
+#         ),
+#         "destination": fields.String(
+#             required=True,
+#             description="What is the destination of this message",
+#             example="ah-1",
+#         ),
+#         "encoded": fields.Boolean(
+#             required=True,
+#             description="Indicate that message raw (encoded) or decoded. "
+#             + "Options: encoded=True, decoded=False",
+#             example=False,
+#         ),
+#         "type": fields.String(
+#             required=True,
+#             description="Type of message",
+#             example="platform_status",
+#         ),
+#         "payload": fields.Raw(
+#             required=True,
+#             description="Content of Message",
+#             # example="{}",
+#         ),
+#     },
+# )
 
-constraints_schema = api.model(
-    "ConstraintsSchema",
-    {
-        "min_altitude": fields.Float(
-            required=True,
-            description="Minimum altitude set for squad.",
-            example=15.2,
-        ),
-        "min_velocity": fields.Float(
-            required=True,
-            description="Minimum velocity set for squad.",
-            example=0.1,
-        ),
-        "max_velocity": fields.Float(
-            required=True,
-            description="Maximum altitude set for squad.",
-            example=0.9,
-        ),
-    },
-)
+# constraints_schema = api.model(
+#     "ConstraintsSchema",
+#     {
+#         "min_altitude": fields.Float(
+#             required=True,
+#             description="Minimum altitude set for squad.",
+#             example=15.2,
+#         ),
+#         "min_velocity": fields.Float(
+#             required=True,
+#             description="Minimum velocity set for squad.",
+#             example=0.1,
+#         ),
+#         "max_velocity": fields.Float(
+#             required=True,
+#             description="Maximum altitude set for squad.",
+#             example=0.9,
+#         ),
+#     },
+# )
 
-platform_schema = api.model(
-    "PlatformSchema",
-    {
-        "platform_ID": fields.Integer(
-            required=True,
-            description="unique identifier for platform",
-            example=1,
-        ),
-        "serial": fields.String(
-            required=True,
-            description="platform serial number",
-            example="reav-60",
-        ),
-        "model": fields.String(
-            required=True,
-            description="platform serial number",
-            example="reav",
-        ),
-        "constraints": fields.Nested(constraints_schema),
-    },
-)
+# platform_schema = api.model(
+#     "PlatformSchema",
+#     {
+#         "platform_ID": fields.Integer(
+#             required=True,
+#             description="unique identifier for platform",
+#             example=1,
+#         ),
+#         "serial": fields.String(
+#             required=True,
+#             description="platform serial number",
+#             example="reav-60",
+#         ),
+#         "model": fields.String(
+#             required=True,
+#             description="platform serial number",
+#             example="reav",
+#         ),
+#         "constraints": fields.Nested(constraints_schema),
+#     },
+# )
diff --git a/formats/acknowledgement.py b/formats/acknowledgement.py
index af0cff0..6c6d965 100644
--- a/formats/acknowledgement.py
+++ b/formats/acknowledgement.py
@@ -2,29 +2,44 @@
     schemas: Acknowledgement status sent by the surface platform to report
     receipt of message.
 """
-from . import api, full_message_schema
-from flask_restx import fields
-
-
-acknowledgement_schema = api.model(
-    "Acknowledgement",
-    {
-        "message": fields.Nested(
-            full_message_schema,
-            required=True,
-            description="Message header",
-        ),
-        "message_ID": fields.Integer(
-            required=True,
-            description="Identifier of message received and executed with "
+acknowledgement_schema = {
+    "properties": {
+        "message_ID": {
+            "type": "string",
+            "description": "Identifier of message received and executed with "
             + "success for mission plans sent by the Autonomy Engine.",
-            example=202,
-        ),
-        "status": fields.String(
-            required=True,
-            description="Highest level of acknowledgement. I.e. `c2_received`:"
+            "example": "b427003c-7bc8-11ed-a1eb-0242ac999999",
+        },
+        "status": {
+            "type": "string",
+            "description": "Highest level of acknowledgement. I.e. `c2_received`:"
             + " Received by C2, `c2_sent`: Sent from C2->Platform, `executed`:"
             + " Executed by platform",
-        ),
+            "example": "executed by platform",
+        },
     },
-)
+    "required": ["message_ID", "status"],
+}
+
+# acknowledgement_schema = api.model(
+#     "Acknowledgement",
+#     {
+#         "message": fields.Nested(
+#             full_message_schema,
+#             required=True,
+#             description="Message header",
+#         ),
+#         "message_ID": fields.Integer(
+#             required=True,
+#             description="Identifier of message received and executed with "
+#             + "success for mission plans sent by the Autonomy Engine.",
+#             example=202,
+#         ),
+#         "status": fields.String(
+#             required=True,
+#             description="Highest level of acknowledgement. I.e. `c2_received`:"
+#             + " Received by C2, `c2_sent`: Sent from C2->Platform, `executed`:"
+#             + " Executed by platform",
+#         ),
+#     },
+# )
diff --git a/formats/message_wrapper.py b/formats/message_wrapper.py
new file mode 100644
index 0000000..b9bebfa
--- /dev/null
+++ b/formats/message_wrapper.py
@@ -0,0 +1,58 @@
+"""
+    schemas: Message Wrapper is used to wrap all message types that contain
+    details of where the message is coming from, which end client is its destination
+    and the type of message.
+"""
+
+message_wrapper_schema = {
+    "type": "object",
+    "discriminator": {
+        "propertyName": "message_type",
+    },
+    "properties": {
+        "message_ID": {
+            "type": "string",
+            "description": "An identifier for the type of " + "message received.",
+            "example": "PlatformStatus",
+        },
+        "timestamp": {
+            "type": "date-time",
+            "description": "Timestamp of message",
+            "example": "2022-11-16T00:00:00Z",
+        },
+        "message_type": {
+            "type": "Type of message",
+            "description": "Type of message",
+            "example": "platform_status",
+        },
+        "version": {
+            "type": "string",
+            "description": "Version of comms bacbone messaging format protocol",
+            "example": 2.0,
+        },
+        "source": {
+            "type": "string",
+            "description": "The sender; Where is this message from",
+            "example": "autonomy_engine",
+        },
+        "destination": {
+            "type": "string",
+            "description": "Publisher topic; What is the destination of this message",
+            "example": "ah1",
+        },
+        "encoded": {
+            "type": "boolean",
+            "description": "Indicate that message raw (encoded) or decoded. "
+            + "Options: encoded=True, decoded=False",
+            "example": False,
+        },
+        "delivery_type": {
+            "type": "string",
+            "description": "To publish or broadcast this message.",
+            "enum": ["broadcast", "publish"],
+            "example": "publish",
+            "default": "publish",
+        },
+    },
+    "required": ["message_type"],
+}
diff --git a/formats/mission_plan.py b/formats/mission_plan.py
index c6af384..46243ca 100644
--- a/formats/mission_plan.py
+++ b/formats/mission_plan.py
@@ -3,83 +3,151 @@
     sent to the respective platform's C2 to compile into a platform-specific
     mission plan.
 """
-from . import api, full_message_schema
-from flask_restx import fields
+# from . import api, full_message_schema
+# from flask_restx import fields
 
-
-action_schema = api.model(
-    "AutonomyEngineAction",
-    {
-        "action": fields.String(
-            required=True,
-            description="Autonomy Engine's action from `move`, `payload`,"
+action_schema = {
+    "type": "object",
+    "properties": {
+        "action": {
+            "type": "string",
+            "description": "Autonomy Engine's action from `move`, `payload`,"
             + " `dive`, `send_hits`, `scanline`, `scanpoint`.",
-            example="move",
-        ),
-        "flight_style": fields.String(
-            required=False,
-            description="Platform-specific modes/flight styles to perform"
+            "example": "move",
+        },
+        "flight_style": {
+            "type": "string",
+            "description": "Platform-specific modes/flight styles to perform"
             + " next action",
-            example="orbit",
-        ),
-        "latitude_waypoint": fields.Float(
-            required=True,
-            description="Next waypoint, x-coordinate",
-            example=-4.187143188645706,
-        ),
-        "longitude_waypoint": fields.Float(
-            required=True,
-            description="Next waypoint, y-coordinate",
-            example=50.37072283932642,
-        ),
-        "altitude": fields.Float(
-            required=False,
-            description="Altitude of next action",
-            example=15.0,
-        ),
-        "depth": fields.Float(
-            required=False,
-            description="Depth of next action",
-            example=15.0,
-        ),
-        "activate_payload": fields.Boolean(
-            required=False,
-            description="To activate/deactivate sensor for Autosub "
+            "example": "orbit",
+        },
+        "latitude_waypoint": {
+            "type": "number",
+            "description": "Next waypoint, x-coordinate",
+            "example": -4.187143188645706,
+        },
+        "longitude_waypoint": {
+            "type": "number",
+            "description": "Next waypoint, y-coordinate",
+            "example": 50.37072283932642,
+        },
+        "altitude": {
+            "type": "number",
+            "description": "Altitude of next action",
+            "example": 15.0,
+        },
+        "depth": {
+            "type": "number",
+            "description": "Depth of next action",
+            "example": 15.0,
+        },
+        "activate_payload": {
+            "type": "boolean",
+            "description": "To activate/deactivate sensor for Autosub "
             + "Hover-1 --> `MBES` sensor and for EcoSUB --> `Sidescan`",
-            example=True,
-        ),
-        "send_environmental_data": fields.Boolean(
-            required=False,
-            description="To trigger the platform to send list of observations"
+            "example": True,
+        },
+        "send_environmental_data": {
+            "type": "boolean",
+            "description": "To trigger the platform to send list of observations"
             + " if any found",
-            example=False,
-        ),
+            "example": False,
+        },
     },
-)
+    "required": [
+        "action",
+        "latitude_waypoint",
+        "longitude_waypoint",
+    ],
+}
 
-mission_plan_schema = api.model(
-    "MissionPlan",
-    {
-        "message": fields.Nested(
-            full_message_schema,
-            required=True,
-            description="Message header",
-        ),
-        "plan_ID": fields.Integer(
-            required=True,
-            description="Identifier of given mission sequence planned",
-            example=1,
-        ),
-        "platform_serial": fields.String(
-            required=True,
-            description="Serial of target platform to send mission to",
-            example="reav-60",
-        ),
-        "plan": fields.List(
-            fields.Nested(action_schema),
-            required=True,
-            description="Sequence of actions/instructions generated by the "
-            + " Autonomy Engine that should be compiled by the respective C2.",
-        ),
+mission_plan_schema = {
+    "allOf": [{"$ref": "#/components/schemas/Message"}],
+    "type": "object",
+    "properties": {
+        "plan_ID": {"type": "integer"},
+        "platform_serial": {"type": "string"},
+        "plan": {
+            "type": "array",
+            "items": action_schema,
+        },
     },
-)
+    "required": ["plan_ID", "platform_serial", "plan"],
+}
+
+# action_schema = api.model(
+#     "AutonomyEngineAction",
+#     {
+#         "action": fields.String(
+#             required=True,
+#             description="Autonomy Engine's action from `move`, `payload`,"
+#             + " `dive`, `send_hits`, `scanline`, `scanpoint`.",
+#             example="move",
+#         ),
+#         "flight_style": fields.String(
+#             required=False,
+#             description="Platform-specific modes/flight styles to perform"
+#             + " next action",
+#             example="orbit",
+#         ),
+#         "latitude_waypoint": fields.Float(
+#             required=True,
+#             description="Next waypoint, x-coordinate",
+#             example=-4.187143188645706,
+#         ),
+#         "longitude_waypoint": fields.Float(
+#             required=True,
+#             description="Next waypoint, y-coordinate",
+#             example=50.37072283932642,
+#         ),
+#         "altitude": fields.Float(
+#             required=False,
+#             description="Altitude of next action",
+#             example=15.0,
+#         ),
+#         "depth": fields.Float(
+#             required=False,
+#             description="Depth of next action",
+#             example=15.0,
+#         ),
+#         "activate_payload": fields.Boolean(
+#             required=False,
+#             description="To activate/deactivate sensor for Autosub "
+#             + "Hover-1 --> `MBES` sensor and for EcoSUB --> `Sidescan`",
+#             example=True,
+#         ),
+#         "send_environmental_data": fields.Boolean(
+#             required=False,
+#             description="To trigger the platform to send list of observations"
+#             + " if any found",
+#             example=False,
+#         ),
+#     },
+# )
+
+# mission_plan_schema = api.model(
+#     "MissionPlan",
+#     {
+#         "message": fields.Nested(
+#             full_message_schema,
+#             required=True,
+#             description="Message header",
+#         ),
+#         "plan_ID": fields.Integer(
+#             required=True,
+#             description="Identifier of given mission sequence planned",
+#             example=1,
+#         ),
+#         "platform_serial": fields.String(
+#             required=True,
+#             description="Serial of target platform to send mission to",
+#             example="reav-60",
+#         ),
+#         "plan": fields.List(
+#             fields.Nested(action_schema),
+#             required=True,
+#             description="Sequence of actions/instructions generated by the "
+#             + " Autonomy Engine that should be compiled by the respective C2.",
+#         ),
+#     },
+# )
diff --git a/formats/observation.py b/formats/observation.py
index 6889b15..8cfa412 100644
--- a/formats/observation.py
+++ b/formats/observation.py
@@ -1,47 +1,79 @@
 """
     schema: platform-specific decoded status message (DRAFT)
 """
-from . import full_message_schema, api
-from flask_restx import fields
+# from . import full_message_schema, api
+# from flask_restx import fields
 
-
-observation_schema = api.model(
-    "Observation",
-    {
-        "message": fields.Nested(
-            full_message_schema,
-            required=True,
-            description="Message header",
-        ),
-        "platform_serial": fields.String(
-            required=True,
-            description="Serial of platform to sendign observations",
-            example="ecosub-3",
-        ),
+observation_schema = {
+    "allOf": [{"$ref": "#/components/schemas/Message"}],
+    "type": "object",
+    "properties": {
+        "platform_serial": {
+            "description": "Serial of platform to sendign observations",
+            "example": "ecosub-3",
+        },
         # "observation_type" ==> payloads tied to different types maybe?
         # properties of each observation?
-        "points_of_interest": fields.Float(
-            required=False,
-            description="Points from features of interest identified by"
+        "points_of_interest": {
+            "description": "Points from features of interest identified by"
             + " platform if any found. DEFINE FORMAT.",
-            example="",
-        ),
-        "region_surveyed": fields.Float(
-            required=False,
-            description="Region surveyed by given platform. DEFINE FORMAT."
+            "example": "",
+        },
+        "region_surveyed": {
+            "description": "Region surveyed by given platform. DEFINE FORMAT."
             + " GEOJSON?",
-            example="",
-        ),
-        "quality_of_points": fields.Float(
-            required=False,
-            description="Quality/strength of points from features of interest"
+            "example": "",
+        },
+        "quality_of_points": {
+            "description": "Quality/strength of points from features of interest"
             + " identified by platform. DEFINE FORMAT.",
-            example=0.98,
-        ),
-        "additional_data": fields.Raw(
-            required=False,
-            description="Placeholder field for any additional data",
-            example={"sensor_payload": False},
-        ),
+            "example": 0.98,
+        },
+        "additional_data": {
+            "description": "Placeholder field for any additional data",
+            "example": {"sensor_payload": False},
+        },
     },
-)
+    "required": ["platform_serial"],
+}
+
+# observation_schema = api.model(
+#     "Observation",
+#     {
+#         "message": fields.Nested(
+#             full_message_schema,
+#             required=True,
+#             description="Message header",
+#         ),
+#         "platform_serial": fields.String(
+#             required=True,
+#             description="Serial of platform to sendign observations",
+#             example="ecosub-3",
+#         ),
+#         # "observation_type" ==> payloads tied to different types maybe?
+#         # properties of each observation?
+#         "points_of_interest": fields.Float(
+#             required=False,
+#             description="Points from features of interest identified by"
+#             + " platform if any found. DEFINE FORMAT.",
+#             example="",
+#         ),
+#         "region_surveyed": fields.Float(
+#             required=False,
+#             description="Region surveyed by given platform. DEFINE FORMAT."
+#             + " GEOJSON?",
+#             example="",
+#         ),
+#         "quality_of_points": fields.Float(
+#             required=False,
+#             description="Quality/strength of points from features of interest"
+#             + " identified by platform. DEFINE FORMAT.",
+#             example=0.98,
+#         ),
+#         "additional_data": fields.Raw(
+#             required=False,
+#             description="Placeholder field for any additional data",
+#             example={"sensor_payload": False},
+#         ),
+#     },
+# )
diff --git a/formats/planning_configuration.py b/formats/planning_configuration.py
index b46cc32..7f1d84e 100644
--- a/formats/planning_configuration.py
+++ b/formats/planning_configuration.py
@@ -2,102 +2,230 @@
     schemas: configuration sent to Autonomy Engine (i.e. during an emergency,
     if a platform needs to be removed from the mission planning)
 """
-from . import api, full_message_schema, platform_schema
-from flask_restx import fields
+# from . import api, full_message_schema, platform_schema
+# from flask_restx import fields
 
 
-region_schema = api.model(
-    "RegionSchema",
-    {
-        "region": fields.Raw(
-            required=True,
-            description="Using GEOJSON, exact region of interest in rectangle"
-            + " format polygon",
-            example={
-                "type": "FeatureCollection",
-                "features": [
-                    {
-                        "type": "Feature",
-                        "properties": {},
-                        "geometry": {
-                            "coordinates": [
-                                [
-                                    [-4.187143188645706, 50.37072283932642],
-                                    [-4.202697005964865, 50.368816892405874],
-                                    [-4.203156724702808, 50.365640144076906],
-                                    [-4.19449868846155, 50.362267670845654],
-                                ]
-                            ],
-                            "type": "Polygon",
-                        },
-                    }
-                ],
-            },
-        ),
+constraints_schema = {
+    "type": "object",
+    "properties": {
+        "min_altitude": {
+            "type": "number",
+            "description": "Minimum altitude set for squad.",
+            "example": 15.2,
+        },
+        "min_velocity": {
+            "type": "number",
+            "description": "Minimum velocity set for squad.",
+            "example": 0.1,
+        },
+        "max_velocity": {
+            "type": "number",
+            "description": "Maximum altitude set for squad.",
+            "example": 0.9,
+        },
     },
-)
+    "required": ["min_altitude", "min_velocity", "max_velocity"],
+}
 
-squad_metadata_schema = api.model(
-    "SquadMetadataSchema",
-    {
-        "squad_ID": fields.Integer(
-            required=True,
-            description="Identifier of given squad",
-            example=23,
-        ),
-        "no_of_platforms": fields.Integer(
-            required=True,
-            description="Number of platforms",
-            example=3,
-        ),
-        "platforms": fields.List(
-            fields.Nested(platform_schema),
-            required=True,
-            description="Squad consists of these platforms",
-        ),
-        "squad_mission_type": fields.String(
-            required=True,
-            description="Mission of given squad: `tracking`, `survey`"
-            + ", `inspection`",
-            example="survey",
-        ),
-        "squad_state": fields.Boolean(
-            required=True,
-            description="In execution, Waiting.. <define further>",
-            example=False,
-        ),
-        "region_of_interest": fields.List(
-            fields.Nested(region_schema),
-            required=False,
-            description="Region of interest and exclusion zones per squad.",
-        ),
-        "exclusion_zones": fields.List(
-            fields.Nested(region_schema),
-            required=True,
-            description="Exclusion zones exclusion zones per squad.",
-        ),
+platform_schema = {
+    "type": "object",
+    "properties": {
+        "platform_ID": {
+            "type": "integer",
+            "description": "Identifier for platform",
+            "example": 23,
+        },
+        "serial": {
+            "type": "string",
+            "description": "platform serial number",
+            "example": "reav-60",
+        },
+        "model": {
+            "type": "string",
+            "example": "reav",
+        },
+        "constraints": constraints_schema,
+    },
+    "required": ["platform_ID", "serial", "model", "constraints"],
+}
+
+region_schema = {
+    "type": "object",
+    "properties": {
+        "geometry_coordinates": {
+            "type": "array",  # TODO: Check if config defn is right.
+            "example": [
+                [
+                    [-4.187143188645706, 50.37072283932642],
+                    [-4.202697005964865, 50.368816892405874],
+                    [-4.203156724702808, 50.365640144076906],
+                    [-4.19449868846155, 50.362267670845654],
+                ]
+            ],
+        },
     },
-)
+    "description": "Using GEOJSON, exact 4-point region (rectangle shaped)",
+    "required": ["geometry_coordinates"],
+}
 
+squad_metadata_schema = {
+    "type": "object",
+    "properties": {
+        "squad_ID": {
+            "type": "integer",
+            "description": "Identifier of given squad",
+            "example": 23,
+        },
+        "no_of_platforms": {
+            "type": "integer",
+            "description": "Number of platforms",
+            "example": 3,
+        },
+        "platforms": {
+            "type": "array",
+            "items": platform_schema,
+            "description": "Squad consists of these platforms",
+        },
+        "squad_mission_type": {
+            "type": "string",
+            "enum": ["tracking", "survey", "inspection"],
+            "description": "Mission of given squad: `tracking`, `survey`"
+            + ", `inspection`",
+            "example": "survey",
+        },
+        "squad_state": {
+            "type": "string",
+            "description": "In execution, Waiting.. <define further>",
+            "example": False,
+        },
+        "region_of_interest": region_schema,
+        "exclusion_zones": {
+            "type": "array",
+            "items": region_schema,
+            "description": "Exclusion zones per squad.",
+        },
+    },
+    "required": [
+        "squad_ID",
+        "no_of_platforms",
+        "platforms",
+        "squad_mission_type",
+        "squad_state",
+        "exclusion_zones",
+    ],
+}
 
-planning_configuration_schema = api.model(
-    "PlanningConfigurationSchema",
-    {
-        "message": fields.Nested(
-            full_message_schema,
-            required=True,
-            description="Message header",
-        ),
-        "ID": fields.Integer(
-            required=True,
-            description="Unique identifier tagged to version of this"
+planning_configuration_schema = {
+    "allOf": [{"$ref": "#/components/schemas/Message"}],
+    "type": "object",
+    "properties": {
+        "config_ID": {
+            "type": "integer",
+            "description": "Unique identifier tagged to version of this"
             + " configuration plan",
-            example=3,
-        ),
-        "squads": fields.Nested(
-            squad_metadata_schema,
-            required=False,
-            description="Details of each squad",
-        ),
+            "example": 3,
+        },
+        "squads": {
+            "type": "array",
+            "items": squad_metadata_schema,
+        },
     },
-)
+    "required": ["config_ID", "squads"],
+}
+
+# region_schema = api.model(
+#     "RegionSchema",
+#     {
+#         "region": fields.Raw(
+#             required=True,
+#             description="Using GEOJSON, exact region of interest in rectangle"
+#             + " format polygon",
+#             example={
+#                 "type": "FeatureCollection",
+#                 "features": [
+#                     {
+#                         "type": "Feature",
+#                         "properties": {},
+#                         "geometry": {
+#                             "coordinates": [
+#                                 [
+#                                     [-4.187143188645706, 50.37072283932642],
+#                                     [-4.202697005964865, 50.368816892405874],
+#                                     [-4.203156724702808, 50.365640144076906],
+#                                     [-4.19449868846155, 50.362267670845654],
+#                                 ]
+#                             ],
+#                             "type": "Polygon",
+#                         },
+#                     }
+#                 ],
+#             },
+#         ),
+#     },
+# )
+
+# squad_metadata_schema = api.model(
+#     "SquadMetadataSchema",
+#     {
+#         "squad_ID": fields.Integer(
+#             required=True,
+#             description="Identifier of given squad",
+#             example=23,
+#         ),
+#         "no_of_platforms": fields.Integer(
+#             required=True,
+#             description="Number of platforms",
+#             example=3,
+#         ),
+#         "platforms": fields.List(
+#             fields.Nested(platform_schema),
+#             required=True,
+#             description="Squad consists of these platforms",
+#         ),
+#         "squad_mission_type": fields.String(
+#             required=True,
+#             description="Mission of given squad: `tracking`, `survey`"
+#             + ", `inspection`",
+#             example="survey",
+#         ),
+#         "squad_state": fields.Boolean(
+#             required=True,
+#             description="In execution, Waiting.. <define further>",
+#             example=False,
+#         ),
+#         "region_of_interest": fields.List(
+#             fields.Nested(region_schema),
+#             required=False,
+#             description="Region of interest and exclusion zones per squad.",
+#         ),
+#         "exclusion_zones": fields.List(
+#             fields.Nested(region_schema),
+#             required=True,
+#             description="Exclusion zones exclusion zones per squad.",
+#         ),
+#     },
+# )
+
+
+# planning_configuration_schema = api.model(
+#     "PlanningConfigurationSchema",
+#     {
+#         "message": fields.Nested(
+#             full_message_schema,
+#             required=True,
+#             description="Message header",
+#         ),
+#         "ID": fields.Integer(
+#             required=True,
+#             description="Unique identifier tagged to version of this"
+#             + " configuration plan",
+#             example=3,
+#         ),
+#         "squads": fields.Nested(
+#             squad_metadata_schema,
+#             required=False,
+#             description="Details of each squad",
+#         ),
+#     },
+# )
diff --git a/formats/platform_status.py b/formats/platform_status.py
index 761b0fc..d3c8157 100644
--- a/formats/platform_status.py
+++ b/formats/platform_status.py
@@ -1,177 +1,346 @@
 """
-    schema: platform-specific decoded status message (DRAFT)
+    schema: platform-specific decoded status message
 """
-from . import full_message_schema, api
-from flask_restx import fields
+# from . import full_message_schema, api
+# from flask_restx import fields
 
-gps_schema = api.model(
-    "GPS",
-    {
-        "gps_source": fields.Float(  # TODO: TBD with partners
-            required=False,
-            description=(
-                "Source of gps position. E.g. USBL (external),"
-                + "platform itself (internal)"
-            ),
-            example="internal",
-        ),
-        "latitude_type": fields.String(
-            required=False,
-            description="",
-            example="",
-        ),
-        "longitude_type": fields.String(
-            required=False,
-            description="",
-            example="",
-        ),
-        "latitude": fields.Float(
-            required=False,
-            description="Latitude in <DEFINE UNITS>",
-            example="",
-        ),
-        "longitude": fields.Float(
-            required=False,
-            description="Longitude in <DEFINE UNITS>",
-            example="",
-        ),
-        "depth": fields.Float(
-            required=False,
-            description="Depth in <DEFINE UNITS>",
-            example="",
-        ),
-        "altitude": fields.Float(
-            required=False,
-            description="Altitude in <DEFINE UNITS>",
-            example="",
-        ),
-        # "gps_fix_seconds_ago"
-    },
-)
 
-sensor_schema = api.model(
-    "SensorSchema",
-    {
-        "sensor_ID": fields.Integer(
-            required=True,
-            description="unique identifier for platform",
-            example=2,
-        ),
-        "serial": fields.String(
-            required=False,
-            description="serial number of sensor",
-            example="mbes-001",
-        ),
-        "sensor_status": fields.Boolean(
-            required=False,
-            description="Sensor switched on (True) or off (False)",
-            example=True,
-        ),
-        "additional_data": fields.Raw(
-            required=False,
-            description="Any addition fields/data to be added here",
-        ),
+gps_schema = {
+    "type": "object",
+    "properties": {
+        "gps_source": {
+            "type": "string",
+            "description": "Source of gps position. E.g. USBL (external),"
+            + "platform itself (internal)",
+            "example": "internal",
+        },
+        "latitude_type": {
+            "type": "string",
+            "description": "TODO: Add description",
+        },
+        "longitude_type": {
+            "type": "string",
+            "description": "TODO: Add description",
+        },
+        "latitude": {
+            "type": "number",
+            "description": "Latitude in decimal degrees.",
+            "example": 178.2,
+        },
+        "longitude": {
+            "type": "number",
+            "description": "Longitude in decimal degrees.",
+            "example": -10.122,
+        },
+        "depth": {
+            "type": "number",
+            "description": "Target depth in metres",
+            "example": 50,
+            "default": 0,
+        },
+        "altitude": {
+            "type": "number",
+            "description": "Target altitude in metres",
+            "example": 20,
+        },
     },
-)
+    "required": [
+        "gps_source",
+        "latitude",
+        "longitude",
+    ],
+}
 
+sensor_schema = {
+    "type": "object",
+    "description": "Scanning sensor on platform available to be controlled by  the Autonomy Engine",
+    "properties": {
+        "sensor_serial": {
+            "type": "string",
+            "description": "serial number of sensor",
+            "example": "mbes-002a",
+        },
+        "sensor_status": {
+            "type": "boolean",
+            "description": "Sensor switched on (True) or off (False)",
+            "example": True,
+        },
+        "additional_data": {
+            "type": "null",
+            "description": "Any addition fields/data to be added here",
+            "example": {"payload": [1.2, 434]},
+        },
+    },
+    "required": [],
+}
 
-platform_status_message_schema = api.model(
-    "platformStatusMessage",
-    {
-        "message": fields.Nested(
-            full_message_schema,
-            required=True,
-            description="Message header",
-        ),
-        "platform_ID": fields.Integer(
-            required=True,
-            description="unique identifier for platform",
-            example=1,
-        ),
-        "active": fields.Boolean(
-            required=False,
-            description="When a platform is in deployment (executing a"
+platform_status_message_schema = {
+    "allOf": [{"$ref": "#/components/schemas/Message"}],
+    "type": "object",
+    "properties": {
+        "platform_ID": {
+            "type": "integer",
+            "description": "Identifier for platform",
+            "example": 1,
+        },
+        "platform_timestamp": {
+            "type": "date-time",
+            "decription": "Timestamp for onboard platform status message",
+            "example": "2022-12-21T00:00:00Z",
+        },
+        "active": {
+            "type": "boolean",
+            "description": "When a platform is in deployment (executing a"
             + " mission plan) this should be True",
-            example=True,
-        ),
-        "platform_state": fields.String(
+            "example": True,
+        },
+        "platform_state": {
             # TODO: Define dictionary with potential STATES of each platform
-            required=False,
-            description="Current state executed by platform. E.g. "
+            "type": "string",
+            "description": "Current state executed by platform. E.g. "
             + "STOP, IDLE, ABORT.",
-            example="IDLE",
-        ),
-        "autonomy_plan_ID": fields.Integer(
-            required=False,
-            description="Last mission plan ID (according to Autonomy Engine's"
+            "example": "ABORT",
+        },
+        "autonomy_plan_ID": {
+            "type": "integer",
+            "description": "Last mission plan ID (according to Autonomy Engine's"
             + " mission plan number) executed by platform",
-            example=1,
-        ),
-        "mission_track_ID": fields.Integer(
-            required=False,
-            description=(
-                "Track number - stage in mission (e.g. "
-                + "4 --> Waypoint 3 to Waypoint 4)"
-            ),
-            example=4,
-        ),
-        "mission_action_ID": fields.Integer(
-            required=False,
-            description="to add description",
-            example=1,
-        ),
-        "range_to_go": fields.Float(
-            required=False,
-            description="Estimated distance to reach next waypoint",
-            example=124.3,
-        ),
-        "speed_over_ground": fields.Float(
-            required=False,
-            description="",
-            example=124.3,
-        ),
-        "water_current_velocity": fields.Float(
-            required=False,
-            description="",
-            example=124.3,
-        ),
-        "thrust_applied": fields.Float(
-            required=False,
-            description="TODO: Needs further consideration",
-            example=124.3,
-        ),
-        "health_status": fields.String(
-            required=False,
-            description="Health status extracted by respective platform "
-            + "if any diagnosis available checks on sensors",
-            example="Warning",
-        ),
-        "gps_data": fields.List(
-            fields.Nested(gps_schema),  # TODO: TBD Do we want a list of
-            # gps readings to allow > 1 reading i.e. platform + usbl
-            required=True,
-            description="Metadata pf each platform",
-        ),
-        "localisation_error": fields.Float(
-            required=False,
-            description="Localisation error at last USBL update.",
-            example="",
-        ),
-        "usbl_fix_seconds_ago": fields.Float(
-            required=False,
-            description="",
-            example="",
-        ),
-        "battery_remaining_capacity": fields.Float(
-            required=True,
-            description="Battery remaining capacity % provided by respective"
-            + " platform/C2.",
-            example=80.0,
-        ),
-        "sensor_config": fields.Nested(
-            sensor_schema
-        ),  # TODO: TBD Do we want a list of sensors to allow > 1 sensor
+            "example": 1,
+        },
+        "mission_track_ID": {
+            "type": "integer",
+            "description": "Track number - stage in mission (e.g. "
+            + "4 --> Waypoint 3 to Waypoint 4)",
+            "example": 4,
+        },
+        "mission_action_ID": {
+            "type": "integer",
+            "description": "TODO: add description",
+            "example": 1,
+        },
+        "range_to_go": {
+            "type": "number",
+            "description": "Estimated distance to reach next waypoint",
+            "example": 124.3,
+        },
+        "speed_over_ground": {
+            "type": "number",
+            "description": "TODO: add description",
+            "example": 124.3,
+        },
+        "water_current_velocity": {
+            "type": "number",
+            "description": "TODO: add description",
+            "example": 124.3,
+        },
+        "thrust_applied": {
+            "type": "number",
+            "description": "TODO: Needs further consideration",
+            "example": 124.3,
+        },
+        "health_status": {
+            "type": "string",
+            "description": "Health status extracted by respective platform "
+            + "if any diagnosis is available to check sensors",
+            "example": "Warning",
+        },
+        "gps_data": {
+            "type": "array",
+            "description": "position of platform",
+            "items": gps_schema,
+        },
+        "localisation_error": {
+            "type": "number",
+            "description": "Localisation error at last USBL update.",
+            "example": 0.000129,
+        },
+        "usbl_fix_seconds_ago": {
+            "type": "number",
+            "description": "USBL Fix received x second ago.",
+            "example": 10.0,
+        },
+        "battery_remaining_capacity": {
+            "type": "number",
+            "description": "Battery remaining capacity % provided by respective",
+            "example": 80.2,
+        },
+        "sensor_config": sensor_schema,
     },
-)
+    "required": [
+        "platform_ID",
+        "platform_timestamp",
+        "gps_data",
+        "battery_remaining_capacity",
+    ],
+}
+
+# gps_schema = api.model(
+#     "GPS",
+#     {
+#         "gps_source": fields.Float(  # TODO: TBD with partners
+#             required=False,
+#             description=(
+#                 "Source of gps position. E.g. USBL (external),"
+#                 + "platform itself (internal)"
+#             ),
+#             example="internal",
+#         ),
+#         "latitude_type": fields.String(
+#             required=False,
+#             description="",
+#             example="",
+#         ),
+#         "longitude_type": fields.String(
+#             required=False,
+#             description="",
+#             example="",
+#         ),
+#         "latitude": fields.Float(
+#             required=False,
+#             description="Latitude in <DEFINE UNITS>",
+#             example="",
+#         ),
+#         "longitude": fields.Float(
+#             required=False,
+#             description="Longitude in <DEFINE UNITS>",
+#             example="",
+#         ),
+#         "depth": fields.Float(
+#             required=False,
+#             description="Depth in <DEFINE UNITS>",
+#             example="",
+#         ),
+#         "altitude": fields.Float(
+#             required=False,
+#             description="Altitude in <DEFINE UNITS>",
+#             example="",
+#         ),
+#         # "gps_fix_seconds_ago"
+#     },
+# )
+
+# sensor_schema = api.model(
+#     "SensorSchema",
+#     {
+#         "sensor_ID": fields.Integer(
+#             required=True,
+#             description="unique identifier for platform",
+#             example=2,
+#         ),
+#         "serial": fields.String(
+#             required=False,
+#             description="serial number of sensor",
+#             example="mbes-001",
+#         ),
+#         "sensor_status": fields.Boolean(
+#             required=False,
+#             description="Sensor switched on (True) or off (False)",
+#             example=True,
+#         ),
+#         "additional_data": fields.Raw(
+#             required=False,
+#             description="Any addition fields/data to be added here",
+#         ),
+#     },
+# )
+
+# platform_status_message_schema = api.model(
+#     "platformStatusMessage",
+#     {
+#         "message": fields.Nested(
+#             full_message_schema,
+#             required=True,
+#             description="Message header",
+#         ),
+#         "platform_ID": fields.Integer(
+#             required=True,
+#             description="unique identifier for platform",
+#             example=1,
+#         ),
+#         "active": fields.Boolean(
+#             required=False,
+#             description="When a platform is in deployment (executing a"
+#             + " mission plan) this should be True",
+#             example=True,
+#         ),
+#         "platform_state": fields.String(
+#             # TODO: Define dictionary with potential STATES of each platform
+#             required=False,
+#             description="Current state executed by platform. E.g. "
+#             + "STOP, IDLE, ABORT.",
+#             example="IDLE",
+#         ),
+#         "autonomy_plan_ID": fields.Integer(
+#             required=False,
+#             description="Last mission plan ID (according to Autonomy Engine's"
+#             + " mission plan number) executed by platform",
+#             example=1,
+#         ),
+#         "mission_track_ID": fields.Integer(
+#             required=False,
+#             description=(
+#                 "Track number - stage in mission (e.g. "
+#                 + "4 --> Waypoint 3 to Waypoint 4)"
+#             ),
+#             example=4,
+#         ),
+#         "mission_action_ID": fields.Integer(
+#             required=False,
+#             description="to add description",
+#             example=1,
+#         ),
+#         "range_to_go": fields.Float(
+#             required=False,
+#             description="Estimated distance to reach next waypoint",
+#             example=124.3,
+#         ),
+#         "speed_over_ground": fields.Float(
+#             required=False,
+#             description="",
+#             example=124.3,
+#         ),
+#         "water_current_velocity": fields.Float(
+#             required=False,
+#             description="",
+#             example=124.3,
+#         ),
+#         "thrust_applied": fields.Float(
+#             required=False,
+#             description="TODO: Needs further consideration",
+#             example=124.3,
+#         ),
+#         "health_status": fields.String(
+#             required=False,
+#             description="Health status extracted by respective platform "
+#             + "if any diagnosis available checks on sensors",
+#             example="Warning",
+#         ),
+#         "gps_data": fields.List(
+#             fields.Nested(gps_schema),  # TODO: TBD Do we want a list of
+#             # gps readings to allow > 1 reading i.e. platform + usbl
+#             required=True,
+#             description="Metadata pf each platform",
+#         ),
+#         "localisation_error": fields.Float(
+#             required=False,
+#             description="Localisation error at last USBL update.",
+#             example="",
+#         ),
+#         "usbl_fix_seconds_ago": fields.Float(
+#             required=False,
+#             description="",
+#             example="",
+#         ),
+#         "battery_remaining_capacity": fields.Float(
+#             required=True,
+#             description="Battery remaining capacity % provided by respective"
+#             + " platform/C2.",
+#             example=80.0,
+#         ),
+#         "sensor_config": fields.Nested(
+#             sensor_schema
+#         ),  # TODO: TBD Do we want a list of sensors to allow > 1 sensor
+#     },
+# )
 
-# TBD: Do we append beacon positions with platform positions?
+# # TBD: Do we append beacon positions with platform positions?
diff --git a/generate_swagger.py b/generate_swagger.py
new file mode 100644
index 0000000..678c1bb
--- /dev/null
+++ b/generate_swagger.py
@@ -0,0 +1,134 @@
+from flask import Flask
+from flasgger import Swagger
+
+# from . import properties
+from formats.message_wrapper import message_wrapper_schema
+from formats.mission_plan import mission_plan_schema
+from formats.observation import observation_schema
+from formats.planning_configuration import planning_configuration_schema
+from formats.platform_status import platform_status_message_schema
+
+app = Flask(__name__)
+
+swagger_config = {
+    "headers": [],
+    "openapi": "3.0.2",
+    "swagger_ui": True,
+    "specs_route": "/soardocs/",
+    "info": {
+        "title": "Backbone Message Formats",
+        "version": "0.1",
+        "description": "SoAR message schemas (i.e. formats)",
+    },
+    "specs": [
+        {
+            "endpoint": "swagger",
+            "route": "/swagger.json",
+            "rule_filter": lambda rule: True,
+            "model_filter": lambda tag: True,
+        }
+    ],
+    "components": {
+        "schemas": {
+            "Message": message_wrapper_schema,
+            "MissionPlan": mission_plan_schema,
+            "Observation": observation_schema,
+            "PlanningConfiguration": planning_configuration_schema,
+            "PlatformStatus": platform_status_message_schema,
+        },
+    },
+    "paths": {
+        "/all_messages": {
+            "get": {
+                "description": "Returns all messages from the system.",
+                "responses": {
+                    "200": {
+                        "description": "A list of messages.",
+                        "content": {
+                            "application/json": {
+                                "schema": {
+                                    "oneOf": [
+                                        {
+                                            "$ref": "#/components/"
+                                            + "schemas/Coordinate"
+                                        },
+                                        {
+                                            "$ref": "#/components/"
+                                            + "schemas/PlatformStatus"
+                                        },
+                                        {
+                                            "$ref": "#/components/"
+                                            + "schemas/MissionPlan"
+                                        },
+                                        {
+                                            "$ref": "#/components/"
+                                            + "schemas/Observation"
+                                        },
+                                        {
+                                            "$ref": "#/components/"
+                                            + "schemas/PlanningConfiguration"
+                                        },
+                                        {
+                                            "$ref": "#/components/"
+                                            + "schemas/PlatformStatus"
+                                        },
+                                    ],
+                                    "discriminator": {
+                                        "propertyName": "message_type",
+                                    },
+                                }
+                            }
+                        },
+                    }
+                },
+            }
+        },
+    },
+    "produces": ["application/json"],
+    "consumes": ["application/json"],
+}
+message_types = [
+    "Message",
+    "Acknowledgement",
+    "MissionPlan",
+    "Observation",
+    "PlanningConfiguration",
+    "PlatformStatus",
+]
+for item in message_types:
+    swagger_config["paths"]["/" + str(item.lower())] = {
+        "get": {
+            "description": "Returns message for " + item,
+            "responses": {
+                "200": {
+                    "description": item + " message.",
+                    "content": {
+                        "application/json": {
+                            "schema": {
+                                "allOf": [
+                                    {
+                                        "$ref": "#/components/schemas"
+                                        + "/" + item,
+                                    },
+                                ],
+                                "discriminator": {
+                                    "propertyName": "message_type",
+                                },
+                            }
+                        }
+                    },
+                }
+            },
+        }
+    }
+
+swag = Swagger(app, config=swagger_config, merge=True)
+
+# app.add_url_rule(
+#     '/coordinates',
+#     view_func=Coordinates.as_view('coordinates'),
+#     methods=['GET']
+# )
+
+if __name__ == "__main__":
+    app.run(debug=True)
-- 
GitLab