esgvoc 0.3.0__py3-none-any.whl → 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of esgvoc might be problematic. Click here for more details.

Files changed (87) hide show
  1. esgvoc/__init__.py +1 -1
  2. esgvoc/api/__init__.py +95 -60
  3. esgvoc/api/data_descriptors/__init__.py +50 -28
  4. esgvoc/api/data_descriptors/activity.py +3 -3
  5. esgvoc/api/data_descriptors/area_label.py +16 -1
  6. esgvoc/api/data_descriptors/branded_suffix.py +20 -0
  7. esgvoc/api/data_descriptors/branded_variable.py +12 -0
  8. esgvoc/api/data_descriptors/consortium.py +14 -13
  9. esgvoc/api/data_descriptors/contact.py +5 -0
  10. esgvoc/api/data_descriptors/conventions.py +6 -0
  11. esgvoc/api/data_descriptors/creation_date.py +5 -0
  12. esgvoc/api/data_descriptors/data_descriptor.py +14 -9
  13. esgvoc/api/data_descriptors/data_specs_version.py +5 -0
  14. esgvoc/api/data_descriptors/date.py +1 -1
  15. esgvoc/api/data_descriptors/directory_date.py +1 -1
  16. esgvoc/api/data_descriptors/experiment.py +13 -11
  17. esgvoc/api/data_descriptors/forcing_index.py +1 -1
  18. esgvoc/api/data_descriptors/frequency.py +3 -3
  19. esgvoc/api/data_descriptors/further_info_url.py +5 -0
  20. esgvoc/api/data_descriptors/grid_label.py +2 -2
  21. esgvoc/api/data_descriptors/horizontal_label.py +15 -1
  22. esgvoc/api/data_descriptors/initialisation_index.py +1 -1
  23. esgvoc/api/data_descriptors/institution.py +8 -5
  24. esgvoc/api/data_descriptors/known_branded_variable.py +23 -0
  25. esgvoc/api/data_descriptors/license.py +3 -3
  26. esgvoc/api/data_descriptors/mip_era.py +1 -1
  27. esgvoc/api/data_descriptors/model_component.py +1 -1
  28. esgvoc/api/data_descriptors/obs_type.py +5 -0
  29. esgvoc/api/data_descriptors/organisation.py +1 -1
  30. esgvoc/api/data_descriptors/physic_index.py +1 -1
  31. esgvoc/api/data_descriptors/product.py +2 -2
  32. esgvoc/api/data_descriptors/publication_status.py +5 -0
  33. esgvoc/api/data_descriptors/realisation_index.py +1 -1
  34. esgvoc/api/data_descriptors/realm.py +1 -1
  35. esgvoc/api/data_descriptors/region.py +5 -0
  36. esgvoc/api/data_descriptors/resolution.py +3 -3
  37. esgvoc/api/data_descriptors/source.py +9 -5
  38. esgvoc/api/data_descriptors/source_type.py +1 -1
  39. esgvoc/api/data_descriptors/table.py +3 -2
  40. esgvoc/api/data_descriptors/temporal_label.py +15 -1
  41. esgvoc/api/data_descriptors/time_range.py +4 -3
  42. esgvoc/api/data_descriptors/title.py +5 -0
  43. esgvoc/api/data_descriptors/tracking_id.py +5 -0
  44. esgvoc/api/data_descriptors/variable.py +25 -12
  45. esgvoc/api/data_descriptors/variant_label.py +3 -3
  46. esgvoc/api/data_descriptors/vertical_label.py +14 -0
  47. esgvoc/api/project_specs.py +120 -4
  48. esgvoc/api/projects.py +733 -505
  49. esgvoc/api/py.typed +0 -0
  50. esgvoc/api/report.py +12 -8
  51. esgvoc/api/search.py +168 -98
  52. esgvoc/api/universe.py +368 -157
  53. esgvoc/apps/drs/constants.py +1 -1
  54. esgvoc/apps/drs/generator.py +51 -69
  55. esgvoc/apps/drs/report.py +60 -15
  56. esgvoc/apps/drs/validator.py +60 -71
  57. esgvoc/apps/jsg/cmip6_template.json +74 -0
  58. esgvoc/apps/jsg/cmip6plus_template.json +74 -0
  59. esgvoc/apps/jsg/json_schema_generator.py +185 -0
  60. esgvoc/apps/py.typed +0 -0
  61. esgvoc/cli/config.py +500 -0
  62. esgvoc/cli/drs.py +3 -2
  63. esgvoc/cli/find.py +138 -0
  64. esgvoc/cli/get.py +46 -38
  65. esgvoc/cli/main.py +10 -3
  66. esgvoc/cli/status.py +27 -18
  67. esgvoc/cli/valid.py +10 -15
  68. esgvoc/core/constants.py +1 -1
  69. esgvoc/core/db/__init__.py +2 -4
  70. esgvoc/core/db/connection.py +5 -3
  71. esgvoc/core/db/models/project.py +57 -15
  72. esgvoc/core/db/models/universe.py +49 -10
  73. esgvoc/core/db/project_ingestion.py +79 -65
  74. esgvoc/core/db/universe_ingestion.py +71 -40
  75. esgvoc/core/exceptions.py +33 -0
  76. esgvoc/core/logging_handler.py +24 -2
  77. esgvoc/core/repo_fetcher.py +61 -59
  78. esgvoc/core/service/data_merger.py +47 -34
  79. esgvoc/core/service/state.py +107 -83
  80. {esgvoc-0.3.0.dist-info → esgvoc-1.0.0.dist-info}/METADATA +7 -20
  81. esgvoc-1.0.0.dist-info/RECORD +95 -0
  82. esgvoc/api/_utils.py +0 -53
  83. esgvoc/core/logging.conf +0 -21
  84. esgvoc-0.3.0.dist-info/RECORD +0 -78
  85. {esgvoc-0.3.0.dist-info → esgvoc-1.0.0.dist-info}/WHEEL +0 -0
  86. {esgvoc-0.3.0.dist-info → esgvoc-1.0.0.dist-info}/entry_points.txt +0 -0
  87. {esgvoc-0.3.0.dist-info → esgvoc-1.0.0.dist-info}/licenses/LICENSE.txt +0 -0
esgvoc/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  import esgvoc.core.logging_handler # noqa
2
2
 
3
- __version__ = "0.3.0"
3
+ __version__ = "1.0.0"
esgvoc/api/__init__.py CHANGED
@@ -1,62 +1,97 @@
1
- from esgvoc.api._utils import APIException
2
- from esgvoc.api.project_specs import (DrsCollection, DrsConstant, DrsPart,
3
- DrsPartKind, DrsSpecification, DrsType,
4
- ProjectSpecs)
1
+ from esgvoc.api.project_specs import (
2
+ DrsCollection,
3
+ DrsConstant,
4
+ DrsPart,
5
+ DrsPartKind,
6
+ DrsSpecification,
7
+ DrsType,
8
+ ProjectSpecs,
9
+ )
5
10
  from esgvoc.api.projects import (
6
- find_collections_in_project, find_project,
7
- find_terms_from_data_descriptor_in_all_projects,
8
- find_terms_from_data_descriptor_in_project, find_terms_in_all_projects,
9
- find_terms_in_collection, find_terms_in_project,
10
- get_all_collections_in_project, get_all_projects,
11
- get_all_terms_in_all_projects, get_all_terms_in_collection,
12
- get_all_terms_in_project, valid_term, valid_term_in_all_projects,
13
- valid_term_in_collection, valid_term_in_project)
14
- from esgvoc.api.report import (ProjectTermError, UniverseTermError,
15
- ValidationError, ValidationErrorVisitor,
16
- ValidationReport)
17
- from esgvoc.api.search import MatchingTerm, SearchSettings, SearchType
18
- from esgvoc.api.universe import (find_data_descriptors_in_universe,
19
- find_terms_in_data_descriptor,
20
- find_terms_in_universe,
21
- get_all_data_descriptors_in_universe,
22
- get_all_terms_in_data_descriptor,
23
- get_all_terms_in_universe)
11
+ find_collections_in_project,
12
+ find_items_in_project,
13
+ find_terms_in_all_projects,
14
+ find_terms_in_collection,
15
+ find_terms_in_project,
16
+ get_all_collections_in_project,
17
+ get_all_projects,
18
+ get_all_terms_in_all_projects,
19
+ get_all_terms_in_collection,
20
+ get_all_terms_in_project,
21
+ get_collection_from_data_descriptor_in_all_projects,
22
+ get_collection_from_data_descriptor_in_project,
23
+ get_collection_in_project,
24
+ get_project,
25
+ get_term_in_collection,
26
+ get_term_in_project,
27
+ valid_term,
28
+ valid_term_in_all_projects,
29
+ valid_term_in_collection,
30
+ valid_term_in_project,
31
+ )
32
+ from esgvoc.api.report import (
33
+ ProjectTermError,
34
+ UniverseTermError,
35
+ ValidationError,
36
+ ValidationErrorVisitor,
37
+ ValidationReport,
38
+ )
39
+ from esgvoc.api.search import MatchingTerm
40
+ from esgvoc.api.universe import (
41
+ find_data_descriptors_in_universe,
42
+ find_items_in_universe,
43
+ find_terms_in_data_descriptor,
44
+ find_terms_in_universe,
45
+ get_all_data_descriptors_in_universe,
46
+ get_all_terms_in_data_descriptor,
47
+ get_all_terms_in_universe,
48
+ get_data_descriptor_in_universe,
49
+ get_term_in_data_descriptor,
50
+ get_term_in_universe,
51
+ )
24
52
 
25
- __all__ = ["MatchingTerm",
26
- "SearchType",
27
- "SearchSettings",
28
- "ValidationError",
29
- "ValidationReport",
30
- "ValidationErrorVisitor",
31
- "ProjectTermError",
32
- "UniverseTermError",
33
- "get_all_terms_in_universe",
34
- "get_all_data_descriptors_in_universe",
35
- "find_data_descriptors_in_universe",
36
- "get_all_terms_in_data_descriptor",
37
- "find_terms_in_universe",
38
- "find_terms_in_data_descriptor",
39
- "get_all_projects",
40
- "find_project",
41
- "get_all_terms_in_all_projects",
42
- "get_all_terms_in_project",
43
- "get_all_collections_in_project",
44
- "find_collections_in_project",
45
- "get_all_terms_in_collection",
46
- "find_terms_in_project",
47
- "find_terms_in_all_projects",
48
- "find_terms_from_data_descriptor_in_all_projects",
49
- "find_terms_from_data_descriptor_in_project",
50
- "find_terms_in_collection",
51
- "valid_term_in_all_projects",
52
- "valid_term_in_project",
53
- "valid_term_in_collection",
54
- "valid_term",
55
- "DrsType",
56
- "DrsPartKind",
57
- "DrsConstant",
58
- "DrsCollection",
59
- "DrsPart",
60
- "DrsSpecification",
61
- "ProjectSpecs",
62
- "APIException"]
53
+ __all__ = [
54
+ "DrsCollection",
55
+ "DrsConstant",
56
+ "DrsPart",
57
+ "DrsPartKind",
58
+ "DrsSpecification",
59
+ "DrsType",
60
+ "find_collections_in_project",
61
+ "find_data_descriptors_in_universe",
62
+ "find_items_in_project",
63
+ "find_items_in_universe",
64
+ "find_terms_in_all_projects",
65
+ "find_terms_in_collection",
66
+ "find_terms_in_data_descriptor",
67
+ "find_terms_in_project",
68
+ "find_terms_in_universe",
69
+ "get_all_collections_in_project",
70
+ "get_all_data_descriptors_in_universe",
71
+ "get_all_projects",
72
+ "get_all_terms_in_all_projects",
73
+ "get_all_terms_in_collection",
74
+ "get_all_terms_in_data_descriptor",
75
+ "get_all_terms_in_project",
76
+ "get_all_terms_in_universe",
77
+ "get_collection_from_data_descriptor_in_all_projects",
78
+ "get_collection_from_data_descriptor_in_project",
79
+ "get_collection_in_project",
80
+ "get_data_descriptor_in_universe",
81
+ "get_project",
82
+ "get_term_in_collection",
83
+ "get_term_in_data_descriptor",
84
+ "get_term_in_project",
85
+ "get_term_in_universe",
86
+ "MatchingTerm",
87
+ "ProjectSpecs",
88
+ "ProjectTermError",
89
+ "UniverseTermError",
90
+ "valid_term",
91
+ "valid_term_in_all_projects",
92
+ "valid_term_in_collection",
93
+ "valid_term_in_project",
94
+ "ValidationError",
95
+ "ValidationErrorVisitor",
96
+ "ValidationReport"
97
+ ]
@@ -1,69 +1,91 @@
1
1
  from esgvoc.api.data_descriptors.activity import Activity
2
+ from esgvoc.api.data_descriptors.area_label import AreaLabel
3
+ from esgvoc.api.data_descriptors.branded_suffix import BrandedSuffix
4
+ from esgvoc.api.data_descriptors.branded_variable import BrandedVariable
2
5
  from esgvoc.api.data_descriptors.consortium import Consortium
6
+ from esgvoc.api.data_descriptors.contact import Contact
7
+ from esgvoc.api.data_descriptors.conventions import Convention
8
+ from esgvoc.api.data_descriptors.creation_date import CreationDate
3
9
  from esgvoc.api.data_descriptors.data_descriptor import DataDescriptor
10
+ from esgvoc.api.data_descriptors.data_specs_version import DataSpecsVersion
4
11
  from esgvoc.api.data_descriptors.date import Date
5
12
  from esgvoc.api.data_descriptors.directory_date import DirectoryDate
6
- from esgvoc.api.data_descriptors.experiment import Experiment
13
+ from esgvoc.api.data_descriptors.experiment import Experiment
7
14
  from esgvoc.api.data_descriptors.forcing_index import ForcingIndex
8
15
  from esgvoc.api.data_descriptors.frequency import Frequency
9
- from esgvoc.api.data_descriptors.grid_label import GridLabel
10
- from esgvoc.api.data_descriptors.initialisation_index import InitialisationIndex
16
+ from esgvoc.api.data_descriptors.further_info_url import FurtherInfoUrl
17
+ from esgvoc.api.data_descriptors.grid_label import GridLabel
18
+ from esgvoc.api.data_descriptors.horizontal_label import HorizontalLabel
19
+ from esgvoc.api.data_descriptors.initialisation_index import InitialisationIndex
11
20
  from esgvoc.api.data_descriptors.institution import Institution
12
- from esgvoc.api.data_descriptors.license import License
21
+ from esgvoc.api.data_descriptors.known_branded_variable import KnownBrandedVariable
22
+ from esgvoc.api.data_descriptors.license import License
13
23
  from esgvoc.api.data_descriptors.mip_era import MipEra
14
24
  from esgvoc.api.data_descriptors.model_component import ModelComponent
15
- from esgvoc.api.data_descriptors.organisation import Organisation
25
+ from esgvoc.api.data_descriptors.obs_type import ObsType
26
+ from esgvoc.api.data_descriptors.organisation import Organisation
16
27
  from esgvoc.api.data_descriptors.physic_index import PhysicIndex
17
28
  from esgvoc.api.data_descriptors.product import Product
18
- from esgvoc.api.data_descriptors.realisation_index import RealisationIndex
29
+ from esgvoc.api.data_descriptors.publication_status import PublicationStatus
30
+ from esgvoc.api.data_descriptors.realisation_index import RealisationIndex
19
31
  from esgvoc.api.data_descriptors.realm import Realm
32
+ from esgvoc.api.data_descriptors.region import Region
20
33
  from esgvoc.api.data_descriptors.resolution import Resolution
21
- from esgvoc.api.data_descriptors.source import Source
22
- from esgvoc.api.data_descriptors.source_type import SourceType
34
+ from esgvoc.api.data_descriptors.source import Source
35
+ from esgvoc.api.data_descriptors.source_type import SourceType
23
36
  from esgvoc.api.data_descriptors.sub_experiment import SubExperiment
24
- from esgvoc.api.data_descriptors.table import Table
25
- from esgvoc.api.data_descriptors.time_range import TimeRange
37
+ from esgvoc.api.data_descriptors.table import Table
38
+ from esgvoc.api.data_descriptors.temporal_label import TemporalLabel
39
+ from esgvoc.api.data_descriptors.time_range import TimeRange
40
+ from esgvoc.api.data_descriptors.title import Title
41
+ from esgvoc.api.data_descriptors.tracking_id import TrackingId
26
42
  from esgvoc.api.data_descriptors.variable import Variable
27
43
  from esgvoc.api.data_descriptors.variant_label import VariantLabel
28
- from esgvoc.api.data_descriptors.area_label import AreaLabel
29
44
  from esgvoc.api.data_descriptors.vertical_label import VerticalLabel
30
- from esgvoc.api.data_descriptors.horizontal_label import HorizontalLabel
31
- from esgvoc.api.data_descriptors.temporal_label import TemporalLabel
32
- from esgvoc.api.data_descriptors.branded_suffix import BrandedSuffix
33
- from esgvoc.api.data_descriptors.branded_variable import BrandedVariable
34
45
 
35
46
  DATA_DESCRIPTOR_CLASS_MAPPING: dict[str, type[DataDescriptor]] = {
36
47
  "activity": Activity,
37
48
  "consortium": Consortium,
38
49
  "date": Date,
39
50
  "directory_date": DirectoryDate,
40
- "experiment": Experiment,
51
+ "experiment": Experiment,
41
52
  "forcing_index": ForcingIndex,
42
53
  "frequency": Frequency,
43
- "grid": GridLabel,#Universe
44
- "grid_label": GridLabel, # cmip6, cmip6plus
45
- "initialisation_index": InitialisationIndex,
54
+ "grid": GridLabel, # Universe
55
+ "grid_label": GridLabel, # cmip6, cmip6plus
56
+ "initialisation_index": InitialisationIndex,
46
57
  "institution": Institution,
47
58
  "license": License,
48
59
  "mip_era": MipEra,
49
60
  "model_component": ModelComponent,
50
- "organisation": Organisation,
61
+ "organisation": Organisation,
51
62
  "physic_index": PhysicIndex,
52
63
  "product": Product,
53
- "realisation_index": RealisationIndex ,
64
+ "realisation_index": RealisationIndex,
54
65
  "realm": Realm,
55
66
  "resolution": Resolution,
56
- "source": Source,
57
- "source_type": SourceType,
67
+ "source": Source,
68
+ "source_type": SourceType,
58
69
  "sub_experiment": SubExperiment,
59
- "table" : Table,
70
+ "table": Table,
60
71
  "time_range": TimeRange,
61
72
  "variable": Variable,
62
73
  "variant_label": VariantLabel,
63
74
  "area_label": AreaLabel,
64
75
  "temporal_label": TemporalLabel,
65
- "vertical_label" : VerticalLabel,
66
- "horizontal_label" : HorizontalLabel,
67
- "branded_suffix" : BrandedSuffix,
68
- "branded_variable" : BrandedVariable
76
+ "vertical_label": VerticalLabel,
77
+ "horizontal_label": HorizontalLabel,
78
+ "branded_suffix": BrandedSuffix,
79
+ "branded_variable": BrandedVariable,
80
+ "publication_status": PublicationStatus,
81
+ "known_branded_variable": KnownBrandedVariable,
82
+ "data_specs_version": DataSpecsVersion,
83
+ "further_info_url": FurtherInfoUrl,
84
+ "tracking_id": TrackingId,
85
+ "creation_date": CreationDate,
86
+ "conventions": Convention,
87
+ "title": Title,
88
+ "contact": Contact,
89
+ "region": Region,
90
+ "obs_type": ObsType, # obs4Mips
69
91
  }
@@ -9,6 +9,6 @@ class Activity(PlainTermDataDescriptor):
9
9
  Activities are often organized around key research themes and may involve multiple experiments, \
10
10
  scenarios, and model configurations.
11
11
  """
12
- name: str
13
- long_name: str
14
- url: str|None
12
+ name: str
13
+ long_name: str
14
+ url: str | None
@@ -2,5 +2,20 @@ from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
2
2
 
3
3
 
4
4
  class AreaLabel(PlainTermDataDescriptor):
5
+ """
6
+ Area sampling label.
7
+
8
+ This label provides information about the area sampling of a given dataset.
9
+ For a list of allowed values, see
10
+ [TODO think about how to cross-reference to somewhere where people can look up the allowed values,
11
+ e.g. some summary of the values in https://github.com/WCRP-CMIP/WCRP-universe/tree/esgvoc/area_label.]
12
+
13
+ This label is used as the area component of a branded variable's suffix
14
+ (see :py:class:`BrandedSuffix`).
15
+ By definition, the area label must be consistent with the branded suffix.
16
+ area labels must not contain dashes
17
+ (as the dash is used as a separator when constructing the branded suffix).
18
+ """
19
+
5
20
  description: str
6
- label: str
21
+ label: str
@@ -2,4 +2,24 @@ from esgvoc.api.data_descriptors.data_descriptor import CompositeTermDataDescrip
2
2
 
3
3
 
4
4
  class BrandedSuffix(CompositeTermDataDescriptor):
5
+ """
6
+ The suffix of a branded variable.
7
+
8
+ A branded variable is composed of two parts.
9
+ The first part is the root variable (see [TODO cross-ref to Variable]).
10
+ The second is the suffix, i.e. the component described here.
11
+ The suffix captures all the information
12
+ about the time sampling, horizontal sampling, vertical sampling
13
+ and area masking of the variable.
14
+
15
+ The suffix is composed of the following components:
16
+
17
+ #. :py:class:`TemporalLabel`
18
+ #. :py:class:`VerticalLabel`
19
+ #. :py:class:`HorizontalLabel`
20
+ #. :py:class:`AreaLabel`
21
+
22
+ These components are separated by a separator to create the branded suffix.
23
+ """
24
+
5
25
  description: str
@@ -2,4 +2,16 @@ from esgvoc.api.data_descriptors.data_descriptor import CompositeTermDataDescrip
2
2
 
3
3
 
4
4
  class BrandedVariable(CompositeTermDataDescriptor):
5
+ """
6
+ A climate-related quantity or measurement, including information about sampling.
7
+
8
+ The concept of a branded variable was introduced in CMIP7.
9
+ A branded variable is composed of two parts.
10
+ The first part is the root variable (see :py:class:`Variable`).
11
+ The second is the suffix (see :py:class:`BrandedSuffix`).
12
+
13
+ For further details on the development of branded variables,
14
+ see [this paper draft](https://docs.google.com/document/d/19jzecgymgiiEsTDzaaqeLP6pTvLT-NzCMaq-wu-QoOc/edit?pli=1&tab=t.0).
15
+ """
16
+
5
17
  description: str
@@ -1,26 +1,27 @@
1
1
  from pydantic import Field
2
- from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor, ConfiguredBaseModel
2
+
3
+ from esgvoc.api.data_descriptors.data_descriptor import ConfiguredBaseModel, PlainTermDataDescriptor
3
4
 
4
5
 
5
6
  class Dates(ConfiguredBaseModel):
6
7
  phase: str
7
- from_: int = Field(...,alias="from") # Cause from is a keyword
8
- to: int|str
9
-
8
+ from_: int = Field(..., alias="from") # Cause from is a keyword
9
+ to: int | str
10
+
10
11
 
11
12
  class Member(ConfiguredBaseModel):
12
- type : str
13
- institution: str # id
13
+ type: str
14
+ institution: str # id
14
15
  dates: list[Dates] = Field(default_factory=list)
15
- membership_type: str # prior, current
16
+ membership_type: str # prior, current
16
17
 
17
18
 
18
19
  class Consortium(PlainTermDataDescriptor):
19
- validation_method: str = Field(default = "list")
20
- name: str|None = None
21
- status: str|None = None
22
- changes: str|None
20
+ validation_method: str = Field(default="list")
21
+ name: str | None = None
22
+ status: str | None = None
23
+ changes: str | None
23
24
  members: list[Member] = Field(default_factory=list)
24
- url: str|None
25
+ url: str | None
25
26
  # TODO: remove default value when all json will have their description.
26
- description: str = Field(default = "")
27
+ description: str = Field(default="")
@@ -0,0 +1,5 @@
1
+ from esgvoc.api.data_descriptors.data_descriptor import PatternTermDataDescriptor
2
+
3
+
4
+ class Contact(PatternTermDataDescriptor):
5
+ pass
@@ -0,0 +1,6 @@
1
+ from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
2
+
3
+
4
+ class Convention(PlainTermDataDescriptor):
5
+ description: str
6
+ label: str
@@ -0,0 +1,5 @@
1
+ from esgvoc.api.data_descriptors.data_descriptor import PatternTermDataDescriptor
2
+
3
+
4
+ class CreationDate(PatternTermDataDescriptor):
5
+ pass
@@ -1,16 +1,17 @@
1
- from typing import Protocol, Any, ClassVar
2
1
  from abc import ABC, abstractmethod
2
+ from typing import Any, ClassVar, Protocol
3
+
3
4
  from pydantic import BaseModel, ConfigDict
4
5
 
5
6
 
6
7
  class ConfiguredBaseModel(BaseModel):
7
8
  model_config = ConfigDict(
8
- validate_assignment = True,
9
- validate_default = True,
10
- extra = "allow",
11
- arbitrary_types_allowed = True,
12
- use_enum_values = True,
13
- strict = False,
9
+ validate_assignment=True,
10
+ validate_default=True,
11
+ extra="allow",
12
+ arbitrary_types_allowed=True,
13
+ use_enum_values=True,
14
+ strict=False,
14
15
  )
15
16
 
16
17
 
@@ -21,12 +22,15 @@ class DataDescriptorVisitor(Protocol):
21
22
  def visit_sub_set_term(self, term: "DataDescriptorSubSet") -> Any:
22
23
  """Visit a sub set of the information of a term."""
23
24
  pass
25
+
24
26
  def visit_plain_term(self, term: "PlainTermDataDescriptor") -> Any:
25
27
  """Visit a plain term."""
26
28
  pass
29
+
27
30
  def visit_pattern_term(self, term: "PatternTermDataDescriptor") -> Any:
28
31
  """Visit a pattern term."""
29
32
  pass
33
+
30
34
  def visit_composite_term(self, term: "CompositeTermDataDescriptor") -> Any:
31
35
  """Visit a composite term."""
32
36
 
@@ -68,6 +72,7 @@ class PlainTermDataDescriptor(DataDescriptor):
68
72
  A data descriptor that describes hand written terms.
69
73
  """
70
74
  drs_name: str
75
+
71
76
  def accept(self, visitor: DataDescriptorVisitor) -> Any:
72
77
  return visitor.visit_plain_term(self)
73
78
 
@@ -86,11 +91,11 @@ class CompositeTermPart(ConfiguredBaseModel):
86
91
  """
87
92
  A reference to a term, part of a composite term.
88
93
  """
89
- id: str
94
+ id: str | list[str] | None = None
90
95
  """The id of the referenced term."""
91
96
  type: str
92
97
  """The type of the referenced term."""
93
- is_required : bool
98
+ is_required: bool
94
99
  """Denote if the term is optional as part of a composite term."""
95
100
 
96
101
 
@@ -0,0 +1,5 @@
1
+ from esgvoc.api.data_descriptors.data_descriptor import PatternTermDataDescriptor
2
+
3
+
4
+ class DataSpecsVersion(PatternTermDataDescriptor):
5
+ pass
@@ -2,4 +2,4 @@ from esgvoc.api.data_descriptors.data_descriptor import PatternTermDataDescripto
2
2
 
3
3
 
4
4
  class Date(PatternTermDataDescriptor):
5
- pass
5
+ pass
@@ -2,4 +2,4 @@ from esgvoc.api.data_descriptors.data_descriptor import PatternTermDataDescripto
2
2
 
3
3
 
4
4
  class DirectoryDate(PatternTermDataDescriptor):
5
- pass
5
+ pass
@@ -1,4 +1,5 @@
1
1
  from pydantic import Field
2
+
2
3
  from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
3
4
 
4
5
 
@@ -10,16 +11,17 @@ class Experiment(PlainTermDataDescriptor):
10
11
  concentrations or solar radiation), and duration, to explore and understand climate behavior \
11
12
  under various scenarios and conditions.
12
13
  """
14
+
13
15
  activity: list[str] = Field(default_factory=list)
14
- description: str
15
- tier: int|None
16
- experiment_id: str
17
- sub_experiment_id: list[str]|None
16
+ description: str
17
+ tier: int | None
18
+ experiment_id: str
19
+ sub_experiment_id: list[str] | None
18
20
  experiment: str
19
- required_model_components: list[str]|None
20
- additional_allowed_model_components: list[str] = Field(default_factory=list)
21
- start_year: int|None
22
- end_year: int|None
23
- min_number_yrs_per_sim: int|None
24
- parent_activity_id: list[str]|None
25
- parent_experiment_id: list[str]|None
21
+ required_model_components: list[str] | None
22
+ additional_allowed_model_components: list[str] = Field(default_factory=list)
23
+ start_year: int | None
24
+ end_year: int | None
25
+ min_number_yrs_per_sim: int | None
26
+ parent_activity_id: list[str] | None
27
+ parent_experiment_id: list[str] | None
@@ -2,4 +2,4 @@ from esgvoc.api.data_descriptors.data_descriptor import PatternTermDataDescripto
2
2
 
3
3
 
4
4
  class ForcingIndex(PatternTermDataDescriptor):
5
- pass
5
+ pass
@@ -3,6 +3,6 @@ from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
3
3
 
4
4
  class Frequency(PlainTermDataDescriptor):
5
5
  description: str
6
- long_name: str
7
- name: str
8
- unit: str
6
+ long_name: str
7
+ name: str
8
+ unit: str
@@ -0,0 +1,5 @@
1
+ from esgvoc.api.data_descriptors.data_descriptor import PatternTermDataDescriptor
2
+
3
+
4
+ class FurtherInfoUrl(PatternTermDataDescriptor):
5
+ pass
@@ -3,6 +3,6 @@ from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
3
3
 
4
4
  class GridLabel(PlainTermDataDescriptor):
5
5
  description: str
6
- short_name: str
7
- name: str
6
+ short_name: str
7
+ name: str
8
8
  region: str
@@ -2,5 +2,19 @@ from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
2
2
 
3
3
 
4
4
  class HorizontalLabel(PlainTermDataDescriptor):
5
+ """
6
+ Horizontal sampling label.
7
+
8
+ This label provides information about the horizontal sampling of a given dataset.
9
+ For a list of allowed values, see
10
+ [TODO think about how to cross-reference to somewhere where people can look up the allowed values,
11
+ e.g. some summary of the values in https://github.com/WCRP-CMIP/WCRP-universe/tree/esgvoc/horizontal_label.]
12
+
13
+ This label is used as the horizontal component of a branded variable's suffix
14
+ (see :py:class:`BrandedSuffix`).
15
+ By definition, the horizontal label must be consistent with the branded suffix.
16
+ Horizontal labels must not contain the separator used when constructing the branded suffix.
17
+ """
18
+
5
19
  description: str
6
- label: str
20
+ label: str
@@ -2,4 +2,4 @@ from esgvoc.api.data_descriptors.data_descriptor import PatternTermDataDescripto
2
2
 
3
3
 
4
4
  class InitialisationIndex(PatternTermDataDescriptor):
5
- pass
5
+ pass
@@ -1,15 +1,18 @@
1
1
  from pydantic import Field
2
+
2
3
  from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
3
4
 
5
+
4
6
  class Institution(PlainTermDataDescriptor):
5
7
  """
6
8
  An registered institution for WCRP modelisation MIP.
7
9
  """
10
+
8
11
  acronyms: list[str] = Field(default_factory=list)
9
12
  aliases: list[str] = Field(default_factory=list)
10
- established: int|None
13
+ established: int | None
11
14
  labels: list[str] = Field(default_factory=list)
12
- location: dict = Field(default_factory=dict)
13
- name: str
14
- ror: str|None
15
- url: list[str] = Field(default_factory=list)
15
+ location: dict = Field(default_factory=dict)
16
+ name: str
17
+ ror: str | None
18
+ url: list[str] = Field(default_factory=list)