1# =====================================================
2# Imports
3# =====================================================
4from typing import Annotated
5from xml.etree import cElementTree as et
6
7import numpy as np
8import pandas as pd
9from pydantic import Field, field_validator
10
11from mt_metadata import __version__
12from mt_metadata.base import MetadataBase
13from mt_metadata.base.helpers import dict_to_xml, element_to_string
14from mt_metadata.common import Person
15from mt_metadata.common.mttime import MTime
16from mt_metadata.transfer_functions.io.emtfxml.metadata import helpers
17
18
19# =====================================================
20class Provenance(MetadataBase):
21 create_time: Annotated[
22 MTime | str | float | int | np.datetime64 | pd.Timestamp,
23 Field(
24 default_factory=lambda: MTime(time_stamp=None),
25 description="date and time the file was created",
26 alias=None,
27 json_schema_extra={
28 "units": None,
29 "required": True,
30 "examples": ["2020-02-08T12:23:40.324600+00:00"],
31 },
32 ),
33 ]
34
35 creating_application: Annotated[
36 str,
37 Field(
38 default="mt_metadata",
39 description="name of the application that created the XML file",
40 alias=None,
41 json_schema_extra={
42 "units": None,
43 "required": True,
44 "examples": ["EMTF File Conversion Utilities 4.0"],
45 },
46 ),
47 ]
48
49 creator: Annotated[
50 Person,
51 Field(
52 default_factory=Person, # type: ignore
53 description="Person or group responsible for creating the data",
54 alias=None,
55 json_schema_extra={
56 "units": None,
57 "required": True,
58 "examples": ["Person(name='John Doe', email='john.doe@example.com')"],
59 },
60 ),
61 ]
62 submitter: Annotated[
63 Person,
64 Field(
65 default_factory=Person, # type: ignore
66 description="Person or group responsible for submitting the data",
67 alias=None,
68 json_schema_extra={
69 "units": None,
70 "required": True,
71 "examples": [
72 "Person(name='Jane Smith', email='jane.smith@example.com')"
73 ],
74 },
75 ),
76 ]
77
78 @field_validator("create_time", mode="before")
79 @classmethod
80 def validate_create_time(
81 cls, field_value: MTime | float | int | np.datetime64 | pd.Timestamp | str
82 ):
83 if isinstance(field_value, MTime):
84 return field_value
85 return MTime(time_stamp=field_value)
86
87 def read_dict(self, input_dict: dict) -> None:
88 """
89 Read the Provenance object from a dictionary.
90
91 Parameters
92 ----------
93 input_dict : dict
94 The input dictionary containing the Provenance data.
95 """
96 helpers._read_element(self, input_dict, "provenance")
97
98 def to_xml(self, string: bool = False, required: bool = True) -> str | et.Element:
99 """
100 Convert the Provenance object to XML format.
101
102 Parameters
103 ----------
104 string : bool, optional
105 Whether to return the XML as a string, by default False
106 required : bool, optional
107 Whether all required fields must be present, by default True
108
109 Returns
110 -------
111 str | et.Element
112 The XML representation of the Provenance object
113 """
114
115 self.creating_application = f"mt_metadata {__version__}"
116 self.create_time = MTime(time_stamp=None).now()
117
118 element = dict_to_xml(self.to_dict(nested=True, required=required))
119 if not string:
120 return element
121 else:
122 return element_to_string(element)