Commit 7ceab743 authored by Trishna Saeharaseelan's avatar Trishna Saeharaseelan
Browse files

docs: add swagger docs

parent 6d9a565f
from . import api
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"
]
"""
Generate swagger to view models/schemas.
Command:
1/ python3 generate_swagger.py
2/ Go to http://127.0.0.1:5000/soardocs
WARNING: API Endpoints are NOT functional. Purely for easy-reading.
"""
# from .formats.autonomy_configuration import autonomy_configuration_schema
from flask import Flask, request
from flasgger import Swagger, LazyString
from flask_restx import Api, fields, Resource
app = Flask(__name__)
# app.json_encoder = LazyJSONEncoder
api = Api(app)
swagger_template = dict(
info={
"title": LazyString(lambda: "SoAR Backbone Message Formats"),
"version": LazyString(lambda: "0.1"),
"description": LazyString(
lambda: "Backbone Message Format component for the Squad of Autonomous Robots (SoAR) message definitions."
),
},
host=LazyString(lambda: request.host),
)
message_header_schema = api.model(
"MessageHeader",
{
"timestamp": fields.DateTime(
required=True,
description="Timestamp of message",
example="2022-11-16T00:00:00Z",
),
"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":# TODO: schema applicable changes according to "type"
},
)
platform_schema = api.model(
"PlatformSchema",
{
"platform_ID": fields.Integer(
required=True,
description="unique identifier for platform",
example="ah-1",
),
"serial": fields.Integer(
required=True,
description="platform serial number",
example="ah-1",
),
"model": fields.Integer(
required=True,
description="platform serial number",
example="ah-1",
),
"active": fields.Boolean(
required=False,
description="platform in mission",
example=True,
),
},
)
squad_metadata_schema = api.model(
"SquadMetadataSchema",
{
"squad_ID": fields.Integer(
required=True,
description="platform serial number",
example="ah-1",
),
"no_of_platforms": fields.Integer(
required=True,
description="number of platform serial number",
example="ah-1",
),
"platforms": fields.List(
fields.Nested(platform_schema),
required=True,
description="Metadata pf each platform",
),
"squad_mission_type": fields.String(
required=True,
description="Survey or Detail",
example="survey",
),
"squad_state": fields.Boolean(
required=True,
description="True if given Squad is executing mission type "
+ "according to the Autonomy Engine plan",
example=False,
),
},
)
constraints_schema = api.model(
"ConstraintsSchema",
# TODO: Should this be per platform instead of squad?
{
"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,
),
},
)
environment_config_schema = api.model( # TODO: Discuss how regions are defined
"EnvironmentConfig",
{
"region_of_interest": fields.String(),
"exclusion_zone": fields.String(),
},
)
# Main Autonomy Configuration Schema
autonomy_configuration_schema = api.model(
"ConfigurationSchema",
{
"message": fields.Nested(
message_header_schema,
required=True,
description="Message header",
),
"ID": fields.Integer(
required=True,
description="Unique identifier tagged to version of this"
+ " configuration plan",
example=3,
),
"time": fields.String(
required=True,
description="",
example="",
),
"squads": fields.Nested(
squad_metadata_schema,
required=False,
description="Details of each squad",
),
"environment": fields.Nested(
environment_config_schema,
required=False,
description="Region of interest and exclusion zone",
),
},
)
gps_schema = api.model(
"GPS",
{
"gps_source": fields.Float( # TODO: TBD with partners
required=False,
description="Source of gps position. E.g. Beacon",
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 <insert units>",
example="",
),
"longitude": fields.Float(
required=False,
description="Longitude in <insert units>",
example="",
),
"depth": fields.Float(
required=False,
description="",
example="",
),
"gps_fix_seconds_ago": fields.Float(
required=False,
description="",
example="",
),
},
)
platform_status_message_schema = api.model(
"PlatformStatusMessage",
{
"message": fields.Nested(
message_header_schema,
required=True,
description="Message header",
),
"platform": fields.Nested(platform_schema),
"time": fields.String(
required=True,
description="Timestamp of message",
example="2022-11-16T00:00:00Z",
),
"version": fields.Integer(
required=False,
description="", # we can track the version of the AE plan?
example="",
),
"platform_state": fields.String(
# TODO: Define dictionary with potential STATES of each platform
required=True,
description="Current state executed by platform. E.g. "
+ "STOP, IDLE, ABORT.",
example="IDLE",
),
"mission_track_number": fields.Integer(
required=False,
description=(
"Track number - stage in mission (e.g. "
+ "4 --> Waypoint 3 to Waypoint 4)"
),
example=4,
),
"range_to_go": fields.Float(
required=False,
description="Estimated distance to reach next waypoint",
example=124.3,
),
"c2_health_status": fields.String(
required=False,
description="Health status extracted by respective platform's C2 "
+ "if any diagnosis available checks on sensors",
example="Warning",
),
"gps_data": fields.Nested(gps_schema),
"battery_voltage": fields.Float(
required=True,
description="Volts",
example=23.0,
),
"battery_current": fields.Float(
required=False,
description="Amps",
example=1.2,
),
"battery_current_per_hour": fields.Float(
required=False,
description="Amp-Hours",
example=1.2,
),
"battery_wattage": fields.Float(
required=False,
description="Watts",
example=23.0,
),
"battery_wattage_per_hour": fields.Float(
required=False,
description="Watt-Hours",
example=23.0,
),
},
)
swagger_config = {
"headers": [],
"specs": [
{
"endpoint": "swagger",
"route": "/swagger.json",
"rule_filter": lambda rule: True,
"model_filter": lambda tag: True,
}
],
"static_url_path": "/flasgger_static",
"swagger_ui": True,
"specs_route": "/soardocs/",
"swagger": "2.0",
"basePath": "/soar",
"info": {
"title": "soar",
"version": "0.1",
"description": "SoAR message schemas",
},
"produces": ["application/json"],
"consumes": ["application/json"],
}
swagger = Swagger(app, template=swagger_template, config=swagger_config)
ns1 = api.namespace("message", description="Message Header Format")
@ns1.route("/header")
class MessageHeader(Resource):
@ns1.response(200, "Success", message_header_schema)
def get(self):
pass
ns2 = api.namespace("platform_status", description="Platform Status Message Format")
@ns2.route("")
class PlatformStatus(Resource):
@ns2.response(200, "Success", platform_status_message_schema)
def get(self):
pass
ns3 = api.namespace(
"autonomy_configuration", description="Autonomy Configuration Format"
)
@ns3.route("")
class AutonomyConfiguration(Resource):
@ns3.response(200, "Success", autonomy_configuration_schema)
def get(self):
pass
# @api.route('/mission-plan/<str:platform_type')
# @api.doc(params={"platform_type": "The type of platform of the mission plan to target."})
ns4 = api.namespace("mission_plan", description="Mission Plan Format per Platform")
@ns4.route("/ecosub")
class MissionPlanEcosub(Resource):
@ns4.response(200, "Success", message_header_schema)
def get(self):
pass
@ns4.route("/hydrosurv")
class MissionPlanHydrosurv(Resource):
@ns4.response(200, "Success", message_header_schema)
def get(self):
pass
@ns4.route("/autosubhover")
class MissionPlanAutosubHover(Resource):
@ns4.response(200, "Success", message_header_schema)
def get(self):
pass
if __name__ == "__main__":
app.run()
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