-
Notifications
You must be signed in to change notification settings - Fork 15
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
MAINT: Refactor 'schema'/'internal' classes #962
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,32 @@ | ||
"""Module for DataIO metadata. | ||
""" | ||
This module contains models used to output the metadata that sit beside the exported | ||
data. | ||
|
||
This contains the _MetaData class which collects and holds all relevant metadata | ||
It contains internal data structures that are designed to depend on external modules, | ||
but not the other way around. This design ensures modularity and flexibility, allowing | ||
external modules to be potentially separated into their own repositories without | ||
dependencies on the internals. | ||
""" | ||
|
||
from __future__ import annotations | ||
|
||
from typing import TYPE_CHECKING, Final | ||
from typing import TYPE_CHECKING, Final, List, Literal, Optional, Union | ||
|
||
from pydantic import ( | ||
AnyHttpUrl, | ||
BaseModel, | ||
Field, | ||
) | ||
|
||
from ._logging import null_logger | ||
from ._model import fields, schema | ||
from ._model import data, fields | ||
from ._model.enums import FMUClass | ||
from ._model.global_configuration import GlobalConfiguration | ||
from ._model.product import Product | ||
from ._model.root import CaseMetadata, FmuResultsSchema, ObjectMetadata | ||
from .exceptions import InvalidMetadataError | ||
from .providers._filedata import FileDataProvider | ||
from .providers.objectdata._base import UnsetData | ||
from .providers.objectdata._provider import objectdata_provider_factory | ||
|
||
if TYPE_CHECKING: | ||
|
@@ -24,6 +38,38 @@ | |
logger: Final = null_logger(__name__) | ||
|
||
|
||
class JsonSchemaMetadata(BaseModel): | ||
"""Mixin to inject the $schema field into exported metadata.""" | ||
|
||
schema_: AnyHttpUrl = Field( | ||
default_factory=lambda: AnyHttpUrl(FmuResultsSchema.url()), | ||
alias="$schema", | ||
frozen=True, | ||
) | ||
|
||
|
||
class ObjectMetadataExport(JsonSchemaMetadata, ObjectMetadata, populate_by_name=True): | ||
"""Wraps the schema ObjectMetadata, adjusting some values to optional for pragmatic | ||
purposes when exporting metadata.""" | ||
|
||
# These type ignores are for making the field optional | ||
fmu: Optional[fields.FMU] # type: ignore | ||
access: Optional[fields.SsdlAccess] # type: ignore | ||
masterdata: Optional[fields.Masterdata] # type: ignore | ||
# !! Keep UnsetData first in this union | ||
data: Union[UnsetData, data.AnyData] # type: ignore | ||
preprocessed: Optional[bool] = Field(alias="_preprocessed", default=None) | ||
|
||
Comment on lines
+51
to
+61
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are no longer creating invalid metadata since version 2.6.0 #793. ➡️ hence we can soon drop the optional fields here: 💥 🙂 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't fully realize this... maybe we can have a chat about it |
||
|
||
class CaseMetadataExport(JsonSchemaMetadata, CaseMetadata, populate_by_name=True): | ||
"""Adds the optional description field for backward compatibility.""" | ||
|
||
class_: Literal[FMUClass.case] = Field( | ||
default=FMUClass.case, alias="class", title="metadata_class" | ||
) | ||
description: Optional[List[str]] = Field(default=None) | ||
|
||
|
||
def _get_meta_filedata( | ||
dataio: ExportData, | ||
obj: types.Inferrable, | ||
|
@@ -72,7 +118,7 @@ def generate_export_metadata( | |
dataio: ExportData, | ||
fmudata: FmuProvider | None = None, | ||
product: Product | None = None, | ||
) -> schema.InternalObjectMetadata: | ||
) -> ObjectMetadataExport: | ||
""" | ||
Main function to generate the full metadata | ||
|
||
|
@@ -102,7 +148,7 @@ def generate_export_metadata( | |
|
||
objdata = objectdata_provider_factory(obj, dataio, product) | ||
|
||
return schema.InternalObjectMetadata( # type: ignore[call-arg] | ||
return ObjectMetadataExport( # type: ignore[call-arg] | ||
class_=objdata.classname, | ||
fmu=_get_meta_fmu(fmudata) if fmudata else None, | ||
masterdata=( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought for a separate PR, could this be removed from here and used in the
_model.root
instead? 🙂Right now we have a mismatch between the
$schema
defined in the main schema and the "exported". That would take us one step closer to removing the need for a separate model for the exported metadata, I look forward to the day we can align them fully!There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it can't actually, this is a bit confusing:
It's confusing because our schema is getting validated by a 'worldwide' schema (validating that it's a valid schema), while our metadata is validated by our schema
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
annoying 😩 .. and confusing yes