Merge pull request #15105 from mvdbeek/model_class_fix

Fix ``model_class`` field annotations
This commit is contained in:
Marius van den Beek
2022-12-06 11:50:42 +01:00
committed by GitHub
5 changed files with 86 additions and 85 deletions
+3 -12
View File
@@ -18,12 +18,7 @@ from galaxy.structured_app import MinimalManagerApp
log = logging.getLogger(__name__)
def datetime_to_iso8601(utc_datetime: datetime) -> str:
"""
Returns the date as string with ISO8601 format.
i.e: 2021-01-23T18:25:43.511Z
"""
return f"{utc_datetime.isoformat()}Z"
SOME_EXAMPLE_DATE = "2021-01-23T18:25:43.511Z"
class Metric(BaseModel):
@@ -36,7 +31,7 @@ class Metric(BaseModel):
..., # Required
title="Timestamp",
description="The timestamp in ISO format.",
example=datetime_to_iso8601(datetime.utcnow()),
example=SOME_EXAMPLE_DATE,
)
level: int = Field(
..., # Required
@@ -54,11 +49,7 @@ class CreateMetricsPayload(BaseModel):
metrics: List[Metric] = Field(
default=[],
title="List of metrics to be recorded.",
example=[
Metric(
namespace="test-source", time=datetime_to_iso8601(datetime.utcnow()), level=0, args='{"test":"value"}'
)
],
example=[Metric(namespace="test-source", time=SOME_EXAMPLE_DATE, level=0, args='{"test":"value"}')],
)
+12 -8
View File
@@ -5,6 +5,10 @@ from typing import (
)
from pydantic import Field
from typing_extensions import (
Annotated,
Literal,
)
from galaxy.schema.fields import (
DecodedDatabaseIdField,
@@ -16,10 +20,10 @@ from galaxy.schema.schema import (
UserModel,
)
QUOTA_MODEL_CLASS_NAME = "Quota"
USER_QUOTA_ASSOCIATION_MODEL_CLASS_NAME = "UserQuotaAssociation"
GROUP_QUOTA_ASSOCIATION_MODEL_CLASS_NAME = "GroupQuotaAssociation"
DEFAULT_QUOTA_ASSOCIATION_MODEL_CLASS_NAME = "DefaultQuotaAssociation"
QUOTA = Literal["Quota"]
USER_QUOTA_ASSOCIATION = Literal["UserQuotaAssociation"]
GROUP_QUOTA_ASSOCIATION = Literal["GroupQuotaAssociation"]
DEFAULT_QUOTA_ASSOCIATION = Literal["DefaultQuotaAssociation"]
class QuotaOperation(str, Enum):
@@ -66,7 +70,7 @@ QuotaOperationField = Field(
class DefaultQuota(Model): # TODO: should this replace lib.galaxy.model.DefaultQuotaAssociation at some point?
model_class: str = ModelClassField(DEFAULT_QUOTA_ASSOCIATION_MODEL_CLASS_NAME)
model_class: Annotated[DEFAULT_QUOTA_ASSOCIATION, ModelClassField()]
type: DefaultQuotaTypes = Field(
...,
title="Type",
@@ -79,7 +83,7 @@ class DefaultQuota(Model): # TODO: should this replace lib.galaxy.model.Default
class UserQuota(Model):
model_class: str = ModelClassField(USER_QUOTA_ASSOCIATION_MODEL_CLASS_NAME)
model_class: Annotated[USER_QUOTA_ASSOCIATION, ModelClassField()]
user: UserModel = Field(
...,
title="User",
@@ -88,7 +92,7 @@ class UserQuota(Model):
class GroupQuota(Model):
model_class: str = ModelClassField(GROUP_QUOTA_ASSOCIATION_MODEL_CLASS_NAME)
model_class: Annotated[GROUP_QUOTA_ASSOCIATION, ModelClassField()]
group: GroupModel = Field(
...,
title="Group",
@@ -99,7 +103,7 @@ class GroupQuota(Model):
class QuotaBase(Model):
"""Base model containing common fields for Quotas."""
model_class: str = ModelClassField(QUOTA_MODEL_CLASS_NAME)
model_class: Annotated[QUOTA, ModelClassField()]
id: DecodedDatabaseIdField = Field(
...,
title="ID",
+1 -3
View File
@@ -94,15 +94,13 @@ class EncodedDatabaseIdField(str, BaseDatabaseIdField):
return cls.security.decode_id(v)
def ModelClassField(class_name: str) -> str:
def ModelClassField():
"""Represents a database model class name annotated as a constant
pydantic Field.
:param class_name: The name of the database class.
:return: A constant pydantic Field with default annotations for model classes.
"""
return Field(
class_name,
title="Model class",
description="The name of the database model class.",
const=True, # Make this field constant
)
+65 -61
View File
@@ -50,15 +50,16 @@ from galaxy.schema.types import (
RelativeUrl,
)
USER_MODEL_CLASS_NAME = "User"
GROUP_MODEL_CLASS_NAME = "Group"
HDA_MODEL_CLASS_NAME = "HistoryDatasetAssociation"
DC_MODEL_CLASS_NAME = "DatasetCollection"
DCE_MODEL_CLASS_NAME = "DatasetCollectionElement"
HDCA_MODEL_CLASS_NAME = "HistoryDatasetCollectionAssociation"
HISTORY_MODEL_CLASS_NAME = "History"
JOB_MODEL_CLASS_NAME = "Job"
STORED_WORKFLOW_MODEL_CLASS_NAME = "StoredWorkflow"
USER_MODEL_CLASS = Literal["User"]
GROUP_MODEL_CLASS = Literal["Group"]
HDA_MODEL_CLASS = Literal["HistoryDatasetAssociation"]
DC_MODEL_CLASS = Literal["DatasetCollection"]
DCE_MODEL_CLASS = Literal["DatasetCollectionElement"]
HDCA_MODEL_CLASS = Literal["HistoryDatasetCollectionAssociation"]
HISTORY_MODEL_CLASS = Literal["History"]
JOB_MODEL_CLASS = Literal["Job"]
STORED_WORKFLOW_MODEL_CLASS = Literal["StoredWorkflow"]
PAGE_MODEL_CLASS = Literal["Page"]
# Generic and common Field annotations that can be reused across models
@@ -204,13 +205,13 @@ class UserModel(Model):
active: bool = Field(title="Active", description="User is active")
deleted: bool = Field(title="Deleted", description="User is deleted")
last_password_change: Optional[datetime] = Field(title="Last password change", description="")
model_class: str = ModelClassField(USER_MODEL_CLASS_NAME)
model_class: Annotated[USER_MODEL_CLASS, ModelClassField()]
class GroupModel(Model):
"""User group model"""
model_class: str = ModelClassField(GROUP_MODEL_CLASS_NAME)
model_class: Annotated[GROUP_MODEL_CLASS, ModelClassField()]
id: DecodedDatabaseIdField = Field(
..., # Required
title="ID",
@@ -448,7 +449,7 @@ HdaLddaField = Field(
class HDADetailed(HDASummary):
"""History Dataset Association detailed information."""
model_class: str = ModelClassField(HDA_MODEL_CLASS_NAME)
model_class: Annotated[HDA_MODEL_CLASS, ModelClassField()]
hda_ldda: DatasetSourceType = HdaLddaField
accessible: bool = AccessibleField
genome_build: Optional[str] = GenomeBuildField
@@ -557,19 +558,21 @@ class HDADetailed(HDASummary):
)
annotation: Optional[str] = AnnotationField
download_url: RelativeUrl = DownloadUrlField
type: str = Field(
"file",
const=True,
title="Type",
description="This is always `file` for datasets.",
)
api_type: str = Field(
"file",
const=True,
title="API Type",
description="TODO",
deprecated=False, # TODO: Should this field be deprecated as announced in release 16.04?
)
type: Annotated[
Literal["file"],
Field(
title="Type",
description="This is always `file` for datasets.",
),
] = "file"
api_type: Annotated[
Literal["file"],
Field(
title="API Type",
description="TODO",
deprecated=False, # TODO: Should this field be deprecated as announced in release 16.04?
),
] = "file"
created_from_basename: Optional[str] = Field(
None,
title="Created from basename",
@@ -600,7 +603,7 @@ class HDAExtended(HDADetailed):
class DCSummary(Model):
"""Dataset Collection summary information."""
model_class: str = ModelClassField(DC_MODEL_CLASS_NAME)
model_class: Annotated[DC_MODEL_CLASS, ModelClassField()]
id: DecodedDatabaseIdField = EntityIdField
create_time: datetime = CreateTimeField
update_time: datetime = UpdateTimeField
@@ -614,7 +617,7 @@ class HDAObject(Model):
"""History Dataset Association Object"""
id: DecodedDatabaseIdField = EntityIdField
model_class: str = ModelClassField(HDA_MODEL_CLASS_NAME)
model_class: Annotated[HDA_MODEL_CLASS, ModelClassField()]
state: Dataset.states = DatasetStateField
hda_ldda: DatasetSourceType = HdaLddaField
history_id: DecodedDatabaseIdField = HistoryIdField
@@ -627,7 +630,7 @@ class DCObject(Model):
"""Dataset Collection Object"""
id: DecodedDatabaseIdField = EntityIdField
model_class: str = ModelClassField(DC_MODEL_CLASS_NAME)
model_class: Annotated[DC_MODEL_CLASS, ModelClassField()]
collection_type: CollectionType = CollectionTypeField
populated: Optional[bool] = PopulatedField
element_count: Optional[int] = ElementCountField
@@ -639,7 +642,7 @@ class DCESummary(Model):
"""Dataset Collection Element summary information."""
id: DecodedDatabaseIdField = EntityIdField
model_class: str = ModelClassField(DCE_MODEL_CLASS_NAME)
model_class: Annotated[DCE_MODEL_CLASS, ModelClassField()]
element_index: int = Field(
...,
title="Element Index",
@@ -745,15 +748,14 @@ class HDCJobStateSummary(Model):
class HDCASummary(HistoryItemCommon):
"""History Dataset Collection Association summary information."""
model_class: str = ModelClassField(
HDCA_MODEL_CLASS_NAME
) # TODO: inconsistency? HDASummary does not have model_class only the detailed view has it...
type: str = Field(
"collection",
const=True,
title="Type",
description="This is always `collection` for dataset collections.",
)
model_class: Annotated[HDCA_MODEL_CLASS, ModelClassField()]
type: Annotated[
Literal["collection"],
Field(
title="Type",
description="This is always `collection` for dataset collections.",
),
] = "collection"
collection_type: CollectionType = CollectionTypeField
populated_state: DatasetCollection.populated_states = PopulatedStateField
populated_state_message: Optional[str] = PopulatedStateMessageField
@@ -904,7 +906,7 @@ class UpdateHistoryContentsPayload(HistoryBase):
class HistorySummary(HistoryBase):
"""History summary information."""
model_class: str = ModelClassField(HISTORY_MODEL_CLASS_NAME)
model_class: Annotated[HISTORY_MODEL_CLASS, ModelClassField()]
id: DecodedDatabaseIdField = EntityIdField
name: str = Field(
...,
@@ -1467,7 +1469,7 @@ class JobIdResponse(Model):
class JobBaseModel(Model):
id: DecodedDatabaseIdField = EntityIdField
model_class: str = ModelClassField(JOB_MODEL_CLASS_NAME)
model_class: Annotated[JOB_MODEL_CLASS, ModelClassField()]
tool_id: str = Field(
...,
title="Tool ID",
@@ -1506,21 +1508,24 @@ class JobImportHistoryResponse(JobBaseModel):
)
class JobStateSummary(Model):
class ItemStateSummary(Model):
id: DecodedDatabaseIdField = EntityIdField
model: str = ModelClassField("Job")
populated_state: DatasetCollection.populated_states = PopulatedStateField
states: Dict[Job.states, int] = Field(
{}, title="States", description=("A dictionary of job states and the number of jobs in that state.")
)
class ImplicitCollectionJobsStateSummary(JobStateSummary):
model: str = ModelClassField("ImplicitCollectionJobs")
class JobStateSummary(ItemStateSummary):
model: Annotated[Literal["Job"], ModelClassField()]
class WorkflowInvocationStateSummary(JobStateSummary):
model: str = ModelClassField("WorkflowInvocation")
class ImplicitCollectionJobsStateSummary(ItemStateSummary):
model: Annotated[Literal["ImplicitCollectionJobs"], ModelClassField()]
class WorkflowInvocationStateSummary(ItemStateSummary):
model: Annotated[Literal["WorkflowInvocation"], ModelClassField()]
class JobSummary(JobBaseModel):
@@ -1687,7 +1692,7 @@ class JobFullDetails(JobDetails):
class StoredWorkflowSummary(Model):
id: DecodedDatabaseIdField = EntityIdField
model_class: str = ModelClassField(STORED_WORKFLOW_MODEL_CLASS_NAME)
model_class: Annotated[STORED_WORKFLOW_MODEL_CLASS, ModelClassField()]
create_time: datetime = CreateTimeField
update_time: datetime = UpdateTimeField
name: str = Field(
@@ -2176,7 +2181,7 @@ class BasicRoleModel(Model):
class RoleModel(BasicRoleModel):
description: Optional[str] = RoleDescriptionField
url: RelativeUrl = RelativeUrlField
model_class: str = ModelClassField("Role")
model_class: Annotated[Literal["Role"], ModelClassField()]
class RoleDefinitionModel(Model):
@@ -2252,7 +2257,7 @@ class InstalledRepositoryToolShedStatus(Model):
class InstalledToolShedRepository(Model):
model_class: str = ModelClassField("ToolShedRepository")
model_class: Annotated[Literal["ToolShedRepository"], ModelClassField()] = "ToolShedRepository"
id: EncodedDatabaseIdField = Field(
...,
title="ID",
@@ -2306,7 +2311,7 @@ class LibraryPermissionScope(str, Enum):
class LibraryLegacySummary(Model):
model_class: str = ModelClassField("Library")
model_class: Annotated[Literal["Library"], ModelClassField()]
id: DecodedDatabaseIdField = Field(
...,
title="ID",
@@ -2553,7 +2558,7 @@ class LibraryFolderPermissionsPayload(LibraryPermissionsPayloadBase):
class LibraryFolderDetails(Model):
model_class: str = ModelClassField("LibraryFolder")
model_class: Annotated[Literal["LibraryFolder"], ModelClassField()]
id: LibraryFolderDatabaseIdField = Field(
...,
title="ID",
@@ -2811,12 +2816,16 @@ AnyHistoryContentItem = Union[
]
AnyJobStateSummary = Union[
JobStateSummary,
ImplicitCollectionJobsStateSummary,
WorkflowInvocationStateSummary,
AnyJobStateSummary = Annotated[
Union[
JobStateSummary,
ImplicitCollectionJobsStateSummary,
WorkflowInvocationStateSummary,
],
Field(..., discriminator="model"),
]
HistoryArchiveExportResult = Union[JobExportHistoryArchiveModel, JobIdResponse]
@@ -3202,12 +3211,7 @@ class PageSummary(PageSummaryBase):
title="ID",
description="Encoded ID of the Page.",
)
model_class: str = Field(
..., # Required
title="Model class",
description="The class of the model associated with the ID.",
example="Page",
)
model_class: Annotated[PAGE_MODEL_CLASS, ModelClassField()]
username: str = Field(
..., # Required
title="Username",
@@ -12,6 +12,10 @@ from pydantic import (
Field,
ValidationError,
)
from typing_extensions import (
Annotated,
Literal,
)
from galaxy import exceptions
from galaxy.datatypes.registry import Registry
@@ -64,7 +68,7 @@ class DatasetCollectionAttributesResult(Model):
dbkey: str = Field(..., description="TODO")
# Are the following fields really used/needed?
extension: str = Field(..., description="The dataset file extension.", example="txt")
model_class: str = ModelClassField("HistoryDatasetCollectionAssociation")
model_class: Annotated[Literal["HistoryDatasetCollectionAssociation"], ModelClassField()]
dbkeys: Optional[Set[str]]
extensions: Optional[Set[str]]
tags: TagCollection