Skip to content

Commit

Permalink
Merge pull request #18668 from davelopez/improve_accept_header_schema
Browse files Browse the repository at this point in the history
Improve accept header API schema
  • Loading branch information
mvdbeek authored Aug 9, 2024
2 parents 0d1f74e + aa33d29 commit 6d291a9
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 26 deletions.
13 changes: 9 additions & 4 deletions client/src/api/schema/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18035,6 +18035,8 @@ export interface operations {
order?: string | null;
};
header?: {
/** @description Accept header to determine the response format. Default is 'application/json'. */
accept?: "application/json" | "application/vnd.galaxy.history.contents.stats+json";
/** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */
"run-as"?: string | null;
};
Expand Down Expand Up @@ -19094,6 +19096,8 @@ export interface operations {
order?: string | null;
};
header?: {
/** @description Accept header to determine the response format. Default is 'application/json'. */
accept?: "application/json" | "application/vnd.galaxy.history.contents.stats+json";
/** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */
"run-as"?: string | null;
};
Expand All @@ -19105,12 +19109,11 @@ export interface operations {
};
};
responses: {
/** @description Successful Response */
/** @description The contents of the history that match the query. */
200: {
content: {
"application/json":
| components["schemas"]["HistoryContentsResult"]
| components["schemas"]["HistoryContentsWithStatsResult"];
"application/json": components["schemas"]["HistoryContentsResult"];
"application/vnd.galaxy.history.contents.stats+json": components["schemas"]["HistoryContentsWithStatsResult"];
};
};
/** @description Request Error */
Expand Down Expand Up @@ -19686,6 +19689,8 @@ export interface operations {
offset?: number | null;
};
header?: {
/** @description Accept header to determine the response format. Default is 'application/json'. */
accept?: "application/json" | "application/vnd.galaxy.task.export+json";
/** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */
"run-as"?: string | null;
};
Expand Down
12 changes: 12 additions & 0 deletions lib/galaxy/schema/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,15 @@ def ModelClassField(default_value):
description="The name of the database model class.",
json_schema_extra={"const": literal_to_value(default_value), "type": "string"},
)


def accept_wildcard_defaults_to_json(v):
assert isinstance(v, str)
# Accept header can have multiple comma separated values.
# If any of these values is the wildcard - we default to application/json.
if "*/*" in v:
return "application/json"
return v


AcceptHeaderValidator = BeforeValidator(accept_wildcard_defaults_to_json)
18 changes: 16 additions & 2 deletions lib/galaxy/webapps/galaxy/api/histories.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from typing import (
Any,
List,
Literal,
Optional,
Union,
)
Expand All @@ -33,7 +34,10 @@
FilterQueryParams,
SerializationParams,
)
from galaxy.schema.fields import DecodedDatabaseIdField
from galaxy.schema.fields import (
AcceptHeaderValidator,
DecodedDatabaseIdField,
)
from galaxy.schema.history import (
HistoryIndexQueryPayload,
HistorySortByEnum,
Expand Down Expand Up @@ -163,6 +167,16 @@ class CreateHistoryFormData(CreateHistoryPayload):
"""Uses Form data instead of JSON"""


IndexExportsAcceptHeader = Annotated[
Literal[
"application/json",
"application/vnd.galaxy.task.export+json",
],
AcceptHeaderValidator,
Header(description="Accept header to determine the response format. Default is 'application/json'."),
]


@router.cbv
class FastAPIHistories:
service: HistoriesService = depends(HistoriesService)
Expand Down Expand Up @@ -516,7 +530,7 @@ def index_exports(
trans: ProvidesHistoryContext = DependsOnTrans,
limit: Optional[int] = LimitQueryParam,
offset: Optional[int] = OffsetQueryParam,
accept: str = Header(default="application/json", include_in_schema=False),
accept: IndexExportsAcceptHeader = "application/json",
) -> Union[JobExportHistoryArchiveListResponse, ExportTaskListResponse]:
"""
By default the legacy job-based history exports (jeha) are returned.
Expand Down
56 changes: 36 additions & 20 deletions lib/galaxy/webapps/galaxy/api/history_contents.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import logging
from typing import (
List,
Literal,
Optional,
Union,
)
Expand All @@ -22,6 +23,7 @@
Response,
StreamingResponse,
)
from typing_extensions import Annotated

from galaxy import util
from galaxy.managers.context import ProvidesHistoryContext
Expand All @@ -30,7 +32,10 @@
SerializationParams,
ValueFilterQueryParams,
)
from galaxy.schema.fields import DecodedDatabaseIdField
from galaxy.schema.fields import (
AcceptHeaderValidator,
DecodedDatabaseIdField,
)
from galaxy.schema.schema import (
AnyHistoryContentItem,
AnyJobStateSummary,
Expand Down Expand Up @@ -374,13 +379,40 @@ def parse_index_jobs_summary_params(
return HistoryContentsIndexJobsSummaryParams(ids=util.listify(ids), types=util.listify(types))


HistoryIndexAcceptContentTypes = Annotated[
Literal[
"application/json",
"application/vnd.galaxy.history.contents.stats+json",
],
AcceptHeaderValidator,
Header(description="Accept header to determine the response format. Default is 'application/json'."),
]

HistoryIndexResponsesSchema = {
200: {
"description": ("The contents of the history that match the query."),
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/HistoryContentsResult"}, # HistoryContentsResult.schema(),
},
HistoryContentsWithStatsResult.__accept_type__: {
"schema": { # HistoryContentsWithStatsResult.schema(),
"$ref": "#/components/schemas/HistoryContentsWithStatsResult"
},
},
},
},
}


@router.cbv
class FastAPIHistoryContents:
service: HistoriesContentsService = depends(HistoriesContentsService)

@router.get(
"/api/histories/{history_id}/contents/{type}s",
summary="Returns the contents of the given history filtered by type.",
responses=HistoryIndexResponsesSchema,
operation_id="history_contents__index_typed",
response_model_exclude_unset=True,
)
Expand All @@ -393,7 +425,7 @@ def index_typed(
legacy_params: LegacyHistoryContentsIndexParams = Depends(get_legacy_index_query_params),
serialization_params: SerializationParams = Depends(query_serialization_params),
filter_query_params: FilterQueryParams = Depends(get_filter_query_params),
accept: str = Header(default="application/json", include_in_schema=False),
accept: HistoryIndexAcceptContentTypes = "application/json",
) -> Union[HistoryContentsResult, HistoryContentsWithStatsResult]:
"""
Return a list of either `HDA`/`HDCA` data for the history with the given ``ID``.
Expand All @@ -419,23 +451,7 @@ def index_typed(
"/api/histories/{history_id}/contents",
name="history_contents",
summary="Returns the contents of the given history.",
responses={
200: {
"description": ("The contents of the history that match the query."),
"content": {
"application/json": {
"schema": { # HistoryContentsResult.schema(),
"$ref": "#/components/schemas/HistoryContentsResult"
},
},
HistoryContentsWithStatsResult.__accept_type__: {
"schema": { # HistoryContentsWithStatsResult.schema(),
"$ref": "#/components/schemas/HistoryContentsWithStatsResult"
},
},
},
},
},
responses=HistoryIndexResponsesSchema,
operation_id="history_contents__index",
response_model_exclude_unset=True,
)
Expand All @@ -448,7 +464,7 @@ def index(
legacy_params: LegacyHistoryContentsIndexParams = Depends(get_legacy_index_query_params),
serialization_params: SerializationParams = Depends(query_serialization_params),
filter_query_params: FilterQueryParams = Depends(get_filter_query_params),
accept: str = Header(default="application/json", include_in_schema=False),
accept: HistoryIndexAcceptContentTypes = "application/json",
) -> Union[HistoryContentsResult, HistoryContentsWithStatsResult]:
"""
Return a list of `HDA`/`HDCA` data for the history with the given ``ID``.
Expand Down

0 comments on commit 6d291a9

Please sign in to comment.