Skip to content

Commit

Permalink
Add InterUSS automated testing APIs (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
BenjaminPelletier authored Oct 26, 2022
1 parent 34fd921 commit 9f06ab7
Show file tree
Hide file tree
Showing 39 changed files with 809 additions and 12 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
[submodule "interfaces/astm/f3548/v21"]
path = interfaces/astm/f3548/v21
url = https://github.com/astm-utm/Protocol
[submodule "interfaces/interuss/automated_testing"]
path = interfaces/interuss/automated_testing
url = https://github.com/interuss/automated_testing_interfaces
1 change: 1 addition & 0 deletions interfaces/interuss/automated_testing
Submodule automated_testing added at fa3a5f
Empty file.
Empty file.
Empty file.
Empty file.
366 changes: 366 additions & 0 deletions src/uas_standards/interuss/automated_testing/flight_planning/v1/api.py

Large diffs are not rendered by default.

Empty file.
Empty file.
181 changes: 181 additions & 0 deletions src/uas_standards/interuss/automated_testing/geo_awareness/v1/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
"""Data types from Geo-Awareness Automated Test Interfaces 0.1.0 OpenAPI"""

# This file is autogenerated; do not modify manually!

from __future__ import annotations

from enum import Enum
from typing import List, Optional

from implicitdict import ImplicitDict, StringBasedDateTime


UUIDv4Format = str
"""String whose format matches a version-4 UUID according to RFC 4122."""


class StatusResponseStatus(str, Enum):
"""The status of the USS automated testing interface.
- `Starting`: the USS is starting and the automated test driver should wait before sending requests.
- `Ready`: the USS is ready to receive test requests.
"""

Starting = "Starting"
Ready = "Ready"


class StatusResponse(ImplicitDict):
status: StatusResponseStatus
"""The status of the USS automated testing interface.
- `Starting`: the USS is starting and the automated test driver should wait before sending requests.
- `Ready`: the USS is ready to receive test requests.
"""

version: Optional[str]
"""Arbitrary string representing the version of the USS system to be tested."""


class GeozoneHttpsSourceFormat(str, Enum):
"""The format of the response expected from the source."""

ED_269 = "ED-269"


class GeozoneHttpsSource(ImplicitDict):
url: str
"""The URL at which the Geozone data shall be downloaded from."""

format: Optional[GeozoneHttpsSourceFormat] = GeozoneHttpsSourceFormat.ED_269
"""The format of the response expected from the source."""


class GeozoneSourceResponseResult(str, Enum):
"""The status of the Geozone source and the handling of its data by the USS.
- `Activating`: the USS is processing the request and is currently activating the Geozone data.
- `Ready`: the Geozone data has been successfully activated and the USS is ready to receive test requests.
- `Deactivating`: the Geozone data is being deactivated.
- `Unsupported`: the USS cannot process the dataset type specified.
- `Rejected`: the Geozone data was rejected because it is invalid.
- `Error`: the Geozone data activation or deactivation failed. The message field is required in this case.
"""

Activating = "Activating"
Ready = "Ready"
Deactivating = "Deactivating"
Unsupported = "Unsupported"
Rejected = "Rejected"
Error = "Error"


class GeozoneSourceResponse(ImplicitDict):
result: GeozoneSourceResponseResult
"""The status of the Geozone source and the handling of its data by the USS.
- `Activating`: the USS is processing the request and is currently activating the Geozone data.
- `Ready`: the Geozone data has been successfully activated and the USS is ready to receive test requests.
- `Deactivating`: the Geozone data is being deactivated.
- `Unsupported`: the USS cannot process the dataset type specified.
- `Rejected`: the Geozone data was rejected because it is invalid.
- `Error`: the Geozone data activation or deactivation failed. The message field is required in this case.
"""

message: Optional[str]
"""Human-readable explanation of the result for debugging purpose only. This field is required when the result value is `Error`."""


class UomDimensions(str, Enum):
M = "M"
FT = "FT"


class VerticalReferenceType(str, Enum):
AGL = "AGL"
AMSL = "AMSL"


USpaceClass = str


class Restriction(str, Enum):
PROHIBITED = "PROHIBITED"
REQ_AUTHORISATION = "REQ_AUTHORISATION"
CONDITIONAL = "CONDITIONAL"
NO_RESTRICTION = "NO_RESTRICTION"


class Position(ImplicitDict):
uomDimensions: UomDimensions

verticalReferenceType: VerticalReferenceType

height: Optional[float] = 0
"""Height above vertical reference datum indicated in `verticalReferenceType`, in units of `uomDimensions`."""

longitude: Optional[float] = 0
"""Longitude, degrees east of prime meridian."""

latitude: Optional[float] = 0
"""Latitude, degrees north of the equator."""


class ED269Filters(ImplicitDict):
"""Filter criteria for the selection of Geozones according to ED-269 characteristics."""

uSpaceClass: Optional[USpaceClass]
"""If specified, only select Geozones which are of the specified `uSpaceClass`."""

acceptableRestrictions: Optional[List[Restriction]]
"""If specified and non-empty, only select Geozones which are one of the specified restriction types."""


class GeozonesCheckResultGeozone(str, Enum):
"""Indication of whether one or more applicable Geozones were selected according to the selection criteria of the corresponding check.
* Present: One or more applicable Geozones were selected. * Absent: No applicable Geozones were selected. * UnsupportedFilter: Applicable Geozones could not be selected because one or more filter criteria are not supported by the USSP. If this value is specified, `message` must be populated. * Error: An error or condition not enumerated above occurred. If this value is specified, `message` must be populated.
"""

Present = "Present"
Absent = "Absent"
UnsupportedFilter = "UnsupportedFilter"
Error = "Error"


class GeozonesCheckResult(ImplicitDict):
geozone: GeozonesCheckResultGeozone
"""Indication of whether one or more applicable Geozones were selected according to the selection criteria of the corresponding check.
* Present: One or more applicable Geozones were selected. * Absent: No applicable Geozones were selected. * UnsupportedFilter: Applicable Geozones could not be selected because one or more filter criteria are not supported by the USSP. If this value is specified, `message` must be populated. * Error: An error or condition not enumerated above occurred. If this value is specified, `message` must be populated.
"""

message: Optional[str]
"""A human-readable description of why the non-standard `geozone` value was reported. Should only be populated when appropriate according to the value of the `geozone` field."""


class CreateGeozoneSourceRequest(ImplicitDict):
https_source: Optional[GeozoneHttpsSource]


class GeozonesFilterSet(ImplicitDict):
"""Set of filters to select only a subset of Geozones. Only Geozones which are applicable to all specified filters within this filter set should be selected."""

position: Optional[Position]
"""If specified, only select Geozones encompassing this position."""

after: Optional[StringBasedDateTime]
"""If specified, only select Geozones which encompass at least some times at or after this time."""

before: Optional[StringBasedDateTime]
"""If specified, only select Geozones which encompass at least some times at or before this time."""

ed269: Optional[ED269Filters]


class GeozonesCheckReply(ImplicitDict):
applicableGeozone: Optional[List[GeozonesCheckResult]] = []
"""Responses to each of the `checks` in the request. The number of entries in this array should match the number of entries in the `checks` field of the request."""


class GeozonesCheck(ImplicitDict):
filterSets: List[GeozonesFilterSet]
"""Select Geozones which match any of the specified filter sets."""


class GeozonesCheckRequest(ImplicitDict):
checks: List[GeozonesCheck]
Empty file.
Empty file.
58 changes: 58 additions & 0 deletions src/uas_standards/interuss/automated_testing/rid/v1/injection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"""Data types from Remote ID Test Data Injection 0.0.1 OpenAPI"""

# This file is autogenerated; do not modify manually!

from __future__ import annotations

from typing import List

from implicitdict import ImplicitDict


from uas_standards.astm.f3411.v19.api import RIDFlightDetails


class TestFlightDetails(ImplicitDict):
"""The set of data with which the Service Provider system under test should respond when queried for the details of a test flight."""

effective_after: str
"""The time after which the Service Provider system under test should respond with `details`, unless other `details` with a more recent `effective_after` time (before the current time) are available."""

details: RIDFlightDetails
"""The details of the flight. Follows the RIDFlightDetails schema from the ASTM remote ID standard."""


from uas_standards.astm.f3411.v19.api import RIDAircraftState


class TestFlight(ImplicitDict):
"""The set of data to be injected into a Service Provider system under test for a single flight."""

injection_id: str
"""ID of the injected test flight. Remains the same regardless of the flight ID/UTM ID reported in the system."""

telemetry: List[RIDAircraftState]
"""The set of telemetry data that should be injected into the system for this flight. Each element follows the RIDAircraftState schema from the ASTM remote ID standard."""

details_responses: List[TestFlightDetails]
"""The details of the flight as a function of time."""


class CreateTestParameters(ImplicitDict):
"""A complete set of data to be injected into a Service Provider system under test."""

requested_flights: List[TestFlight]
"""One or more logical flights, each containing test data to inject into the system. Elements should be sorted in ascending order of `timestamp`."""


class ChangeTestResponse(ImplicitDict):
injected_flights: List[TestFlight]
"""The complete set of test data actually injected into the Service Provider system under test."""

version: str
"""Version of test. Used to delete test."""


class DeleteTestResponse(ImplicitDict):
injected_flights: List[TestFlight]
"""The complete set of test data deleted."""
68 changes: 68 additions & 0 deletions src/uas_standards/interuss/automated_testing/rid/v1/observation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""Data types from Remote ID Display Data Observation 0.0.1 OpenAPI"""

# This file is autogenerated; do not modify manually!

from __future__ import annotations

from typing import List, Optional

from implicitdict import ImplicitDict


class GetDetailsResponse(ImplicitDict):
"""Response to a request to get details about a flight."""



class Position(ImplicitDict):
"""A position on Earth."""

lat: float
"""Degrees of latitude north of the equator, with reference to the WGS84 ellipsoid."""

lng: float
"""Degrees of longitude east of the Prime Meridian, with reference to the WGS84 ellipsoid."""

alt: Optional[float]
"""Geodetic altitude (NOT altitude above launch, altitude above ground, or EGM96): aircraft distance above the WGS84 ellipsoid as measured along a line that passes through the aircraft and is normal to the surface of the WGS84 ellipsoid."""


class Path(ImplicitDict):
"""Path followed by a flight."""

positions: List[Position]
"""Sequential positions available for a flight."""


class Flight(ImplicitDict):
id: str
"""Identifier of flight that may be used to obtain details about the flight. This is not necessarily the UTM/flight ID in the remote ID system."""

most_recent_position: Optional[Position]
"""Most recent position known for the flight."""

recent_paths: Optional[List[Path]]
"""Paths the flight recently traveled, if available."""


class Cluster(ImplicitDict):
"""A general area containing one or more flight."""

corners: List[Position]
"""Two opposite corners of a rectangular lat-lng box bounding the cluster."""

area_sqm: float
"""Area of the cluster in square meters."""

number_of_flights: int
"""Number of flights within the cluster."""


class GetDisplayDataResponse(ImplicitDict):
"""Response to a request for current data that would be visualized by a Display Application."""

flights: Optional[List[Flight]] = []
"""Current information for set of discovered flights whose precise locations are known."""

clusters: Optional[List[Cluster]] = []
"""Current information for sets of discovered flights whose precise locations are not known."""
Empty file added tests/__init__.py
Empty file.
Empty file added tests/astm/__init__.py
Empty file.
Empty file added tests/astm/f3411/__init__.py
Empty file.
Empty file.
5 changes: 5 additions & 0 deletions tests/astm/f3411/v19/test_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from uas_standards.astm.f3411.v19.api import *


def test_import():
pass
Empty file.
5 changes: 5 additions & 0 deletions tests/astm/f3411/v22a/test_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from uas_standards.astm.f3411.v22a.api import *


def test_import():
pass
Empty file added tests/astm/f3548/__init__.py
Empty file.
Empty file.
5 changes: 5 additions & 0 deletions tests/astm/f3548/v21/test_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from uas_standards.astm.f3548.v21.api import *


def test_import():
pass
Empty file added tests/interuss/__init__.py
Empty file.
Empty file.
Empty file.
5 changes: 5 additions & 0 deletions tests/interuss/automated_testing/flight_planning/test_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from uas_standards.interuss.automated_testing.flight_planning.v1.api import *


def test_import():
pass
Empty file.
Empty file.
5 changes: 5 additions & 0 deletions tests/interuss/automated_testing/geo_awareness/v1/test_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from uas_standards.interuss.automated_testing.geo_awareness.v1.api import *


def test_import():
pass
Empty file.
Empty file.
5 changes: 5 additions & 0 deletions tests/interuss/automated_testing/rid/v1/test_injection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from uas_standards.interuss.automated_testing.rid.v1.injection import *


def test_import():
pass
5 changes: 5 additions & 0 deletions tests/interuss/automated_testing/rid/v1/test_observation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from uas_standards.interuss.automated_testing.rid.v1.observation import *


def test_import():
pass
5 changes: 4 additions & 1 deletion tools/openapi_conversion/convert_openapi_to_implicitdict.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ def _parse_args():
help='Source YAML to preprocess.')
parser.add_argument('--python_output', dest='python_output', type=str,
help='Output file for generated Python code')
parser.add_argument('--default_package', dest='default_package', type=str,
help='If this API refers to objects in another API, the Python package name where those other objects may be found',
default='<not_defined>')

return parser.parse_args()

Expand All @@ -33,7 +36,7 @@ def main():
# Render Python code
with open(args.python_output, 'w') as f:
f.write(f'"""Data types from {spec["info"]["title"]} {spec["info"]["version"]} OpenAPI"""\n\n')
f.write('\n'.join(rendering.data_types(types)))
f.write('\n'.join(rendering.data_types(types, args.default_package)))


if __name__ == '__main__':
Expand Down
Loading

0 comments on commit 9f06ab7

Please sign in to comment.