esgvoc 0.2.1__py3-none-any.whl → 0.4.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.
- esgvoc/__init__.py +3 -1
- esgvoc/api/__init__.py +96 -72
- esgvoc/api/data_descriptors/__init__.py +18 -12
- esgvoc/api/data_descriptors/activity.py +8 -45
- esgvoc/api/data_descriptors/area_label.py +6 -0
- esgvoc/api/data_descriptors/branded_suffix.py +5 -0
- esgvoc/api/data_descriptors/branded_variable.py +5 -0
- esgvoc/api/data_descriptors/consortium.py +16 -56
- esgvoc/api/data_descriptors/data_descriptor.py +106 -0
- esgvoc/api/data_descriptors/date.py +3 -46
- esgvoc/api/data_descriptors/directory_date.py +3 -46
- esgvoc/api/data_descriptors/experiment.py +19 -54
- esgvoc/api/data_descriptors/forcing_index.py +3 -45
- esgvoc/api/data_descriptors/frequency.py +6 -43
- esgvoc/api/data_descriptors/grid_label.py +6 -44
- esgvoc/api/data_descriptors/horizontal_label.py +6 -0
- esgvoc/api/data_descriptors/initialisation_index.py +3 -44
- esgvoc/api/data_descriptors/institution.py +11 -54
- esgvoc/api/data_descriptors/license.py +4 -44
- esgvoc/api/data_descriptors/mip_era.py +6 -44
- esgvoc/api/data_descriptors/model_component.py +7 -45
- esgvoc/api/data_descriptors/organisation.py +3 -40
- esgvoc/api/data_descriptors/physic_index.py +3 -45
- esgvoc/api/data_descriptors/product.py +4 -43
- esgvoc/api/data_descriptors/realisation_index.py +3 -44
- esgvoc/api/data_descriptors/realm.py +4 -42
- esgvoc/api/data_descriptors/resolution.py +6 -44
- esgvoc/api/data_descriptors/source.py +18 -53
- esgvoc/api/data_descriptors/source_type.py +3 -41
- esgvoc/api/data_descriptors/sub_experiment.py +3 -41
- esgvoc/api/data_descriptors/table.py +6 -48
- esgvoc/api/data_descriptors/temporal_label.py +6 -0
- esgvoc/api/data_descriptors/time_range.py +3 -27
- esgvoc/api/data_descriptors/variable.py +13 -71
- esgvoc/api/data_descriptors/variant_label.py +3 -47
- esgvoc/api/data_descriptors/vertical_label.py +5 -0
- esgvoc/api/project_specs.py +3 -2
- esgvoc/api/projects.py +727 -446
- esgvoc/api/py.typed +0 -0
- esgvoc/api/report.py +29 -16
- esgvoc/api/search.py +140 -95
- esgvoc/api/universe.py +362 -156
- esgvoc/apps/__init__.py +3 -4
- esgvoc/apps/drs/constants.py +1 -1
- esgvoc/apps/drs/generator.py +185 -198
- esgvoc/apps/drs/report.py +272 -136
- esgvoc/apps/drs/validator.py +132 -145
- esgvoc/apps/py.typed +0 -0
- esgvoc/cli/drs.py +32 -21
- esgvoc/cli/get.py +35 -31
- esgvoc/cli/install.py +11 -8
- esgvoc/cli/main.py +0 -2
- esgvoc/cli/status.py +5 -5
- esgvoc/cli/valid.py +40 -40
- esgvoc/core/constants.py +1 -1
- esgvoc/core/db/__init__.py +2 -4
- esgvoc/core/db/connection.py +5 -3
- esgvoc/core/db/models/project.py +50 -8
- esgvoc/core/db/models/universe.py +51 -12
- esgvoc/core/db/project_ingestion.py +60 -46
- esgvoc/core/db/universe_ingestion.py +58 -29
- esgvoc/core/exceptions.py +33 -0
- esgvoc/core/logging_handler.py +1 -1
- esgvoc/core/repo_fetcher.py +4 -3
- esgvoc/core/service/__init__.py +37 -5
- esgvoc/core/service/configuration/config_manager.py +188 -0
- esgvoc/core/service/configuration/setting.py +88 -0
- esgvoc/core/service/state.py +49 -32
- {esgvoc-0.2.1.dist-info → esgvoc-0.4.0.dist-info}/METADATA +34 -3
- esgvoc-0.4.0.dist-info/RECORD +80 -0
- esgvoc/api/_utils.py +0 -39
- esgvoc/cli/config.py +0 -82
- esgvoc/core/service/settings.py +0 -73
- esgvoc/core/service/settings.toml +0 -17
- esgvoc/core/service/settings_default.toml +0 -17
- esgvoc-0.2.1.dist-info/RECORD +0 -73
- {esgvoc-0.2.1.dist-info → esgvoc-0.4.0.dist-info}/WHEEL +0 -0
- {esgvoc-0.2.1.dist-info → esgvoc-0.4.0.dist-info}/entry_points.txt +0 -0
- {esgvoc-0.2.1.dist-info → esgvoc-0.4.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
from typing import ClassVar, Dict, Optional
|
|
2
|
+
import toml
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ProjectSettings(BaseModel):
|
|
7
|
+
project_name: str
|
|
8
|
+
github_repo: str
|
|
9
|
+
branch: Optional[str] = "main"
|
|
10
|
+
local_path: Optional[str] = None
|
|
11
|
+
db_path: Optional[str] = None
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class UniverseSettings(BaseModel):
|
|
15
|
+
github_repo: str
|
|
16
|
+
branch: Optional[str] = None
|
|
17
|
+
local_path: Optional[str] = None
|
|
18
|
+
db_path: Optional[str] = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ServiceSettings(BaseModel):
|
|
22
|
+
universe: UniverseSettings
|
|
23
|
+
projects: Dict[str, ProjectSettings] = Field(default_factory=dict)
|
|
24
|
+
|
|
25
|
+
# 🔹 Define default settings
|
|
26
|
+
DEFAULT_SETTINGS : ClassVar[dict]= {
|
|
27
|
+
"universe": {
|
|
28
|
+
"github_repo": "https://github.com/WCRP-CMIP/WCRP-universe",
|
|
29
|
+
"branch": "esgvoc",
|
|
30
|
+
"local_path": "repos/WCRP-universe",
|
|
31
|
+
"db_path": "dbs/universe.sqlite",
|
|
32
|
+
},
|
|
33
|
+
"projects": [
|
|
34
|
+
{
|
|
35
|
+
"project_name": "cmip6",
|
|
36
|
+
"github_repo": "https://github.com/WCRP-CMIP/CMIP6_CVs",
|
|
37
|
+
"branch": "esgvoc",
|
|
38
|
+
"local_path": "repos/CMIP6_CVs",
|
|
39
|
+
"db_path": "dbs/cmip6.sqlite",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"project_name": "cmip6plus",
|
|
43
|
+
"github_repo": "https://github.com/WCRP-CMIP/CMIP6Plus_CVs",
|
|
44
|
+
"branch": "esgvoc",
|
|
45
|
+
"local_path": "repos/CMIP6Plus_CVs",
|
|
46
|
+
"db_path": "dbs/cmip6plus.sqlite",
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
def load_from_file(cls, file_path: str) -> "ServiceSettings":
|
|
53
|
+
"""Load configuration from a TOML file, falling back to defaults if necessary."""
|
|
54
|
+
try:
|
|
55
|
+
data = toml.load(file_path)
|
|
56
|
+
except FileNotFoundError:
|
|
57
|
+
data = cls.DEFAULT_SETTINGS # Use defaults if the file is missing
|
|
58
|
+
|
|
59
|
+
projects = {p["project_name"]: ProjectSettings(**p) for p in data.pop("projects", [])}
|
|
60
|
+
return cls(universe=UniverseSettings(**data["universe"]), projects=projects)
|
|
61
|
+
|
|
62
|
+
@classmethod
|
|
63
|
+
def load_default(cls) -> "ServiceSettings":
|
|
64
|
+
"""Load default settings."""
|
|
65
|
+
return cls.load_from_dict(cls.DEFAULT_SETTINGS)
|
|
66
|
+
|
|
67
|
+
@classmethod
|
|
68
|
+
def load_from_dict(cls, config_data: dict) -> "ServiceSettings":
|
|
69
|
+
"""Load configuration from a dictionary."""
|
|
70
|
+
projects = {p["project_name"]: ProjectSettings(**p) for p in config_data.get("projects", [])}
|
|
71
|
+
return cls(universe=UniverseSettings(**config_data["universe"]), projects=projects)
|
|
72
|
+
|
|
73
|
+
def save_to_file(self, file_path: str):
|
|
74
|
+
"""Save the configuration to a TOML file."""
|
|
75
|
+
data = {
|
|
76
|
+
"universe": self.universe.model_dump(),
|
|
77
|
+
"projects": [p.model_dump() for p in self.projects.values()],
|
|
78
|
+
}
|
|
79
|
+
with open(file_path, "w") as f:
|
|
80
|
+
toml.dump(data, f)
|
|
81
|
+
|
|
82
|
+
def dump(self)->dict:
|
|
83
|
+
data = {
|
|
84
|
+
"universe": self.universe.model_dump(),
|
|
85
|
+
"projects": [p.model_dump() for p in self.projects.values()],
|
|
86
|
+
}
|
|
87
|
+
return data
|
|
88
|
+
|
esgvoc/core/service/state.py
CHANGED
|
@@ -4,7 +4,7 @@ from pathlib import Path
|
|
|
4
4
|
from typing import Optional
|
|
5
5
|
|
|
6
6
|
from esgvoc.core.repo_fetcher import RepoFetcher
|
|
7
|
-
from esgvoc.core.service.
|
|
7
|
+
from esgvoc.core.service.configuration.setting import UniverseSettings, ProjectSettings, ServiceSettings
|
|
8
8
|
from esgvoc.core.db.connection import DBConnection
|
|
9
9
|
|
|
10
10
|
from rich.table import Table
|
|
@@ -13,27 +13,38 @@ from sqlmodel import select
|
|
|
13
13
|
from esgvoc.core.db.models.universe import Universe
|
|
14
14
|
from esgvoc.core.db.models.project import Project
|
|
15
15
|
|
|
16
|
+
|
|
16
17
|
logger = logging.getLogger(__name__)
|
|
17
18
|
|
|
18
19
|
class BaseState:
|
|
19
20
|
def __init__(self, github_repo: str, branch: str = "main", local_path: Optional[str] = None, db_path: Optional[str] = None):
|
|
20
|
-
|
|
21
|
-
self.github_repo = github_repo
|
|
22
|
-
self.branch = branch
|
|
23
|
-
self.github_access = True # False if we dont have internet and some other cases
|
|
24
|
-
self.github_version = None
|
|
25
21
|
|
|
26
|
-
|
|
27
|
-
self.
|
|
28
|
-
|
|
22
|
+
from esgvoc.core.service import config_manager
|
|
23
|
+
self.base_dir = config_manager.data_config_dir # needed for repofetcher
|
|
24
|
+
|
|
25
|
+
self.github_repo : str = github_repo
|
|
26
|
+
self.branch : str = branch
|
|
27
|
+
self.github_access : bool = True # False if we dont have internet and some other cases
|
|
28
|
+
self.github_version : str | None = None
|
|
29
29
|
|
|
30
|
-
self.
|
|
31
|
-
self.
|
|
32
|
-
self.
|
|
30
|
+
self.local_path : str | None = self._get_absolute_path(str(self.base_dir),local_path)
|
|
31
|
+
self.local_access : bool = True # False if we dont have cloned the remote repo yet
|
|
32
|
+
self.local_version : str | None = None
|
|
33
33
|
|
|
34
|
-
self.
|
|
34
|
+
self.db_path : str | None = self._get_absolute_path(str(self.base_dir), db_path)
|
|
35
|
+
self.db_access : bool = True # False if we cant access the db for some reason
|
|
36
|
+
self.db_version : str | None = None
|
|
37
|
+
|
|
38
|
+
self.rf = RepoFetcher(local_path=str(self.base_dir))
|
|
35
39
|
self.db_connection:DBConnection|None = None
|
|
36
|
-
self.db_sqlmodel = None
|
|
40
|
+
self.db_sqlmodel :Universe | Project| None = None
|
|
41
|
+
|
|
42
|
+
def _get_absolute_path(self,base_dir:str,path:str|None)->str|None:
|
|
43
|
+
if base_dir !="" and path is not None:
|
|
44
|
+
return base_dir + "/"+ path
|
|
45
|
+
if base_dir == "":
|
|
46
|
+
return path
|
|
47
|
+
|
|
37
48
|
|
|
38
49
|
def fetch_version_local(self):
|
|
39
50
|
if self.local_path:
|
|
@@ -54,9 +65,12 @@ class BaseState:
|
|
|
54
65
|
self.github_version = self.rf.get_github_version(owner, repo, self.branch)
|
|
55
66
|
self.github_access = True
|
|
56
67
|
logger.debug(f"Latest GitHub commit: {self.github_version}")
|
|
68
|
+
except IndexError as e:
|
|
69
|
+
self.github_access = False
|
|
57
70
|
except Exception as e:
|
|
58
71
|
logger.exception(f"Failed to fetch GitHub version: {e} ,for {self.github_repo},owner : {owner}, repo : {repo},branch : {self.branch}")
|
|
59
72
|
self.github_access = False
|
|
73
|
+
|
|
60
74
|
if self.github_version is None:
|
|
61
75
|
self.github_access = False
|
|
62
76
|
|
|
@@ -67,7 +81,7 @@ class BaseState:
|
|
|
67
81
|
self.db_access = False
|
|
68
82
|
else:
|
|
69
83
|
try:
|
|
70
|
-
self.db_connection =DBConnection(db_file_path= Path(self.db_path))
|
|
84
|
+
self.db_connection = DBConnection(db_file_path= Path(self.db_path))
|
|
71
85
|
with self.db_connection.create_session() as session:
|
|
72
86
|
self.db_version = session.exec(select(self.db_sqlmodel.git_hash)).one()
|
|
73
87
|
self.db_access = True
|
|
@@ -82,7 +96,8 @@ class BaseState:
|
|
|
82
96
|
|
|
83
97
|
|
|
84
98
|
def fetch_versions(self):
|
|
85
|
-
self.
|
|
99
|
+
if self.github_access:
|
|
100
|
+
self.fetch_version_remote()
|
|
86
101
|
self.fetch_version_local()
|
|
87
102
|
self.fetch_version_db()
|
|
88
103
|
|
|
@@ -92,18 +107,17 @@ class BaseState:
|
|
|
92
107
|
"github" : self.github_version if self.github_version else None,
|
|
93
108
|
"local": self.local_version if self.local_version else None,
|
|
94
109
|
"db" : self.db_version if self.db_version else None,
|
|
95
|
-
"github_local_sync": self.github_version == self.local_version if self.github_access and self.github_version and self.local_version else
|
|
96
|
-
"local_db_sync": self.local_version == self.db_version if self.local_access and self.local_version
|
|
97
|
-
|
|
98
|
-
"github_db_sync": self.github_version == self.db_version if self.github_access and self.github_version and self.db_version else None
|
|
110
|
+
"github_local_sync": self.github_version == self.local_version if self.github_access and self.github_version and self.local_version else False,
|
|
111
|
+
"local_db_sync": self.local_version == self.db_version if self.local_access and self.local_version else False,
|
|
112
|
+
"github_db_sync": self.github_version == self.db_version if self.github_access and self.github_version else False
|
|
99
113
|
}
|
|
100
114
|
|
|
101
115
|
def clone_remote(self):
|
|
102
116
|
owner, repo = self.github_repo.lstrip("https://github.com/").split("/")
|
|
103
|
-
#TODO add destination "local_path" in clone_repo
|
|
104
|
-
self.rf.clone_repository(owner, repo, self.branch)
|
|
117
|
+
#TODO add destination "local_path" in clone_repo, done in a wierd way Improve that:
|
|
118
|
+
self.rf.clone_repository(owner, repo, self.branch, self.local_path)
|
|
105
119
|
self.fetch_version_local()
|
|
106
|
-
|
|
120
|
+
|
|
107
121
|
|
|
108
122
|
def build_db(self):
|
|
109
123
|
from esgvoc.core.db.project_ingestion import ingest_project
|
|
@@ -121,25 +135,25 @@ class BaseState:
|
|
|
121
135
|
if self.db_sqlmodel == Universe: # Ugly
|
|
122
136
|
print("Building Universe DB from ",self.local_path)
|
|
123
137
|
universe_create_db(Path(self.db_path))
|
|
124
|
-
|
|
138
|
+
self.db_connection = DBConnection(db_file_path= Path(self.db_path))
|
|
139
|
+
|
|
140
|
+
ingest_metadata_universe(self.db_connection,self.local_version)
|
|
125
141
|
print("Filling Universe DB")
|
|
126
|
-
|
|
142
|
+
if self.local_path:
|
|
143
|
+
ingest_universe(Path(self.local_path), Path(self.db_path))
|
|
127
144
|
|
|
128
145
|
elif self.db_sqlmodel == Project:
|
|
129
146
|
print("Building Project DB from ", self.local_path)
|
|
130
147
|
project_create_db(Path(self.db_path))
|
|
131
148
|
print("Filling project DB")
|
|
132
|
-
|
|
149
|
+
if self.local_path and self.local_version:
|
|
150
|
+
ingest_project(Path(self.local_path),Path(self.db_path),self.local_version)
|
|
133
151
|
self.fetch_version_db()
|
|
134
152
|
|
|
135
153
|
|
|
136
154
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
155
|
def sync(self):
|
|
141
156
|
summary = self.check_sync_status()
|
|
142
|
-
|
|
143
157
|
if self.github_access and summary["github_db_sync"] is None and summary["local_db_sync"]is None and summary["github_local_sync"] is None:
|
|
144
158
|
self.clone_remote()
|
|
145
159
|
self.build_db()
|
|
@@ -148,7 +162,7 @@ class BaseState:
|
|
|
148
162
|
if not summary["local_db_sync"] and summary["local_db_sync"] is not None:
|
|
149
163
|
self.clone_remote()
|
|
150
164
|
self.build_db()
|
|
151
|
-
elif not summary["github_local_sync"]
|
|
165
|
+
elif not summary["github_local_sync"] :
|
|
152
166
|
self.clone_remote()
|
|
153
167
|
self.build_db()
|
|
154
168
|
else: # can be simply build in root and clone if neccessary
|
|
@@ -194,13 +208,16 @@ class StateService:
|
|
|
194
208
|
proj_state.fetch_versions()
|
|
195
209
|
|
|
196
210
|
def synchronize_all(self):
|
|
211
|
+
print("sync universe")
|
|
197
212
|
self.universe.sync()
|
|
213
|
+
print("sync projects")
|
|
198
214
|
for project in self.projects.values():
|
|
199
215
|
project.sync()
|
|
216
|
+
|
|
200
217
|
def table(self):
|
|
201
218
|
table = Table(show_header=False, show_lines=True)
|
|
202
219
|
table.add_row("","Remote github repo","Local repository","Cache Database")
|
|
203
|
-
table.add_row("Universe path",self.universe.github_repo,self.universe.local_path,self.universe.db_path)
|
|
220
|
+
table.add_row("Universe path",self.universe.github_repo,self.universe.local_path,self.universe.db_path)
|
|
204
221
|
table.add_row("Version",self.universe.github_version,self.universe.local_version,self.universe.db_version)
|
|
205
222
|
for proj_name,proj in self.projects.items():
|
|
206
223
|
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: esgvoc
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.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>
|
|
7
7
|
License: CECILL-2.1
|
|
8
8
|
Requires-Python: <3.13,>=3.12
|
|
9
9
|
Requires-Dist: idna>=3.10
|
|
10
|
+
Requires-Dist: platformdirs>=4.3.6
|
|
10
11
|
Requires-Dist: pydantic>=2.9.2
|
|
11
12
|
Requires-Dist: pyld>=2.0.4
|
|
12
13
|
Requires-Dist: requests>=2.32.3
|
|
13
|
-
Requires-Dist: sphinx-copybutton>=0.5.2
|
|
14
|
-
Requires-Dist: sphinx-tabs>=3.4.7
|
|
15
14
|
Requires-Dist: sqlalchemy>=2.0.36
|
|
16
15
|
Requires-Dist: sqlmodel>=0.0.22
|
|
17
16
|
Requires-Dist: toml>=0.10.2
|
|
@@ -56,3 +55,35 @@ Following this command to install or update the latest CVs.
|
|
|
56
55
|
```bash
|
|
57
56
|
esgvoc install
|
|
58
57
|
```
|
|
58
|
+
|
|
59
|
+
## How to contribute
|
|
60
|
+
|
|
61
|
+
### Install Python dev environment
|
|
62
|
+
|
|
63
|
+
* Pip
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pip install -e .
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
* Rye
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
rye sync
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Linters & code formatters
|
|
76
|
+
|
|
77
|
+
* Pip
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pip install pre-commit
|
|
81
|
+
pre-commit install
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
* Rye
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
rye install
|
|
88
|
+
rye run pre-commit install
|
|
89
|
+
```
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
esgvoc/__init__.py,sha256=1U7uasmBR5VzekoxCEz4GBNgpPcsEU5BwY-QOSW37qA,66
|
|
2
|
+
esgvoc/api/__init__.py,sha256=w68CdVRS553bDWezZoCTxIFq_vsP7mFluSoO4yUo_Uc,4130
|
|
3
|
+
esgvoc/api/project_specs.py,sha256=a-hEL-tXsfvwFeSU5PBnQZq_tqB7L67wxpB1ACah-no,2330
|
|
4
|
+
esgvoc/api/projects.py,sha256=y6qcBSuW22a4nDB9V8lU6PFUj1j2SOrj3xtu9FKVyS4,57466
|
|
5
|
+
esgvoc/api/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
esgvoc/api/report.py,sha256=OlK5ApnaikMKmC6FyJ1uTSBeTezZe85yTCJwsk14uZE,3526
|
|
7
|
+
esgvoc/api/search.py,sha256=Ss_-EvCQHZc6pBTDJzPUrOE_ErTcdqa-zmLkcBjsVkk,6667
|
|
8
|
+
esgvoc/api/universe.py,sha256=8aEvkTHWv9PEWz9hw_JYDdjJBbHzizi_RdVg9Ua-ook,21830
|
|
9
|
+
esgvoc/api/data_descriptors/__init__.py,sha256=6ldSy7x4rnol7ZykPBn9xtnKq1bT_d8G19LIyJnc_mw,3248
|
|
10
|
+
esgvoc/api/data_descriptors/activity.py,sha256=HZIaFqOVeYKmMJd1B_ihbKTAAAr13wr8IFISZI_jdO8,620
|
|
11
|
+
esgvoc/api/data_descriptors/area_label.py,sha256=sJqHuuLeXqDajZfEatAWX7Jot6I0xnCd1gvFJaA2s_M,161
|
|
12
|
+
esgvoc/api/data_descriptors/branded_suffix.py,sha256=7uvoUfJ5KBWMWmEu_QmjJ9wEzLhvqGuFqsvdS9sXrNQ,157
|
|
13
|
+
esgvoc/api/data_descriptors/branded_variable.py,sha256=vnZxR3EQv9X1z3pRmY_4C_sXkKkYf9-9gebY_F2ldDI,159
|
|
14
|
+
esgvoc/api/data_descriptors/consortium.py,sha256=F8qFon8aKnVrUDkrBIg1DoQwZLUNt8QYUTQaxyYvMCI,807
|
|
15
|
+
esgvoc/api/data_descriptors/data_descriptor.py,sha256=xmrJv1ZLMBBBysVZI6zCC2ZRyUwkOv-aKRHPw9d4bhk,3116
|
|
16
|
+
esgvoc/api/data_descriptors/date.py,sha256=PsLSEI_qNXYxxgdcA2cmxmD5wo9Dd_uoaw9f5hmFHTs,131
|
|
17
|
+
esgvoc/api/data_descriptors/directory_date.py,sha256=UcmBEV-n8-Nl6ML5xVjIswAnOVCvi25aJHj8-1HE8tY,140
|
|
18
|
+
esgvoc/api/data_descriptors/experiment.py,sha256=dZQe0VURghn5zZuX3fPRx9ukGqe4R-8IoIsw7iEiKNY,1073
|
|
19
|
+
esgvoc/api/data_descriptors/forcing_index.py,sha256=ELEUgv5VaRD548EEl1T-_PpdqPdz1rmWPdh-7mfGLQU,139
|
|
20
|
+
esgvoc/api/data_descriptors/frequency.py,sha256=LmDjBSAwHi8vuHIz3SW0r4ewrqh1W94kbFEetCJuPNs,193
|
|
21
|
+
esgvoc/api/data_descriptors/grid_label.py,sha256=HuR37-usYh6FjzE2_e6b7WBbrgAvyjUCc29NJnBEHDE,197
|
|
22
|
+
esgvoc/api/data_descriptors/horizontal_label.py,sha256=V-QkV5Qn3uVYAZ6BGCiaTLxlBx9x1bJZ_nc6H8kH00s,167
|
|
23
|
+
esgvoc/api/data_descriptors/initialisation_index.py,sha256=IknUFQkFCsyvawsUETomiVYhR1vEmCZSeeMqfgie0_8,146
|
|
24
|
+
esgvoc/api/data_descriptors/institution.py,sha256=8AzWTg9tNqkpVa9TnAmfx119opZ_JzvXnnJg-VuSmDE,542
|
|
25
|
+
esgvoc/api/data_descriptors/license.py,sha256=nJaVoJ-CGHd1JYDE8-mo0P6xljRKg1Y9ZopEOcWLeVk,176
|
|
26
|
+
esgvoc/api/data_descriptors/mip_era.py,sha256=WsNPE1t8LBY9HXz97SVoQHWRz0Ao0_5-e1fO4J1lEAE,177
|
|
27
|
+
esgvoc/api/data_descriptors/model_component.py,sha256=rmpKs0njm4mKQ2lxTV0vhZ4aORBSCuouI5zT_DzW6ZE,227
|
|
28
|
+
esgvoc/api/data_descriptors/organisation.py,sha256=m5CHah1NxVl0OmNOUb_Nln8MwMG_Mx-Y3VRlpqY377w,135
|
|
29
|
+
esgvoc/api/data_descriptors/physic_index.py,sha256=jWa1sQdLm90U0TY1JdQ3kgnhhpyJaMUswxdjamMJy8U,138
|
|
30
|
+
esgvoc/api/data_descriptors/product.py,sha256=PYsV_mu8jj62pv4FQJcUoqe7MM_9JqRe-Otn4RdrgQw,157
|
|
31
|
+
esgvoc/api/data_descriptors/realisation_index.py,sha256=zWgUnoM0DWsME5WciQUjb7pIw_FAzDfGPDCyGQ4xSOo,143
|
|
32
|
+
esgvoc/api/data_descriptors/realm.py,sha256=s1J-FsTlEr_BOgW3veynUPVzSwbv71V03TWM4wbUYds,154
|
|
33
|
+
esgvoc/api/data_descriptors/resolution.py,sha256=cEfu1XstWsVIwRs4z34lcyP5wiZYNMyhWNQZ5IplVps,190
|
|
34
|
+
esgvoc/api/data_descriptors/source.py,sha256=IAVh0a3yXEOv0_O025wIRPyZET5_EwgyPxCKfyBwOQ8,1128
|
|
35
|
+
esgvoc/api/data_descriptors/source_type.py,sha256=FQUQwAix2JDo_rx_E-iVV5vHdL3pVGajoSaQMCjDOGQ,145
|
|
36
|
+
esgvoc/api/data_descriptors/sub_experiment.py,sha256=HAQLq8Aq9XQjdmKfkAewTAe4rO7oTiEGdPqhDITVzJg,149
|
|
37
|
+
esgvoc/api/data_descriptors/table.py,sha256=rZp5CpoJSFzc869IaJOMjMDTb6KfcUEZM_fthtVt1Gc,254
|
|
38
|
+
esgvoc/api/data_descriptors/temporal_label.py,sha256=lcEfH36GmWEYL83B0uG5S5Uat17GG8F-9EeFiZ3O01M,165
|
|
39
|
+
esgvoc/api/data_descriptors/time_range.py,sha256=4G9-69DG9bikb1-X9ja2Hsocd_id0Fhco7L35E0uf-c,151
|
|
40
|
+
esgvoc/api/data_descriptors/variable.py,sha256=WtWlYRO0NLPRn1qe7Dt84doJWZYNCvCCqhC0slOPidk,1014
|
|
41
|
+
esgvoc/api/data_descriptors/variant_label.py,sha256=FL8nz0BfvJgKFjMmfBgNyRb8jcHaLBDLPpOvr6mBx9A,155
|
|
42
|
+
esgvoc/api/data_descriptors/vertical_label.py,sha256=g2t-38eE-FY4H_aHrOj-ScZSPHIX6m71oltLcRHOtqI,141
|
|
43
|
+
esgvoc/apps/__init__.py,sha256=Kyq36qRjvTWN7gu4_iFaLOjNUYvW0k1xp8bvkgJlQ5w,269
|
|
44
|
+
esgvoc/apps/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
|
+
esgvoc/apps/drs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
|
+
esgvoc/apps/drs/constants.py,sha256=rVWq1QQwAFgISjvl3YzJDLLPNUPXHpqgv66spmjyPMQ,96
|
|
47
|
+
esgvoc/apps/drs/generator.py,sha256=M0QMtpAaMU4E0142FPqdhix3n034CU_QaPuwvXsWtlA,22392
|
|
48
|
+
esgvoc/apps/drs/report.py,sha256=ZRu5l6T-U-hqY7O3ZwAseYbWZPcJiMhJ2dpFKZJE3Gk,17371
|
|
49
|
+
esgvoc/apps/drs/validator.py,sha256=yNijdOPhF9adgZbya5Ugvs13GbL4MvgQepCT38A66vM,13825
|
|
50
|
+
esgvoc/cli/drs.py,sha256=PvVbLxef34A1IO600AFWOEWb5iLaWrBRHwwgMJ4u-PM,9237
|
|
51
|
+
esgvoc/cli/get.py,sha256=zwLWkWOfAddK5onyRjWZ0zU909MtTDjEB_YrQtIwXqw,5242
|
|
52
|
+
esgvoc/cli/install.py,sha256=zMssevZDrigrUlw1QHWITGUL1TvsHMZBQdYeNtHgWQA,433
|
|
53
|
+
esgvoc/cli/main.py,sha256=kjB-yus-cmG9rOmVIPBhmjOr3tkwB13dHLcNqrdpYAM,483
|
|
54
|
+
esgvoc/cli/status.py,sha256=hmpyrszrb5ke9l_1SgendPSeoXW1h-h7nH0zGFt_vUw,1357
|
|
55
|
+
esgvoc/cli/valid.py,sha256=XrseGONeWR6gnnwZrRMJNjVBFQLT82Uzn5rHrjjM1Uk,7040
|
|
56
|
+
esgvoc/core/constants.py,sha256=i03VR29sQmg89DdQpGZ1fzBT-elT3-_S0bTNraGA6T4,432
|
|
57
|
+
esgvoc/core/convert.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
58
|
+
esgvoc/core/data_handler.py,sha256=BmcD_dSvX5fCkUEGAQnadPTeuKA7IvgMmQtesMXKh5g,5004
|
|
59
|
+
esgvoc/core/exceptions.py,sha256=hs2D1lRWYhFuXDRbApKyJmEZMs8HxTPlSGkDSpkeQiA,538
|
|
60
|
+
esgvoc/core/logging.conf,sha256=GK52lsTu17CfC2tKiMAIvkuHkIt5tqPmkWv68COOilc,278
|
|
61
|
+
esgvoc/core/logging_handler.py,sha256=VgRBWeW_xdC4HtXG0TleQFwoy_YbJR4wlpci_sFezK0,147
|
|
62
|
+
esgvoc/core/repo_fetcher.py,sha256=Rg668F4NN60jd8Ydz9dXpJQxd2eQOgaO0Ziwm53mcaI,9823
|
|
63
|
+
esgvoc/core/db/__init__.py,sha256=fszGxJfRUa6uuuogrdh8_ExtdyMLZSaaVawpdgXzqKM,113
|
|
64
|
+
esgvoc/core/db/connection.py,sha256=AIFo0IWznu0Alk0SK_4bqp6FL5ZqSezNrfc_AlM9Z14,882
|
|
65
|
+
esgvoc/core/db/project_ingestion.py,sha256=M0Yruh7w--Q9JyRnbLynoPiVfmufp8b6h5UuUeNnnPA,7687
|
|
66
|
+
esgvoc/core/db/universe_ingestion.py,sha256=vPNr_svmduX3JKuLA_-SQMTxO2FWMqCNyCWkPSDznNE,6522
|
|
67
|
+
esgvoc/core/db/models/mixins.py,sha256=S4_6iuKf1kYLdUXAgqRKSTXs8H9I--43MKlEq4F-dm4,445
|
|
68
|
+
esgvoc/core/db/models/project.py,sha256=hkDCPJNo3wGt-UMOfujeQYPgju_aH1oExDAnIgoe96M,4369
|
|
69
|
+
esgvoc/core/db/models/universe.py,sha256=vrR1TMD9ZI6RSGRi-qnLEKHD2Qk6Mh3qz8gciPgsELQ,4199
|
|
70
|
+
esgvoc/core/service/__init__.py,sha256=hveqCB4oC6gKDf_L-wZxu9iBz7RiY4x9OeJGP6S5xtU,1534
|
|
71
|
+
esgvoc/core/service/data_merger.py,sha256=GNFp5DTV2jlBVJZNpILngi6jCbUvVGcqka4EMWKj_Os,3456
|
|
72
|
+
esgvoc/core/service/esg_voc.py,sha256=5G0P4_xmQzoI_RG_agpq-yHoYYZx220P27v2nPrpyNs,2420
|
|
73
|
+
esgvoc/core/service/state.py,sha256=f1Pb11yYRAcLyK93zJ60i5l-mifDXP8_81tJQtMAvPo,10622
|
|
74
|
+
esgvoc/core/service/configuration/config_manager.py,sha256=K-gU3Kd-eJMunxDKOk4x72CRcyJ50IZXLfqQgyI9zTs,8282
|
|
75
|
+
esgvoc/core/service/configuration/setting.py,sha256=WJgo9ZjZJrTGR9WEBhp1d7ab0Yb2Y6XmnO1oImTPc2s,3042
|
|
76
|
+
esgvoc-0.4.0.dist-info/METADATA,sha256=rDbK18ahBLJtPMTi00NI64tEhNn8ulPlfvMoJ4TBIlc,2165
|
|
77
|
+
esgvoc-0.4.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
78
|
+
esgvoc-0.4.0.dist-info/entry_points.txt,sha256=ZXufSC7Jlx1lb52U6Buv9IitJMcqAAXOerR2V9DaIto,48
|
|
79
|
+
esgvoc-0.4.0.dist-info/licenses/LICENSE.txt,sha256=rWJoZt3vach8ZNdLq-Ee5djzCMFnJ1gIfBeJU5RIop4,21782
|
|
80
|
+
esgvoc-0.4.0.dist-info/RECORD,,
|
esgvoc/api/_utils.py
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
from typing import Sequence
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import esgvoc.core.constants as api_settings
|
|
5
|
-
from esgvoc.api.data_descriptors import DATA_DESCRIPTOR_CLASS_MAPPING
|
|
6
|
-
from esgvoc.core.db.models.project import PTerm
|
|
7
|
-
from esgvoc.core.db.models.universe import UTerm
|
|
8
|
-
from pydantic import BaseModel
|
|
9
|
-
from sqlmodel import Session
|
|
10
|
-
|
|
11
|
-
import esgvoc.core.service as service
|
|
12
|
-
UNIVERSE_DB_CONNECTION = service.state_service.universe.db_connection
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def get_pydantic_class(data_descriptor_id_or_term_type: str) -> type[BaseModel]:
|
|
16
|
-
if data_descriptor_id_or_term_type in DATA_DESCRIPTOR_CLASS_MAPPING:
|
|
17
|
-
return DATA_DESCRIPTOR_CLASS_MAPPING[data_descriptor_id_or_term_type]
|
|
18
|
-
else:
|
|
19
|
-
raise ValueError(f"{data_descriptor_id_or_term_type} pydantic class not found")
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def get_universe_session() -> Session:
|
|
23
|
-
|
|
24
|
-
if UNIVERSE_DB_CONNECTION:
|
|
25
|
-
return UNIVERSE_DB_CONNECTION.create_session()
|
|
26
|
-
else:
|
|
27
|
-
raise RuntimeError('universe connection is not initialized')
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def instantiate_pydantic_term(term: UTerm|PTerm) -> BaseModel:
|
|
31
|
-
term_class = get_pydantic_class(term.specs[api_settings.TERM_TYPE_JSON_KEY])
|
|
32
|
-
return term_class(**term.specs)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def instantiate_pydantic_terms(db_terms: Sequence[UTerm|PTerm],
|
|
36
|
-
list_to_populate: list[BaseModel]) -> None:
|
|
37
|
-
for db_term in db_terms:
|
|
38
|
-
term = instantiate_pydantic_term(db_term)
|
|
39
|
-
list_to_populate.append(term)
|
esgvoc/cli/config.py
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import json
|
|
3
|
-
from rich.syntax import Syntax
|
|
4
|
-
import typer
|
|
5
|
-
from esgvoc.core.service.settings import SETTINGS_FILE, ServiceSettings, load_settings
|
|
6
|
-
from rich import print
|
|
7
|
-
import toml
|
|
8
|
-
|
|
9
|
-
app = typer.Typer()
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def get_nested_value(settings_dict: dict, key_path: str):
|
|
13
|
-
"""Navigate through nested dictionary keys using dot-separated key paths."""
|
|
14
|
-
keys = key_path.split(".")
|
|
15
|
-
value = settings_dict
|
|
16
|
-
for key in keys:
|
|
17
|
-
value = value[key]
|
|
18
|
-
return value
|
|
19
|
-
|
|
20
|
-
def set_nested_value(settings_dict: dict, key_path: str, new_value):
|
|
21
|
-
"""Set a value in a nested dictionary using a dot-separated key path."""
|
|
22
|
-
keys = key_path.split(".")
|
|
23
|
-
sub_dict = settings_dict
|
|
24
|
-
for key in keys[:-1]:
|
|
25
|
-
sub_dict = sub_dict[key]
|
|
26
|
-
sub_dict[keys[-1]] = new_value
|
|
27
|
-
return settings_dict
|
|
28
|
-
|
|
29
|
-
@app.command()
|
|
30
|
-
def config(key: str |None = typer.Argument(None), value: str|None = typer.Argument(None)):
|
|
31
|
-
"""
|
|
32
|
-
Manage configuration settings.
|
|
33
|
-
|
|
34
|
-
- With no arguments: display all settings.
|
|
35
|
-
- With one argument (key): display the value of the key.
|
|
36
|
-
- With two arguments (key and value): modify the key's value and save.
|
|
37
|
-
|
|
38
|
-
usage :
|
|
39
|
-
esgvoc config universe.db_path .cache/dbs/somethingelse
|
|
40
|
-
"""
|
|
41
|
-
|
|
42
|
-
settings = load_settings()
|
|
43
|
-
if key is None:
|
|
44
|
-
# No key provided, print all settings
|
|
45
|
-
# typer.echo(settings.model_dump())
|
|
46
|
-
syntax = Syntax(toml.dumps(settings.model_dump()), "toml")
|
|
47
|
-
print(syntax)
|
|
48
|
-
return
|
|
49
|
-
if value is None:
|
|
50
|
-
# Key provided but no value, print the specific key's value
|
|
51
|
-
try:
|
|
52
|
-
selected_value = get_nested_value(json.loads(settings.model_dump_json()),key)
|
|
53
|
-
typer.echo(selected_value)
|
|
54
|
-
except KeyError:
|
|
55
|
-
try:
|
|
56
|
-
selected_value = get_nested_value(json.loads(settings.model_dump_json()),"projects."+key)
|
|
57
|
-
typer.echo(selected_value)
|
|
58
|
-
return
|
|
59
|
-
except KeyError:
|
|
60
|
-
pass
|
|
61
|
-
typer.echo(f"Key '{key}' not found in settings.")
|
|
62
|
-
return
|
|
63
|
-
|
|
64
|
-
# Modify the key's value
|
|
65
|
-
try :
|
|
66
|
-
selected_value = get_nested_value(json.loads(settings.model_dump_json()),key)
|
|
67
|
-
except Exception:
|
|
68
|
-
key = "projects."+key
|
|
69
|
-
try :
|
|
70
|
-
selected_value = get_nested_value(json.loads(settings.model_dump_json()),key)
|
|
71
|
-
if selected_value:
|
|
72
|
-
new_settings_dict = set_nested_value(json.loads(settings.model_dump_json()),key, value )
|
|
73
|
-
new_settings = ServiceSettings(**new_settings_dict)
|
|
74
|
-
new_settings.save_to_file(str(SETTINGS_FILE)) #TODO improved that .. remove SETTINGS_FILE dependancy
|
|
75
|
-
# save_settings(new_settings)
|
|
76
|
-
typer.echo(f"New settings {new_settings.model_dump_json(indent=4)}")
|
|
77
|
-
typer.echo(f"Updated '{key}' to '{value}'.")
|
|
78
|
-
else:
|
|
79
|
-
typer.echo(f"Key '{key}' not found in settings.")
|
|
80
|
-
except Exception as e:
|
|
81
|
-
typer.echo(f"Error updating settings: {e}")
|
|
82
|
-
|
esgvoc/core/service/settings.py
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
from pydantic import BaseModel, Field
|
|
2
|
-
from typing import Dict, Optional
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
import toml
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
SETTINGS_FILE = Path(__file__).parent / "settings.toml"
|
|
8
|
-
|
|
9
|
-
class ProjectSettings(BaseModel):
|
|
10
|
-
project_name: str
|
|
11
|
-
github_repo: str
|
|
12
|
-
branch: Optional[str] = "main"
|
|
13
|
-
local_path: Optional[str] = None
|
|
14
|
-
db_path: Optional[str] = None
|
|
15
|
-
|
|
16
|
-
class UniverseSettings(BaseModel):
|
|
17
|
-
github_repo: str
|
|
18
|
-
branch: Optional[str] = None
|
|
19
|
-
local_path: Optional[str] = None
|
|
20
|
-
db_path: Optional[str] = None
|
|
21
|
-
|
|
22
|
-
class ServiceSettings(BaseModel):
|
|
23
|
-
universe: UniverseSettings
|
|
24
|
-
projects: Dict[str, ProjectSettings] = Field(default_factory=dict)
|
|
25
|
-
|
|
26
|
-
@classmethod
|
|
27
|
-
def load_from_file(cls, file_path: str) -> "ServiceSettings":
|
|
28
|
-
data = toml.load(file_path)
|
|
29
|
-
projects = {p['project_name']: ProjectSettings(**p) for p in data.pop('projects', [])}
|
|
30
|
-
return cls(universe=UniverseSettings(**data['universe']), projects=projects)
|
|
31
|
-
|
|
32
|
-
def save_to_file(self, file_path: str):
|
|
33
|
-
data = {
|
|
34
|
-
"universe": self.universe.model_dump(),
|
|
35
|
-
"projects": [p.model_dump() for p in self.projects.values()]
|
|
36
|
-
}
|
|
37
|
-
with open(file_path, "w") as f:
|
|
38
|
-
toml.dump(data, f)
|
|
39
|
-
|
|
40
|
-
def load_settings() -> ServiceSettings:
|
|
41
|
-
"""Load the settings from the TOML file."""
|
|
42
|
-
if SETTINGS_FILE.exists():
|
|
43
|
-
return ServiceSettings.load_from_file(str(SETTINGS_FILE))
|
|
44
|
-
else:
|
|
45
|
-
default_settings = ServiceSettings(
|
|
46
|
-
universe=UniverseSettings(
|
|
47
|
-
github_repo="https://github.com/WCRP-CMIP/WCRP-universe",
|
|
48
|
-
branch="esgvoc",
|
|
49
|
-
local_path=".cache/repos/WCRP-universe",
|
|
50
|
-
db_path=".cache/dbs/universe.sqlite"
|
|
51
|
-
),
|
|
52
|
-
projects={"cmip6plus":ProjectSettings(
|
|
53
|
-
project_name="CMIP6Plus_CVs",
|
|
54
|
-
github_repo="https://github.com/WCRP-CMIP/CMIP6Plus_CVs",
|
|
55
|
-
branch="esgvoc",
|
|
56
|
-
local_path=".cache/repos/CMIP6Plus_CVs",
|
|
57
|
-
db_path=".cache/dbs/cmip6plus.sqlite"
|
|
58
|
-
),
|
|
59
|
-
|
|
60
|
-
"cmip6":ProjectSettings(
|
|
61
|
-
project_name="CMIP6_CVs",
|
|
62
|
-
github_repo="https://github.com/WCRP-CMIP/CMIP6_CVs",
|
|
63
|
-
branch="esgvoc",
|
|
64
|
-
local_path=".cache/repos/CMIP6_CVs",
|
|
65
|
-
db_path=".cache/dbs/cmip6.sqlite"
|
|
66
|
-
)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
default_settings.save_to_file(str(SETTINGS_FILE))
|
|
73
|
-
return default_settings
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
[[projects]]
|
|
2
|
-
project_name = "cmip6"
|
|
3
|
-
github_repo = "https://github.com/WCRP-CMIP/CMIP6_CVs"
|
|
4
|
-
branch = "esgvoc"
|
|
5
|
-
local_path = ".cache/repos/CMIP6_CVs"
|
|
6
|
-
db_path = ".cache/dbs/cmip6.sqlite"
|
|
7
|
-
[[projects]]
|
|
8
|
-
project_name = "cmip6plus"
|
|
9
|
-
github_repo = "https://github.com/WCRP-CMIP/CMIP6Plus_CVs"
|
|
10
|
-
branch = "esgvoc"
|
|
11
|
-
local_path = ".cache/repos/CMIP6Plus_CVs"
|
|
12
|
-
db_path = ".cache/dbs/cmip6plus.sqlite"
|
|
13
|
-
[universe]
|
|
14
|
-
github_repo = "https://github.com/WCRP-CMIP/WCRP-universe"
|
|
15
|
-
branch = "esgvoc"
|
|
16
|
-
local_path = ".cache/repos/WCRP-universe"
|
|
17
|
-
db_path = ".cache/dbs/universe.sqlite"
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
[[projects]]
|
|
2
|
-
project_name = "cmip6"
|
|
3
|
-
github_repo = "https://github.com/WCRP-CMIP/CMIP6_CVs"
|
|
4
|
-
branch = "esgvoc"
|
|
5
|
-
local_path = ".cache/repos/CMIP6_CVs"
|
|
6
|
-
db_path = ".cache/dbs/cmip6.sqlite"
|
|
7
|
-
[[projects]]
|
|
8
|
-
project_name = "cmip6plus"
|
|
9
|
-
github_repo = "https://github.com/WCRP-CMIP/CMIP6Plus_CVs"
|
|
10
|
-
branch = "esgvoc"
|
|
11
|
-
local_path = ".cache/repos/CMIP6Plus_CVs"
|
|
12
|
-
db_path = ".cache/dbs/cmip6plus.sqlite"
|
|
13
|
-
[universe]
|
|
14
|
-
github_repo = "https://github.com/WCRP-CMIP/WCRP-universe"
|
|
15
|
-
branch = "esgvoc"
|
|
16
|
-
local_path = ".cache/repos/WCRP-universe"
|
|
17
|
-
db_path = ".cache/dbs/universe.sqlite"
|