CMIP7-data-request-api 1.2b2__tar.gz → 1.2.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.
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/PKG-INFO +20 -11
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/README.md +19 -10
- cmip7_data_request_api-1.2.1/binder/environment.yml +13 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/CMIP7_data_request_api.egg-info/PKG-INFO +20 -11
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/CMIP7_data_request_api.egg-info/SOURCES.txt +5 -2
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/command_line/config.py +4 -3
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/command_line/estimate_dreq_volume.py +33 -11
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/command_line/export_dreq_lists_json.py +4 -3
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/content/consolidate_export.py +70 -8
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/content/dreq_content.py +15 -12
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/content/dump_transformation.py +6 -5
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/content/mapping_table.py +61 -16
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/content/transform.json +32 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/query/data_request.py +86 -56
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/query/dreq_query.py +109 -28
- cmip7_data_request_api-1.2.1/data_request_api/data_request_api/query/filtering.json +24 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/query/vocabulary_server.py +1 -0
- cmip7_data_request_api-1.2.1/data_request_api/data_request_api/tests/test_cli.py +501 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_data_request.py +7 -7
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_decorator.py +26 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_dreq_content.py +14 -4
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/utilities/config.py +44 -3
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/utilities/decorators.py +3 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/version.py +2 -2
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/command_line/config.html +4 -3
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/command_line/estimate_dreq_volume.html +33 -11
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/command_line/export_dreq_lists_json.html +4 -3
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/content/consolidate_export.html +8 -1
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/content/dreq_content.html +10 -11
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/content/dump_transformation.html +6 -5
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/content/mapping_table.html +11 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/query/data_request.html +157 -105
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/query/dreq_query.html +110 -29
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/query/vocabulary_server.html +2 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/tests/test_cli.html +572 -70
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/tests/test_data_request.html +14 -14
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/tests/test_decorator.html +27 -1
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/tests/test_dreq_content.html +31 -8
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/utilities/config.html +49 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/utilities/decorators.html +3 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/launch_test_with_coverage.sh +7 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/requirements.txt +0 -1
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/scripts/check_consolidation.py +8 -2
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/scripts/check_consolidation2.py +169 -43
- cmip7_data_request_api-1.2.1/scripts/check_consolidation_and_transformation.py +627 -0
- cmip7_data_request_api-1.2b2/scripts/examples/requested_v1.2.json → cmip7_data_request_api-1.2.1/scripts/examples/requested_v1.2.1.json +3 -107
- cmip7_data_request_api-1.2b2/scripts/examples/variables_v1.2.json → cmip7_data_request_api-1.2.1/scripts/examples/variables_v1.2.1.json +9564 -4009
- cmip7_data_request_api-1.2.1/scripts/sandbox/create_brand_name.py +214 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/scripts/workflow_example.py +2 -2
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/scripts/workflow_example_2.py +15 -1
- cmip7_data_request_api-1.2b2/data_request_api/data_request_api/query/filtering.json +0 -41
- cmip7_data_request_api-1.2b2/data_request_api/data_request_api/tests/test_cli.py +0 -290
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/.DS_Store +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/.github/.DS_Store +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/.github/workflows/pip_install.yml +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/.github/workflows/publish2pypi.yml +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/.github/workflows/updates.yml +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/.gitignore +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/LICENSE +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/.DS_Store +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/CMIP7_data_request_api.egg-info/dependency_links.txt +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/CMIP7_data_request_api.egg-info/entry_points.txt +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/CMIP7_data_request_api.egg-info/requires.txt +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/CMIP7_data_request_api.egg-info/top_level.txt +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/__init__.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/command_line/__init__.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/command_line/compare_variables.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/command_line/get_variables_metadata.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/content/README.MD +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/content/__init__.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/query/__init__.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/query/dreq_classes.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/__init__.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_config.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_config_cli.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_consolidation.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_datasets/one_base_DR_dump.txt +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_datasets/one_base_DR_output.json +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_datasets/one_base_VS_output.json +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_datasets/one_base_input.json +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_datasets/one_base_output_format.json +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_datasets/one_base_output_transform.json +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_datasets/several_bases_DR_output.json +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_datasets/several_bases_VS_output.json +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_datasets/several_bases_input.json +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_datasets/several_bases_output_format.json +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_datasets/several_bases_output_transform.json +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_dump_transformation.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_optimize.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/tests/test_vocabulary_server.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/utilities/__init__.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/utilities/logger.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/utilities/parser.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/data_request_api/data_request_api/utilities/tools.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/command_line/compare_variables.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/command_line/get_variables_metadata.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/command_line/index.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/content/index.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/index.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/query/dreq_classes.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/query/index.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/content/consolidate_export.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/content/dreq_content.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/content/dump_transformation.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/content/index.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/content/mapping_table.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/index.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/query/data_request.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/query/dreq_classes.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/query/dreq_query.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/query/index.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/query/vocabulary_server.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/utilities/config.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/utilities/decorators.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/utilities/index.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/utilities/logger.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/utilities/parser.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/stable/utilities/tools.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/tests/index.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/tests/test_config.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/tests/test_config_cli.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/tests/test_consolidation.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/tests/test_dump_transformation.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/tests/test_optimize.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/tests/test_vocabulary_server.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/utilities/index.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/utilities/logger.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/utilities/parser.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/utilities/tools.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/docs/data_request_api/version.html +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/env.yml +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/notebooks/HowTo-00_Install_the_DR_Software.ipynb +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/notebooks/HowTo-01_Import_and_Load_the_DR.ipynb +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/notebooks/HowTo-02_Discover_What_is_in_DR.ipynb +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/notebooks/HowTo-03a_Find_Experiments_and_Variables_for_given_Opportunities.ipynb +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/notebooks/HowTo-03b_Find_Experiments_and_Variables_for_given_Opportunities.ipynb +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/notebooks/HowTo-04a_View_Attributes_of_Experiments_and_Variables.ipynb +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/notebooks/HowTo-04b_View_Attributes_of_Variables.ipynb +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/notebooks/HowTo-05_Apply_Various_Search_Critria.ipynb +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/notebooks/README.md +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/notebooks/outdir/.gitkeep +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/notebooks/workflow_example.ipynb +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/pyproject.toml +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/scripts/check_variables_attributes.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/scripts/database_transformation.py +0 -0
- {cmip7_data_request_api-1.2b2 → cmip7_data_request_api-1.2.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: CMIP7_data_request_api
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: A programmatic interface to the CMIP7 Data Request
|
|
5
5
|
Author: James Anstey, Gaëlle Rigoudy, Martin Schupfner, Matthew Mizielinski, Daniel Ellis, Elisabeth Dingley, Marie-Pierre Moine
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,6 +20,7 @@ Dynamic: license-file
|
|
|
20
20
|
|
|
21
21
|
[](https://pypi.python.org/pypi/CMIP7-data-request-api)
|
|
22
22
|
[](https://mybinder.org/v2/gh/CMIP-Data-Request/CMIP7_DReq_Software/main?filepath=notebooks)
|
|
23
|
+
[](https://colab.research.google.com/github/CMIP-Data-Request/CMIP7_DReq_Software/)
|
|
23
24
|
[](https://nbviewer.jupyter.org/github/CMIP-Data-Request/CMIP7_DReq_Software/tree/main/notebooks/)
|
|
24
25
|
[](https://github.com/CMIP-Data-Request/CMIP7_DReq_Software/blob/main/LICENSE)
|
|
25
26
|
[](https://www.repostatus.org/#active)
|
|
@@ -29,7 +30,7 @@ Dynamic: license-file
|
|
|
29
30
|
Python software to interact with the [CMIP7 data request](https://wcrp-cmip.org/cmip7/cmip7-data-request/).
|
|
30
31
|
It provides an API to query and utilize the information in the data request, including example scripts and notebooks showing how to use the API.
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
Please see below for the [installation guide](#installation) or how to [try it without installation](#try-it-without-installation).
|
|
33
34
|
|
|
34
35
|
The Data Request Task Team encourages user feedback to help us improve the software.
|
|
35
36
|
Here are some ways to provide feedback:
|
|
@@ -37,22 +38,25 @@ Here are some ways to provide feedback:
|
|
|
37
38
|
- For more general questions or concerns, such as suggestions for new features, contribute to the Software's [github discussion forum](https://github.com/CMIP-Data-Request/CMIP7_DReq_Software/discussions).
|
|
38
39
|
|
|
39
40
|
|
|
40
|
-
## v1.2 Data Request release
|
|
41
|
+
## v1.2.1 Data Request release
|
|
41
42
|
|
|
42
|
-
The latest **official release** of the CMIP7 Data Request is `v1.2` (
|
|
43
|
-
|
|
43
|
+
The latest **official release** of the CMIP7 Data Request is `v1.2.1` (26 April 2025).
|
|
44
|
+
[Learn more about this release on the CMIP website](https://wcrp-cmip.org/cmip7-data-request-v1-2-1/).
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
|
|
47
|
+
## Try It Without Installation
|
|
48
|
+
|
|
49
|
+
You can launch and interact with this repository in a live environment via [Binder](https://mybinder.org/) or [Google Colab](https://colab.research.google.com/) — no installation needed, just click on one of the badges to run it in your browser:
|
|
50
|
+
|
|
51
|
+
[](https://mybinder.org/v2/gh/CMIP-Data-Request/CMIP7_DReq_Software/main?filepath=notebooks)
|
|
52
|
+
[](https://colab.research.google.com/github/CMIP-Data-Request/CMIP7_DReq_Software/)
|
|
49
53
|
|
|
50
54
|
|
|
51
55
|
## Installation
|
|
52
56
|
|
|
53
57
|
### Quick Start
|
|
54
58
|
|
|
55
|
-
In a python virtual environment
|
|
59
|
+
In a python virtual environment or conda environment in which you want to install the package, do:
|
|
56
60
|
|
|
57
61
|
```bash
|
|
58
62
|
pip install CMIP7-data-request-api
|
|
@@ -64,9 +68,14 @@ If an environment first needs to be created, you can do:
|
|
|
64
68
|
python -m venv my_dreq_env
|
|
65
69
|
source my_dreq_env/bin/activate
|
|
66
70
|
pip install --upgrade pip
|
|
71
|
+
pip install CMIP7-data-request-api
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
This will automatically install the dependencies, but if necessary they can be manually installed by doing:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
67
77
|
wget https://raw.githubusercontent.com/CMIP-Data-Request/CMIP7_DReq_Software/refs/heads/main/requirements.txt
|
|
68
78
|
pip install -r requirements.txt
|
|
69
|
-
pip install CMIP7-data-request-api
|
|
70
79
|
```
|
|
71
80
|
|
|
72
81
|
using the `requirements.txt` file from the top-level directory of this repository, which lists the package dependencies, and `my_dreq_env` can be changed to whatever environment name is preferred.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
[](https://pypi.python.org/pypi/CMIP7-data-request-api)
|
|
2
2
|
[](https://mybinder.org/v2/gh/CMIP-Data-Request/CMIP7_DReq_Software/main?filepath=notebooks)
|
|
3
|
+
[](https://colab.research.google.com/github/CMIP-Data-Request/CMIP7_DReq_Software/)
|
|
3
4
|
[](https://nbviewer.jupyter.org/github/CMIP-Data-Request/CMIP7_DReq_Software/tree/main/notebooks/)
|
|
4
5
|
[](https://github.com/CMIP-Data-Request/CMIP7_DReq_Software/blob/main/LICENSE)
|
|
5
6
|
[](https://www.repostatus.org/#active)
|
|
@@ -9,7 +10,7 @@
|
|
|
9
10
|
Python software to interact with the [CMIP7 data request](https://wcrp-cmip.org/cmip7/cmip7-data-request/).
|
|
10
11
|
It provides an API to query and utilize the information in the data request, including example scripts and notebooks showing how to use the API.
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
Please see below for the [installation guide](#installation) or how to [try it without installation](#try-it-without-installation).
|
|
13
14
|
|
|
14
15
|
The Data Request Task Team encourages user feedback to help us improve the software.
|
|
15
16
|
Here are some ways to provide feedback:
|
|
@@ -17,22 +18,25 @@ Here are some ways to provide feedback:
|
|
|
17
18
|
- For more general questions or concerns, such as suggestions for new features, contribute to the Software's [github discussion forum](https://github.com/CMIP-Data-Request/CMIP7_DReq_Software/discussions).
|
|
18
19
|
|
|
19
20
|
|
|
20
|
-
## v1.2 Data Request release
|
|
21
|
+
## v1.2.1 Data Request release
|
|
21
22
|
|
|
22
|
-
The latest **official release** of the CMIP7 Data Request is `v1.2` (
|
|
23
|
-
|
|
23
|
+
The latest **official release** of the CMIP7 Data Request is `v1.2.1` (26 April 2025).
|
|
24
|
+
[Learn more about this release on the CMIP website](https://wcrp-cmip.org/cmip7-data-request-v1-2-1/).
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
|
|
27
|
+
## Try It Without Installation
|
|
28
|
+
|
|
29
|
+
You can launch and interact with this repository in a live environment via [Binder](https://mybinder.org/) or [Google Colab](https://colab.research.google.com/) — no installation needed, just click on one of the badges to run it in your browser:
|
|
30
|
+
|
|
31
|
+
[](https://mybinder.org/v2/gh/CMIP-Data-Request/CMIP7_DReq_Software/main?filepath=notebooks)
|
|
32
|
+
[](https://colab.research.google.com/github/CMIP-Data-Request/CMIP7_DReq_Software/)
|
|
29
33
|
|
|
30
34
|
|
|
31
35
|
## Installation
|
|
32
36
|
|
|
33
37
|
### Quick Start
|
|
34
38
|
|
|
35
|
-
In a python virtual environment
|
|
39
|
+
In a python virtual environment or conda environment in which you want to install the package, do:
|
|
36
40
|
|
|
37
41
|
```bash
|
|
38
42
|
pip install CMIP7-data-request-api
|
|
@@ -44,9 +48,14 @@ If an environment first needs to be created, you can do:
|
|
|
44
48
|
python -m venv my_dreq_env
|
|
45
49
|
source my_dreq_env/bin/activate
|
|
46
50
|
pip install --upgrade pip
|
|
51
|
+
pip install CMIP7-data-request-api
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This will automatically install the dependencies, but if necessary they can be manually installed by doing:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
47
57
|
wget https://raw.githubusercontent.com/CMIP-Data-Request/CMIP7_DReq_Software/refs/heads/main/requirements.txt
|
|
48
58
|
pip install -r requirements.txt
|
|
49
|
-
pip install CMIP7-data-request-api
|
|
50
59
|
```
|
|
51
60
|
|
|
52
61
|
using the `requirements.txt` file from the top-level directory of this repository, which lists the package dependencies, and `my_dreq_env` can be changed to whatever environment name is preferred.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: CMIP7_data_request_api
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: A programmatic interface to the CMIP7 Data Request
|
|
5
5
|
Author: James Anstey, Gaëlle Rigoudy, Martin Schupfner, Matthew Mizielinski, Daniel Ellis, Elisabeth Dingley, Marie-Pierre Moine
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,6 +20,7 @@ Dynamic: license-file
|
|
|
20
20
|
|
|
21
21
|
[](https://pypi.python.org/pypi/CMIP7-data-request-api)
|
|
22
22
|
[](https://mybinder.org/v2/gh/CMIP-Data-Request/CMIP7_DReq_Software/main?filepath=notebooks)
|
|
23
|
+
[](https://colab.research.google.com/github/CMIP-Data-Request/CMIP7_DReq_Software/)
|
|
23
24
|
[](https://nbviewer.jupyter.org/github/CMIP-Data-Request/CMIP7_DReq_Software/tree/main/notebooks/)
|
|
24
25
|
[](https://github.com/CMIP-Data-Request/CMIP7_DReq_Software/blob/main/LICENSE)
|
|
25
26
|
[](https://www.repostatus.org/#active)
|
|
@@ -29,7 +30,7 @@ Dynamic: license-file
|
|
|
29
30
|
Python software to interact with the [CMIP7 data request](https://wcrp-cmip.org/cmip7/cmip7-data-request/).
|
|
30
31
|
It provides an API to query and utilize the information in the data request, including example scripts and notebooks showing how to use the API.
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
Please see below for the [installation guide](#installation) or how to [try it without installation](#try-it-without-installation).
|
|
33
34
|
|
|
34
35
|
The Data Request Task Team encourages user feedback to help us improve the software.
|
|
35
36
|
Here are some ways to provide feedback:
|
|
@@ -37,22 +38,25 @@ Here are some ways to provide feedback:
|
|
|
37
38
|
- For more general questions or concerns, such as suggestions for new features, contribute to the Software's [github discussion forum](https://github.com/CMIP-Data-Request/CMIP7_DReq_Software/discussions).
|
|
38
39
|
|
|
39
40
|
|
|
40
|
-
## v1.2 Data Request release
|
|
41
|
+
## v1.2.1 Data Request release
|
|
41
42
|
|
|
42
|
-
The latest **official release** of the CMIP7 Data Request is `v1.2` (
|
|
43
|
-
|
|
43
|
+
The latest **official release** of the CMIP7 Data Request is `v1.2.1` (26 April 2025).
|
|
44
|
+
[Learn more about this release on the CMIP website](https://wcrp-cmip.org/cmip7-data-request-v1-2-1/).
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
|
|
47
|
+
## Try It Without Installation
|
|
48
|
+
|
|
49
|
+
You can launch and interact with this repository in a live environment via [Binder](https://mybinder.org/) or [Google Colab](https://colab.research.google.com/) — no installation needed, just click on one of the badges to run it in your browser:
|
|
50
|
+
|
|
51
|
+
[](https://mybinder.org/v2/gh/CMIP-Data-Request/CMIP7_DReq_Software/main?filepath=notebooks)
|
|
52
|
+
[](https://colab.research.google.com/github/CMIP-Data-Request/CMIP7_DReq_Software/)
|
|
49
53
|
|
|
50
54
|
|
|
51
55
|
## Installation
|
|
52
56
|
|
|
53
57
|
### Quick Start
|
|
54
58
|
|
|
55
|
-
In a python virtual environment
|
|
59
|
+
In a python virtual environment or conda environment in which you want to install the package, do:
|
|
56
60
|
|
|
57
61
|
```bash
|
|
58
62
|
pip install CMIP7-data-request-api
|
|
@@ -64,9 +68,14 @@ If an environment first needs to be created, you can do:
|
|
|
64
68
|
python -m venv my_dreq_env
|
|
65
69
|
source my_dreq_env/bin/activate
|
|
66
70
|
pip install --upgrade pip
|
|
71
|
+
pip install CMIP7-data-request-api
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
This will automatically install the dependencies, but if necessary they can be manually installed by doing:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
67
77
|
wget https://raw.githubusercontent.com/CMIP-Data-Request/CMIP7_DReq_Software/refs/heads/main/requirements.txt
|
|
68
78
|
pip install -r requirements.txt
|
|
69
|
-
pip install CMIP7-data-request-api
|
|
70
79
|
```
|
|
71
80
|
|
|
72
81
|
using the `requirements.txt` file from the top-level directory of this repository, which lists the package dependencies, and `my_dreq_env` can be changed to whatever environment name is preferred.
|
|
@@ -10,6 +10,7 @@ requirements.txt
|
|
|
10
10
|
.github/workflows/pip_install.yml
|
|
11
11
|
.github/workflows/publish2pypi.yml
|
|
12
12
|
.github/workflows/updates.yml
|
|
13
|
+
binder/environment.yml
|
|
13
14
|
data_request_api/.DS_Store
|
|
14
15
|
data_request_api/CMIP7_data_request_api.egg-info/PKG-INFO
|
|
15
16
|
data_request_api/CMIP7_data_request_api.egg-info/SOURCES.txt
|
|
@@ -131,9 +132,11 @@ notebooks/workflow_example.ipynb
|
|
|
131
132
|
notebooks/outdir/.gitkeep
|
|
132
133
|
scripts/check_consolidation.py
|
|
133
134
|
scripts/check_consolidation2.py
|
|
135
|
+
scripts/check_consolidation_and_transformation.py
|
|
134
136
|
scripts/check_variables_attributes.py
|
|
135
137
|
scripts/database_transformation.py
|
|
136
138
|
scripts/workflow_example.py
|
|
137
139
|
scripts/workflow_example_2.py
|
|
138
|
-
scripts/examples/requested_v1.2.json
|
|
139
|
-
scripts/examples/variables_v1.2.json
|
|
140
|
+
scripts/examples/requested_v1.2.1.json
|
|
141
|
+
scripts/examples/variables_v1.2.1.json
|
|
142
|
+
scripts/sandbox/create_brand_name.py
|
|
@@ -8,6 +8,7 @@ from data_request_api.utilities import config as dreqcfg
|
|
|
8
8
|
def main():
|
|
9
9
|
parser = argparse.ArgumentParser(
|
|
10
10
|
description="Config CLI",
|
|
11
|
+
formatter_class=argparse.RawTextHelpFormatter,
|
|
11
12
|
epilog="""Arguments:
|
|
12
13
|
init (or no arguments): Initialize the config file,
|
|
13
14
|
i.e. create a config file with default values if it does not exist.
|
|
@@ -17,8 +18,8 @@ def main():
|
|
|
17
18
|
help: print this help message.
|
|
18
19
|
|
|
19
20
|
Examples:
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
CMIP7_data_request_api_config offline true
|
|
22
|
+
CMIP7_data_request_api_config reset""",
|
|
22
23
|
)
|
|
23
24
|
|
|
24
25
|
if parser.prog.startswith("config"):
|
|
@@ -38,7 +39,7 @@ Examples:
|
|
|
38
39
|
dreqcfg.CONFIG_FILE = args.cfgfile
|
|
39
40
|
|
|
40
41
|
if len(args.command) == 0 or args.command[0] == "init":
|
|
41
|
-
print("Initializing config file:")
|
|
42
|
+
print(f"Initializing config file: '{dreqcfg.CONFIG_FILE}'")
|
|
42
43
|
dreqcfg.load_config()
|
|
43
44
|
elif args.command[0] == "reset":
|
|
44
45
|
print("Resetting config with defaults:")
|
|
@@ -64,7 +64,7 @@ def get_variable_size(var_info, dreq_dim_sizes, time_dims, freq_times_per_year,
|
|
|
64
64
|
n = 24 * 12
|
|
65
65
|
else:
|
|
66
66
|
n = freq_times_per_year[frequency]
|
|
67
|
-
temporal_shape = dim
|
|
67
|
+
temporal_shape = time_dims[dim]
|
|
68
68
|
elif dim in config['dimensions']:
|
|
69
69
|
# Use model-specific dimension size
|
|
70
70
|
n = config['dimensions'][dim]
|
|
@@ -74,7 +74,7 @@ def get_variable_size(var_info, dreq_dim_sizes, time_dims, freq_times_per_year,
|
|
|
74
74
|
n = dreq_dim_sizes[dim]
|
|
75
75
|
|
|
76
76
|
if n is None:
|
|
77
|
-
raise ValueError(f'No size found for dimension {dim}')
|
|
77
|
+
raise ValueError(f'No size found for dimension: {dim}')
|
|
78
78
|
|
|
79
79
|
dim_sizes[dim] = n
|
|
80
80
|
|
|
@@ -101,7 +101,7 @@ def parse_args():
|
|
|
101
101
|
parser.add_argument('request', type=str,
|
|
102
102
|
help='json file specifying variables requested by experiment' +
|
|
103
103
|
' (output from export_dreq_lists_json, which specifies the data request version)' +
|
|
104
|
-
' OR can be a data request version (e.g. "v1.2")
|
|
104
|
+
' OR can be a data request version (e.g. "v1.2")')
|
|
105
105
|
# Optional arguments
|
|
106
106
|
parser.add_argument('-v', '--variables', nargs='+', type=str,
|
|
107
107
|
help='include only the specified variables in the estimate')
|
|
@@ -167,12 +167,13 @@ years: 1
|
|
|
167
167
|
config = yaml.safe_load(f)
|
|
168
168
|
print('Loaded ' + config_file)
|
|
169
169
|
|
|
170
|
-
warning_msg = '\n * * * WARNING * * *'
|
|
171
|
-
warning_msg += '\n These volumes are an initial estimate
|
|
172
|
-
warning_msg += '\n They should be used with caution and verified against known data volumes
|
|
170
|
+
warning_msg = '\n * * * * * * * * * * * * * * * WARNING * * * * * * * * * * * * * * *'
|
|
171
|
+
warning_msg += '\n These volumes are an initial estimate.'
|
|
172
|
+
warning_msg += '\n They should be used with caution and verified against known data volumes.'
|
|
173
|
+
warning_msg += '\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n'
|
|
173
174
|
|
|
174
175
|
request_from_input_file = None
|
|
175
|
-
if os.path.
|
|
176
|
+
if os.path.isfile(args.request):
|
|
176
177
|
# Argument is a file that lists requested variables
|
|
177
178
|
filepath = args.request
|
|
178
179
|
with open(filepath, 'r') as f:
|
|
@@ -232,8 +233,20 @@ years: 1
|
|
|
232
233
|
if set(freq_times_per_year.keys()) != set(freqs):
|
|
233
234
|
raise Exception('Times per year must be defined for all available frequencies')
|
|
234
235
|
|
|
235
|
-
# Get
|
|
236
|
-
|
|
236
|
+
# Get mapping from time dimension name to temporal shape name
|
|
237
|
+
# {'time1': 'time-point', 'time': 'time-intv', ... etc}
|
|
238
|
+
time_dims = {}
|
|
239
|
+
for rec in dreq_tables['temporal shape'].records.values():
|
|
240
|
+
shape_name = rec.name
|
|
241
|
+
if hasattr(rec, 'dimensions'):
|
|
242
|
+
assert len(rec.dimensions) == 1
|
|
243
|
+
link = rec.dimensions[0]
|
|
244
|
+
dim_rec = dreq_tables['coordinates and dimensions'].get_record(link)
|
|
245
|
+
dim_name = dim_rec.name
|
|
246
|
+
else:
|
|
247
|
+
dim_name = 'None'
|
|
248
|
+
assert dim_name not in time_dims, 'time dimension names are not unique'
|
|
249
|
+
time_dims[dim_name] = shape_name
|
|
237
250
|
|
|
238
251
|
# Get metadata for variables
|
|
239
252
|
variables = dq.get_variables_metadata(
|
|
@@ -307,7 +320,11 @@ years: 1
|
|
|
307
320
|
for expt in expts:
|
|
308
321
|
expt_rec = expt_records[expt]
|
|
309
322
|
|
|
310
|
-
|
|
323
|
+
if hasattr(expt_rec, 'size_years_minimum'):
|
|
324
|
+
num_years = expt_rec.size_years_minimum
|
|
325
|
+
else:
|
|
326
|
+
num_years = 100
|
|
327
|
+
print(f'Warning: number of years not found for experiment {expt}, assuming size_years_minimum = {num_years}')
|
|
311
328
|
num_ensem = 1
|
|
312
329
|
|
|
313
330
|
# Loop over priority levels of requeste variables
|
|
@@ -339,7 +356,12 @@ years: 1
|
|
|
339
356
|
# Assume this is a climatology, so don't multiply by number of years
|
|
340
357
|
pass
|
|
341
358
|
else:
|
|
342
|
-
|
|
359
|
+
valid_shapes = ['time-intv', 'time-point', 'monthly-mean-daily-stat']
|
|
360
|
+
version_tuple = dq.get_dreq_version_tuple(use_dreq_version)
|
|
361
|
+
if version_tuple[:2] < (1, 2):
|
|
362
|
+
# Prior to v1.2, monthly-mean-daily-stat was called monthly-mean-stat
|
|
363
|
+
valid_shapes.append('monthly-mean-stat')
|
|
364
|
+
assert temporal_shape in valid_shapes, \
|
|
343
365
|
'Unknown temporal shape: ' + str(temporal_shape)
|
|
344
366
|
# Multiply the 1-year size by the minimum number of request years for this experiment
|
|
345
367
|
size *= num_years
|
|
@@ -149,18 +149,19 @@ def main():
|
|
|
149
149
|
|
|
150
150
|
# Get metadata for variables
|
|
151
151
|
all_var_info = dq.get_variables_metadata(
|
|
152
|
-
base,
|
|
152
|
+
base, use_dreq_version,
|
|
153
153
|
compound_names=all_var_names,
|
|
154
|
-
use_dreq_version=use_dreq_version # TO DEPRECATE
|
|
154
|
+
# use_dreq_version=use_dreq_version # TO DEPRECATE
|
|
155
155
|
)
|
|
156
156
|
|
|
157
157
|
# Write output file(s)
|
|
158
158
|
for filepath in args.variables_metadata:
|
|
159
159
|
dq.write_variables_metadata(
|
|
160
160
|
all_var_info,
|
|
161
|
+
use_dreq_version,
|
|
161
162
|
filepath,
|
|
162
163
|
api_version=data_request_api.version,
|
|
163
|
-
use_dreq_version=use_dreq_version,
|
|
164
|
+
# use_dreq_version=use_dreq_version,
|
|
164
165
|
content_path=dc._dreq_content_loaded['json_path']
|
|
165
166
|
)
|
|
166
167
|
|
|
@@ -122,7 +122,7 @@ def _apply_hard_fixes(data):
|
|
|
122
122
|
return data
|
|
123
123
|
|
|
124
124
|
|
|
125
|
-
def _filter_references(val, key, table, rid):
|
|
125
|
+
def _filter_references(val, key, table, rid, dtype=None):
|
|
126
126
|
"""
|
|
127
127
|
Filters lists of or strings with comma-separated references to other records.
|
|
128
128
|
"""
|
|
@@ -142,8 +142,8 @@ def _filter_references(val, key, table, rid):
|
|
|
142
142
|
f"'{table}': Filtered {len(val) - len(filtered)} of {len(val)}"
|
|
143
143
|
f" references for '{key}' of record '{rid}'."
|
|
144
144
|
)
|
|
145
|
-
return filtered
|
|
146
|
-
elif isinstance(val, str) and "rec"
|
|
145
|
+
return _fix_dtype(key, filtered, dtype)
|
|
146
|
+
elif isinstance(val, str) and val.startswith("rec"):
|
|
147
147
|
if "," in val:
|
|
148
148
|
vallist = [v.strip() for v in val.split(",")]
|
|
149
149
|
filtered = [v for v in vallist if v not in filtered_records]
|
|
@@ -157,14 +157,14 @@ def _filter_references(val, key, table, rid):
|
|
|
157
157
|
f"'{table}': Filtered {len(vallist) - len(filtered)} of"
|
|
158
158
|
f" {len(vallist)} references for '{key}' of record '{rid}'."
|
|
159
159
|
)
|
|
160
|
-
return ",".join(filtered)
|
|
160
|
+
return _fix_dtype(key, ",".join(filtered), dtype)
|
|
161
161
|
elif val.strip() in filtered_records:
|
|
162
162
|
logger.warning(f"'{table}': Filtered the only reference for '{key}' of record '{rid}'.")
|
|
163
|
-
return ""
|
|
163
|
+
return _fix_dtype(key, "", dtype)
|
|
164
164
|
else:
|
|
165
|
-
return val
|
|
165
|
+
return _fix_dtype(key, _fix_str(val), dtype)
|
|
166
166
|
else:
|
|
167
|
-
return val
|
|
167
|
+
return _fix_dtype(key, _fix_str(val), dtype)
|
|
168
168
|
|
|
169
169
|
|
|
170
170
|
def _gen_rid_uid_map(data):
|
|
@@ -194,6 +194,61 @@ def _gen_rid_uid_map(data):
|
|
|
194
194
|
return rid_uid_map
|
|
195
195
|
|
|
196
196
|
|
|
197
|
+
def _fix_str(var):
|
|
198
|
+
"""Adds missing space after commas and strips whitespace from strings."""
|
|
199
|
+
if isinstance(var, str):
|
|
200
|
+
return re.sub(r",(?=\S)", ", ", var).strip()
|
|
201
|
+
else:
|
|
202
|
+
return var
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def _fix_str_nested(data):
|
|
206
|
+
"""Adds missing space after commas and strips whitespace from strings in nested dictionary."""
|
|
207
|
+
sub = re.sub
|
|
208
|
+
pattern = r",(?=\S)"
|
|
209
|
+
for table in data.values():
|
|
210
|
+
for record in table["records"].values():
|
|
211
|
+
record.update({k: sub(pattern, ", ", v).strip() if isinstance(v, str) else v for k, v in record.items()})
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _fix_dtype(fkey, fval, dtype=None):
|
|
215
|
+
"""Fixes data types for record fields."""
|
|
216
|
+
logger = get_logger()
|
|
217
|
+
|
|
218
|
+
if dtype is None:
|
|
219
|
+
return fval
|
|
220
|
+
elif dtype == "str":
|
|
221
|
+
logger.debug(f"Consolidate export: Converting field '{fkey}' ('{fval}') to string.")
|
|
222
|
+
return str(fval)
|
|
223
|
+
elif dtype == "int":
|
|
224
|
+
logger.debug(f"Consolidate export: Converting field '{fkey}' ('{fval}') to int.")
|
|
225
|
+
return int(fval)
|
|
226
|
+
elif dtype == "float":
|
|
227
|
+
logger.debug(f"Consolidate export: Converting field '{fkey}' ('{fval}') to float.")
|
|
228
|
+
return float(fval)
|
|
229
|
+
elif dtype == "listofstr":
|
|
230
|
+
logger.debug(f"Consolidate export: Converting field '{fkey}' to a list of strings.")
|
|
231
|
+
if isinstance(fval, list):
|
|
232
|
+
return [str(v) for v in fval]
|
|
233
|
+
else:
|
|
234
|
+
return [str(fval)]
|
|
235
|
+
elif dtype == "listofint":
|
|
236
|
+
logger.debug(f"Consolidate export: Converting field '{fkey}' to a list of ints.")
|
|
237
|
+
if isinstance(fval, list):
|
|
238
|
+
return [int(v) for v in fval]
|
|
239
|
+
else:
|
|
240
|
+
return [int(fval)]
|
|
241
|
+
elif dtype == "listoffloat":
|
|
242
|
+
logger.debug(f"Consolidate export: Converting field '{fkey}' to a list of floats.")
|
|
243
|
+
if isinstance(fval, list):
|
|
244
|
+
return [float(v) for v in fval]
|
|
245
|
+
else:
|
|
246
|
+
return [float(fval)]
|
|
247
|
+
else:
|
|
248
|
+
logger.warning(f"Consolidate export: Unsupported data type '{dtype}' for field '{fkey}'.")
|
|
249
|
+
return fval
|
|
250
|
+
|
|
251
|
+
|
|
197
252
|
def map_data(data, mapping_table, version, **kwargs):
|
|
198
253
|
"""
|
|
199
254
|
Maps the data to the one-base structure using the mapping table.
|
|
@@ -310,7 +365,11 @@ def map_data(data, mapping_table, version, **kwargs):
|
|
|
310
365
|
"records": {
|
|
311
366
|
record_id: {
|
|
312
367
|
mapinfo["internal_consistency"].get(reckey, reckey): _filter_references(
|
|
313
|
-
recvalue,
|
|
368
|
+
recvalue,
|
|
369
|
+
reckey,
|
|
370
|
+
table,
|
|
371
|
+
record_id,
|
|
372
|
+
mapinfo["field_dtypes"].get(mapinfo["internal_consistency"].get(reckey, reckey), None),
|
|
314
373
|
)
|
|
315
374
|
for reckey, recvalue in record.items()
|
|
316
375
|
if reckey not in mapinfo["drop_keys"]
|
|
@@ -525,6 +584,9 @@ def map_data(data, mapping_table, version, **kwargs):
|
|
|
525
584
|
# Consistency fixes
|
|
526
585
|
mapped_data = next(iter(data.values()))
|
|
527
586
|
mapped_data = _apply_consistency_fixes(mapped_data)
|
|
587
|
+
# String fixes
|
|
588
|
+
logger.debug("Consolidation: Removing / Adding (un)necessary whitespace to strings.")
|
|
589
|
+
_fix_str_nested(mapped_data)
|
|
528
590
|
mapped_data["version"] = version
|
|
529
591
|
return {"Data Request": mapped_data}
|
|
530
592
|
else:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import atexit
|
|
4
4
|
import json
|
|
5
5
|
import os
|
|
6
6
|
import re
|
|
@@ -65,6 +65,10 @@ except KeyError:
|
|
|
65
65
|
|
|
66
66
|
_dreq_content_loaded = {}
|
|
67
67
|
|
|
68
|
+
# Internal flag used to determine whether a warning on API version can be issued
|
|
69
|
+
# (Purpose is to prevent the warning being issued more than once per session)
|
|
70
|
+
_CHECK_API_VERSION = True
|
|
71
|
+
|
|
68
72
|
|
|
69
73
|
def _parse_version(version):
|
|
70
74
|
"""Parse a version tag and return a tuple for sorting.
|
|
@@ -121,9 +125,6 @@ def get_cached(**kwargs):
|
|
|
121
125
|
json_export = _json_raw
|
|
122
126
|
elif kwargs["export"] == "release":
|
|
123
127
|
json_export = _json_release
|
|
124
|
-
else:
|
|
125
|
-
warnings.warn(f"Unknown export type '{kwargs['export']}'. Defaulting to 'release'.")
|
|
126
|
-
json_export = _json_release
|
|
127
128
|
local_versions = [
|
|
128
129
|
name for name in os.listdir(_dreq_res) if os.path.isfile(os.path.join(_dreq_res, name, json_export))
|
|
129
130
|
]
|
|
@@ -293,6 +294,7 @@ def get_versions(target="tags", **kwargs):
|
|
|
293
294
|
"""
|
|
294
295
|
global versions
|
|
295
296
|
global _versions_retrieved_last
|
|
297
|
+
global _CHECK_API_VERSION
|
|
296
298
|
|
|
297
299
|
if target not in ["tags", "branches"]:
|
|
298
300
|
raise ValueError("target must be 'tags' or 'branches'.")
|
|
@@ -314,7 +316,14 @@ def get_versions(target="tags", **kwargs):
|
|
|
314
316
|
if target == "tags" and "dev" not in versions[target]:
|
|
315
317
|
versions[target].append("dev")
|
|
316
318
|
|
|
317
|
-
|
|
319
|
+
if kwargs['check_api_version'] and not kwargs["offline"]:
|
|
320
|
+
# Warn user if the API version is not the latest one available on PyPI
|
|
321
|
+
if _CHECK_API_VERSION:
|
|
322
|
+
atexit.register(dreqcfg.check_api_version)
|
|
323
|
+
# Set flag to prevent the same warning being shown more than once
|
|
324
|
+
_CHECK_API_VERSION = False
|
|
325
|
+
|
|
326
|
+
# List tags of dreq versions hosted on GitHub
|
|
318
327
|
return versions[target]
|
|
319
328
|
|
|
320
329
|
|
|
@@ -393,7 +402,7 @@ def retrieve(version="latest_stable", **kwargs):
|
|
|
393
402
|
if versions == [None] or not versions:
|
|
394
403
|
raise ValueError(f"Version '{version}' not found.")
|
|
395
404
|
elif version in ["v1.0alpha"] and "export" in kwargs and kwargs["export"] == "raw":
|
|
396
|
-
warnings.warn(f"For version '{version}' no raw export exists.")
|
|
405
|
+
warnings.warn(f"For version '{version}' no raw export exists. Defaulting to release export.")
|
|
397
406
|
|
|
398
407
|
json_paths = dict()
|
|
399
408
|
for version in versions:
|
|
@@ -406,8 +415,6 @@ def retrieve(version="latest_stable", **kwargs):
|
|
|
406
415
|
json_export = _json_release
|
|
407
416
|
elif kwargs["export"] == "raw":
|
|
408
417
|
json_export = _json_raw
|
|
409
|
-
else:
|
|
410
|
-
warnings.warn(f"Unknown export type '{kwargs['export']}'.")
|
|
411
418
|
elif _version_pattern.match(version):
|
|
412
419
|
json_export = _json_release
|
|
413
420
|
else:
|
|
@@ -544,10 +551,6 @@ def delete(version="all", keep_latest=False, **kwargs):
|
|
|
544
551
|
cached_files = [os.path.join(_dreq_res, v, _json_raw) for v in local_versions]
|
|
545
552
|
elif kwargs["export"] == "release":
|
|
546
553
|
cached_files = [os.path.join(_dreq_res, v, _json_release) for v in local_versions]
|
|
547
|
-
else:
|
|
548
|
-
# Since files are to be deleted, not defaulting to "release" but rather
|
|
549
|
-
# raising a ValueError
|
|
550
|
-
raise ValueError(f"Unknown export type '{kwargs['export']}'.")
|
|
551
554
|
|
|
552
555
|
# Delete files
|
|
553
556
|
for f in cached_files:
|
|
@@ -290,11 +290,12 @@ def tidy_content(content, record_to_uid_index):
|
|
|
290
290
|
to_remove_entries[subelt][(record_id, uid)] += 1
|
|
291
291
|
content_string = tmp_content_string
|
|
292
292
|
content[content_subelt] = json.loads(content_string)
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
293
|
+
for content_subelt in ["opportunities", "coordinates_and_dimensions"]:
|
|
294
|
+
if content_subelt in to_remove_entries:
|
|
295
|
+
to_remove = [elt for (elt, nb) in to_remove_entries[content_subelt].items() if nb == len_list_content]
|
|
296
|
+
for record_id, _ in to_remove:
|
|
297
|
+
del record_to_uid_index[content_subelt][record_id]
|
|
298
|
+
del to_remove_entries[content_subelt]
|
|
298
299
|
for (subelt, to_remove) in to_remove_entries.items():
|
|
299
300
|
to_remove = [elt for (elt, nb) in to_remove.items() if nb == len_list_content]
|
|
300
301
|
for (record_id, uid) in to_remove:
|