Skip to content

Commit

Permalink
Merge pull request #48 from hydroshare/47-annotate-optional-fields-as…
Browse files Browse the repository at this point in the history
…-optional

Annotate optional fields as Optional
  • Loading branch information
pkdash authored Apr 25, 2024
2 parents f9fc223 + d556113 commit 78a5c25
Show file tree
Hide file tree
Showing 9 changed files with 264 additions and 92 deletions.
73 changes: 51 additions & 22 deletions hsmodels/schemas/aggregations.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from datetime import date
from typing import Dict, List, Union
from typing import Dict, List, Optional, Union

from pydantic import AnyUrl, ConfigDict, Field, GetJsonSchemaHandler, model_validator, field_validator
from pydantic.json_schema import JsonSchemaValue
Expand Down Expand Up @@ -61,12 +61,12 @@ class BaseAggregationMetadataIn(BaseMetadata):
title="Additional metadata",
description="A dictionary of additional metadata elements expressed as key-value pairs",
)
spatial_coverage: Union[PointCoverage, BoxCoverage] = Field(
spatial_coverage: Optional[Union[PointCoverage, BoxCoverage]] = Field(
default=None,
title="Spatial coverage",
description="An object containing the geospatial coverage for the aggregation expressed as either a bounding box or point",
)
period_coverage: PeriodCoverage = Field(
period_coverage: Optional[PeriodCoverage] = Field(
default=None,
title="Temporal coverage",
description="An object containing the temporal coverage for a aggregation expressed as a date range",
Expand Down Expand Up @@ -116,6 +116,11 @@ class GeographicRasterMetadataIn(BaseAggregationMetadataIn):
title="Band information",
description="An object containing information about the bands contained in the raster dataset",
)
spatial_coverage: Union[PointCoverage, BoxCoverage] = Field(
default=None,
title="Spatial coverage",
description="An object containing the geospatial coverage for the aggregation expressed as either a bounding box or point",
)
spatial_reference: Union[BoxSpatialReference, PointSpatialReference] = Field(
default=None,
title="Spatial reference",
Expand All @@ -142,7 +147,7 @@ class GeographicRasterMetadata(GeographicRasterMetadataIn):
json_schema_extra={"readOnly": True},
)

rights: Rights = Field(
rights: Optional[Rights] = Field(
default=None,
title="Rights statement",
description="An object containing information about the rights held in and over the aggregation and the license under which a aggregation is shared",
Expand Down Expand Up @@ -171,6 +176,11 @@ class GeographicFeatureMetadataIn(BaseAggregationMetadataIn):
title="Geometry information",
description="An object containing information about the geometry of the features in the dataset",
)
spatial_coverage: Union[PointCoverage, BoxCoverage] = Field(
default=None,
title="Spatial coverage",
description="An object containing the geospatial coverage for the aggregation expressed as either a bounding box or point",
)
spatial_reference: Union[BoxSpatialReference, PointSpatialReference] = Field(
default=None,
title="Spatial reference",
Expand All @@ -194,7 +204,7 @@ class GeographicFeatureMetadata(GeographicFeatureMetadataIn):
json_schema_extra={"readOnly": True},
)

rights: Rights = Field(
rights: Optional[Rights] = Field(
default=None,
title="Rights statement",
description="An object containing information about the rights held in and over the aggregation and the license under which a aggregation is shared",
Expand All @@ -218,12 +228,21 @@ class MultidimensionalMetadataIn(BaseAggregationMetadataIn):
title="Variables",
description="A list containing information about the variables for which data are stored in the dataset",
)
spatial_coverage: Union[PointCoverage, BoxCoverage] = Field(
default=None,
title="Spatial coverage",
description="An object containing the geospatial coverage for the aggregation expressed as either a bounding box or point",
)
spatial_reference: Union[MultidimensionalBoxSpatialReference, MultidimensionalPointSpatialReference] = Field(
default=None,
title="Spatial reference",
description="An object containing spatial reference information for the dataset",
)

period_coverage: PeriodCoverage = Field(
default=None,
title="Temporal coverage",
description="An object containing the temporal coverage for a aggregation expressed as a date range",
)
_parse_spatial_reference = field_validator("spatial_reference", mode='before')(
parse_multidimensional_spatial_reference
)
Expand All @@ -243,7 +262,7 @@ class MultidimensionalMetadata(MultidimensionalMetadataIn):
json_schema_extra={"readOnly": True},
)

rights: Rights = Field(
rights: Optional[Rights] = Field(
default=None,
title="Rights statement",
description="An object containing information about the rights held in and over the aggregation and the license under which a aggregation is shared",
Expand Down Expand Up @@ -278,7 +297,7 @@ class ReferencedTimeSeriesMetadata(ReferencedTimeSeriesMetadataIn):
json_schema_extra={"readOnly": True},
)

rights: Rights = Field(
rights: Optional[Rights] = Field(
default=None,
title="Rights statement",
description="An object containing information about the rights held in and over the aggregation and the license under which a aggregation is shared",
Expand Down Expand Up @@ -313,7 +332,7 @@ class FileSetMetadata(FileSetMetadataIn):
json_schema_extra={"readOnly": True},
)

rights: Rights = Field(
rights: Optional[Rights] = Field(
default=None,
title="Rights statement",
description="An object containing information about the rights held in and over the aggregation and the license under which a aggregation is shared",
Expand Down Expand Up @@ -347,7 +366,7 @@ class SingleFileMetadata(SingleFileMetadataIn):
json_schema_extra={"readOnly": True},
)

rights: Rights = Field(
rights: Optional[Rights] = Field(
default=None,
title="Rights statement",
description="An object containing information about the rights held in and over the aggregation and the license under which a aggregation is shared",
Expand Down Expand Up @@ -375,7 +394,17 @@ class TimeSeriesMetadataIn(BaseAggregationMetadataIn):
description="A list of time series results contained within the time series aggregation",
)

abstract: str = Field(default=None, title="Abstract", description="A string containing a summary of a aggregation")
abstract: Optional[str] = Field(default=None, title="Abstract", description="A string containing a summary of a aggregation")
spatial_coverage: Union[PointCoverage, BoxCoverage] = Field(
default=None,
title="Spatial coverage",
description="An object containing the geospatial coverage for the aggregation expressed as either a bounding box or point",
)
period_coverage: PeriodCoverage = Field(
default=None,
title="Temporal coverage",
description="An object containing the temporal coverage for a aggregation expressed as a date range",
)

_parse_abstract = model_validator(mode='before')(parse_abstract)

Expand All @@ -394,7 +423,7 @@ class TimeSeriesMetadata(TimeSeriesMetadataIn):
json_schema_extra={"readOnly": True},
)

rights: Rights = Field(
rights: Optional[Rights] = Field(
default=None,
title="Rights statement",
description="An object containing information about the rights held in and over the aggregation and the license under which a aggregation is shared",
Expand All @@ -410,7 +439,7 @@ class ModelProgramMetadataIn(BaseAggregationMetadataIn):

model_config = ConfigDict(title="Model Program Aggregation Metadata")

version: str = Field(
version: Optional[str] = Field(
default=None, title="Version", description="The software version or build number of the model", max_length=255
)

Expand All @@ -428,17 +457,17 @@ class ModelProgramMetadataIn(BaseAggregationMetadataIn):
description="Compatible operating systems to setup and run the model",
)

release_date: date = Field(
release_date: Optional[date] = Field(
default=None, title="Release Date", description="The date that this version of the model was released"
)

website: AnyUrl = Field(
website: Optional[AnyUrl] = Field(
default=None,
title='Website',
description='A URL to a website describing the model that is maintained by the model developers',
)

code_repository: AnyUrl = Field(
code_repository: Optional[AnyUrl] = Field(
default=None,
title='Software Repository',
description='A URL to the source code repository for the model code (e.g., git, mercurial, svn, etc.)',
Expand All @@ -448,7 +477,7 @@ class ModelProgramMetadataIn(BaseAggregationMetadataIn):
default=[], title='File Types', description='File types used by the model program'
)

program_schema_json: AnyUrl = Field(
program_schema_json: Optional[AnyUrl] = Field(
default=None,
title='Model program schema',
description='A url to the JSON metadata schema for the model program',
Expand All @@ -471,7 +500,7 @@ class ModelProgramMetadata(ModelProgramMetadataIn):
json_schema_extra={"readOnly": True},
)

rights: Rights = Field(
rights: Optional[Rights] = Field(
default=None,
title="Rights statement",
description="An object containing information about the rights held in and over the aggregation and the license under which a aggregation is shared",
Expand All @@ -492,19 +521,19 @@ class ModelInstanceMetadataIn(BaseAggregationMetadataIn):
description="Indicates whether model output files are included in the aggregation",
)

executed_by: AnyUrl = Field(
executed_by: Optional[AnyUrl] = Field(
default=None,
title="Executed By",
description="A URL to the Model Program that can be used to execute this model instance",
)

program_schema_json: AnyUrl = Field(
program_schema_json: Optional[AnyUrl] = Field(
default=None,
title="JSON Metadata schema URL",
description="A URL to the JSON metadata schema for the related model program",
)

program_schema_json_values: AnyUrl = Field(
program_schema_json_values: Optional[AnyUrl] = Field(
default=None,
title="JSON metadata schema values URL",
description="A URL to a JSON file containing the metadata values conforming to the JSON metadata schema for the related model program",
Expand All @@ -525,7 +554,7 @@ class ModelInstanceMetadata(ModelInstanceMetadataIn):
json_schema_extra={"readOnly": True},
)

rights: Rights = Field(
rights: Optional[Rights] = Field(
default=None,
title="Rights statement",
description="An object containing information about the rights held in and over the aggregation and the license under which a aggregation is shared",
Expand Down
25 changes: 18 additions & 7 deletions hsmodels/schemas/base_models.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
from datetime import datetime
from typing import Any, Dict, Union
from typing import Any, Literal, Union

import typing_extensions
from pydantic import BaseModel, ConfigDict


class BaseMetadata(BaseModel):
def model_dump(
self,
*,
include: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None,
exclude: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None,
mode: Union[typing_extensions.Literal['json', 'python'], str] = 'python',
include: 'IncEx' = None,
exclude: 'IncEx' = None,
context: Union[dict[str, Any], None] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = True,
round_trip: bool = False,
warnings: bool = False,
warnings: Union[bool, Literal['none', 'warn', 'error']] = False,
serialize_as_any: bool = False,
to_rdf: bool = False,
) -> dict[str, Any]:
"""
Expand All @@ -28,14 +32,17 @@ def model_dump(
Override the default of exclude_none to True
"""
d = super().model_dump(
mode=mode,
include=include,
exclude=exclude,
context=context,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude_none=exclude_none,
round_trip=round_trip,
warnings=warnings,
serialize_as_any=serialize_as_any,
)
if to_rdf and "additional_metadata" in d:
additional_metadata = d["additional_metadata"]
Expand All @@ -47,14 +54,16 @@ def model_dump_json(
self,
*,
indent: Union[int, None] = None,
include: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None,
exclude: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None,
include: 'IncEx' = None,
exclude: 'IncEx' = None,
context: Union[dict[str, Any], None] = None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = True,
round_trip: bool = False,
warnings: bool = False,
warnings: Union[bool, Literal['none', 'warn', 'error']] = False,
serialize_as_any: bool = False,
) -> str:
"""
Generate a JSON representation of the model, `include` and `exclude` arguments as per `dict()`.
Expand All @@ -67,12 +76,14 @@ def model_dump_json(
indent=indent,
include=include,
exclude=exclude,
context=context,
by_alias=by_alias,
exclude_unset=exclude_unset,
exclude_defaults=exclude_defaults,
exclude_none=exclude_none,
round_trip=round_trip,
warnings=warnings,
serialize_as_any=serialize_as_any,
)

model_config = ConfigDict(validate_assignment=True)
Expand Down
Loading

0 comments on commit 78a5c25

Please sign in to comment.