diff --git a/src/fmu/dataio/_metadata.py b/src/fmu/dataio/_metadata.py index bb390c972..58364c558 100644 --- a/src/fmu/dataio/_metadata.py +++ b/src/fmu/dataio/_metadata.py @@ -11,7 +11,7 @@ from ._definitions import SCHEMA, SOURCE, VERSION from ._logging import null_logger -from ._model import fields, internal +from ._model import fields, schema from .exceptions import InvalidMetadataError from .providers._filedata import FileDataProvider from .providers.objectdata._provider import objectdata_provider_factory @@ -42,7 +42,7 @@ def _get_meta_filedata( ).get_metadata() -def _get_meta_fmu(fmudata: FmuProvider) -> internal.FMUClassMetaData | None: +def _get_meta_fmu(fmudata: FmuProvider) -> schema.InternalFMU | None: try: return fmudata.get_metadata() except InvalidMetadataError: @@ -77,7 +77,7 @@ def generate_export_metadata( dataio: ExportData, fmudata: FmuProvider | None = None, compute_md5: bool = True, -) -> internal.DataClassMeta: +) -> schema.InternalObjectMetadata: """ Main function to generate the full metadata @@ -108,7 +108,7 @@ def generate_export_metadata( objdata = objectdata_provider_factory(obj, dataio) masterdata = dataio.config.get("masterdata") - return internal.DataClassMeta( + return schema.InternalObjectMetadata( schema_=TypeAdapter(AnyHttpUrl).validate_strings(SCHEMA), # type: ignore[call-arg] version=VERSION, source=SOURCE, diff --git a/src/fmu/dataio/_model/internal.py b/src/fmu/dataio/_model/schema.py similarity index 89% rename from src/fmu/dataio/_model/internal.py rename to src/fmu/dataio/_model/schema.py index 649d54f4a..b95ec2c68 100644 --- a/src/fmu/dataio/_model/internal.py +++ b/src/fmu/dataio/_model/schema.py @@ -1,5 +1,5 @@ """ -This module, `datastructure._internal`, contains internal data structures that +This module, `_model.schema`, 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 @@ -108,21 +108,16 @@ class JsonSchemaMetadata(BaseModel, populate_by_name=True): source: str = Field(default=SOURCE) -class FMUModelCase(BaseModel): - model: fields.Model - case: fields.Case - - class Context(BaseModel, use_enum_values=True): stage: enums.FMUContext # Remove the two models below when content is required as input. -class UnsetContent(data.Data): +class InternalUnsetData(data.Data): content: Literal["unset"] # type: ignore @model_validator(mode="after") - def _deprecation_warning(self) -> UnsetContent: + def _deprecation_warning(self) -> InternalUnsetData: valid_contents = [m.value for m in enums.Content] warnings.warn( "The is not provided which will produce invalid metadata. " @@ -134,18 +129,18 @@ def _deprecation_warning(self) -> UnsetContent: return self -class UnsetAnyContent(data.AnyData): - root: UnsetContent # type: ignore +class InternalAnyData(data.AnyData): + root: InternalUnsetData # type: ignore -class FMUClassMetaData(fields.FMU): +class InternalFMU(fields.FMU): # This class is identical to the one used in the schema # exept for more fmu context values beeing allowed internally context: Context # type: ignore -class DataClassMeta(JsonSchemaMetadata): - # TODO: aim to use meta.FMUDataClassMeta as base +class InternalObjectMetadata(JsonSchemaMetadata): + # TODO: aim to use root.ObjectMetadata as base # class and disallow creating invalid metadata. class_: Literal[ enums.FMUClass.surface, @@ -158,20 +153,20 @@ class DataClassMeta(JsonSchemaMetadata): enums.FMUClass.points, enums.FMUClass.dictionary, ] = Field(alias="class") - fmu: Optional[FMUClassMetaData] + fmu: Optional[InternalFMU] masterdata: Optional[fields.Masterdata] access: Optional[fields.SsdlAccess] - data: Union[data.AnyData, UnsetAnyContent] + data: Union[data.AnyData, InternalAnyData] file: fields.File display: fields.Display tracklog: fields.Tracklog preprocessed: Optional[bool] = Field(alias="_preprocessed", default=None) -class CaseSchema(JsonSchemaMetadata): +class InternalCaseMetadata(JsonSchemaMetadata): class_: Literal["case"] = Field(alias="class", default="case") masterdata: fields.Masterdata access: fields.Access - fmu: FMUModelCase + fmu: fields.FMUBase description: Optional[List[str]] = Field(default=None) tracklog: fields.Tracklog diff --git a/src/fmu/dataio/aggregation.py b/src/fmu/dataio/aggregation.py index f853cae5a..56bca216b 100644 --- a/src/fmu/dataio/aggregation.py +++ b/src/fmu/dataio/aggregation.py @@ -12,7 +12,7 @@ from . import _utils, dataio, types from ._logging import null_logger -from ._model import internal +from ._model import schema from ._model.enums import FMUContext from .exceptions import InvalidMetadataError from .providers.objectdata._provider import objectdata_provider_factory @@ -65,7 +65,7 @@ class AggregatedData: tagname: str = "" verbosity: str = "DEPRECATED" # keep for while - _metadata: internal.DataClassMeta = field(init=False) + _metadata: schema.InternalObjectMetadata = field(init=False) _metafile: Path = field(default_factory=Path, init=False) def __post_init__(self) -> None: @@ -274,7 +274,7 @@ def _set_metadata( template["data"]["bbox"] = bbox try: - self._metadata = internal.DataClassMeta.model_validate(template) + self._metadata = schema.InternalObjectMetadata.model_validate(template) except ValidationError as err: raise InvalidMetadataError( f"The existing metadata for the aggregated data is invalid. " diff --git a/src/fmu/dataio/case.py b/src/fmu/dataio/case.py index bee65f075..5251be398 100644 --- a/src/fmu/dataio/case.py +++ b/src/fmu/dataio/case.py @@ -13,7 +13,7 @@ from . import _utils from ._logging import null_logger -from ._model import global_configuration, internal +from ._model import global_configuration, schema from ._model.fields import Access, Case, Masterdata, Model, User logger: Final = null_logger(__name__) @@ -118,10 +118,10 @@ def generate_metadata(self) -> dict: warnings.warn(exists_warning, UserWarning) return {} - self._metadata = internal.CaseSchema( + self._metadata = schema.InternalCaseMetadata( masterdata=Masterdata.model_validate(self.config["masterdata"]), access=Access.model_validate(self.config["access"]), - fmu=internal.FMUModelCase( + fmu=fields.FMUBase( model=Model.model_validate( self.config["model"], ), diff --git a/src/fmu/dataio/preprocessed.py b/src/fmu/dataio/preprocessed.py index 2a3909f17..b1151d085 100644 --- a/src/fmu/dataio/preprocessed.py +++ b/src/fmu/dataio/preprocessed.py @@ -10,7 +10,7 @@ from pydantic import ValidationError from ._logging import null_logger -from ._model import enums, internal +from ._model import enums, schema from ._model.enums import FMUContext from ._model.fields import File from ._utils import export_metadata_file, md5sum @@ -186,7 +186,9 @@ def _get_updated_metadata(self, meta_existing: dict, objfile: Path) -> dict: try: # TODO: Would like to use meta.Root.model_validate() here # but then the '$schema' field is dropped from the meta_existing - validated_metadata = internal.DataClassMeta.model_validate(meta_existing) + validated_metadata = schema.InternalObjectMetadata.model_validate( + meta_existing + ) validated_metadata.tracklog.extend(enums.TrackLogEventType.merged) return validated_metadata.model_dump( mode="json", exclude_none=True, by_alias=True diff --git a/src/fmu/dataio/providers/_fmu.py b/src/fmu/dataio/providers/_fmu.py index 9af48bd51..460cf1607 100644 --- a/src/fmu/dataio/providers/_fmu.py +++ b/src/fmu/dataio/providers/_fmu.py @@ -39,7 +39,7 @@ from fmu.config import utilities as ut from fmu.dataio import _utils from fmu.dataio._logging import null_logger -from fmu.dataio._model import fields, internal +from fmu.dataio._model import fields, schema from fmu.dataio._model.enums import FMUContext from fmu.dataio.exceptions import InvalidMetadataError @@ -165,7 +165,7 @@ def get_runpath(self) -> Path | None: """Return runpath for a FMU run.""" return self._runpath - def get_metadata(self) -> internal.FMUClassMetaData: + def get_metadata(self) -> schema.InternalFMU: """Construct the metadata FMU block for an ERT forward job.""" logger.debug("Generate ERT metadata...") @@ -175,7 +175,7 @@ def get_metadata(self) -> internal.FMUClassMetaData: case_meta = self._get_case_meta() if self.fmu_context != FMUContext.realization: - return internal.FMUClassMetaData( + return schema.InternalFMU( case=case_meta.fmu.case, context=self._get_fmucontext_meta(), model=self._get_fmumodel_meta() if self.model else case_meta.fmu.model, @@ -186,7 +186,7 @@ def get_metadata(self) -> internal.FMUClassMetaData: iter_uuid, real_uuid = self._get_iteration_and_real_uuid( case_meta.fmu.case.uuid ) - return internal.FMUClassMetaData( + return schema.InternalFMU( case=case_meta.fmu.case, context=self._get_fmucontext_meta(), model=self._get_fmumodel_meta() if self.model else case_meta.fmu.model, @@ -262,7 +262,7 @@ def _get_restart_data_uuid(self) -> UUID | None: ) return None - restart_metadata = internal.CaseSchema.model_validate( + restart_metadata = schema.InternalCaseMetadata.model_validate( ut.yaml_load(restart_case_metafile, loader="standard") ) return _utils.uuid_from_string( @@ -288,12 +288,12 @@ def _get_iteration_and_real_uuid(self, case_uuid: UUID) -> tuple[UUID, UUID]: real_uuid = _utils.uuid_from_string(f"{case_uuid}{iter_uuid}{self._real_id}") return iter_uuid, real_uuid - def _get_case_meta(self) -> internal.CaseSchema: + def _get_case_meta(self) -> schema.InternalCaseMetadata: """Parse and validate the CASE metadata.""" logger.debug("Loading case metadata file and return pydantic case model") assert self._casepath is not None case_metafile = self._casepath / ERT_RELATIVE_CASE_METADATA_FILE - return internal.CaseSchema.model_validate( + return schema.InternalCaseMetadata.model_validate( ut.yaml_load(case_metafile, loader="standard") ) @@ -315,8 +315,8 @@ def _get_iteration_meta(self, iter_uuid: UUID) -> fields.Iteration: else None, ) - def _get_fmucontext_meta(self) -> internal.Context: - return internal.Context(stage=self.fmu_context) + def _get_fmucontext_meta(self) -> schema.Context: + return schema.Context(stage=self.fmu_context) def _get_fmumodel_meta(self) -> fields.Model: return fields.Model.model_validate(self.model) diff --git a/src/fmu/dataio/providers/objectdata/_base.py b/src/fmu/dataio/providers/objectdata/_base.py index 5d9b48a9a..4bf6c09af 100644 --- a/src/fmu/dataio/providers/objectdata/_base.py +++ b/src/fmu/dataio/providers/objectdata/_base.py @@ -15,7 +15,7 @@ Timestamp, ) from fmu.dataio._model.enums import Content -from fmu.dataio._model.internal import AllowedContent, UnsetAnyContent +from fmu.dataio._model.schema import AllowedContent, InternalAnyData from fmu.dataio._utils import generate_description from fmu.dataio.providers._base import Provider @@ -65,7 +65,7 @@ class ObjectDataProvider(Provider): # result properties; the most important is metadata which IS the 'data' part in # the resulting metadata. But other variables needed later are also given # as instance properties in addition (for simplicity in other classes/functions) - _metadata: AnyData | UnsetAnyContent | None = field(default=None) + _metadata: AnyData | InternalAnyData | None = field(default=None) name: str = field(default="") time0: datetime | None = field(default=None) time1: datetime | None = field(default=None) @@ -118,7 +118,7 @@ def __post_init__(self) -> None: metadata["description"] = generate_description(self.dataio.description) self._metadata = ( - UnsetAnyContent.model_validate(metadata) + InternalAnyData.model_validate(metadata) if metadata["content"] == "unset" else AnyData.model_validate(metadata) ) @@ -166,7 +166,7 @@ def get_bbox(self) -> BoundingBox2D | BoundingBox3D | None: def get_spec(self) -> AnySpecification | None: raise NotImplementedError - def get_metadata(self) -> AnyData | UnsetAnyContent: + def get_metadata(self) -> AnyData | InternalAnyData: assert self._metadata is not None return self._metadata