nore documentation for routing and positioning API

This commit is contained in:
Laura Klünder 2023-12-04 19:24:14 +01:00
parent 964574e535
commit 0e73643bb3
2 changed files with 108 additions and 21 deletions

View file

@ -1,4 +1,4 @@
from typing import Annotated, Optional
from typing import Annotated, Union
from django.core.exceptions import ValidationError
from ninja import Field as APIField
@ -20,19 +20,55 @@ positioning_api_router = APIRouter(tags=["positioning"])
class LocateRequestPeerSchema(Schema):
bssid: BSSIDSchema
ssid: NonEmptyStr
rssi: NegativeInt
frequency: Optional[PositiveInt] = None
distance: Optional[float] = None
bssid: BSSIDSchema = APIField(
title="BSSID",
description="BSSID of the peer",
example="c3:42:13:37:ac:ab",
)
ssid: NonEmptyStr = APIField(
title="SSID",
description="(E)SSID of the peer",
example="c3nav-locate",
)
rssi: NegativeInt = APIField(
title="RSSI",
description="RSSI in dBm",
example=-42,
)
frequency: Union[
PositiveInt,
Annotated[None, APIField(title="null", description="frequency not given")]
] = APIField(
default=None,
title="frequency",
description="frequency in KHz",
example=2472,
)
distance: Union[
float,
Annotated[None, APIField(title="null", description="distance was not measured")]
] = APIField(
default=None,
title="distance",
description="measured distance in meters",
example=8.32
)
class LocateRequestSchema(Schema):
peers: list[LocateRequestPeerSchema]
peers: list[LocateRequestPeerSchema] = APIField(
title="list of visible/measured location beacons",
)
class PositioningResult(Schema):
location: Optional[CustomLocationSchema]
location: Union[
Annotated[CustomLocationSchema, APIField(title="location")],
Annotated[None, APIField(title="null", description="position could not be determined")]
] = APIField(
title="location",
description="positinoing result",
)
@positioning_api_router.post('/locate/', summary="determine position",

View file

@ -53,31 +53,73 @@ class AltitudeWayTypeChoice(StrEnum):
AVOID = "avoid"
class RouteOptionsSchema(Schema):
class UpdateRouteOptionsSchema(Schema):
# todo: default is wrong, this should be optional
mode: RouteMode = RouteMode.FASTEST
walk_speed: WalkSpeed = WalkSpeed.DEFAULT
mode: Union[
Annotated[RouteMode, APIField(title="route mode", description="routing mode to use")],
Annotated[None, APIField(title="null", description="don't change routing mode")],
] = APIField(
default=None,
title="routing mode",
)
walk_speed: Union[
Annotated[WalkSpeed, APIField(title="walk speed", description="walk speed to use")],
Annotated[None, APIField(title="null", description="don't change walk speed")],
] = APIField(
default=None,
title="walk speed",
)
way_types: dict[
Annotated[NonEmptyStr, APIField(title="waytype")],
Union[
Annotated[LevelWayTypeChoice, APIField(default=LevelWayTypeChoice.ALLOW)],
Annotated[AltitudeWayTypeChoice, APIField(default=AltitudeWayTypeChoice.ALLOW)],
Annotated[LevelWayTypeChoice, APIField(title="waytype without altitude change")],
Annotated[AltitudeWayTypeChoice, APIField(title="waytype with altitude change")],
]
] = APIField(default_factory=dict)
] = APIField(
default_factory=dict,
title="waytype settings",
)
class RouteOptionsSchema(Schema):
# todo: default is wrong, this should be optional
mode: RouteMode = APIField(name="routing mode")
walk_speed: WalkSpeed = APIField(name="walk speed")
way_types: dict[
Annotated[NonEmptyStr, APIField(title="waytype")],
Union[
Annotated[LevelWayTypeChoice, APIField(title="waytype without altitude change")],
Annotated[AltitudeWayTypeChoice, APIField(title="waytype with altitude change")],
]
] = APIField(
title="waytype settings",
)
class RouteParametersSchema(Schema):
origin: AnyLocationID
destination: AnyLocationID
options_override: Optional[RouteOptionsSchema] = None
options_override: UpdateRouteOptionsSchema = APIField(
title="override routing options",
default_factory=dict,
)
class RouteItemSchema(Schema):
id: PositiveInt
coordinates: Coordinates3D
waytype: Optional[dict] = None # todo: improve
space: Optional[dict] = APIField(None, title="new space being entered")
level: Optional[dict] = APIField(None, title="new level being entered")
waytype: Union[
Annotated[dict, APIField(title="waytype", descripiton="waytype used for this segment")],
Annotated[None, APIField(title="null", description="no waytype (normal walking)")],
] = APIField(None, title="waytype")
space: Union[
Annotated[dict, APIField(title="space", descripiton="new space that is being entered")],
Annotated[None, APIField(title="null", description="staying in the same space")],
] = APIField(None, description="new space being entered")
level: Union[
Annotated[dict, APIField(title="level", descripiton="new level that is being entered")],
Annotated[None, APIField(title="null", description="staying in the same level")],
] = APIField(None, description="new level being entered")
descriptions: list[tuple[
Annotated[NonEmptyStr, APIField(
title="icon name",
@ -108,12 +150,21 @@ class RouteResponse(Schema):
report_issue_url: NonEmptyStr
result: RouteSchema
class Config(Schema.Config):
title = "route found"
class NoRouteResponse(Schema):
""" the routing parameters were valid, but it was not possible to determine a route for these parameters """
request: RouteParametersSchema
options: RouteOptionsSchema
error: NonEmptyStr = APIField(name="error description")
error: NonEmptyStr = APIField(
name="error description",
description=("the routing parameters were valid, but it was not possible to determine a route. "
"this field contains the reason.")
)
class Config(Schema.Config):
title = "route could not be determined"
def get_request_pk(location):
@ -222,7 +273,7 @@ def get_route_options(request):
@routing_api_router.put('/options/', summary="set route options",
description="set current preferred route options for this user (or session, if signed out)",
response={200: RouteOptionsSchema, **validate_responses, **auth_responses})
def set_route_options(request, new_options: RouteOptionsSchema):
def set_route_options(request, new_options: UpdateRouteOptionsSchema):
options = RouteOptions.get_for_request(request)
_new_update_route_options(options, new_options)