esgvoc 2.0.2__py3-none-any.whl → 2.1.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.
- esgvoc/__init__.py +1 -1
- esgvoc/api/data_descriptors/EMD_models/coordinate.py +27 -43
- esgvoc/api/data_descriptors/EMD_models/reference.py +11 -12
- esgvoc/api/data_descriptors/EMD_models/resolution.py +26 -39
- esgvoc/api/data_descriptors/data_descriptor.py +32 -3
- esgvoc/api/projects.py +51 -34
- esgvoc/api/pydantic_handler.py +30 -20
- esgvoc/api/universe.py +26 -17
- esgvoc/cli/get.py +48 -8
- {esgvoc-2.0.2.dist-info → esgvoc-2.1.0.dist-info}/METADATA +1 -1
- {esgvoc-2.0.2.dist-info → esgvoc-2.1.0.dist-info}/RECORD +14 -14
- {esgvoc-2.0.2.dist-info → esgvoc-2.1.0.dist-info}/WHEEL +0 -0
- {esgvoc-2.0.2.dist-info → esgvoc-2.1.0.dist-info}/entry_points.txt +0 -0
- {esgvoc-2.0.2.dist-info → esgvoc-2.1.0.dist-info}/licenses/LICENSE.txt +0 -0
esgvoc/__init__.py
CHANGED
|
@@ -3,50 +3,34 @@ from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
|
|
|
3
3
|
|
|
4
4
|
class Coordinate(PlainTermDataDescriptor):
|
|
5
5
|
"""
|
|
6
|
-
Native vertical grid coordinate type.
|
|
6
|
+
Native vertical grid coordinate type.
|
|
7
|
+
|
|
8
|
+
The coordinate types are all CF standard names (except where indicated)
|
|
9
|
+
with the same definitions. See section 5.2 Native vertical grid properties.
|
|
10
|
+
|
|
7
11
|
Options for the native vertical grid Coordinate property:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
• sea_water_pressure
|
|
31
|
-
◦ Sea water pressure is the pressure that exists in the medium of sea water.
|
|
32
|
-
• sea_water_potential_temperature
|
|
33
|
-
◦ Sea water potential temperature is the temperature a parcel of sea water would have if moved adiabatically to sea level pressure.
|
|
34
|
-
• ocean_sigma_coordinate
|
|
35
|
-
◦ Parametric ocean sigma coordinate.
|
|
36
|
-
• ocean_s_coordinate
|
|
37
|
-
◦ Parametric ocean s-coordinate.
|
|
38
|
-
• ocean_s_coordinate_g1
|
|
39
|
-
◦ Parametric ocean s-coordinate, generic form 1.
|
|
40
|
-
• ocean_s_coordinate_g2
|
|
41
|
-
◦ Parametric ocean s-coordinate, generic form 2.
|
|
42
|
-
• ocean_sigma_z_coordinate
|
|
43
|
-
◦ Parametric ocean sigma over z coordinate.
|
|
44
|
-
• ocean_double_sigma_coordinate
|
|
45
|
-
◦ Parametric ocean double sigma coordinate.
|
|
46
|
-
• land_ice_sigma_coordinate
|
|
47
|
-
◦ Land ice (glaciers, ice-caps and ice-sheets resting on bedrock and also includes ice-shelves) sigma coordinate.
|
|
48
|
-
• z*
|
|
49
|
-
◦ (Not a standard name) The z* coordinate of Adcroft and Campin (2004).
|
|
12
|
+
|
|
13
|
+
* **none** - (Not a standard name) There is no vertical dimension.
|
|
14
|
+
* **height** - Height is the vertical distance above the earth's surface.
|
|
15
|
+
* **geopotential_height** - Geopotential height is the geopotential divided by the standard acceleration due to gravity.
|
|
16
|
+
* **air_pressure** - Air pressure is the pressure that exists in the medium of air.
|
|
17
|
+
* **air_potential_temperature** - Air potential temperature is the temperature a parcel of air would have if moved dry adiabatically to a standard pressure.
|
|
18
|
+
* **atmosphere_ln_pressure_coordinate** - Parametric atmosphere natural log pressure coordinate.
|
|
19
|
+
* **atmosphere_sigma_coordinate** - Parametric atmosphere sigma coordinate.
|
|
20
|
+
* **atmosphere_hybrid_sigma_pressure_coordinate** - Parametric atmosphere hybrid sigma pressure coordinate.
|
|
21
|
+
* **atmosphere_hybrid_height_coordinate** - Parametric atmosphere hybrid height coordinate.
|
|
22
|
+
* **atmosphere_sleve_coordinate** - Parametric atmosphere smooth vertical level coordinate.
|
|
23
|
+
* **depth** - Depth is the vertical distance below the earth's surface.
|
|
24
|
+
* **sea_water_pressure** - Sea water pressure is the pressure that exists in the medium of sea water.
|
|
25
|
+
* **sea_water_potential_temperature** - Sea water potential temperature is the temperature a parcel of sea water would have if moved adiabatically to sea level pressure.
|
|
26
|
+
* **ocean_sigma_coordinate** - Parametric ocean sigma coordinate.
|
|
27
|
+
* **ocean_s_coordinate** - Parametric ocean s-coordinate.
|
|
28
|
+
* **ocean_s_coordinate_g1** - Parametric ocean s-coordinate, generic form 1.
|
|
29
|
+
* **ocean_s_coordinate_g2** - Parametric ocean s-coordinate, generic form 2.
|
|
30
|
+
* **ocean_sigma_z_coordinate** - Parametric ocean sigma over z coordinate.
|
|
31
|
+
* **ocean_double_sigma_coordinate** - Parametric ocean double sigma coordinate.
|
|
32
|
+
* **land_ice_sigma_coordinate** - Land ice (glaciers, ice-caps and ice-sheets resting on bedrock and also includes ice-shelves) sigma coordinate.
|
|
33
|
+
* **z*** - (Not a standard name) The z* coordinate of Adcroft and Campin (2004).
|
|
50
34
|
"""
|
|
51
35
|
|
|
52
36
|
pass
|
|
@@ -14,18 +14,17 @@ class Reference(PlainTermDataDescriptor):
|
|
|
14
14
|
An academic reference to published work for the top-level model or one of its model
|
|
15
15
|
components is defined by the following properties:
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
◦ E.g. https://doi.org/10.1029/2021MS002520
|
|
17
|
+
* **Citation** - A human-readable citation for the work.
|
|
18
|
+
E.g. Smith, R. S., Mathiot, P., Siahaan, A., Lee, V., Cornford, S. L., Gregory, J. M.,
|
|
19
|
+
et al. (2021). Coupling the U.K. Earth System model to dynamic models of the Greenland
|
|
20
|
+
and Antarctic ice sheets. Journal of Advances in Modeling Earth Systems, 13,
|
|
21
|
+
e2021MS002520. https://doi.org/10.1029/2021MS002520, 2023
|
|
22
|
+
|
|
23
|
+
* **DOI** - The persistent identifier (DOI) used to identify the work.
|
|
24
|
+
A DOI is required for all references. A reference that does not already have a DOI
|
|
25
|
+
(as could be the case for some technical reports, for instance) must be given one
|
|
26
|
+
(e.g. with a service like Zenodo).
|
|
27
|
+
E.g. https://doi.org/10.1029/2021MS002520
|
|
29
28
|
"""
|
|
30
29
|
|
|
31
30
|
citation: str = Field(description="A human-readable citation for the work.", min_length=1)
|
|
@@ -3,46 +3,33 @@ from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
|
|
|
3
3
|
|
|
4
4
|
class EMDResolution(PlainTermDataDescriptor):
|
|
5
5
|
"""
|
|
6
|
-
The nominal resolution (in km) characterises the resolution of a model's native horizontal grid.
|
|
7
|
-
Options for the native horizontal grid nominal resolution property are defined in the following table as a function of the value of the mean resolution km property:
|
|
6
|
+
The nominal resolution (in km) characterises the resolution of a model's native horizontal grid.
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
nominal resolution
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
0.
|
|
17
|
-
0.
|
|
18
|
-
0.
|
|
19
|
-
0.
|
|
20
|
-
1 km
|
|
21
|
-
1.6 ≤ R < 3.6
|
|
22
|
-
2
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
250 km
|
|
35
|
-
360 ≤ R < 720
|
|
36
|
-
500 km
|
|
37
|
-
720 ≤ R < 1600
|
|
38
|
-
1000 km
|
|
39
|
-
1600 ≤ R < 3600
|
|
40
|
-
2500 km
|
|
41
|
-
3600 ≤ R < 7200
|
|
42
|
-
5000 km
|
|
43
|
-
7200 ≤ R < 16000
|
|
44
|
-
10000 km
|
|
45
|
-
7.10. Native vertical grid "Coordinate" CV
|
|
8
|
+
See section 5.1 Native horizontal grid properties.
|
|
9
|
+
Options for the native horizontal grid nominal resolution property are defined
|
|
10
|
+
in the following table as a function of the value of the mean resolution km property:
|
|
11
|
+
|
|
12
|
+
==================== ====================
|
|
13
|
+
Mean resolution R Nominal resolution
|
|
14
|
+
==================== ====================
|
|
15
|
+
0.036 ≤ R < 0.072 0.05 km
|
|
16
|
+
0.072 ≤ R < 0.16 0.1 km
|
|
17
|
+
0.16 ≤ R < 0.36 0.25 km
|
|
18
|
+
0.36 ≤ R < 0.72 0.5 km
|
|
19
|
+
0.72 ≤ R < 1.6 1 km
|
|
20
|
+
1.6 ≤ R < 3.6 2.5 km
|
|
21
|
+
3.6 ≤ R < 7.2 5 km
|
|
22
|
+
7.2 ≤ R < 16 10 km
|
|
23
|
+
16 ≤ R < 36 25 km
|
|
24
|
+
36 ≤ R < 72 50 km
|
|
25
|
+
72 ≤ R < 160 100 km
|
|
26
|
+
160 ≤ R < 360 250 km
|
|
27
|
+
360 ≤ R < 720 500 km
|
|
28
|
+
720 ≤ R < 1600 1000 km
|
|
29
|
+
1600 ≤ R < 3600 2500 km
|
|
30
|
+
3600 ≤ R < 7200 5000 km
|
|
31
|
+
7200 ≤ R < 16000 10000 km
|
|
32
|
+
==================== ====================
|
|
46
33
|
"""
|
|
47
34
|
|
|
48
35
|
mean_resolution: str
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
2
|
from typing import Any, ClassVar, Protocol
|
|
3
3
|
|
|
4
|
-
from pydantic import BaseModel, ConfigDict
|
|
4
|
+
from pydantic import BaseModel, ConfigDict, Field, model_serializer
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class ConfiguredBaseModel(BaseModel):
|
|
@@ -68,10 +68,39 @@ class DataDescriptor(ConfiguredBaseModel, ABC):
|
|
|
68
68
|
class DataDescriptorSubSet(DataDescriptor):
|
|
69
69
|
"""
|
|
70
70
|
A sub set of the information contains in a term.
|
|
71
|
+
When using selected_term_fields, only id is guaranteed to be present.
|
|
72
|
+
Other fields (type, description) may be None if not selected.
|
|
71
73
|
"""
|
|
72
74
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
# Override inherited fields to make them truly optional using Field()
|
|
76
|
+
# Using default_factory to ensure Pydantic treats them as optional
|
|
77
|
+
type: str | None = Field(default=None, validate_default=False) # type: ignore[assignment]
|
|
78
|
+
"""The data descriptor to which the term belongs (optional in subset)."""
|
|
79
|
+
description: str | None = Field(default=None, validate_default=False) # type: ignore[assignment]
|
|
80
|
+
"""The description of the term (optional in subset)."""
|
|
81
|
+
|
|
82
|
+
MANDATORY_TERM_FIELDS: ClassVar[tuple[str]] = ("id",)
|
|
83
|
+
"""The set of mandatory term fields (only id is guaranteed when using selected_term_fields)."""
|
|
84
|
+
|
|
85
|
+
@model_serializer(mode='wrap')
|
|
86
|
+
def serialize_model(self, serializer: Any) -> dict[str, Any]:
|
|
87
|
+
"""
|
|
88
|
+
Custom serializer that only includes fields that actually exist on the instance.
|
|
89
|
+
This prevents Pydantic warnings when fields are removed via delattr().
|
|
90
|
+
Uses 'wrap' mode to override default serialization behavior completely.
|
|
91
|
+
"""
|
|
92
|
+
# Serialize all attributes from __dict__ that are not private
|
|
93
|
+
result = {
|
|
94
|
+
field_name: field_value
|
|
95
|
+
for field_name, field_value in self.__dict__.items()
|
|
96
|
+
if not field_name.startswith('_')
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
# Also include extra fields (like drs_name) that are stored in __pydantic_extra__
|
|
100
|
+
if hasattr(self, '__pydantic_extra__') and self.__pydantic_extra__:
|
|
101
|
+
result.update(self.__pydantic_extra__)
|
|
102
|
+
|
|
103
|
+
return result
|
|
75
104
|
|
|
76
105
|
def accept(self, visitor: DataDescriptorVisitor) -> Any:
|
|
77
106
|
return visitor.visit_sub_set_term(self)
|
esgvoc/api/projects.py
CHANGED
|
@@ -8,7 +8,7 @@ from sqlmodel import Session, and_, col, select
|
|
|
8
8
|
import esgvoc.api.universe as universe
|
|
9
9
|
import esgvoc.core.constants as constants
|
|
10
10
|
import esgvoc.core.service as service
|
|
11
|
-
from esgvoc.api.data_descriptors.data_descriptor import DataDescriptor
|
|
11
|
+
from esgvoc.api.data_descriptors.data_descriptor import DataDescriptor, DataDescriptorSubSet
|
|
12
12
|
from esgvoc.api.project_specs import ProjectSpecs
|
|
13
13
|
from esgvoc.api.report import ProjectTermError, UniverseTermError, ValidationReport
|
|
14
14
|
from esgvoc.api.pydantic_handler import instantiate_pydantic_term
|
|
@@ -483,7 +483,7 @@ def valid_term_in_all_projects(value: str) -> list[MatchingTerm]:
|
|
|
483
483
|
|
|
484
484
|
def get_all_terms_in_collection(
|
|
485
485
|
project_id: str, collection_id: str, selected_term_fields: Iterable[str] | None = None
|
|
486
|
-
) -> list[DataDescriptor]:
|
|
486
|
+
) -> list[DataDescriptor | DataDescriptorSubSet]:
|
|
487
487
|
"""
|
|
488
488
|
Gets all terms of the given collection of a project.
|
|
489
489
|
This function performs an exact match on the `project_id` and `collection_id`,
|
|
@@ -496,10 +496,13 @@ def get_all_terms_in_collection(
|
|
|
496
496
|
:param collection_id: A collection id
|
|
497
497
|
:type collection_id: str
|
|
498
498
|
:param selected_term_fields: A list of term fields to select or `None`. If `None`, all the \
|
|
499
|
-
fields of the terms are returned. If
|
|
499
|
+
fields of the terms are returned (full DataDescriptor). If provided, only the selected fields \
|
|
500
|
+
are included (returns DataDescriptorSubSet with id + selected fields that exist).
|
|
500
501
|
:type selected_term_fields: Iterable[str] | None
|
|
501
|
-
:returns:
|
|
502
|
-
|
|
502
|
+
:returns: A list of term instances. Each term is a full DataDescriptor when \
|
|
503
|
+
selected_term_fields is None, or a DataDescriptorSubSet when selected_term_fields is provided. \
|
|
504
|
+
Returns an empty list if no matches are found.
|
|
505
|
+
:rtype: list[DataDescriptor | DataDescriptorSubSet]
|
|
503
506
|
"""
|
|
504
507
|
result = list()
|
|
505
508
|
if connection := _get_project_connection(project_id):
|
|
@@ -610,7 +613,7 @@ def _get_all_terms_in_collection(
|
|
|
610
613
|
|
|
611
614
|
def get_all_terms_in_project(
|
|
612
615
|
project_id: str, selected_term_fields: Iterable[str] | None = None
|
|
613
|
-
) -> list[DataDescriptor]:
|
|
616
|
+
) -> list[DataDescriptor | DataDescriptorSubSet]:
|
|
614
617
|
"""
|
|
615
618
|
Gets all terms of the given project.
|
|
616
619
|
This function performs an exact match on the `project_id` and
|
|
@@ -621,10 +624,13 @@ def get_all_terms_in_project(
|
|
|
621
624
|
:param project_id: A project id
|
|
622
625
|
:type project_id: str
|
|
623
626
|
:param selected_term_fields: A list of term fields to select or `None`. If `None`, all the \
|
|
624
|
-
fields of the terms are returned. If
|
|
627
|
+
fields of the terms are returned (full DataDescriptor). If provided, only the selected fields \
|
|
628
|
+
are included (returns DataDescriptorSubSet with id + selected fields that exist).
|
|
625
629
|
:type selected_term_fields: Iterable[str] | None
|
|
626
|
-
:returns: A list of term instances.
|
|
627
|
-
|
|
630
|
+
:returns: A list of term instances. Each term is a full DataDescriptor when \
|
|
631
|
+
selected_term_fields is None, or a DataDescriptorSubSet when selected_term_fields is provided. \
|
|
632
|
+
Returns an empty list if no matches are found.
|
|
633
|
+
:rtype: list[DataDescriptor | DataDescriptorSubSet]
|
|
628
634
|
"""
|
|
629
635
|
result = list()
|
|
630
636
|
if connection := _get_project_connection(project_id):
|
|
@@ -638,15 +644,17 @@ def get_all_terms_in_project(
|
|
|
638
644
|
|
|
639
645
|
def get_all_terms_in_all_projects(
|
|
640
646
|
selected_term_fields: Iterable[str] | None = None,
|
|
641
|
-
) -> list[tuple[str, list[DataDescriptor]]]:
|
|
647
|
+
) -> list[tuple[str, list[DataDescriptor | DataDescriptorSubSet]]]:
|
|
642
648
|
"""
|
|
643
649
|
Gets all terms of all projects.
|
|
644
650
|
|
|
645
651
|
:param selected_term_fields: A list of term fields to select or `None`. If `None`, all the \
|
|
646
|
-
fields of the terms are returned. If
|
|
652
|
+
fields of the terms are returned (full DataDescriptor). If provided, only the selected fields \
|
|
653
|
+
are included (returns DataDescriptorSubSet with id + selected fields that exist).
|
|
647
654
|
:type selected_term_fields: Iterable[str] | None
|
|
648
|
-
:returns: A list of
|
|
649
|
-
|
|
655
|
+
:returns: A list of tuples containing (project_id, terms). Each term is a full DataDescriptor when \
|
|
656
|
+
selected_term_fields is None, or a DataDescriptorSubSet when selected_term_fields is provided.
|
|
657
|
+
:rtype: list[tuple[str, list[DataDescriptor | DataDescriptorSubSet]]]
|
|
650
658
|
"""
|
|
651
659
|
project_ids = get_all_projects()
|
|
652
660
|
result = list()
|
|
@@ -676,7 +684,7 @@ def _get_term_in_project(term_id: str, session: Session) -> PTerm | None:
|
|
|
676
684
|
|
|
677
685
|
def get_term_in_project(
|
|
678
686
|
project_id: str, term_id: str, selected_term_fields: Iterable[str] | None = None
|
|
679
|
-
) -> DataDescriptor | None:
|
|
687
|
+
) -> DataDescriptor | DataDescriptorSubSet | None:
|
|
680
688
|
"""
|
|
681
689
|
Returns the first occurrence of the terms, in the given project, whose id corresponds exactly to
|
|
682
690
|
the given term id.
|
|
@@ -691,12 +699,14 @@ def get_term_in_project(
|
|
|
691
699
|
:param term_id: The id of a term to be found.
|
|
692
700
|
:type term_id: str
|
|
693
701
|
:param selected_term_fields: A list of term fields to select or `None`. If `None`, all the \
|
|
694
|
-
fields of the terms are returned. If
|
|
702
|
+
fields of the terms are returned (full DataDescriptor). If provided, only the selected fields \
|
|
703
|
+
are included (returns DataDescriptorSubSet with id + selected fields that exist).
|
|
695
704
|
:type selected_term_fields: Iterable[str] | None
|
|
696
|
-
:returns: A term instance.
|
|
697
|
-
|
|
705
|
+
:returns: A term instance. The term is a full DataDescriptor when selected_term_fields is None, \
|
|
706
|
+
or a DataDescriptorSubSet when selected_term_fields is provided. Returns `None` if no match is found.
|
|
707
|
+
:rtype: DataDescriptor | DataDescriptorSubSet | None
|
|
698
708
|
"""
|
|
699
|
-
result: DataDescriptor | None = None
|
|
709
|
+
result: DataDescriptor | DataDescriptorSubSet | None = None
|
|
700
710
|
if connection := _get_project_connection(project_id):
|
|
701
711
|
with connection.create_session() as session:
|
|
702
712
|
term_found = _get_term_in_project(term_id, session)
|
|
@@ -714,7 +724,7 @@ def _get_term_in_collection(collection_id: str, term_id: str, session: Session)
|
|
|
714
724
|
|
|
715
725
|
def get_term_in_collection(
|
|
716
726
|
project_id: str, collection_id: str, term_id: str, selected_term_fields: Iterable[str] | None = None
|
|
717
|
-
) -> DataDescriptor | None:
|
|
727
|
+
) -> DataDescriptor | DataDescriptorSubSet | None:
|
|
718
728
|
"""
|
|
719
729
|
Returns the term, in the given project and collection,
|
|
720
730
|
whose id corresponds exactly to the given term id.
|
|
@@ -730,12 +740,14 @@ def get_term_in_collection(
|
|
|
730
740
|
:param term_id: The id of a term to be found.
|
|
731
741
|
:type term_id: str
|
|
732
742
|
:param selected_term_fields: A list of term fields to select or `None`. If `None`, all the \
|
|
733
|
-
fields of the terms are returned. If
|
|
743
|
+
fields of the terms are returned (full DataDescriptor). If provided, only the selected fields \
|
|
744
|
+
are included (returns DataDescriptorSubSet with id + selected fields that exist).
|
|
734
745
|
:type selected_term_fields: Iterable[str] | None
|
|
735
|
-
:returns: A term instance.
|
|
736
|
-
|
|
746
|
+
:returns: A term instance. The term is a full DataDescriptor when selected_term_fields is None, \
|
|
747
|
+
or a DataDescriptorSubSet when selected_term_fields is provided. Returns `None` if no match is found.
|
|
748
|
+
:rtype: DataDescriptor | DataDescriptorSubSet | None
|
|
737
749
|
"""
|
|
738
|
-
result: DataDescriptor | None = None
|
|
750
|
+
result: DataDescriptor | DataDescriptorSubSet | None = None
|
|
739
751
|
if connection := _get_project_connection(project_id):
|
|
740
752
|
with connection.create_session() as session:
|
|
741
753
|
term_found = _get_term_in_collection(collection_id, term_id, session)
|
|
@@ -871,7 +883,7 @@ def _get_term_from_universe_term_id_in_project(
|
|
|
871
883
|
|
|
872
884
|
def get_term_from_universe_term_id_in_project(
|
|
873
885
|
project_id: str, data_descriptor_id: str, universe_term_id: str, selected_term_fields: Iterable[str] | None = None
|
|
874
|
-
) -> tuple[str, DataDescriptor] | None:
|
|
886
|
+
) -> tuple[str, DataDescriptor | DataDescriptorSubSet] | None:
|
|
875
887
|
"""
|
|
876
888
|
Returns the term, in the given project, that corresponds to the given term in the universe.
|
|
877
889
|
This function performs an exact match on the `project_id`, `data_descriptor_id`
|
|
@@ -887,12 +899,15 @@ def get_term_from_universe_term_id_in_project(
|
|
|
887
899
|
:param universe_term_id: The id of the given universe term.
|
|
888
900
|
:type universe_term_id: str
|
|
889
901
|
:param selected_term_fields: A list of term fields to select or `None`. If `None`, all the \
|
|
890
|
-
fields of the terms are returned. If
|
|
902
|
+
fields of the terms are returned (full DataDescriptor). If provided, only the selected fields \
|
|
903
|
+
are included (returns DataDescriptorSubSet with id + selected fields that exist).
|
|
891
904
|
:type selected_term_fields: Iterable[str] | None
|
|
892
|
-
:returns: A collection id and the project term instance.
|
|
893
|
-
|
|
905
|
+
:returns: A collection id and the project term instance. The term is a full DataDescriptor when \
|
|
906
|
+
selected_term_fields is None, or a DataDescriptorSubSet when selected_term_fields is provided. \
|
|
907
|
+
Returns `None` if no matches are found.
|
|
908
|
+
:rtype: tuple[str, DataDescriptor | DataDescriptorSubSet] | None
|
|
894
909
|
"""
|
|
895
|
-
result: tuple[str, DataDescriptor] | None = None
|
|
910
|
+
result: tuple[str, DataDescriptor | DataDescriptorSubSet] | None = None
|
|
896
911
|
if connection := _get_project_connection(project_id):
|
|
897
912
|
with connection.create_session() as session:
|
|
898
913
|
term_found = _get_term_from_universe_term_id_in_project(data_descriptor_id, universe_term_id, session)
|
|
@@ -904,7 +919,7 @@ def get_term_from_universe_term_id_in_project(
|
|
|
904
919
|
|
|
905
920
|
def get_term_from_universe_term_id_in_all_projects(
|
|
906
921
|
data_descriptor_id: str, universe_term_id: str, selected_term_fields: Iterable[str] | None = None
|
|
907
|
-
) -> list[tuple[str, str, DataDescriptor]]:
|
|
922
|
+
) -> list[tuple[str, str, DataDescriptor | DataDescriptorSubSet]]:
|
|
908
923
|
"""
|
|
909
924
|
Returns the terms, in all projects, that correspond to the given term in the universe.
|
|
910
925
|
This function performs an exact match on the `data_descriptor_id`
|
|
@@ -918,13 +933,15 @@ def get_term_from_universe_term_id_in_all_projects(
|
|
|
918
933
|
:param universe_term_id: The id of the given universe term.
|
|
919
934
|
:type universe_term_id: str
|
|
920
935
|
:param selected_term_fields: A list of term fields to select or `None`. If `None`, all the \
|
|
921
|
-
fields of the terms are returned. If
|
|
936
|
+
fields of the terms are returned (full DataDescriptor). If provided, only the selected fields \
|
|
937
|
+
are included (returns DataDescriptorSubSet with id + selected fields that exist).
|
|
922
938
|
:type selected_term_fields: Iterable[str] | None
|
|
923
|
-
:returns: A project_id,
|
|
924
|
-
|
|
925
|
-
|
|
939
|
+
:returns: A list of tuples containing (project_id, collection_id, term). The term is a full \
|
|
940
|
+
DataDescriptor when selected_term_fields is None, or a DataDescriptorSubSet when \
|
|
941
|
+
selected_term_fields is provided. Returns an empty list if no matches are found.
|
|
942
|
+
:rtype: list[tuple[str, str, DataDescriptor | DataDescriptorSubSet]]
|
|
926
943
|
"""
|
|
927
|
-
result: list[tuple[str, str, DataDescriptor]] = list()
|
|
944
|
+
result: list[tuple[str, str, DataDescriptor | DataDescriptorSubSet]] = list()
|
|
928
945
|
project_ids = get_all_projects()
|
|
929
946
|
for project_id in project_ids:
|
|
930
947
|
term_found = get_term_from_universe_term_id_in_project(
|
esgvoc/api/pydantic_handler.py
CHANGED
|
@@ -6,7 +6,7 @@ import esgvoc.core.constants as api_settings
|
|
|
6
6
|
from esgvoc.core.exceptions import EsgvocDbError
|
|
7
7
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
|
-
from esgvoc.api.data_descriptors.data_descriptor import DataDescriptor
|
|
9
|
+
from esgvoc.api.data_descriptors.data_descriptor import DataDescriptor, DataDescriptorSubSet
|
|
10
10
|
from esgvoc.core.db.models.project import PTerm
|
|
11
11
|
from esgvoc.core.db.models.universe import UTerm
|
|
12
12
|
|
|
@@ -103,7 +103,7 @@ def get_pydantic_class(data_descriptor_id_or_term_type: str) -> type["DataDescri
|
|
|
103
103
|
raise EsgvocDbError(f"'{data_descriptor_id_or_term_type}' pydantic class not found")
|
|
104
104
|
|
|
105
105
|
|
|
106
|
-
def instantiate_pydantic_term(term: "UTerm | PTerm", selected_term_fields: Iterable[str] | None) -> "DataDescriptor":
|
|
106
|
+
def instantiate_pydantic_term(term: "UTerm | PTerm", selected_term_fields: Iterable[str] | None) -> "DataDescriptor | DataDescriptorSubSet":
|
|
107
107
|
"""
|
|
108
108
|
Instantiate a Pydantic DataDescriptor from a database term.
|
|
109
109
|
|
|
@@ -112,32 +112,42 @@ def instantiate_pydantic_term(term: "UTerm | PTerm", selected_term_fields: Itera
|
|
|
112
112
|
selected_term_fields: Optional list of specific fields to include. If None, all fields are included.
|
|
113
113
|
|
|
114
114
|
Returns:
|
|
115
|
-
A DataDescriptor instance (
|
|
115
|
+
A DataDescriptor instance (full model) when selected_term_fields is None,
|
|
116
|
+
or a DataDescriptorSubSet instance when selected_term_fields is provided.
|
|
116
117
|
"""
|
|
117
118
|
from esgvoc.api.data_descriptors.data_descriptor import DataDescriptorSubSet
|
|
118
119
|
|
|
119
120
|
type = term.specs[api_settings.TERM_TYPE_JSON_KEY]
|
|
120
121
|
if selected_term_fields is not None:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
# Build data dict with only id (truly mandatory) + selected fields
|
|
123
|
+
data = {
|
|
124
|
+
"id": term.id,
|
|
125
|
+
}
|
|
125
126
|
|
|
127
|
+
# Add selected fields from term.specs, but only if they exist
|
|
126
128
|
for field in selected_term_fields:
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
if field in term.specs:
|
|
130
|
+
data[field] = term.specs[field]
|
|
131
|
+
|
|
132
|
+
# Create instance with all fields initially
|
|
133
|
+
# We need type for validation, will remove it if not selected
|
|
134
|
+
if "type" not in data:
|
|
135
|
+
data["type"] = type
|
|
136
|
+
if "description" not in data:
|
|
137
|
+
data["description"] = "" # Use default value
|
|
138
|
+
|
|
139
|
+
subset = DataDescriptorSubSet.model_construct(**data)
|
|
140
|
+
|
|
141
|
+
# Now remove unselected optional fields using delattr
|
|
142
|
+
# This maintains backward compatibility (hasattr will return False)
|
|
143
|
+
if "type" not in selected_term_fields and hasattr(subset, "type"):
|
|
144
|
+
delattr(subset, "type")
|
|
145
|
+
if "description" not in selected_term_fields and hasattr(subset, "description"):
|
|
146
|
+
delattr(subset, "description")
|
|
147
|
+
|
|
148
|
+
# Mark which fields were actually set
|
|
149
|
+
subset.__pydantic_fields_set__ = {"id"} | set(selected_term_fields)
|
|
133
150
|
|
|
134
|
-
for field in DataDescriptorSubSet.MANDATORY_TERM_FIELDS:
|
|
135
|
-
# Use model's default value if field is missing from specs
|
|
136
|
-
if field in model_fields and field not in term.specs:
|
|
137
|
-
default_value = model_fields[field].default
|
|
138
|
-
setattr(subset, field, default_value if default_value is not None else term.specs.get(field, None))
|
|
139
|
-
else:
|
|
140
|
-
setattr(subset, field, term.specs.get(field, None))
|
|
141
151
|
return subset
|
|
142
152
|
else:
|
|
143
153
|
term_class = get_pydantic_class(type)
|
esgvoc/api/universe.py
CHANGED
|
@@ -3,7 +3,7 @@ from typing import Iterable, Sequence
|
|
|
3
3
|
from sqlalchemy import text
|
|
4
4
|
from sqlmodel import Session, col, select
|
|
5
5
|
|
|
6
|
-
from esgvoc.api.data_descriptors.data_descriptor import DataDescriptor
|
|
6
|
+
from esgvoc.api.data_descriptors.data_descriptor import DataDescriptor, DataDescriptorSubSet
|
|
7
7
|
from esgvoc.api.pydantic_handler import instantiate_pydantic_term
|
|
8
8
|
from esgvoc.api.search import (
|
|
9
9
|
Item,
|
|
@@ -28,7 +28,7 @@ def _get_all_terms_in_data_descriptor(
|
|
|
28
28
|
|
|
29
29
|
def get_all_terms_in_data_descriptor(
|
|
30
30
|
data_descriptor_id: str, selected_term_fields: Iterable[str] | None = None
|
|
31
|
-
) -> list[DataDescriptor]:
|
|
31
|
+
) -> list[DataDescriptor | DataDescriptorSubSet]:
|
|
32
32
|
"""
|
|
33
33
|
Gets all the terms of the given data descriptor.
|
|
34
34
|
This function performs an exact match on the `data_descriptor_id` and does not search
|
|
@@ -38,10 +38,13 @@ def get_all_terms_in_data_descriptor(
|
|
|
38
38
|
:param data_descriptor_id: A data descriptor id
|
|
39
39
|
:type data_descriptor_id: str
|
|
40
40
|
:param selected_term_fields: A list of term fields to select or `None`. If `None`, all the \
|
|
41
|
-
fields of the terms are returned. If
|
|
41
|
+
fields of the terms are returned (full DataDescriptor). If provided, only the selected fields \
|
|
42
|
+
are included (returns DataDescriptorSubSet with id + selected fields that exist).
|
|
42
43
|
:type selected_term_fields: Iterable[str] | None
|
|
43
|
-
:returns:
|
|
44
|
-
|
|
44
|
+
:returns: A list of term instances. Each term is a full DataDescriptor when \
|
|
45
|
+
selected_term_fields is None, or a DataDescriptorSubSet when selected_term_fields is provided. \
|
|
46
|
+
Returns an empty list if no matches are found.
|
|
47
|
+
:rtype: list[DataDescriptor | DataDescriptorSubSet]
|
|
45
48
|
"""
|
|
46
49
|
with get_universe_session() as session:
|
|
47
50
|
data_descriptor = _get_data_descriptor_in_universe(data_descriptor_id, session)
|
|
@@ -74,16 +77,18 @@ def get_all_data_descriptors_in_universe() -> list[str]:
|
|
|
74
77
|
return result
|
|
75
78
|
|
|
76
79
|
|
|
77
|
-
def get_all_terms_in_universe(selected_term_fields: Iterable[str] | None = None) -> list[DataDescriptor]:
|
|
80
|
+
def get_all_terms_in_universe(selected_term_fields: Iterable[str] | None = None) -> list[DataDescriptor | DataDescriptorSubSet]:
|
|
78
81
|
"""
|
|
79
82
|
Gets all the terms of the universe.
|
|
80
83
|
Terms are unique within a data descriptor but may have some synonyms in the universe.
|
|
81
84
|
|
|
82
85
|
:param selected_term_fields: A list of term fields to select or `None`. If `None`, all the \
|
|
83
|
-
fields of the terms are returned. If
|
|
86
|
+
fields of the terms are returned (full DataDescriptor). If provided, only the selected fields \
|
|
87
|
+
are included (returns DataDescriptorSubSet with id + selected fields that exist).
|
|
84
88
|
:type selected_term_fields: Iterable[str] | None
|
|
85
|
-
:returns: A list of term instances.
|
|
86
|
-
|
|
89
|
+
:returns: A list of term instances. Each term is a full DataDescriptor when \
|
|
90
|
+
selected_term_fields is None, or a DataDescriptorSubSet when selected_term_fields is provided.
|
|
91
|
+
:rtype: list[DataDescriptor | DataDescriptorSubSet]
|
|
87
92
|
"""
|
|
88
93
|
result = list()
|
|
89
94
|
with get_universe_session() as session:
|
|
@@ -104,7 +109,7 @@ def _get_term_in_data_descriptor(data_descriptor_id: str, term_id: str, session:
|
|
|
104
109
|
|
|
105
110
|
def get_term_in_data_descriptor(
|
|
106
111
|
data_descriptor_id: str, term_id: str, selected_term_fields: Iterable[str] | None = None
|
|
107
|
-
) -> DataDescriptor | None:
|
|
112
|
+
) -> DataDescriptor | DataDescriptorSubSet | None:
|
|
108
113
|
"""
|
|
109
114
|
Returns the term, in the given data descriptor, whose id corresponds exactly to the given term id.
|
|
110
115
|
This function performs an exact match on the `term_id` and the `data_descriptor_id` and does
|
|
@@ -116,10 +121,12 @@ def get_term_in_data_descriptor(
|
|
|
116
121
|
:param term_id: The id of a term to be found.
|
|
117
122
|
:type term_id: str
|
|
118
123
|
:param selected_term_fields: A list of term fields to select or `None`. If `None`, all the \
|
|
119
|
-
fields of the terms are returned. If
|
|
124
|
+
fields of the terms are returned (full DataDescriptor). If provided, only the selected fields \
|
|
125
|
+
are included (returns DataDescriptorSubSet with id + selected fields that exist).
|
|
120
126
|
:type selected_term_fields: Iterable[str] | None
|
|
121
|
-
:returns: A term instance.
|
|
122
|
-
|
|
127
|
+
:returns: A term instance. The term is a full DataDescriptor when selected_term_fields is None, \
|
|
128
|
+
or a DataDescriptorSubSet when selected_term_fields is provided. Returns `None` if no match is found.
|
|
129
|
+
:rtype: DataDescriptor | DataDescriptorSubSet | None
|
|
123
130
|
"""
|
|
124
131
|
with get_universe_session() as session:
|
|
125
132
|
term_found = _get_term_in_data_descriptor(data_descriptor_id, term_id, session)
|
|
@@ -137,7 +144,7 @@ def _get_term_in_universe(term_id: str, session: Session) -> UTerm | None:
|
|
|
137
144
|
return result
|
|
138
145
|
|
|
139
146
|
|
|
140
|
-
def get_term_in_universe(term_id: str, selected_term_fields: Iterable[str] | None = None) -> DataDescriptor | None:
|
|
147
|
+
def get_term_in_universe(term_id: str, selected_term_fields: Iterable[str] | None = None) -> DataDescriptor | DataDescriptorSubSet | None:
|
|
141
148
|
"""
|
|
142
149
|
Returns the first occurrence of the terms, in the universe, whose id corresponds exactly to
|
|
143
150
|
the given term id.
|
|
@@ -148,10 +155,12 @@ def get_term_in_universe(term_id: str, selected_term_fields: Iterable[str] | Non
|
|
|
148
155
|
:param term_id: The id of a term to be found.
|
|
149
156
|
:type term_id: str
|
|
150
157
|
:param selected_term_fields: A list of term fields to select or `None`. If `None`, all the \
|
|
151
|
-
fields of the terms are returned. If
|
|
158
|
+
fields of the terms are returned (full DataDescriptor). If provided, only the selected fields \
|
|
159
|
+
are included (returns DataDescriptorSubSet with id + selected fields that exist).
|
|
152
160
|
:type selected_term_fields: Iterable[str] | None
|
|
153
|
-
:returns: A term instance.
|
|
154
|
-
|
|
161
|
+
:returns: A term instance. The term is a full DataDescriptor when selected_term_fields is None, \
|
|
162
|
+
or a DataDescriptorSubSet when selected_term_fields is provided. Returns `None` if no match is found.
|
|
163
|
+
:rtype: DataDescriptor | DataDescriptorSubSet | None
|
|
155
164
|
"""
|
|
156
165
|
with get_universe_session() as session:
|
|
157
166
|
term_found = _get_term_in_universe(term_id, session)
|
esgvoc/cli/get.py
CHANGED
|
@@ -107,7 +107,7 @@ def display(data: Any):
|
|
|
107
107
|
@app.command()
|
|
108
108
|
def get(
|
|
109
109
|
keys: List[str] = typer.Argument(..., help="List of keys in XXXX:YYYY:ZZZZ format"),
|
|
110
|
-
select: Optional[List[str]] = typer.Option(None, "--select", help="keys selected for the result"),
|
|
110
|
+
select: Optional[List[str]] = typer.Option(None, "--select", help="keys selected for the result. Can be used as --select field1 --select field2 or --select [field1,field2]"),
|
|
111
111
|
):
|
|
112
112
|
"""
|
|
113
113
|
Retrieve a specific value from the database system.\n
|
|
@@ -117,25 +117,65 @@ def get(
|
|
|
117
117
|
|
|
118
118
|
Usage:\n
|
|
119
119
|
`get <project>:<collection>:<term>`\n
|
|
120
|
+
`get <project>:<collection>:<term> --select <field>`\n
|
|
121
|
+
`get <project>:<collection>:<term> --select [<field1>,<field2>,...]`\n
|
|
120
122
|
\n
|
|
121
123
|
Arguments:\n
|
|
122
124
|
<project>\tThe project id to query. like `cmip6plus`\n
|
|
123
125
|
<collection>\tThe collection id in the specified database.\n
|
|
124
126
|
<term>\t\tThe term id within the specified collection.\n
|
|
125
127
|
\n
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
Options:\n
|
|
129
|
+
--select\tSelect specific fields to display. By default, all fields are returned.\n
|
|
130
|
+
\t\tThe result will always include the 'id' field plus the selected fields.\n
|
|
131
|
+
\t\tYou can use this option in multiple ways:\n
|
|
132
|
+
\t\t - Single field: --select drs_name\n
|
|
133
|
+
\t\t - Multiple flags: --select drs_name --select description\n
|
|
134
|
+
\t\t - Bracket notation: --select [drs_name,description]\n
|
|
135
|
+
\n
|
|
136
|
+
Examples:\n
|
|
137
|
+
Retrieve full term information:\n
|
|
128
138
|
`get cmip6plus:institution_id:ipsl`\n
|
|
129
|
-
|
|
130
|
-
|
|
139
|
+
\n
|
|
140
|
+
Retrieve only specific fields:\n
|
|
141
|
+
`get :activity:volmip --select drs_name`\n
|
|
142
|
+
Returns: id='volmip' drs_name='VolMIP'\n
|
|
143
|
+
\n
|
|
144
|
+
Retrieve multiple fields using bracket notation:\n
|
|
145
|
+
`get :activity:volmip --select [drs_name,description]`\n
|
|
146
|
+
Returns: id='volmip' drs_name='VolMIP' description=...\n
|
|
147
|
+
\n
|
|
148
|
+
Retrieve multiple fields using multiple flags:\n
|
|
149
|
+
`get :activity:volmip --select drs_name --select description`\n
|
|
150
|
+
\n
|
|
151
|
+
List all terms in a collection with selected fields:\n
|
|
152
|
+
`get :activity: --select drs_name`\n
|
|
153
|
+
\n
|
|
154
|
+
The default project is the universe CV: the argument would be like `universe:institution:ipsl` or `:institution:ipsl`\n
|
|
131
155
|
\n
|
|
132
156
|
\n
|
|
133
157
|
Notes:\n
|
|
134
158
|
- Ensure data exist in your system before using this command (use `esgvoc status` command to see whats available).\n
|
|
135
159
|
- Use a colon (`:`) to separate the parts of the argument. \n
|
|
136
|
-
-
|
|
160
|
+
- If more than one argument is given i.e get X:Y:Z A:B:C the 2 results are appended. \n
|
|
161
|
+
- The 'id' field is always included in the result, even when using --select.\n
|
|
137
162
|
\n
|
|
138
163
|
"""
|
|
164
|
+
# Parse select parameter to handle bracket notation [field1,field2,...]
|
|
165
|
+
parsed_select = None
|
|
166
|
+
if select is not None:
|
|
167
|
+
parsed_select = []
|
|
168
|
+
for item in select:
|
|
169
|
+
# Check if item is in bracket notation like [field1,field2]
|
|
170
|
+
if item.startswith("[") and item.endswith("]"):
|
|
171
|
+
# Remove brackets and split by comma
|
|
172
|
+
fields = item[1:-1].split(",")
|
|
173
|
+
# Strip whitespace and quotes from each field
|
|
174
|
+
parsed_select.extend([f.strip().strip("'\"") for f in fields if f.strip()])
|
|
175
|
+
else:
|
|
176
|
+
# Regular field, just add it
|
|
177
|
+
parsed_select.append(item.strip().strip("'\""))
|
|
178
|
+
|
|
139
179
|
known_projects = get_all_projects()
|
|
140
180
|
|
|
141
181
|
# Validate and process each key
|
|
@@ -146,9 +186,9 @@ def get(
|
|
|
146
186
|
what = what if what != "" else None
|
|
147
187
|
who = who if who != "" else None
|
|
148
188
|
if where == "" or where == "universe":
|
|
149
|
-
res = handle_universe(what, who,
|
|
189
|
+
res = handle_universe(what, who, parsed_select)
|
|
150
190
|
elif where in known_projects:
|
|
151
|
-
res = handle_project(where, what, who,
|
|
191
|
+
res = handle_project(where, what, who, parsed_select)
|
|
152
192
|
else:
|
|
153
193
|
res = handle_unknown(where, what, who)
|
|
154
194
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: esgvoc
|
|
3
|
-
Version: 2.0
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: python library and CLI to interact with WCRP CVs
|
|
5
5
|
Project-URL: Repository, https://github.com/ESGF/esgf-vocab
|
|
6
6
|
Author-email: Sébastien Gardoll <sebastien@gardoll.fr>, Guillaume Levavasseur <guillaume.levavasseur@ipsl.fr>, Laurent Troussellier <laurent.troussellier@ipsl.fr>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
esgvoc/__init__.py,sha256=
|
|
1
|
+
esgvoc/__init__.py,sha256=2csMOm138N0yfN9CTw8qW94oSOWgtMvOh5_oryxlx9E,66
|
|
2
2
|
esgvoc/api/__init__.py,sha256=5MK2lhD2L8DC_qlVjj5KNJNQ90UkX60eoPJOBuSG18A,3916
|
|
3
3
|
esgvoc/api/project_specs.py,sha256=-kjNx6EcFRKJrMU7yy_0YmMqTv4Crvh4e2fPI2wGrbI,4285
|
|
4
|
-
esgvoc/api/projects.py,sha256=
|
|
4
|
+
esgvoc/api/projects.py,sha256=6KCmVnTOnni6DcNK8oQi8TRdBQJ5ftg7RF2a1-tMOvc,61187
|
|
5
5
|
esgvoc/api/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
esgvoc/api/pydantic_handler.py,sha256=
|
|
6
|
+
esgvoc/api/pydantic_handler.py,sha256=10m7h7WlMDwaToaa7FVAB5bV9I_7_dzY7QhupxsPuVQ,6254
|
|
7
7
|
esgvoc/api/report.py,sha256=OlK5ApnaikMKmC6FyJ1uTSBeTezZe85yTCJwsk14uZE,3526
|
|
8
8
|
esgvoc/api/search.py,sha256=W0RHTymqn67exjp0DJWNMC9mxX4EpMgLKEdMXsOYeLw,6665
|
|
9
|
-
esgvoc/api/universe.py,sha256=
|
|
9
|
+
esgvoc/api/universe.py,sha256=6w4va8sm0afunAOjelfIwE7kytMT5a_RA-czw4JT3hA,22455
|
|
10
10
|
esgvoc/api/data_descriptors/__init__.py,sha256=yqTDrr7VydWPUUkoZ3EC9c4xclHrKXKscSDB8cnELmM,8090
|
|
11
11
|
esgvoc/api/data_descriptors/activity.py,sha256=ZJ5_jHNaFcX78Hho_ve-G7YiArSm_-U7wVd0rtnKzoE,2179
|
|
12
12
|
esgvoc/api/data_descriptors/archive.py,sha256=5tmY5AsKAvyoU8839VdzLCbvP0pAhrCYP6EggZXFMTY,131
|
|
@@ -17,7 +17,7 @@ esgvoc/api/data_descriptors/citation_url.py,sha256=R0bjM8MU6IdqvLzc4q0aeAbndmRod
|
|
|
17
17
|
esgvoc/api/data_descriptors/contact.py,sha256=q1tNm8VcG7xvv4ophVIuy58_2y-rSozs86c7_gMupdk,135
|
|
18
18
|
esgvoc/api/data_descriptors/conventions.py,sha256=U3qugWG1KRIqxQqvUTFFc5v9DtTdxNAIQxc_bZAA6ns,1072
|
|
19
19
|
esgvoc/api/data_descriptors/creation_date.py,sha256=QftPsJwoEmpitTs6xnWHVGZytppYymiouD33Vanp8gM,566
|
|
20
|
-
esgvoc/api/data_descriptors/data_descriptor.py,sha256=
|
|
20
|
+
esgvoc/api/data_descriptors/data_descriptor.py,sha256=ndenK4yInquk8ehiuIAQpIuZH9xkCVhffUU7z1mOwxI,4832
|
|
21
21
|
esgvoc/api/data_descriptors/data_specs_version.py,sha256=Sy1JI2bZOP0RNylkGMfJveV-OhSQgyPYCwkhUuKDHyo,1003
|
|
22
22
|
esgvoc/api/data_descriptors/date.py,sha256=mkWivY0orl0wha38sMamrVbUbdZks-iUS_Wf6Gqz0-4,132
|
|
23
23
|
esgvoc/api/data_descriptors/directory_date.py,sha256=lq50IGnUrgWstPHjwW0w0_DMFDYDet19BesZWly9nQE,743
|
|
@@ -62,7 +62,7 @@ esgvoc/api/data_descriptors/EMD_models/arrangement.py,sha256=W8PR1dJ4DJTKDIY2h-z
|
|
|
62
62
|
esgvoc/api/data_descriptors/EMD_models/calendar.py,sha256=jBLtjK5aQBoPPnWzPse6ZDRhlcBAjvEAJitBvm1kmZU,132
|
|
63
63
|
esgvoc/api/data_descriptors/EMD_models/cell_variable_type.py,sha256=T12HPRU1l3HGoQEkfMLee7NQjwE_nOyBIU5mIk6hd1I,488
|
|
64
64
|
esgvoc/api/data_descriptors/EMD_models/component_type.py,sha256=3oMEtc9DMqHnN09zbRNKN6FEHub5i4O_Umw_5j0of6E,137
|
|
65
|
-
esgvoc/api/data_descriptors/EMD_models/coordinate.py,sha256=
|
|
65
|
+
esgvoc/api/data_descriptors/EMD_models/coordinate.py,sha256=5YNb8eT0bGES4_FoQ-1yH3WolXZkJ3SawBVk4pY6Y4Q,2470
|
|
66
66
|
esgvoc/api/data_descriptors/EMD_models/grid_mapping.py,sha256=dI0tH5Ag36af-39OYNuKKKoF52xyxRhtN8Xd3z3D6F4,436
|
|
67
67
|
esgvoc/api/data_descriptors/EMD_models/grid_region.py,sha256=GUaJwSidLHVCdKNJetPgAAoqyBqMfyRWx9495Y1-T7k,445
|
|
68
68
|
esgvoc/api/data_descriptors/EMD_models/grid_type.py,sha256=Z4MFHr8WWIVskv8w9JsjtFeaSaAyWYfjuNdCuxt52_Y,444
|
|
@@ -72,8 +72,8 @@ esgvoc/api/data_descriptors/EMD_models/horizontal_subgrid.py,sha256=vSUsrDhRX6VV
|
|
|
72
72
|
esgvoc/api/data_descriptors/EMD_models/horizontal_units.py,sha256=npSeoQNf0-OqFCzhLGwZGXIjoTK2R7DE288o3-qPYLQ,139
|
|
73
73
|
esgvoc/api/data_descriptors/EMD_models/model.py,sha256=CGQ9iosUqHr0zboJnugEsPJxMBgWiOp7WX6dxE8dCfw,5031
|
|
74
74
|
esgvoc/api/data_descriptors/EMD_models/model_component.py,sha256=Cy3kF2HccH5VObes3AWcEdimOw5JSBMGhP3Yr8-Op4c,4629
|
|
75
|
-
esgvoc/api/data_descriptors/EMD_models/reference.py,sha256
|
|
76
|
-
esgvoc/api/data_descriptors/EMD_models/resolution.py,sha256=
|
|
75
|
+
esgvoc/api/data_descriptors/EMD_models/reference.py,sha256=-Gywq1a-H1yhqJSjI_Vn9HAalGX_A5iXrGjNfmq71Fg,2464
|
|
76
|
+
esgvoc/api/data_descriptors/EMD_models/resolution.py,sha256=iFT4Bm0xiK4AKgzMdQ1u9_9Zf0_HfQivGvITiR8Hv3I,1261
|
|
77
77
|
esgvoc/api/data_descriptors/EMD_models/temporal_refinement.py,sha256=7vSJb5kUkoH_0AWKOLO-MsuJ9JCYGsuE0ts4CbQm09A,421
|
|
78
78
|
esgvoc/api/data_descriptors/EMD_models/truncation_method.py,sha256=TBKVGeha7Tjg2xSrLVRzhCQdQc5Y14Vx-aoVjJRz1eQ,383
|
|
79
79
|
esgvoc/api/data_descriptors/EMD_models/vertical_computational_grid.py,sha256=3EQtYfLI8ncYkxrvnPgaoPvdNTqdzLNcjW8AkSjlG9U,4176
|
|
@@ -110,7 +110,7 @@ esgvoc/cli/cmor.py,sha256=Q1Q0AvP3Up8wAkylSGveBw1c_Mqo752wEE2NTUDqCYw,1098
|
|
|
110
110
|
esgvoc/cli/config.py,sha256=iPU6OKkHQEo2qXdzjl35C5-C_I8pu122E2H7xj0HpYs,52555
|
|
111
111
|
esgvoc/cli/drs.py,sha256=X89syVrxs82ZIc1YdWRPw_HmafOZH1u-wXRe6N-xBcM,9427
|
|
112
112
|
esgvoc/cli/find.py,sha256=DxpEvSbQIJ3-XL-pgH5RicBzS3asjG2Cn_fJhjXKSoU,4497
|
|
113
|
-
esgvoc/cli/get.py,sha256=
|
|
113
|
+
esgvoc/cli/get.py,sha256=hxVUEkVOcZPq47fHXA4SRPTwlCYDvLN3g-6sw9S8so8,7368
|
|
114
114
|
esgvoc/cli/install.py,sha256=qTtWQp0SlpQ7uIJnUeFUfdU0RRb2s55QAv11TogfwGk,1381
|
|
115
115
|
esgvoc/cli/main.py,sha256=QzDhSXRnc1e3RlXD7KJBCwlnQV_DL-f9zaAlzlqoyx4,1866
|
|
116
116
|
esgvoc/cli/offline.py,sha256=I9gccId98FLXPQ9VOmmZQ9aU_zfZYtCGZyO7XabQnc8,9007
|
|
@@ -140,8 +140,8 @@ esgvoc/core/service/term_cache.py,sha256=xH8No2w8KXDg7N3L9b4bv-dMGwqvlbko1bPxPMT
|
|
|
140
140
|
esgvoc/core/service/uri_resolver.py,sha256=USDvnEkJwPJgdGduup_EQJODHZyAWj62MG8-AEaLMTo,3963
|
|
141
141
|
esgvoc/core/service/configuration/config_manager.py,sha256=adKeK8xDE72UIfYqQ4pc7pPxAmBuCsybyx7ZdchbL6U,8797
|
|
142
142
|
esgvoc/core/service/configuration/setting.py,sha256=aaBE6P8TttQr0kJjSRNH4Vaa_guWPFQGHdB24B1oYtU,13514
|
|
143
|
-
esgvoc-2.0.
|
|
144
|
-
esgvoc-2.0.
|
|
145
|
-
esgvoc-2.0.
|
|
146
|
-
esgvoc-2.0.
|
|
147
|
-
esgvoc-2.0.
|
|
143
|
+
esgvoc-2.1.0.dist-info/METADATA,sha256=NSc8Jrv6DX_8Kaav4TQfyjryfJ-lc7vcjtL0_92aPbE,2368
|
|
144
|
+
esgvoc-2.1.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
145
|
+
esgvoc-2.1.0.dist-info/entry_points.txt,sha256=ZXufSC7Jlx1lb52U6Buv9IitJMcqAAXOerR2V9DaIto,48
|
|
146
|
+
esgvoc-2.1.0.dist-info/licenses/LICENSE.txt,sha256=rWJoZt3vach8ZNdLq-Ee5djzCMFnJ1gIfBeJU5RIop4,21782
|
|
147
|
+
esgvoc-2.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|