esgvoc 0.4.0__tar.gz → 1.0.1__tar.gz

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 (179) hide show
  1. {esgvoc-0.4.0 → esgvoc-1.0.1}/.github/workflows/docs.yml +9 -7
  2. {esgvoc-0.4.0 → esgvoc-1.0.1}/.github/workflows/pypi-publish.yml +10 -9
  3. esgvoc-1.0.1/.github/workflows/unit_tests.yml +34 -0
  4. {esgvoc-0.4.0 → esgvoc-1.0.1}/.gitignore +1 -0
  5. {esgvoc-0.4.0 → esgvoc-1.0.1}/.pre-commit-config.yaml +0 -8
  6. {esgvoc-0.4.0 → esgvoc-1.0.1}/PKG-INFO +5 -20
  7. {esgvoc-0.4.0 → esgvoc-1.0.1}/README.md +3 -18
  8. esgvoc-1.0.1/docs/source/api_documentation/jsg.md +7 -0
  9. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/index.md +2 -1
  10. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/user/introduction.md +3 -3
  11. {esgvoc-0.4.0 → esgvoc-1.0.1}/pyproject.toml +11 -17
  12. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/__init__.py +1 -1
  13. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/__init__.py +52 -28
  14. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/activity.py +3 -3
  15. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/area_label.py +21 -0
  16. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/branded_suffix.py +25 -0
  17. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/branded_variable.py +17 -0
  18. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/consortium.py +27 -0
  19. esgvoc-0.4.0/src/esgvoc/api/data_descriptors/vertical_label.py → esgvoc-1.0.1/src/esgvoc/api/data_descriptors/contact.py +1 -1
  20. esgvoc-0.4.0/src/esgvoc/api/data_descriptors/area_label.py → esgvoc-1.0.1/src/esgvoc/api/data_descriptors/conventions.py +2 -2
  21. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/creation_date.py +5 -0
  22. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/data_descriptor.py +14 -9
  23. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/data_specs_version.py +5 -0
  24. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/date.py +1 -1
  25. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/directory_date.py +1 -1
  26. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/experiment.py +13 -11
  27. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/forcing_index.py +1 -1
  28. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/frequency.py +3 -3
  29. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/further_info_url.py +5 -0
  30. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/grid_label.py +2 -2
  31. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/horizontal_label.py +20 -0
  32. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/initialisation_index.py +1 -1
  33. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/institution.py +8 -5
  34. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/known_branded_variable.py +23 -0
  35. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/license.py +3 -3
  36. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/member_id.py +9 -0
  37. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/mip_era.py +1 -1
  38. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/model_component.py +1 -1
  39. esgvoc-0.4.0/src/esgvoc/api/data_descriptors/temporal_label.py → esgvoc-1.0.1/src/esgvoc/api/data_descriptors/obs_type.py +1 -2
  40. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/organisation.py +1 -1
  41. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/physic_index.py +1 -1
  42. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/product.py +2 -2
  43. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/publication_status.py +5 -0
  44. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/realisation_index.py +1 -1
  45. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/realm.py +1 -1
  46. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/region.py +5 -0
  47. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/resolution.py +3 -3
  48. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/source.py +9 -5
  49. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/source_type.py +1 -1
  50. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/table.py +3 -2
  51. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/temporal_label.py +20 -0
  52. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/time_range.py +5 -0
  53. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/title.py +5 -0
  54. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/tracking_id.py +5 -0
  55. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/variable.py +32 -0
  56. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/variant_label.py +5 -0
  57. esgvoc-1.0.1/src/esgvoc/api/data_descriptors/vertical_label.py +19 -0
  58. esgvoc-1.0.1/src/esgvoc/api/project_specs.py +198 -0
  59. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/projects.py +328 -287
  60. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/search.py +30 -3
  61. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/universe.py +42 -27
  62. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/apps/drs/generator.py +87 -74
  63. esgvoc-1.0.1/src/esgvoc/apps/jsg/cmip6_template.json +74 -0
  64. esgvoc-1.0.1/src/esgvoc/apps/jsg/json_schema_generator.py +194 -0
  65. esgvoc-1.0.1/src/esgvoc/cli/config.py +500 -0
  66. esgvoc-1.0.1/src/esgvoc/cli/find.py +138 -0
  67. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/cli/get.py +43 -38
  68. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/cli/main.py +10 -3
  69. esgvoc-1.0.1/src/esgvoc/cli/status.py +47 -0
  70. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/cli/valid.py +10 -15
  71. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/db/models/project.py +11 -11
  72. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/db/models/universe.py +3 -3
  73. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/db/project_ingestion.py +40 -40
  74. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/db/universe_ingestion.py +36 -33
  75. esgvoc-1.0.1/src/esgvoc/core/logging_handler.py +26 -0
  76. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/repo_fetcher.py +61 -59
  77. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/service/data_merger.py +47 -34
  78. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/service/state.py +107 -83
  79. {esgvoc-0.4.0 → esgvoc-1.0.1}/tests/Dockerfile +2 -2
  80. esgvoc-1.0.1/tests/api_inputs.py +1051 -0
  81. esgvoc-1.0.1/tests/conftest.py +37 -0
  82. {esgvoc-0.4.0 → esgvoc-1.0.1}/tests/test_api_project.py +64 -68
  83. {esgvoc-0.4.0 → esgvoc-1.0.1}/tests/test_api_universe.py +25 -13
  84. esgvoc-1.0.1/tests/test_cli_drs.py +75 -0
  85. esgvoc-1.0.1/tests/test_config.py +98 -0
  86. {esgvoc-0.4.0 → esgvoc-1.0.1}/tests/test_drs_generator.py +91 -76
  87. esgvoc-1.0.1/tests/test_js_generator.py +95 -0
  88. esgvoc-0.4.0/src/esgvoc/api/data_descriptors/branded_suffix.py +0 -5
  89. esgvoc-0.4.0/src/esgvoc/api/data_descriptors/branded_variable.py +0 -5
  90. esgvoc-0.4.0/src/esgvoc/api/data_descriptors/consortium.py +0 -26
  91. esgvoc-0.4.0/src/esgvoc/api/data_descriptors/horizontal_label.py +0 -6
  92. esgvoc-0.4.0/src/esgvoc/api/data_descriptors/time_range.py +0 -4
  93. esgvoc-0.4.0/src/esgvoc/api/data_descriptors/variable.py +0 -19
  94. esgvoc-0.4.0/src/esgvoc/api/data_descriptors/variant_label.py +0 -5
  95. esgvoc-0.4.0/src/esgvoc/api/project_specs.py +0 -83
  96. esgvoc-0.4.0/src/esgvoc/cli/status.py +0 -38
  97. esgvoc-0.4.0/src/esgvoc/core/logging.conf +0 -21
  98. esgvoc-0.4.0/src/esgvoc/core/logging_handler.py +0 -4
  99. esgvoc-0.4.0/tests/api_inputs.py +0 -829
  100. esgvoc-0.4.0/tests/test_cli_drs.py +0 -32
  101. esgvoc-0.4.0/tests/test_config.py +0 -54
  102. {esgvoc-0.4.0 → esgvoc-1.0.1}/.flake8 +0 -0
  103. {esgvoc-0.4.0 → esgvoc-1.0.1}/LICENSE.txt +0 -0
  104. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/Makefile +0 -0
  105. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/build.sh +0 -0
  106. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/API_Valid_Term.png +0 -0
  107. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/API_Valid_all_project.png +0 -0
  108. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/API_Valid_collection.png +0 -0
  109. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/API_Valid_project.png +0 -0
  110. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/API_drsgen_frombag.png +0 -0
  111. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/API_drsgen_map.png +0 -0
  112. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/API_drsvalid_one.png +0 -0
  113. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/CLI_Valid_all_project.png +0 -0
  114. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/CLI_Valid_collection.png +0 -0
  115. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/CLI_Valid_project.png +0 -0
  116. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/CLI_Valid_term.png +0 -0
  117. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/CLI_drsgen_frombag.png +0 -0
  118. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/CLI_drsvalid_one.png +0 -0
  119. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/Jup_one_term.png +0 -0
  120. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/Jup_one_term_from_one_CV.png +0 -0
  121. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/Jup_terms_from_one_collection.png +0 -0
  122. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/Jup_terms_from_one_dd.png +0 -0
  123. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/all_collection.png +0 -0
  124. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/all_term_from_one_collection.png +0 -0
  125. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/install.png +0 -0
  126. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/one_term.png +0 -0
  127. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/one_term_from_one_cv.png +0 -0
  128. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/status_after_install.png +0 -0
  129. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/_static/status_before_install.png +0 -0
  130. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/api_documentation/data_descriptors.md +0 -0
  131. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/api_documentation/drs.md +0 -0
  132. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/api_documentation/miscellaneous.md +0 -0
  133. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/api_documentation/project_specs.md +0 -0
  134. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/api_documentation/projects.md +0 -0
  135. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/api_documentation/universe.md +0 -0
  136. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/conf.py +0 -0
  137. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/guides/basics_drs.ipynb +0 -0
  138. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/guides/basics_esgvoc.ipynb +0 -0
  139. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/guides/status_install.png +0 -0
  140. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/how_to/generate_drs.rst +0 -0
  141. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/how_to/get.rst +0 -0
  142. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/how_to/valid.rst +0 -0
  143. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/how_to/validate_drs.rst +0 -0
  144. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/user/api.md +0 -0
  145. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/user/cached_database.md +0 -0
  146. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/user/cli.md +0 -0
  147. {esgvoc-0.4.0 → esgvoc-1.0.1}/docs/source/user/terms.md +0 -0
  148. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/__init__.py +0 -0
  149. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/data_descriptors/sub_experiment.py +0 -0
  150. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/py.typed +0 -0
  151. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/api/report.py +0 -0
  152. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/apps/__init__.py +0 -0
  153. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/apps/drs/__init__.py +0 -0
  154. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/apps/drs/constants.py +0 -0
  155. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/apps/drs/report.py +0 -0
  156. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/apps/drs/validator.py +0 -0
  157. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/apps/py.typed +0 -0
  158. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/cli/drs.py +0 -0
  159. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/cli/install.py +0 -0
  160. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/constants.py +0 -0
  161. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/convert.py +0 -0
  162. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/data_handler.py +0 -0
  163. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/db/__init__.py +0 -0
  164. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/db/connection.py +0 -0
  165. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/db/models/mixins.py +0 -0
  166. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/exceptions.py +0 -0
  167. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/service/__init__.py +0 -0
  168. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/service/configuration/config_manager.py +0 -0
  169. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/service/configuration/setting.py +0 -0
  170. {esgvoc-0.4.0 → esgvoc-1.0.1}/src/esgvoc/core/service/esg_voc.py +0 -0
  171. {esgvoc-0.4.0 → esgvoc-1.0.1}/tests/__init__.py +0 -0
  172. {esgvoc-0.4.0 → esgvoc-1.0.1}/tests/cli_input_drsgen.txt +0 -0
  173. {esgvoc-0.4.0 → esgvoc-1.0.1}/tests/cli_input_drsvalid.txt +0 -0
  174. {esgvoc-0.4.0 → esgvoc-1.0.1}/tests/integration/test_scenario_basic.py +0 -0
  175. {esgvoc-0.4.0 → esgvoc-1.0.1}/tests/test_cli_config.py +0 -0
  176. {esgvoc-0.4.0 → esgvoc-1.0.1}/tests/test_data_handler.py +0 -0
  177. {esgvoc-0.4.0 → esgvoc-1.0.1}/tests/test_data_merger.py +0 -0
  178. {esgvoc-0.4.0 → esgvoc-1.0.1}/tests/test_drs_validator.py +0 -0
  179. {esgvoc-0.4.0 → esgvoc-1.0.1}/tests/test_repo_fetcher.py +0 -0
@@ -11,22 +11,24 @@ on:
11
11
 
12
12
  jobs:
13
13
  documentation:
14
+ name: Publish documentation
14
15
  runs-on: ubuntu-latest
15
16
  steps:
16
- - uses: actions/checkout@v4
17
+ - name: Checkout
18
+ uses: actions/checkout@v4
17
19
 
18
- - name: Install the latest version of rye
19
- uses: eifinger/setup-rye@v4
20
+ - name: Install UV
21
+ uses: astral-sh/setup-uv@v5
20
22
  with:
21
23
  enable-cache: true
22
24
 
23
- - name: Sync dependencies
24
- run: rye sync
25
+ - name: Sync
26
+ run: uv sync
25
27
 
26
- - name: build
28
+ - name: Build
27
29
  run: docs/build.sh
28
30
 
29
- - name: deploy
31
+ - name: Deploy
30
32
  uses: peaceiris/actions-gh-pages@v3
31
33
  if: ${{ github.ref == 'refs/heads/documentation' }}
32
34
  with:
@@ -8,7 +8,7 @@ on:
8
8
 
9
9
  jobs:
10
10
  pypi-publish:
11
- name: upload release to PyPI
11
+ name: Publish new release
12
12
  runs-on: ubuntu-latest
13
13
  permissions:
14
14
  # This permission is needed for private repositories.
@@ -16,18 +16,19 @@ jobs:
16
16
  # IMPORTANT: this permission is mandatory for trusted publishing
17
17
  id-token: write
18
18
  steps:
19
- - uses: actions/checkout@v3
19
+ - name: Checkout
20
+ uses: actions/checkout@v4
20
21
 
21
- - name: Install the latest version of rye
22
- uses: eifinger/setup-rye@v4
22
+ - name: Install UV
23
+ uses: astral-sh/setup-uv@v5
23
24
  with:
24
25
  enable-cache: true
25
26
 
26
- - name: Sync dependencies
27
- run: rye sync
27
+ - name: Sync
28
+ run: uv sync
28
29
 
29
- - name: Build package
30
- run: rye build
30
+ - name: Build
31
+ run: uv build
31
32
 
32
- - name: Publish package distributions to PyPI
33
+ - name: Upload
33
34
  uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,34 @@
1
+ name: Unit tests
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - integration
7
+ paths:
8
+ - src/**
9
+ - tests/**
10
+ pull_request:
11
+ branches:
12
+ - main
13
+ paths:
14
+ - src/**
15
+ - tests/**
16
+
17
+ jobs:
18
+ unit_tests:
19
+ name: Run unit tests
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - name: Checkout
23
+ uses: actions/checkout@v4
24
+
25
+ - name: Install UV
26
+ uses: astral-sh/setup-uv@v5
27
+ with:
28
+ enable-cache: true
29
+
30
+ - name: Sync
31
+ run: uv sync
32
+
33
+ - name: Test
34
+ run: uv run pytest tests
@@ -28,3 +28,4 @@ tmp*
28
28
  sb.py
29
29
  CHANGELOG.md
30
30
  .coverage
31
+ codemcp.toml
@@ -22,14 +22,6 @@ repos:
22
22
  - id: ruff
23
23
  name: ruff-sort-imports
24
24
  args: [--select, I, --fix]
25
- - repo: local
26
- hooks:
27
- - id: wily
28
- name: wily
29
- entry: wily diff
30
- verbose: true
31
- language: python
32
- additional_dependencies: [wily]
33
25
  - repo: https://github.com/PyCQA/flake8
34
26
  rev: 7.1.2
35
27
  hooks:
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: esgvoc
3
- Version: 0.4.0
3
+ Version: 1.0.1
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
- Requires-Python: <3.13,>=3.12
8
+ Requires-Python: >=3.10
9
9
  Requires-Dist: idna>=3.10
10
10
  Requires-Dist: platformdirs>=4.3.6
11
11
  Requires-Dist: pydantic>=2.9.2
@@ -58,32 +58,17 @@ esgvoc install
58
58
 
59
59
  ## How to contribute
60
60
 
61
- ### Install Python dev environment
62
-
63
61
  * Pip
64
62
 
65
63
  ```bash
66
64
  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
65
  pip install pre-commit
81
66
  pre-commit install
82
67
  ```
83
68
 
84
- * Rye
69
+ * UV
85
70
 
86
71
  ```bash
87
- rye install
88
- rye run pre-commit install
72
+ uv sync
73
+ uv run pre-commit install
89
74
  ```
@@ -39,32 +39,17 @@ esgvoc install
39
39
 
40
40
  ## How to contribute
41
41
 
42
- ### Install Python dev environment
43
-
44
42
  * Pip
45
43
 
46
44
  ```bash
47
45
  pip install -e .
48
- ```
49
-
50
- * Rye
51
-
52
- ```bash
53
- rye sync
54
- ```
55
-
56
- ### Linters & code formatters
57
-
58
- * Pip
59
-
60
- ```bash
61
46
  pip install pre-commit
62
47
  pre-commit install
63
48
  ```
64
49
 
65
- * Rye
50
+ * UV
66
51
 
67
52
  ```bash
68
- rye install
69
- rye run pre-commit install
53
+ uv sync
54
+ uv run pre-commit install
70
55
  ```
@@ -0,0 +1,7 @@
1
+ # Json schema generator
2
+
3
+ ```{eval-rst}
4
+ .. automodule:: esgvoc.apps.jsg.json_schema_generator
5
+ :members:
6
+ :member-order: groupwise
7
+ ```
@@ -111,7 +111,8 @@ guides/basics_drs.ipynb
111
111
  api_documentation/universe.md
112
112
  api_documentation/projects.md
113
113
  api_documentation/project_specs.md
114
- api_documentation/drs.md
115
114
  api_documentation/data_descriptors.md
115
+ api_documentation/drs.md
116
+ api_documentation/jsg.md
116
117
  api_documentation/miscellaneous.md
117
118
  ```
@@ -26,12 +26,12 @@ Previously, controlled vocabularies were stored in multiple locations and format
26
26
 
27
27
  You can install `ESGVOC` using recent Python packaging tools. It is only available in pypi.org (not in anaconda.org). We recommend the following methods:
28
28
 
29
- ### Using Rye (preferred)
29
+ ### Using UV (preferred)
30
30
 
31
- [Rye](https://rye-up.com/) is recommended for managing dependencies and isolating the library:
31
+ [UV](https://docs.astral.sh/uv/) is recommended for managing dependencies and isolating the library:
32
32
 
33
33
  ```bash
34
- rye add esgvoc
34
+ uv add esgvoc
35
35
  ```
36
36
 
37
37
  This ensures all dependencies are installed, and cached repositories and databases will be stored in the `.cache` directory alongside the `.venv` folder. This approach simplifies updates and uninstallation.
@@ -23,7 +23,7 @@ dependencies = [
23
23
  "platformdirs>=4.3.6",
24
24
  ]
25
25
  readme = "README.md"
26
- requires-python = ">= 3.12, <3.13"
26
+ requires-python = ">= 3.10"
27
27
 
28
28
  [build-system]
29
29
  requires = ["hatchling==1.26.3"]
@@ -37,21 +37,14 @@ esgvoc = "esgvoc.cli.main:main"
37
37
 
38
38
  ######## TOOLS ########
39
39
 
40
- [tool.rye.scripts]
41
- ev = { cmd = "python src/esgvoc/cli/main.py" }
42
- evc = { cmd = "python src/esgvoc/cli/main.py config" }
43
- evcp = { cmd = "python src/esgvoc/cli/main.py config projects." }
44
- evg = { cmd = "python src/esgvoc/cli/main.py get" }
45
- evs = {cmd = "python src/esgvoc/cli/main.py status"}
46
- evv = {cmd = "python src/esgvoc/cli/main.py valid"}
47
-
48
- [tool.rye]
40
+ [tool.uv]
49
41
  managed = true
50
- dev-dependencies = [
51
- "pytest>=8.3.3",
42
+ default-groups = "all"
43
+
44
+ [dependency-groups]
45
+ dev = [
52
46
  "jupyter-console>=6.6.3",
53
- "mypy>=1.13.0",
54
- "pytest-mock>=3.14.0",
47
+ "hatch>=1.14.0", # Required for version updating through uv.
55
48
  "sphinx>=8.1.3",
56
49
  "sphinx-book-theme>=1.1.3",
57
50
  "autodoc-pydantic>=2.2.0",
@@ -59,12 +52,13 @@ dev-dependencies = [
59
52
  "sphinx-tabs>=3.4.7",
60
53
  "sphinx-copybutton>=0.5.2",
61
54
  "pre-commit>=4.1.0",
62
- "hatch>=1.14.0", # Required for version updating through rye.
63
- "pytest-cov>=6.0.0",
64
- "wily>=1.25.0",
65
55
  "flake8>=7.1.2",
66
56
  "ruff>=0.11.0",
67
57
  "pyright>=1.1.396",
58
+ "mypy>=1.13.0",
59
+ "pytest>=8.3.5",
60
+ "pytest-mock>=3.14.0",
61
+ "pytest-cov>=6.0.0",
68
62
  ]
69
63
 
70
64
  [tool.hatch.metadata]
@@ -1,3 +1,3 @@
1
1
  import esgvoc.core.logging_handler # noqa
2
2
 
3
- __version__ = "0.4.0"
3
+ __version__ = "1.0.1"
@@ -1,69 +1,93 @@
1
1
  from esgvoc.api.data_descriptors.activity import Activity
2
+ from esgvoc.api.data_descriptors.area_label import AreaLabel
3
+ from esgvoc.api.data_descriptors.branded_suffix import BrandedSuffix
4
+ from esgvoc.api.data_descriptors.branded_variable import BrandedVariable
2
5
  from esgvoc.api.data_descriptors.consortium import Consortium
6
+ from esgvoc.api.data_descriptors.contact import Contact
7
+ from esgvoc.api.data_descriptors.conventions import Convention
8
+ from esgvoc.api.data_descriptors.creation_date import CreationDate
3
9
  from esgvoc.api.data_descriptors.data_descriptor import DataDescriptor
10
+ from esgvoc.api.data_descriptors.data_specs_version import DataSpecsVersion
4
11
  from esgvoc.api.data_descriptors.date import Date
5
12
  from esgvoc.api.data_descriptors.directory_date import DirectoryDate
6
- from esgvoc.api.data_descriptors.experiment import Experiment
13
+ from esgvoc.api.data_descriptors.experiment import Experiment
7
14
  from esgvoc.api.data_descriptors.forcing_index import ForcingIndex
8
15
  from esgvoc.api.data_descriptors.frequency import Frequency
9
- from esgvoc.api.data_descriptors.grid_label import GridLabel
10
- from esgvoc.api.data_descriptors.initialisation_index import InitialisationIndex
16
+ from esgvoc.api.data_descriptors.further_info_url import FurtherInfoUrl
17
+ from esgvoc.api.data_descriptors.grid_label import GridLabel
18
+ from esgvoc.api.data_descriptors.horizontal_label import HorizontalLabel
19
+ from esgvoc.api.data_descriptors.initialisation_index import InitialisationIndex
11
20
  from esgvoc.api.data_descriptors.institution import Institution
12
- from esgvoc.api.data_descriptors.license import License
21
+ from esgvoc.api.data_descriptors.known_branded_variable import KnownBrandedVariable
22
+ from esgvoc.api.data_descriptors.license import License
23
+ from esgvoc.api.data_descriptors.member_id import MemberId
13
24
  from esgvoc.api.data_descriptors.mip_era import MipEra
14
25
  from esgvoc.api.data_descriptors.model_component import ModelComponent
15
- from esgvoc.api.data_descriptors.organisation import Organisation
26
+ from esgvoc.api.data_descriptors.obs_type import ObsType
27
+ from esgvoc.api.data_descriptors.organisation import Organisation
16
28
  from esgvoc.api.data_descriptors.physic_index import PhysicIndex
17
29
  from esgvoc.api.data_descriptors.product import Product
18
- from esgvoc.api.data_descriptors.realisation_index import RealisationIndex
30
+ from esgvoc.api.data_descriptors.publication_status import PublicationStatus
31
+ from esgvoc.api.data_descriptors.realisation_index import RealisationIndex
19
32
  from esgvoc.api.data_descriptors.realm import Realm
33
+ from esgvoc.api.data_descriptors.region import Region
20
34
  from esgvoc.api.data_descriptors.resolution import Resolution
21
- from esgvoc.api.data_descriptors.source import Source
22
- from esgvoc.api.data_descriptors.source_type import SourceType
35
+ from esgvoc.api.data_descriptors.source import Source
36
+ from esgvoc.api.data_descriptors.source_type import SourceType
23
37
  from esgvoc.api.data_descriptors.sub_experiment import SubExperiment
24
- from esgvoc.api.data_descriptors.table import Table
25
- from esgvoc.api.data_descriptors.time_range import TimeRange
38
+ from esgvoc.api.data_descriptors.table import Table
39
+ from esgvoc.api.data_descriptors.temporal_label import TemporalLabel
40
+ from esgvoc.api.data_descriptors.time_range import TimeRange
41
+ from esgvoc.api.data_descriptors.title import Title
42
+ from esgvoc.api.data_descriptors.tracking_id import TrackingId
26
43
  from esgvoc.api.data_descriptors.variable import Variable
27
44
  from esgvoc.api.data_descriptors.variant_label import VariantLabel
28
- from esgvoc.api.data_descriptors.area_label import AreaLabel
29
45
  from esgvoc.api.data_descriptors.vertical_label import VerticalLabel
30
- from esgvoc.api.data_descriptors.horizontal_label import HorizontalLabel
31
- from esgvoc.api.data_descriptors.temporal_label import TemporalLabel
32
- from esgvoc.api.data_descriptors.branded_suffix import BrandedSuffix
33
- from esgvoc.api.data_descriptors.branded_variable import BrandedVariable
34
46
 
35
47
  DATA_DESCRIPTOR_CLASS_MAPPING: dict[str, type[DataDescriptor]] = {
36
48
  "activity": Activity,
37
49
  "consortium": Consortium,
38
50
  "date": Date,
39
51
  "directory_date": DirectoryDate,
40
- "experiment": Experiment,
52
+ "experiment": Experiment,
41
53
  "forcing_index": ForcingIndex,
42
54
  "frequency": Frequency,
43
- "grid": GridLabel,#Universe
44
- "grid_label": GridLabel, # cmip6, cmip6plus
45
- "initialisation_index": InitialisationIndex,
55
+ "grid": GridLabel, # Universe
56
+ "grid_label": GridLabel, # cmip6, cmip6plus
57
+ "initialisation_index": InitialisationIndex,
46
58
  "institution": Institution,
47
59
  "license": License,
48
60
  "mip_era": MipEra,
49
61
  "model_component": ModelComponent,
50
- "organisation": Organisation,
62
+ "organisation": Organisation,
51
63
  "physic_index": PhysicIndex,
52
64
  "product": Product,
53
- "realisation_index": RealisationIndex ,
65
+ "realisation_index": RealisationIndex,
54
66
  "realm": Realm,
55
67
  "resolution": Resolution,
56
- "source": Source,
57
- "source_type": SourceType,
68
+ "source": Source,
69
+ "source_type": SourceType,
58
70
  "sub_experiment": SubExperiment,
59
- "table" : Table,
71
+ "table": Table,
60
72
  "time_range": TimeRange,
61
73
  "variable": Variable,
62
74
  "variant_label": VariantLabel,
63
75
  "area_label": AreaLabel,
64
76
  "temporal_label": TemporalLabel,
65
- "vertical_label" : VerticalLabel,
66
- "horizontal_label" : HorizontalLabel,
67
- "branded_suffix" : BrandedSuffix,
68
- "branded_variable" : BrandedVariable
77
+ "vertical_label": VerticalLabel,
78
+ "horizontal_label": HorizontalLabel,
79
+ "branded_suffix": BrandedSuffix,
80
+ "branded_variable": BrandedVariable,
81
+ "publication_status": PublicationStatus,
82
+ "known_branded_variable": KnownBrandedVariable,
83
+ "data_specs_version": DataSpecsVersion,
84
+ "further_info_url": FurtherInfoUrl,
85
+ "tracking_id": TrackingId,
86
+ "creation_date": CreationDate,
87
+ "conventions": Convention,
88
+ "title": Title,
89
+ "contact": Contact,
90
+ "region": Region,
91
+ "member_id": MemberId,
92
+ "obs_type": ObsType, # obs4Mips
69
93
  }
@@ -9,6 +9,6 @@ class Activity(PlainTermDataDescriptor):
9
9
  Activities are often organized around key research themes and may involve multiple experiments, \
10
10
  scenarios, and model configurations.
11
11
  """
12
- name: str
13
- long_name: str
14
- url: str|None
12
+ name: str
13
+ long_name: str
14
+ url: str | None
@@ -0,0 +1,21 @@
1
+ from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
2
+
3
+
4
+ class AreaLabel(PlainTermDataDescriptor):
5
+ """
6
+ Area sampling label.
7
+
8
+ This label provides information about the area sampling of a given dataset.
9
+ For a list of allowed values, see
10
+ [TODO think about how to cross-reference to somewhere where people can look up the allowed values,
11
+ e.g. some summary of the values in https://github.com/WCRP-CMIP/WCRP-universe/tree/esgvoc/area_label.]
12
+
13
+ This label is used as the area component of a branded variable's suffix
14
+ (see :py:class:`BrandedSuffix`).
15
+ By definition, the area label must be consistent with the branded suffix.
16
+ area labels must not contain dashes
17
+ (as the dash is used as a separator when constructing the branded suffix).
18
+ """
19
+
20
+ description: str
21
+ label: str
@@ -0,0 +1,25 @@
1
+ from esgvoc.api.data_descriptors.data_descriptor import CompositeTermDataDescriptor
2
+
3
+
4
+ class BrandedSuffix(CompositeTermDataDescriptor):
5
+ """
6
+ The suffix of a branded variable.
7
+
8
+ A branded variable is composed of two parts.
9
+ The first part is the root variable (see [TODO cross-ref to Variable]).
10
+ The second is the suffix, i.e. the component described here.
11
+ The suffix captures all the information
12
+ about the time sampling, horizontal sampling, vertical sampling
13
+ and area masking of the variable.
14
+
15
+ The suffix is composed of the following components:
16
+
17
+ #. :py:class:`TemporalLabel`
18
+ #. :py:class:`VerticalLabel`
19
+ #. :py:class:`HorizontalLabel`
20
+ #. :py:class:`AreaLabel`
21
+
22
+ These components are separated by a separator to create the branded suffix.
23
+ """
24
+
25
+ description: str
@@ -0,0 +1,17 @@
1
+ from esgvoc.api.data_descriptors.data_descriptor import CompositeTermDataDescriptor
2
+
3
+
4
+ class BrandedVariable(CompositeTermDataDescriptor):
5
+ """
6
+ A climate-related quantity or measurement, including information about sampling.
7
+
8
+ The concept of a branded variable was introduced in CMIP7.
9
+ A branded variable is composed of two parts.
10
+ The first part is the root variable (see :py:class:`Variable`).
11
+ The second is the suffix (see :py:class:`BrandedSuffix`).
12
+
13
+ For further details on the development of branded variables,
14
+ see [this paper draft](https://docs.google.com/document/d/19jzecgymgiiEsTDzaaqeLP6pTvLT-NzCMaq-wu-QoOc/edit?pli=1&tab=t.0).
15
+ """
16
+
17
+ description: str
@@ -0,0 +1,27 @@
1
+ from pydantic import Field
2
+
3
+ from esgvoc.api.data_descriptors.data_descriptor import ConfiguredBaseModel, PlainTermDataDescriptor
4
+
5
+
6
+ class Dates(ConfiguredBaseModel):
7
+ phase: str
8
+ from_: int = Field(..., alias="from") # Cause from is a keyword
9
+ to: int | str
10
+
11
+
12
+ class Member(ConfiguredBaseModel):
13
+ type: str
14
+ institution: str # id
15
+ dates: list[Dates] = Field(default_factory=list)
16
+ membership_type: str # prior, current
17
+
18
+
19
+ class Consortium(PlainTermDataDescriptor):
20
+ validation_method: str = Field(default="list")
21
+ name: str | None = None
22
+ status: str | None = None
23
+ changes: str | None
24
+ members: list[Member] = Field(default_factory=list)
25
+ url: str | None
26
+ # TODO: remove default value when all json will have their description.
27
+ description: str = Field(default="")
@@ -1,5 +1,5 @@
1
1
  from esgvoc.api.data_descriptors.data_descriptor import PatternTermDataDescriptor
2
2
 
3
3
 
4
- class VerticalLabel(PatternTermDataDescriptor):
4
+ class Contact(PatternTermDataDescriptor):
5
5
  pass
@@ -1,6 +1,6 @@
1
1
  from esgvoc.api.data_descriptors.data_descriptor import PlainTermDataDescriptor
2
2
 
3
3
 
4
- class AreaLabel(PlainTermDataDescriptor):
4
+ class Convention(PlainTermDataDescriptor):
5
5
  description: str
6
- label: str
6
+ label: str
@@ -0,0 +1,5 @@
1
+ from esgvoc.api.data_descriptors.data_descriptor import PatternTermDataDescriptor
2
+
3
+
4
+ class CreationDate(PatternTermDataDescriptor):
5
+ pass
@@ -1,16 +1,17 @@
1
- from typing import Protocol, Any, ClassVar
2
1
  from abc import ABC, abstractmethod
2
+ from typing import Any, ClassVar, Protocol
3
+
3
4
  from pydantic import BaseModel, ConfigDict
4
5
 
5
6
 
6
7
  class ConfiguredBaseModel(BaseModel):
7
8
  model_config = ConfigDict(
8
- validate_assignment = True,
9
- validate_default = True,
10
- extra = "allow",
11
- arbitrary_types_allowed = True,
12
- use_enum_values = True,
13
- strict = False,
9
+ validate_assignment=True,
10
+ validate_default=True,
11
+ extra="allow",
12
+ arbitrary_types_allowed=True,
13
+ use_enum_values=True,
14
+ strict=False,
14
15
  )
15
16
 
16
17
 
@@ -21,12 +22,15 @@ class DataDescriptorVisitor(Protocol):
21
22
  def visit_sub_set_term(self, term: "DataDescriptorSubSet") -> Any:
22
23
  """Visit a sub set of the information of a term."""
23
24
  pass
25
+
24
26
  def visit_plain_term(self, term: "PlainTermDataDescriptor") -> Any:
25
27
  """Visit a plain term."""
26
28
  pass
29
+
27
30
  def visit_pattern_term(self, term: "PatternTermDataDescriptor") -> Any:
28
31
  """Visit a pattern term."""
29
32
  pass
33
+
30
34
  def visit_composite_term(self, term: "CompositeTermDataDescriptor") -> Any:
31
35
  """Visit a composite term."""
32
36
 
@@ -68,6 +72,7 @@ class PlainTermDataDescriptor(DataDescriptor):
68
72
  A data descriptor that describes hand written terms.
69
73
  """
70
74
  drs_name: str
75
+
71
76
  def accept(self, visitor: DataDescriptorVisitor) -> Any:
72
77
  return visitor.visit_plain_term(self)
73
78
 
@@ -86,11 +91,11 @@ class CompositeTermPart(ConfiguredBaseModel):
86
91
  """
87
92
  A reference to a term, part of a composite term.
88
93
  """
89
- id: str
94
+ id: str | list[str] | None = None
90
95
  """The id of the referenced term."""
91
96
  type: str
92
97
  """The type of the referenced term."""
93
- is_required : bool
98
+ is_required: bool
94
99
  """Denote if the term is optional as part of a composite term."""
95
100
 
96
101
 
@@ -0,0 +1,5 @@
1
+ from esgvoc.api.data_descriptors.data_descriptor import PatternTermDataDescriptor
2
+
3
+
4
+ class DataSpecsVersion(PatternTermDataDescriptor):
5
+ pass
@@ -2,4 +2,4 @@ from esgvoc.api.data_descriptors.data_descriptor import PatternTermDataDescripto
2
2
 
3
3
 
4
4
  class Date(PatternTermDataDescriptor):
5
- pass
5
+ pass
@@ -2,4 +2,4 @@ from esgvoc.api.data_descriptors.data_descriptor import PatternTermDataDescripto
2
2
 
3
3
 
4
4
  class DirectoryDate(PatternTermDataDescriptor):
5
- pass
5
+ pass