Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#47] Annotate optional fields as Optional #48

Merged
merged 5 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading