Skip to content

Commit

Permalink
api-server: Support generic labels (#949)
Browse files Browse the repository at this point in the history
* save generic labels

Signed-off-by: Teo Koon Peng <[email protected]>

* document problems with tortoise-orm

Signed-off-by: Teo Koon Peng <[email protected]>

* cleanup

Signed-off-by: Teo Koon Peng <[email protected]>

* cleanup

Signed-off-by: Teo Koon Peng <[email protected]>

* port generic label filtering from main

Signed-off-by: Teo Koon Peng <[email protected]>

* successfully ported generic label sorting

Signed-off-by: Teo Koon Peng <[email protected]>

* fix test leaking to other tests

Signed-off-by: Teo Koon Peng <[email protected]>

* add TODO

Signed-off-by: Teo Koon Peng <[email protected]>

* update client api

Signed-off-by: Teo Koon Peng <[email protected]>

* uncomment out test

Signed-off-by: Teo Koon Peng <[email protected]>

* fix api call

Signed-off-by: Teo Koon Peng <[email protected]>

---------

Signed-off-by: Teo Koon Peng <[email protected]>
  • Loading branch information
koonpeng authored Jun 5, 2024
1 parent 38d5869 commit d39a031
Show file tree
Hide file tree
Showing 17 changed files with 371 additions and 200 deletions.
86 changes: 35 additions & 51 deletions packages/api-client/lib/openapi/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,12 @@ export interface DeliveryAlert {
*/
message: string;
}
/**
*
* @export
* @interface Description
*/
export interface Description {}
/**
* Detailed information about a task, phase, or event
* @export
Expand Down Expand Up @@ -2403,47 +2409,10 @@ export interface Task {
export interface TaskBookingLabel {
/**
*
* @type {TaskBookingLabelDescription}
* @type {{ [key: string]: Description; }}
* @memberof TaskBookingLabel
*/
description: TaskBookingLabelDescription;
}
/**
* This description holds several fields that could be useful for frontend dashboards when dispatching a task, to then be identified or rendered accordingly back on the same frontend.
* @export
* @interface TaskBookingLabelDescription
*/
export interface TaskBookingLabelDescription {
/**
*
* @type {string}
* @memberof TaskBookingLabelDescription
*/
task_definition_id: string;
/**
*
* @type {number}
* @memberof TaskBookingLabelDescription
*/
unix_millis_warn_time?: number;
/**
*
* @type {string}
* @memberof TaskBookingLabelDescription
*/
pickup?: string;
/**
*
* @type {string}
* @memberof TaskBookingLabelDescription
*/
destination?: string;
/**
*
* @type {string}
* @memberof TaskBookingLabelDescription
*/
cart_id?: string;
description: { [key: string]: Description };
}
/**
* Response to a request to cancel a task
Expand Down Expand Up @@ -9529,15 +9498,16 @@ export const TasksApiAxiosParamCreator = function (configuration?: Configuration
};
},
/**
*
* Note that sorting by `pickup` and `destination` is mutually exclusive and sorting by either of them will filter only tasks which has those labels.
* @summary Query Task States
* @param {string} [taskId] comma separated list of task ids
* @param {string} [category] comma separated list of task categories
* @param {string} [requester] comma separated list of requester names
* @param {string} [pickup] comma separated list of pickup names
* @param {string} [destination] comma separated list of destination names
* @param {string} [pickup] comma separated list of pickup names. [deprecated] use &#x60;label&#x60; instead
* @param {string} [destination] comma separated list of destination names, [deprecated] use &#x60;label&#x60; instead
* @param {string} [assignedTo] comma separated list of assigned robot names
* @param {string} [status] comma separated list of statuses
* @param {string} [label] comma separated list of labels, each item must be in the form &lt;key&gt;&#x3D;&lt;value&gt;, multiple items will filter tasks with all the labels
* @param {string} [requestTimeBetween] The period of request time to fetch, in unix millis. This must be a comma separated string, \&#39;X,Y\&#39; to fetch between X millis and Y millis inclusive. Example: \&quot;1000,2000\&quot; - Fetches logs between unix millis 1000 and 2000.
* @param {string} [startTimeBetween] The period of starting time to fetch, in unix millis. This must be a comma separated string, \&#39;X,Y\&#39; to fetch between X millis and Y millis inclusive. Example: \&quot;1000,2000\&quot; - Fetches logs between unix millis 1000 and 2000.
* @param {string} [finishTimeBetween] The period of finishing time to fetch, in unix millis. This must be a comma separated string, \&#39;X,Y\&#39; to fetch between X millis and Y millis inclusive. Example: \&quot;1000,2000\&quot; - Fetches logs between unix millis 1000 and 2000. \&quot;-60000\&quot; - Fetches logs in the last minute.
Expand All @@ -9555,6 +9525,7 @@ export const TasksApiAxiosParamCreator = function (configuration?: Configuration
destination?: string,
assignedTo?: string,
status?: string,
label?: string,
requestTimeBetween?: string,
startTimeBetween?: string,
finishTimeBetween?: string,
Expand Down Expand Up @@ -9603,6 +9574,10 @@ export const TasksApiAxiosParamCreator = function (configuration?: Configuration
localVarQueryParameter['status'] = status;
}

if (label !== undefined) {
localVarQueryParameter['label'] = label;
}

if (requestTimeBetween !== undefined) {
localVarQueryParameter['request_time_between'] = requestTimeBetween;
}
Expand Down Expand Up @@ -10163,15 +10138,16 @@ export const TasksApiFp = function (configuration?: Configuration) {
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* Note that sorting by `pickup` and `destination` is mutually exclusive and sorting by either of them will filter only tasks which has those labels.
* @summary Query Task States
* @param {string} [taskId] comma separated list of task ids
* @param {string} [category] comma separated list of task categories
* @param {string} [requester] comma separated list of requester names
* @param {string} [pickup] comma separated list of pickup names
* @param {string} [destination] comma separated list of destination names
* @param {string} [pickup] comma separated list of pickup names. [deprecated] use &#x60;label&#x60; instead
* @param {string} [destination] comma separated list of destination names, [deprecated] use &#x60;label&#x60; instead
* @param {string} [assignedTo] comma separated list of assigned robot names
* @param {string} [status] comma separated list of statuses
* @param {string} [label] comma separated list of labels, each item must be in the form &lt;key&gt;&#x3D;&lt;value&gt;, multiple items will filter tasks with all the labels
* @param {string} [requestTimeBetween] The period of request time to fetch, in unix millis. This must be a comma separated string, \&#39;X,Y\&#39; to fetch between X millis and Y millis inclusive. Example: \&quot;1000,2000\&quot; - Fetches logs between unix millis 1000 and 2000.
* @param {string} [startTimeBetween] The period of starting time to fetch, in unix millis. This must be a comma separated string, \&#39;X,Y\&#39; to fetch between X millis and Y millis inclusive. Example: \&quot;1000,2000\&quot; - Fetches logs between unix millis 1000 and 2000.
* @param {string} [finishTimeBetween] The period of finishing time to fetch, in unix millis. This must be a comma separated string, \&#39;X,Y\&#39; to fetch between X millis and Y millis inclusive. Example: \&quot;1000,2000\&quot; - Fetches logs between unix millis 1000 and 2000. \&quot;-60000\&quot; - Fetches logs in the last minute.
Expand All @@ -10189,6 +10165,7 @@ export const TasksApiFp = function (configuration?: Configuration) {
destination?: string,
assignedTo?: string,
status?: string,
label?: string,
requestTimeBetween?: string,
startTimeBetween?: string,
finishTimeBetween?: string,
Expand All @@ -10205,6 +10182,7 @@ export const TasksApiFp = function (configuration?: Configuration) {
destination,
assignedTo,
status,
label,
requestTimeBetween,
startTimeBetween,
finishTimeBetween,
Expand Down Expand Up @@ -10625,15 +10603,16 @@ export const TasksApiFactory = function (
.then((request) => request(axios, basePath));
},
/**
*
* Note that sorting by `pickup` and `destination` is mutually exclusive and sorting by either of them will filter only tasks which has those labels.
* @summary Query Task States
* @param {string} [taskId] comma separated list of task ids
* @param {string} [category] comma separated list of task categories
* @param {string} [requester] comma separated list of requester names
* @param {string} [pickup] comma separated list of pickup names
* @param {string} [destination] comma separated list of destination names
* @param {string} [pickup] comma separated list of pickup names. [deprecated] use &#x60;label&#x60; instead
* @param {string} [destination] comma separated list of destination names, [deprecated] use &#x60;label&#x60; instead
* @param {string} [assignedTo] comma separated list of assigned robot names
* @param {string} [status] comma separated list of statuses
* @param {string} [label] comma separated list of labels, each item must be in the form &lt;key&gt;&#x3D;&lt;value&gt;, multiple items will filter tasks with all the labels
* @param {string} [requestTimeBetween] The period of request time to fetch, in unix millis. This must be a comma separated string, \&#39;X,Y\&#39; to fetch between X millis and Y millis inclusive. Example: \&quot;1000,2000\&quot; - Fetches logs between unix millis 1000 and 2000.
* @param {string} [startTimeBetween] The period of starting time to fetch, in unix millis. This must be a comma separated string, \&#39;X,Y\&#39; to fetch between X millis and Y millis inclusive. Example: \&quot;1000,2000\&quot; - Fetches logs between unix millis 1000 and 2000.
* @param {string} [finishTimeBetween] The period of finishing time to fetch, in unix millis. This must be a comma separated string, \&#39;X,Y\&#39; to fetch between X millis and Y millis inclusive. Example: \&quot;1000,2000\&quot; - Fetches logs between unix millis 1000 and 2000. \&quot;-60000\&quot; - Fetches logs in the last minute.
Expand All @@ -10651,6 +10630,7 @@ export const TasksApiFactory = function (
destination?: string,
assignedTo?: string,
status?: string,
label?: string,
requestTimeBetween?: string,
startTimeBetween?: string,
finishTimeBetween?: string,
Expand All @@ -10668,6 +10648,7 @@ export const TasksApiFactory = function (
destination,
assignedTo,
status,
label,
requestTimeBetween,
startTimeBetween,
finishTimeBetween,
Expand Down Expand Up @@ -11114,15 +11095,16 @@ export class TasksApi extends BaseAPI {
}

/**
*
* Note that sorting by `pickup` and `destination` is mutually exclusive and sorting by either of them will filter only tasks which has those labels.
* @summary Query Task States
* @param {string} [taskId] comma separated list of task ids
* @param {string} [category] comma separated list of task categories
* @param {string} [requester] comma separated list of requester names
* @param {string} [pickup] comma separated list of pickup names
* @param {string} [destination] comma separated list of destination names
* @param {string} [pickup] comma separated list of pickup names. [deprecated] use &#x60;label&#x60; instead
* @param {string} [destination] comma separated list of destination names, [deprecated] use &#x60;label&#x60; instead
* @param {string} [assignedTo] comma separated list of assigned robot names
* @param {string} [status] comma separated list of statuses
* @param {string} [label] comma separated list of labels, each item must be in the form &lt;key&gt;&#x3D;&lt;value&gt;, multiple items will filter tasks with all the labels
* @param {string} [requestTimeBetween] The period of request time to fetch, in unix millis. This must be a comma separated string, \&#39;X,Y\&#39; to fetch between X millis and Y millis inclusive. Example: \&quot;1000,2000\&quot; - Fetches logs between unix millis 1000 and 2000.
* @param {string} [startTimeBetween] The period of starting time to fetch, in unix millis. This must be a comma separated string, \&#39;X,Y\&#39; to fetch between X millis and Y millis inclusive. Example: \&quot;1000,2000\&quot; - Fetches logs between unix millis 1000 and 2000.
* @param {string} [finishTimeBetween] The period of finishing time to fetch, in unix millis. This must be a comma separated string, \&#39;X,Y\&#39; to fetch between X millis and Y millis inclusive. Example: \&quot;1000,2000\&quot; - Fetches logs between unix millis 1000 and 2000. \&quot;-60000\&quot; - Fetches logs in the last minute.
Expand All @@ -11141,6 +11123,7 @@ export class TasksApi extends BaseAPI {
destination?: string,
assignedTo?: string,
status?: string,
label?: string,
requestTimeBetween?: string,
startTimeBetween?: string,
finishTimeBetween?: string,
Expand All @@ -11158,6 +11141,7 @@ export class TasksApi extends BaseAPI {
destination,
assignedTo,
status,
label,
requestTimeBetween,
startTimeBetween,
finishTimeBetween,
Expand Down
2 changes: 1 addition & 1 deletion packages/api-client/lib/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import { version as rmfModelVer } from 'rmf-models';

export const version = {
rmfModels: rmfModelVer,
rmfServer: '98741b14ceca74208ca98e4bb0c3ca9e41ca1e3c',
rmfServer: 'd536f9525f277088015d827b6b7198035d1a856b',
openapiGenerator: '6.2.1',
};
49 changes: 31 additions & 18 deletions packages/api-client/schema/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,8 @@ export default {
get: {
tags: ['Tasks'],
summary: 'Query Task States',
description:
'Note that sorting by `pickup` and `destination` is mutually exclusive and sorting\nby either of them will filter only tasks which has those labels.',
operationId: 'query_task_states_tasks_get',
parameters: [
{
Expand Down Expand Up @@ -745,23 +747,27 @@ export default {
in: 'query',
},
{
description: 'comma separated list of pickup names',
description: 'comma separated list of pickup names. [deprecated] use `label` instead',
required: false,
deprecated: true,
schema: {
title: 'Pickup',
type: 'string',
description: 'comma separated list of pickup names',
description: 'comma separated list of pickup names. [deprecated] use `label` instead',
},
name: 'pickup',
in: 'query',
},
{
description: 'comma separated list of destination names',
description:
'comma separated list of destination names, [deprecated] use `label` instead',
required: false,
deprecated: true,
schema: {
title: 'Destination',
type: 'string',
description: 'comma separated list of destination names',
description:
'comma separated list of destination names, [deprecated] use `label` instead',
},
name: 'destination',
in: 'query',
Expand All @@ -788,6 +794,19 @@ export default {
name: 'status',
in: 'query',
},
{
description:
'comma separated list of labels, each item must be in the form <key>=<value>, multiple items will filter tasks with all the labels',
required: false,
schema: {
title: 'Label',
type: 'string',
description:
'comma separated list of labels, each item must be in the form <key>=<value>, multiple items will filter tasks with all the labels',
},
name: 'label',
in: 'query',
},
{
description:
'\n The period of request time to fetch, in unix millis.\n\n This must be a comma separated string, \'X,Y\' to fetch between X millis and Y millis inclusive.\n\n Example:\n "1000,2000" - Fetches logs between unix millis 1000 and 2000.\n ',
Expand Down Expand Up @@ -3675,23 +3694,17 @@ export default {
title: 'TaskBookingLabel',
required: ['description'],
type: 'object',
properties: { description: { $ref: '#/components/schemas/TaskBookingLabelDescription' } },
description:
'This label is to be populated by any frontend during a task dispatch, by\nbeing added to TaskRequest.labels, which in turn populates\nTaskState.booking.labels, and can be used to display relevant information\nneeded for any frontends.',
},
TaskBookingLabelDescription: {
title: 'TaskBookingLabelDescription',
required: ['task_definition_id'],
type: 'object',
properties: {
task_definition_id: { title: 'Task Definition Id', type: 'string' },
unix_millis_warn_time: { title: 'Unix Millis Warn Time', type: 'integer' },
pickup: { title: 'Pickup', type: 'string' },
destination: { title: 'Destination', type: 'string' },
cart_id: { title: 'Cart Id', type: 'string' },
description: {
title: 'Description',
type: 'object',
additionalProperties: {
anyOf: [{ type: 'string' }, { type: 'integer' }, { type: 'number' }],
},
},
},
description:
'This description holds several fields that could be useful for frontend\ndashboards when dispatching a task, to then be identified or rendered\naccordingly back on the same frontend.',
'This label is to be populated by any frontend during a task dispatch, by\nbeing added to TaskRequest.labels, which in turn populates\nTaskState.booking.labels, and can be used to display relevant information\nneeded for any frontends.',
},
TaskCancelResponse: {
title: 'TaskCancelResponse',
Expand Down
1 change: 1 addition & 0 deletions packages/api-server/api_server/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from .doors import *
from .health import *
from .ingestors import *
from .labels import *
from .lifts import *
from .pagination import *
from .rmf_api.activity_discovery_request import ActivityDiscoveryRequest
Expand Down
25 changes: 25 additions & 0 deletions packages/api-server/api_server/models/labels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from typing import Sequence

from pydantic import BaseModel


class Labels(BaseModel):
"""
Labels for a resource.
"""

__root__: dict[str, str]

@staticmethod
def _parse_label(s: str) -> tuple[str, str]:
sep = s.find("=")
if sep == -1:
return s, ""
return s[:sep], s[sep + 1 :]

@staticmethod
def from_strings(labels: Sequence[str]) -> "Labels":
return Labels(__root__=dict(Labels._parse_label(s) for s in labels))

def to_strings(self) -> list[str]:
return [f"{k}={v}" for k, v in self.__root__.items()]
26 changes: 1 addition & 25 deletions packages/api-server/api_server/models/task_booking_label.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,6 @@
import pydantic
from pydantic import BaseModel

# NOTE: This label model needs to exactly match the fields that are defined and
# populated by the dashboard. Any changes to either side will require syncing.


class TaskBookingLabelDescription(BaseModel):
"""
This description holds several fields that could be useful for frontend
dashboards when dispatching a task, to then be identified or rendered
accordingly back on the same frontend.
"""

task_definition_id: str
unix_millis_warn_time: Optional[int]
pickup: Optional[str]
destination: Optional[str]
cart_id: Optional[str]

@staticmethod
def from_json_string(json_str: str) -> Optional["TaskBookingLabelDescription"]:
try:
return TaskBookingLabelDescription.parse_raw(json_str)
except pydantic.error_wrappers.ValidationError:
return None


class TaskBookingLabel(BaseModel):
"""
Expand All @@ -36,7 +12,7 @@ class TaskBookingLabel(BaseModel):
needed for any frontends.
"""

description: TaskBookingLabelDescription
description: dict[str, str | int | float]

@staticmethod
def from_json_string(json_str: str) -> Optional["TaskBookingLabel"]:
Expand Down
Loading

0 comments on commit d39a031

Please sign in to comment.