esgvoc 0.2.1__py3-none-any.whl → 0.3.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 (70) hide show
  1. esgvoc/__init__.py +3 -1
  2. esgvoc/api/__init__.py +23 -34
  3. esgvoc/api/_utils.py +28 -14
  4. esgvoc/api/data_descriptors/__init__.py +18 -12
  5. esgvoc/api/data_descriptors/activity.py +8 -45
  6. esgvoc/api/data_descriptors/area_label.py +6 -0
  7. esgvoc/api/data_descriptors/branded_suffix.py +5 -0
  8. esgvoc/api/data_descriptors/branded_variable.py +5 -0
  9. esgvoc/api/data_descriptors/consortium.py +16 -56
  10. esgvoc/api/data_descriptors/data_descriptor.py +106 -0
  11. esgvoc/api/data_descriptors/date.py +3 -46
  12. esgvoc/api/data_descriptors/directory_date.py +3 -46
  13. esgvoc/api/data_descriptors/experiment.py +19 -54
  14. esgvoc/api/data_descriptors/forcing_index.py +3 -45
  15. esgvoc/api/data_descriptors/frequency.py +6 -43
  16. esgvoc/api/data_descriptors/grid_label.py +6 -44
  17. esgvoc/api/data_descriptors/horizontal_label.py +6 -0
  18. esgvoc/api/data_descriptors/initialisation_index.py +3 -44
  19. esgvoc/api/data_descriptors/institution.py +11 -54
  20. esgvoc/api/data_descriptors/license.py +4 -44
  21. esgvoc/api/data_descriptors/mip_era.py +6 -44
  22. esgvoc/api/data_descriptors/model_component.py +7 -45
  23. esgvoc/api/data_descriptors/organisation.py +3 -40
  24. esgvoc/api/data_descriptors/physic_index.py +3 -45
  25. esgvoc/api/data_descriptors/product.py +4 -43
  26. esgvoc/api/data_descriptors/realisation_index.py +3 -44
  27. esgvoc/api/data_descriptors/realm.py +4 -42
  28. esgvoc/api/data_descriptors/resolution.py +6 -44
  29. esgvoc/api/data_descriptors/source.py +18 -53
  30. esgvoc/api/data_descriptors/source_type.py +3 -41
  31. esgvoc/api/data_descriptors/sub_experiment.py +3 -41
  32. esgvoc/api/data_descriptors/table.py +6 -48
  33. esgvoc/api/data_descriptors/temporal_label.py +6 -0
  34. esgvoc/api/data_descriptors/time_range.py +3 -27
  35. esgvoc/api/data_descriptors/variable.py +13 -71
  36. esgvoc/api/data_descriptors/variant_label.py +3 -47
  37. esgvoc/api/data_descriptors/vertical_label.py +5 -0
  38. esgvoc/api/projects.py +187 -171
  39. esgvoc/api/report.py +21 -12
  40. esgvoc/api/search.py +3 -1
  41. esgvoc/api/universe.py +44 -34
  42. esgvoc/apps/__init__.py +3 -4
  43. esgvoc/apps/drs/generator.py +166 -161
  44. esgvoc/apps/drs/report.py +222 -131
  45. esgvoc/apps/drs/validator.py +103 -105
  46. esgvoc/cli/drs.py +29 -19
  47. esgvoc/cli/get.py +26 -25
  48. esgvoc/cli/install.py +11 -8
  49. esgvoc/cli/main.py +0 -2
  50. esgvoc/cli/status.py +5 -5
  51. esgvoc/cli/valid.py +40 -40
  52. esgvoc/core/db/models/universe.py +3 -3
  53. esgvoc/core/db/project_ingestion.py +1 -1
  54. esgvoc/core/db/universe_ingestion.py +6 -5
  55. esgvoc/core/logging_handler.py +1 -1
  56. esgvoc/core/repo_fetcher.py +4 -3
  57. esgvoc/core/service/__init__.py +37 -5
  58. esgvoc/core/service/configuration/config_manager.py +188 -0
  59. esgvoc/core/service/configuration/setting.py +88 -0
  60. esgvoc/core/service/state.py +49 -32
  61. {esgvoc-0.2.1.dist-info → esgvoc-0.3.0.dist-info}/METADATA +34 -3
  62. esgvoc-0.3.0.dist-info/RECORD +78 -0
  63. esgvoc/cli/config.py +0 -82
  64. esgvoc/core/service/settings.py +0 -73
  65. esgvoc/core/service/settings.toml +0 -17
  66. esgvoc/core/service/settings_default.toml +0 -17
  67. esgvoc-0.2.1.dist-info/RECORD +0 -73
  68. {esgvoc-0.2.1.dist-info → esgvoc-0.3.0.dist-info}/WHEEL +0 -0
  69. {esgvoc-0.2.1.dist-info → esgvoc-0.3.0.dist-info}/entry_points.txt +0 -0
  70. {esgvoc-0.2.1.dist-info → esgvoc-0.3.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -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.settings import UniverseSettings, ProjectSettings, ServiceSettings
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
- self.local_path = local_path
27
- self.local_access = True # False if we dont have cloned the remote repo yet
28
- self.local_version = None
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.db_path = db_path
31
- self.db_access = True # False if we cant access the db for some reason
32
- self.db_version = None
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.rf = RepoFetcher()
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.fetch_version_remote()
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 None,
96
- "local_db_sync": self.local_version == self.db_version if self.local_access and self.local_version and self.db_version else None,
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
- ingest_metadata_universe(DBConnection(Path(self.db_path)),self.local_version)
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
- ingest_universe(Path(self.local_path), Path(self.db_path))
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
- ingest_project(Path(self.local_path),Path(self.db_path),self.local_version)
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"] and summary["github_local_sync"] is not None:
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.2.1
3
+ Version: 0.3.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,78 @@
1
+ esgvoc/__init__.py,sha256=D1rteIBXx1OIT6Jg9Yqo4pOud1VZTXZI8vrhJxm7Nvs,66
2
+ esgvoc/api/__init__.py,sha256=Oe6ch-MhVnN886jQAJ-OuyCI1eO3BxOtB_zvdbkVTXk,2764
3
+ esgvoc/api/_utils.py,sha256=pddSwnqYqLua0r2SXX6098OaCDxWJxaW7zlt2Xarl9o,2149
4
+ esgvoc/api/project_specs.py,sha256=uX1zqvTC8Dj5bOegZQVMAqU1VOle01s_8ncPXvtp0J4,2328
5
+ esgvoc/api/projects.py,sha256=E-Jt3vlu4vhPpVUixDGc7SHSj1HrNeIYz7n3cd9GhWI,42306
6
+ esgvoc/api/report.py,sha256=rAqOwYTqmzMguONT54YzNU1i7ZtmjYaCRD0Yz7mJsOI,3511
7
+ esgvoc/api/search.py,sha256=yV00GjvC9ZRodmfTp9HhOSk5OBsKq1s6ZNfpfxkbCwc,4208
8
+ esgvoc/api/universe.py,sha256=oFgYXCwVZP4HSgdGXYMFmGolSah1uCmfCMWKhNTuhog,10581
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/drs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
+ esgvoc/apps/drs/constants.py,sha256=kZxFo7Aa8DNy3WBq2j0FuZVEqOyxG53ZAkkjQaObE8s,95
46
+ esgvoc/apps/drs/generator.py,sha256=2-l68Zp4XVzZ42a6x1GN5hHwqYDe--JaiVjfWIGgiBw,22996
47
+ esgvoc/apps/drs/report.py,sha256=HywC7LXA7ER8VQu5g56izm5Z-zLxhoDekQJbhNUNkmI,17316
48
+ esgvoc/apps/drs/validator.py,sha256=-hX5PEYeiuRyIwS6jsY9XRyvj-wPpdcUD8PJn31D9hE,14913
49
+ esgvoc/cli/drs.py,sha256=ykisrZEOz3sl9rFuQehJfgOf4xsE9tKjPd_CmMWR08M,9133
50
+ esgvoc/cli/get.py,sha256=NrNCb2nWftlPkdRmYysbMU_pVUksFTeYItCuVviAAqQ,5171
51
+ esgvoc/cli/install.py,sha256=zMssevZDrigrUlw1QHWITGUL1TvsHMZBQdYeNtHgWQA,433
52
+ esgvoc/cli/main.py,sha256=kjB-yus-cmG9rOmVIPBhmjOr3tkwB13dHLcNqrdpYAM,483
53
+ esgvoc/cli/status.py,sha256=hmpyrszrb5ke9l_1SgendPSeoXW1h-h7nH0zGFt_vUw,1357
54
+ esgvoc/cli/valid.py,sha256=XrseGONeWR6gnnwZrRMJNjVBFQLT82Uzn5rHrjjM1Uk,7040
55
+ esgvoc/core/constants.py,sha256=b9GoM3pTICki95gMCnUZbg4_mMiywKhJX5ME01pgwMs,431
56
+ esgvoc/core/convert.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
+ esgvoc/core/data_handler.py,sha256=BmcD_dSvX5fCkUEGAQnadPTeuKA7IvgMmQtesMXKh5g,5004
58
+ esgvoc/core/logging.conf,sha256=GK52lsTu17CfC2tKiMAIvkuHkIt5tqPmkWv68COOilc,278
59
+ esgvoc/core/logging_handler.py,sha256=VgRBWeW_xdC4HtXG0TleQFwoy_YbJR4wlpci_sFezK0,147
60
+ esgvoc/core/repo_fetcher.py,sha256=Rg668F4NN60jd8Ydz9dXpJQxd2eQOgaO0Ziwm53mcaI,9823
61
+ esgvoc/core/db/__init__.py,sha256=gjAT_lUJtPqxsc8WnwbG_sxDqSIFAlG8vEKxdGyH82w,150
62
+ esgvoc/core/db/connection.py,sha256=dhnCy1mwytUUvt149WHk7eYW0KSP64IaF3kMvKOQSJE,877
63
+ esgvoc/core/db/project_ingestion.py,sha256=c7sgl91ScPfB4n05OR6HbtDqxNELv0jTiFf77S7tqc4,6327
64
+ esgvoc/core/db/universe_ingestion.py,sha256=kH9TryeHbahLMaF1BFfOzrakWkcllIi9KWz90IKAphI,5215
65
+ esgvoc/core/db/models/mixins.py,sha256=S4_6iuKf1kYLdUXAgqRKSTXs8H9I--43MKlEq4F-dm4,445
66
+ esgvoc/core/db/models/project.py,sha256=tuVcwNOkv0fQLFojpQCWacpnM7ZIX3eMDq6Mnko5OI0,2284
67
+ esgvoc/core/db/models/universe.py,sha256=_WwuqrLGrheLbSOXaFN-2rWmHmeEGseO5sN400p6BuY,2202
68
+ esgvoc/core/service/__init__.py,sha256=hveqCB4oC6gKDf_L-wZxu9iBz7RiY4x9OeJGP6S5xtU,1534
69
+ esgvoc/core/service/data_merger.py,sha256=GNFp5DTV2jlBVJZNpILngi6jCbUvVGcqka4EMWKj_Os,3456
70
+ esgvoc/core/service/esg_voc.py,sha256=5G0P4_xmQzoI_RG_agpq-yHoYYZx220P27v2nPrpyNs,2420
71
+ esgvoc/core/service/state.py,sha256=f1Pb11yYRAcLyK93zJ60i5l-mifDXP8_81tJQtMAvPo,10622
72
+ esgvoc/core/service/configuration/config_manager.py,sha256=K-gU3Kd-eJMunxDKOk4x72CRcyJ50IZXLfqQgyI9zTs,8282
73
+ esgvoc/core/service/configuration/setting.py,sha256=WJgo9ZjZJrTGR9WEBhp1d7ab0Yb2Y6XmnO1oImTPc2s,3042
74
+ esgvoc-0.3.0.dist-info/METADATA,sha256=nIkD0iIw2LFnD7DTYzWIml_af3Rx5Io6KkCFKmADoZE,2165
75
+ esgvoc-0.3.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
76
+ esgvoc-0.3.0.dist-info/entry_points.txt,sha256=ZXufSC7Jlx1lb52U6Buv9IitJMcqAAXOerR2V9DaIto,48
77
+ esgvoc-0.3.0.dist-info/licenses/LICENSE.txt,sha256=rWJoZt3vach8ZNdLq-Ee5djzCMFnJ1gIfBeJU5RIop4,21782
78
+ esgvoc-0.3.0.dist-info/RECORD,,
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
-
@@ -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"
@@ -1,73 +0,0 @@
1
- esgvoc/__init__.py,sha256=kPejgt5LFlzacS1O0vGN5JC7AlpRpWCmGIHUcBr_6-M,35
2
- esgvoc/api/__init__.py,sha256=eGYIcKbz0y4mmgEJtHf3EYAtp-iKaoTKDzHQCnILd9s,3327
3
- esgvoc/api/_utils.py,sha256=eIVP7d3jbr7u_LNliLoM2Up3Zl5rcxIw_hjqLdfaxUA,1390
4
- esgvoc/api/project_specs.py,sha256=uX1zqvTC8Dj5bOegZQVMAqU1VOle01s_8ncPXvtp0J4,2328
5
- esgvoc/api/projects.py,sha256=n6zXTjEJ8yXJEFri6YZ4RdhvPOtdxTSOOKMz7pdPCnM,40605
6
- esgvoc/api/report.py,sha256=F6hs1cNnlH4OodQiko-jWO0Pu1ji0TrLFN_eFSADgyI,3341
7
- esgvoc/api/search.py,sha256=XE7kAfDA9gAb_wYUm5viA0lT4-_L3P0hclerpU42Q1U,4097
8
- esgvoc/api/universe.py,sha256=W9liJW2NPF7vYxgoOIute2o4aNNhYrtgd90l4iB3OY4,9643
9
- esgvoc/api/data_descriptors/__init__.py,sha256=9XGHmSDsRmQPvu9WxtJy_lNxe-iabAfV6UxhfiPr3aA,3085
10
- esgvoc/api/data_descriptors/activity.py,sha256=o-RlmAFJkIb9TkUZIjEJaHi9dnQ70GHH5-5bKACRwMI,1371
11
- esgvoc/api/data_descriptors/consortium.py,sha256=fhAaEqxBpBDSmO7rIya1nnEz9aRyhQQFnIBExcyQxQM,1467
12
- esgvoc/api/data_descriptors/date.py,sha256=q4YXqaEryrcXO3ndk4SwyKwn56iGuBiJbHs8JSUpXJU,781
13
- esgvoc/api/data_descriptors/directory_date.py,sha256=uX89W68SqrX8iC52K1Voth6VI9T8UV5O13SrAWDRoiY,906
14
- esgvoc/api/data_descriptors/experiment.py,sha256=DCPYhgGWgD7LKgheqreXKGd5_0pQ6a1GnJ17IDt5WXY,1838
15
- esgvoc/api/data_descriptors/forcing_index.py,sha256=m2SBobNTN8P_TFS-uIwMyqbJ9d6CNr21bzW7qT3MVe0,796
16
- esgvoc/api/data_descriptors/frequency.py,sha256=XIu1v5NIcaNKj-9K3WNa4jH_Lds5XO5CP4M79nNVuVE,842
17
- esgvoc/api/data_descriptors/grid_label.py,sha256=i7bZJv_Y1s8gx2TR5D02i3Xify1rMu9lXRAwvYRugEY,846
18
- esgvoc/api/data_descriptors/initialisation_index.py,sha256=TtxvKO0IaD4ZEzm6LKCqKEaRYFHtLyTKo4UGj4kL9fI,809
19
- esgvoc/api/data_descriptors/institution.py,sha256=sr4pgTrNIEnl_GcaJeNndsYfYXSMKwFybzZDquD0qdM,1316
20
- esgvoc/api/data_descriptors/license.py,sha256=4hQiAQoBbecYZbApAzr2mnR8063yL13j7b_VSKgkIhA,933
21
- esgvoc/api/data_descriptors/mip_era.py,sha256=P7Vyen9uFCoOhh4qooPy-hDJ_jcP-1ISl25cmZBC9KI,824
22
- esgvoc/api/data_descriptors/model_component.py,sha256=WGsv_bd5TrNeyBx1a6f-wjXRXDMMf5C5hyJtTknjk68,864
23
- esgvoc/api/data_descriptors/organisation.py,sha256=dyB2l1lYDb3SMCuO4Ptsz9gImooeD3fqaTr6Ih2N_vg,855
24
- esgvoc/api/data_descriptors/physic_index.py,sha256=S_G-0hrbbGFqWj0xks6kAIwKkjPYRrRCDHaeZqvOdYk,794
25
- esgvoc/api/data_descriptors/product.py,sha256=rYhmSZy5vPwzZ2ZYIQXkoW5E-FeG8lAS_1lPaU7sDtg,805
26
- esgvoc/api/data_descriptors/realisation_index.py,sha256=spmDj6fBYfnqFiTJRH_OHJbm9gRmq-QqEvt1UJMXwl8,805
27
- esgvoc/api/data_descriptors/realm.py,sha256=GAebWcwyR48EyZiuapLD8eZxYEv3oGQ6Cndeho0DVAs,799
28
- esgvoc/api/data_descriptors/resolution.py,sha256=70eg9lAYGFS7Qws5mL2QwrU9N7tleA0YQp-V5ZIMj0E,841
29
- esgvoc/api/data_descriptors/source.py,sha256=1wWZY63NXk-8b3io8OYdsaZpVaXHS1d-M1bBhf54Ysc,1898
30
- esgvoc/api/data_descriptors/source_type.py,sha256=1GRDoFun3ncRLcAhjRvl3OgGL2ieq7Cv8v1_hcI60BU,793
31
- esgvoc/api/data_descriptors/sub_experiment.py,sha256=Z-GxS96201hIYtDgGnymHpkpKt16xjvk4QQnY_vSjr0,799
32
- esgvoc/api/data_descriptors/table.py,sha256=bhh-bSx7UYAAETmMAGNOIfwkyvywIhX0HlJh9a2njV0,1009
33
- esgvoc/api/data_descriptors/time_range.py,sha256=bBVRwmc7NEeGacV-UA0vadQXsyrlwBjyjVoYTw26rYA,630
34
- esgvoc/api/data_descriptors/variable.py,sha256=2Y6MfDzRvLF3FR5bhhJ6jTmPc2NTZVsoGF1Y2SEGeLU,2145
35
- esgvoc/api/data_descriptors/variant_label.py,sha256=ExP68t3v1xtjFEjOgVr2NFEOkQVGmf9GzStRlSPmNMU,931
36
- esgvoc/apps/__init__.py,sha256=k_IDucNtxAJsP1RkDCwEkqTHZqMRhALBVCdD0J9qUbY,300
37
- esgvoc/apps/drs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
- esgvoc/apps/drs/constants.py,sha256=kZxFo7Aa8DNy3WBq2j0FuZVEqOyxG53ZAkkjQaObE8s,95
39
- esgvoc/apps/drs/generator.py,sha256=BB-qHkpPNkZiLKOLC4DYB-os_1UlfVapB5EPmQezugI,22724
40
- esgvoc/apps/drs/report.py,sha256=37ETMcnx56B30NQqGPVGKc4jDdfpAToh3W6UId9nd-Q,13720
41
- esgvoc/apps/drs/validator.py,sha256=HlDKKS9Xfxr0vlA_-6NC6JTnqPpKnbd-dhjiBhCaMfM,14803
42
- esgvoc/cli/config.py,sha256=BCRshQ8kdeTMv4b2uN4qaZoFrEi7k43mKJT79vitrP4,2951
43
- esgvoc/cli/drs.py,sha256=C0TsBvcoK7C6dEhHpEcq9HpKSYFsqxDlUai_5e1NycI,8672
44
- esgvoc/cli/get.py,sha256=dz_BsegIg9hSD1s11DREQiQq3DbXyneO4Kjs3dUPMgg,5134
45
- esgvoc/cli/install.py,sha256=tJl9Z9UoBbRXK8dMAehTTHfH9aT6fAqtEX7tt5Wl0F8,236
46
- esgvoc/cli/main.py,sha256=Yx5hWVl11GEu44vug_udmia-lr8j0AzZjtZOesKdNIY,557
47
- esgvoc/cli/status.py,sha256=-IG41NorXwE2C6YD3RHFKNBLsCqpcVBovKyLJ9MXgSM,1312
48
- esgvoc/cli/valid.py,sha256=QO2RJhBDFUKNL9PCBt6CrLp2FBNwnQ2yRlAWBgcjOtI,6909
49
- esgvoc/core/constants.py,sha256=b9GoM3pTICki95gMCnUZbg4_mMiywKhJX5ME01pgwMs,431
50
- esgvoc/core/convert.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
- esgvoc/core/data_handler.py,sha256=BmcD_dSvX5fCkUEGAQnadPTeuKA7IvgMmQtesMXKh5g,5004
52
- esgvoc/core/logging.conf,sha256=GK52lsTu17CfC2tKiMAIvkuHkIt5tqPmkWv68COOilc,278
53
- esgvoc/core/logging_handler.py,sha256=NhqKX2nFYVi01EhZPysFZ4UWBWJwgxafC_pWtd28YlU,115
54
- esgvoc/core/repo_fetcher.py,sha256=m0Qh2kBAa-ij2ZJ7uEYYW-CakoLs5deFHl7zniLgW5Y,9738
55
- esgvoc/core/db/__init__.py,sha256=gjAT_lUJtPqxsc8WnwbG_sxDqSIFAlG8vEKxdGyH82w,150
56
- esgvoc/core/db/connection.py,sha256=dhnCy1mwytUUvt149WHk7eYW0KSP64IaF3kMvKOQSJE,877
57
- esgvoc/core/db/project_ingestion.py,sha256=sVtQFg-gF6TTYjEPasqk2Ox4V4Al8rrd1Q_A6Zvn18U,6330
58
- esgvoc/core/db/universe_ingestion.py,sha256=K1IeMlQ0SoAH0HgXNwzj9Z3qR0KLsGIfrca8a5PTvWM,5197
59
- esgvoc/core/db/models/mixins.py,sha256=S4_6iuKf1kYLdUXAgqRKSTXs8H9I--43MKlEq4F-dm4,445
60
- esgvoc/core/db/models/project.py,sha256=tuVcwNOkv0fQLFojpQCWacpnM7ZIX3eMDq6Mnko5OI0,2284
61
- esgvoc/core/db/models/universe.py,sha256=32oWFvzqqFr86M14phbfvfmEzlldi3DSTAALjTigR_8,2199
62
- esgvoc/core/service/__init__.py,sha256=ByAE1LhD5cKIcwrSIH0Y___KP2Ewh55P57sAMQ4CHeM,308
63
- esgvoc/core/service/data_merger.py,sha256=GNFp5DTV2jlBVJZNpILngi6jCbUvVGcqka4EMWKj_Os,3456
64
- esgvoc/core/service/esg_voc.py,sha256=5G0P4_xmQzoI_RG_agpq-yHoYYZx220P27v2nPrpyNs,2420
65
- esgvoc/core/service/settings.py,sha256=bFAEX1k866jLrp4gQRmls5v7eL2bjuECHx3cll-CC80,2471
66
- esgvoc/core/service/settings.toml,sha256=NSd-d_OyK7hOfG8zltUXK4XP1d79GEu09eK8JI9z9y8,551
67
- esgvoc/core/service/settings_default.toml,sha256=NSd-d_OyK7hOfG8zltUXK4XP1d79GEu09eK8JI9z9y8,551
68
- esgvoc/core/service/state.py,sha256=nppULtefcpahpHOOkOxayJ5Hp8u-pA2VBYfx5P9wMWE,9676
69
- esgvoc-0.2.1.dist-info/METADATA,sha256=50Q2tsO63h1I7-FZ1w_xIAUpA2dKHtUjB3-Wzk8cfY8,1928
70
- esgvoc-0.2.1.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
71
- esgvoc-0.2.1.dist-info/entry_points.txt,sha256=ZXufSC7Jlx1lb52U6Buv9IitJMcqAAXOerR2V9DaIto,48
72
- esgvoc-0.2.1.dist-info/licenses/LICENSE.txt,sha256=rWJoZt3vach8ZNdLq-Ee5djzCMFnJ1gIfBeJU5RIop4,21782
73
- esgvoc-0.2.1.dist-info/RECORD,,
File without changes