CMIP7-data-request-api 1.1.2__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.
- CMIP7_data_request_api-1.1.2.dist-info/LICENSE +21 -0
- CMIP7_data_request_api-1.1.2.dist-info/METADATA +210 -0
- CMIP7_data_request_api-1.1.2.dist-info/RECORD +36 -0
- CMIP7_data_request_api-1.1.2.dist-info/WHEEL +5 -0
- CMIP7_data_request_api-1.1.2.dist-info/entry_points.txt +2 -0
- CMIP7_data_request_api-1.1.2.dist-info/top_level.txt +1 -0
- data_request_api/__init__.py +1 -0
- data_request_api/command_line/__init__.py +0 -0
- data_request_api/command_line/export_dreq_lists_json.py +136 -0
- data_request_api/dev/JA/__init__.py +0 -0
- data_request_api/dev/JA/check_plev_requests.py +416 -0
- data_request_api/dev/JA/read_feedback_spreadsheet.py +141 -0
- data_request_api/dev/JA/workflow_example_GRtest.py +275 -0
- data_request_api/dev/JA/workflow_example_test.py +222 -0
- data_request_api/dev/MM/checksum.py +68 -0
- data_request_api/dev/MM/walking_data_request.ipynb +380 -0
- data_request_api/dev/MS/dreq_content_and_walking_data_request.ipynb +3755 -0
- data_request_api/dev/__init__.py +0 -0
- data_request_api/stable/__init__.py +0 -0
- data_request_api/stable/content/README.MD +106 -0
- data_request_api/stable/content/__init__.py +0 -0
- data_request_api/stable/content/dreq_api/__init__.py +0 -0
- data_request_api/stable/content/dreq_api/consolidate_export.py +488 -0
- data_request_api/stable/content/dreq_api/dreq_content.py +593 -0
- data_request_api/stable/content/dreq_api/mapping_table.py +335 -0
- data_request_api/stable/content/dreq_api/test_dreq_content.py +194 -0
- data_request_api/stable/content/dump_transformation.py +550 -0
- data_request_api/stable/query/__init__.py +0 -0
- data_request_api/stable/query/data_request.py +1120 -0
- data_request_api/stable/query/dreq_classes.py +372 -0
- data_request_api/stable/query/dreq_query.py +981 -0
- data_request_api/stable/query/vocabulary_server.py +208 -0
- data_request_api/stable/utilities/__init__.py +0 -0
- data_request_api/stable/utilities/logger.py +71 -0
- data_request_api/stable/utilities/tools.py +49 -0
- data_request_api/version.py +16 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2025 CMIP IPO
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: CMIP7_data_request_api
|
|
3
|
+
Version: 1.1.2
|
|
4
|
+
Summary: A programatic interface to the CMIP7 Data Request
|
|
5
|
+
Author: James Anstey, Gaëlle Rigoudy, Martin Schupfner, Matthew Mizielinski, Daniel Ellis, Elisabeth Dingley, Marie-Pierre Moine
|
|
6
|
+
Project-URL: Homepage, https://github.com/CMIP-Data-Request/CMIP7_DReq_Software
|
|
7
|
+
Project-URL: Issues, https://github.com/CMIP-Data-Request/CMIP7_DReq_Software/issues
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: pooch
|
|
15
|
+
Requires-Dist: openpyxl
|
|
16
|
+
Requires-Dist: requests
|
|
17
|
+
Requires-Dist: beautifulsoup4
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# CMIP7 Data Request Software
|
|
21
|
+
|
|
22
|
+
This repository contains python code to interact with the [CMIP7 data request](https://wcrp-cmip.org/cmip7/cmip7-data-request/).
|
|
23
|
+
Its aim is to provide an API and scripts that can produce lists of the variables requested for each CMIP7 experiment, information about the requested variables, and in general allow users to query and utilize the information in the data request.
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
## v1.1 release
|
|
27
|
+
|
|
28
|
+
The latest **official release** of the Data Request (30 Jan 2025) is tagged as `v1.1`.
|
|
29
|
+
Access all information about the v1.1 release [on the CMIP website](https://wcrp-cmip.org/cmip7-data-request-v1-1/).
|
|
30
|
+
Those trying out the Software should use:
|
|
31
|
+
- the `v1.1` tag, or
|
|
32
|
+
- the latest stable version, which will be the most recent commmit on the `main` branch.
|
|
33
|
+
|
|
34
|
+
For the **Quick Start** guide, please see below.
|
|
35
|
+
The **Overview** section explains more about what the Software is intended to do and how this relates to the Content of the data request.
|
|
36
|
+
|
|
37
|
+
**This Software is under active development** and will continue to evolve following the `v1.1` release.
|
|
38
|
+
Accordingly we encourage users to try the latest stable version in order to access the latest features.
|
|
39
|
+
|
|
40
|
+
The next sections provide a brief overview of the Software and explain how to get started.
|
|
41
|
+
While the Software is a work in progress, **the Data Request Task Team encourages user feedback to help us improve upcoming versions.**
|
|
42
|
+
Here are some ways to provide feedback:
|
|
43
|
+
- For specific questions or issues (such as bugs) please [open a github issue](https://github.com/CMIP-Data-Request/CMIP7_DReq_Software/issues).
|
|
44
|
+
- 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).
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## Overview
|
|
48
|
+
|
|
49
|
+
The CMIP7 data request **Software** and **Content** are version controlled in separate github repositories.
|
|
50
|
+
Official releases of the data request correspond to a tag in each of these repositories (e.g., `v1.1`).
|
|
51
|
+
However the Software can interact with different versions of the Content - for example, to examine changes that have occurred when a new version of the data request is issued.
|
|
52
|
+
|
|
53
|
+
The data request **Content**, which is version controlled [here](https://github.com/CMIP-Data-Request/CMIP7_DReq_Content), refers to all of the information comprising the data request.
|
|
54
|
+
This includes descriptions of Opportunities and their lists of requested variables, definitions of the variables, etc.
|
|
55
|
+
The Content is stored as a large `json` file, which is read by the data request Software.
|
|
56
|
+
However users should not interact with this `json` file directly and its structure is not designed for readability.
|
|
57
|
+
Users do not need to manually download the Content as this is done automatically by the Software (see "Getting Started", below, for further details).
|
|
58
|
+
|
|
59
|
+
The data request Content is an automatic export from **Airtable**, which a cloud platform used by the Data Request Task Team and CMIP IPO to facilitate ongoing community engagement in developing the data request.
|
|
60
|
+
Airtable provides users with a browseable web interface to explore data request information contained in relational databases that are referred to as "bases".
|
|
61
|
+
These Airtable bases contain interlinked tables that constitute the primary source of data request information.
|
|
62
|
+
|
|
63
|
+
The Content of each official release of the data request can be explored online using the [Airtable interface](https://bit.ly/CMIP7-DReq-v1_0).
|
|
64
|
+
This provides a browseable web view of the Content, allowing users to follow links between different elements of the data request - for example, to view the variables requested by a given Opportunity, or to view the Opportunities that request a given variable.
|
|
65
|
+
This view is complementary to the access to the Content that is provided via the Software, and both access methods (Airtable and Software) are based on the same underlying information.
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
Using the data request **Software** provides a way to interact programmatically with the data request Content, such as to:
|
|
69
|
+
|
|
70
|
+
- Given a list of supported Opportunities and their priorities, produce lists of variables to output for each experiment (see Getting Started section to test this functionality),
|
|
71
|
+
- Output the CF-compliant metadata characterizing each variable - an example file with some of the metadata for each requested variable is [available since v1.0](https://github.com/CMIP-Data-Request/CMIP7_DReq_Software/tree/main/scripts/variable_info/all_var_info.json),
|
|
72
|
+
- Compare the requested output of CMIP7 experiments to a given model's published CMIP6 output.
|
|
73
|
+
|
|
74
|
+
An aim of the Software is to facilitate integration of the data request into modelling workflows.
|
|
75
|
+
Suggestions for functionality are welcome in the [github discussion forum](https://github.com/CMIP-Data-Request/CMIP7_DReq_Software/discussions).
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
During development, the Software and Content repositories reside in the github organisation https://github.com/CMIP-Data-Request.
|
|
79
|
+
Stable releases will eventually be migrated into the https://github.com/WCRP-CMIP organisation.
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
## Quick Start
|
|
83
|
+
|
|
84
|
+
To get started by cloning from github, in a shell session clone the Software and navigate to the `scripts/` directory:
|
|
85
|
+
```bash
|
|
86
|
+
git clone git@github.com:CMIP-Data-Request/CMIP7_DReq_Software.git
|
|
87
|
+
cd CMIP7_DReq_Software
|
|
88
|
+
```
|
|
89
|
+
Alternately, see below for instructions on installing using `pip`, but note the following section's guidance on setting up an environment with the required dependencies.
|
|
90
|
+
|
|
91
|
+
### Environment setup
|
|
92
|
+
|
|
93
|
+
The `env.yml` file can be used to create a conda environment in which to run the Software:
|
|
94
|
+
```bash
|
|
95
|
+
conda env create -n my_dreq_env --file env.yml
|
|
96
|
+
```
|
|
97
|
+
where `my_dreq_env` should be replaced with your preferred environment name.
|
|
98
|
+
Activate this environment:
|
|
99
|
+
```bash
|
|
100
|
+
conda activate my_dreq_env
|
|
101
|
+
```
|
|
102
|
+
(On some systems it may be `source activate my_dreq_env`.)
|
|
103
|
+
Note that `env.yml` explicitly avoids using the conda `defaults` channel.
|
|
104
|
+
|
|
105
|
+
Alternately, the `requirements.txt` file can be used to create a python virtual environment:
|
|
106
|
+
```bash
|
|
107
|
+
python -m venv my_dreq_env_dir
|
|
108
|
+
source my_dreq_env_dir/bin/activate
|
|
109
|
+
pip install --upgrade pip
|
|
110
|
+
pip install -r requirements.txt
|
|
111
|
+
```
|
|
112
|
+
replacing `my_dreq_env_dir` with the path where you wish to store your environment.
|
|
113
|
+
This approach avoids using `conda`.
|
|
114
|
+
|
|
115
|
+
### Running the software
|
|
116
|
+
|
|
117
|
+
There are two example workflow scripts in the `scripts/` directory.
|
|
118
|
+
In a shell session where the environment (conda or venv/virtualenv, as explained above) has been activated, running:
|
|
119
|
+
```bash
|
|
120
|
+
python workflow_example.py
|
|
121
|
+
```
|
|
122
|
+
will produce a `json` file listing requested variables for each CMIP7 experiment.
|
|
123
|
+
The same functionality is available from a **command-line interface**, which can be accessed by installing the python package using pip (see below) and then using the `export_dreq_lists_json` command.
|
|
124
|
+
Running:
|
|
125
|
+
```bash
|
|
126
|
+
python workflow_example_2.py
|
|
127
|
+
```
|
|
128
|
+
will produce a set of `csv` files (i.e., spreadsheets) summarizing different aspects of the data request content.
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
## Pip installation
|
|
132
|
+
|
|
133
|
+
If you have a conda or virtual (venv, virtualenv) environment which already has the dependencies of
|
|
134
|
+
this package you can install the code using
|
|
135
|
+
```bash
|
|
136
|
+
python -m pip install git+https://github.com/CMIP-Data-Request/CMIP7_DReq_Software.git@<tag>
|
|
137
|
+
```
|
|
138
|
+
where `<tag>` needs to be replaced with the version you wish to
|
|
139
|
+
install.
|
|
140
|
+
|
|
141
|
+
If installation is successful you should be able to run the command
|
|
142
|
+
```bash
|
|
143
|
+
export_dreq_lists_json --all_opportunities v1.1 amip.json --experiments amip
|
|
144
|
+
```
|
|
145
|
+
to confirm that the variable list for the amip experiment can be produced.
|
|
146
|
+
Multiple experiments can be specified as a space-delimited list of case-sensitive experiment names (e.g., `--experiments amip historical piControl`).
|
|
147
|
+
Omitting the `--experiments` argument is equivalent to including all experiments in the data request.
|
|
148
|
+
To produce variable lists that support only a subset of Opportunities, use the `--opportunities_file` argument by running:
|
|
149
|
+
```bash
|
|
150
|
+
export_dreq_lists_json --opportunities_file opportunities.json v1.1 output.json
|
|
151
|
+
```
|
|
152
|
+
This will generate the `opportunities.json` template file in which Opportunity support can be specified (note that the list of available Opportunities may be updated in newer data request versions).
|
|
153
|
+
Edit this file to by setting unsupported Opportunities to `false` and then re-run the exact same command as above to generate the output file with lists of requested variables.
|
|
154
|
+
|
|
155
|
+
The package can be uninstalled using
|
|
156
|
+
```bash
|
|
157
|
+
python -m pip uninstall CMIP7_data_request_api
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
### Development
|
|
163
|
+
|
|
164
|
+
To install from a local copy for development purposes cd to the root
|
|
165
|
+
of the repository and run
|
|
166
|
+
```bash
|
|
167
|
+
python -m pip install -e .
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Command line utilities should be hosted under the
|
|
171
|
+
`data_request_api.command_line` package and pointed at by adding
|
|
172
|
+
references to the appropriate `main()` routine into the
|
|
173
|
+
`[project:scripts]` section of the pyproject.toml file.
|
|
174
|
+
|
|
175
|
+
## Further details
|
|
176
|
+
|
|
177
|
+
Th example script and the command-line tool contain a workflow to access the data request Content, specify a list of Opportunities and priority levels of variables, and output the lists of variables requested from each experiment in the specified Opportunities.
|
|
178
|
+
An example of the json file produced by running this script, which contains the names of output variables requested for each experiment, is available in `scripts/examples/`.
|
|
179
|
+
The example output file assumes that all data request Opportunities are supported at all priority levels, but this choice can be modified by the user.
|
|
180
|
+
|
|
181
|
+
Each listed variable in the output file is currently identified by a unique "compound name" using CMIP6-era table names and short variable names (`Amon.tas`, `Omon.tos`, etc).
|
|
182
|
+
Variable names may change in upcoming releases, but in any case a mapping to CMIP6-era variable names will be retained in the data request so as to allow comparison with CMIP6 output (for those variables that were defined in CMIP6).
|
|
183
|
+
|
|
184
|
+
To access the data request Content, the example script first needs to identify the version of the data request Content that is being used.
|
|
185
|
+
This is done in the example script by specifying a tag in the Content repo and calling the retrieval function.
|
|
186
|
+
For example:
|
|
187
|
+
```python
|
|
188
|
+
dc.retrieve('v1.1')
|
|
189
|
+
```
|
|
190
|
+
downloads `v1.1` of the Content into local cache, if it is not already there.
|
|
191
|
+
The script can then access it by loading it into a python dict variable:
|
|
192
|
+
```python
|
|
193
|
+
content = dc.load('v1.1')
|
|
194
|
+
```
|
|
195
|
+
Currently a single version of the Content `json` file for a versioned release is roughly 20 MB in size.
|
|
196
|
+
The size of local cache can be managed by deleting unused versions.
|
|
197
|
+
For example, to remove a specific version:
|
|
198
|
+
```python
|
|
199
|
+
dc.delete('v1.1')
|
|
200
|
+
```
|
|
201
|
+
Or to remove all locally cached versions:
|
|
202
|
+
```python
|
|
203
|
+
dc.delete()
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Contributors
|
|
207
|
+
|
|
208
|
+
[](https://github.com/CMIP-Data-Request/CMIP7_DReq_Software/graphs/contributors/)
|
|
209
|
+
|
|
210
|
+
Thanks to our contributors!
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
data_request_api/__init__.py,sha256=4-ghPak2S6zfMqmnlxW2GCgPb5s79znpKa2hGEGXcE4,24
|
|
2
|
+
data_request_api/version.py,sha256=nmVMEP2kpLDIzjgS-U1taCdJbVrmv_k8ao6RojGcvRg,411
|
|
3
|
+
data_request_api/command_line/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
data_request_api/command_line/export_dreq_lists_json.py,sha256=NfAMd86Zm_MwSPpODhLEloTx-ZXOKyW7NrkcR3SQue8,6230
|
|
5
|
+
data_request_api/dev/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
data_request_api/dev/JA/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
data_request_api/dev/JA/check_plev_requests.py,sha256=1DSOEM4ZqREVgWwjS3vnBc_cRNVDMGaHD8NTJfrMTwI,16978
|
|
8
|
+
data_request_api/dev/JA/read_feedback_spreadsheet.py,sha256=424hz7ti-YUcvZzOxvnGL-nqTY-dVvkIrEPszR3rFfE,5334
|
|
9
|
+
data_request_api/dev/JA/workflow_example_GRtest.py,sha256=bywNLFXCEMv5ALoU15UfUFWtNpBZlQ-tieD34nIA0Co,9536
|
|
10
|
+
data_request_api/dev/JA/workflow_example_test.py,sha256=fMcAsgpgFRhaWZrmUjHxQHBk4QHp_h_EZPEdYdEvxB8,6616
|
|
11
|
+
data_request_api/dev/MM/checksum.py,sha256=_ZICl46LerjVSSAspS6mrOWOXA6liyDoDeBur5pYMsE,1884
|
|
12
|
+
data_request_api/dev/MM/walking_data_request.ipynb,sha256=urrmicRTPrkQhyy8Ux4w0l-2Nx7Dlg35jWi-RCwaf-U,13457
|
|
13
|
+
data_request_api/dev/MS/dreq_content_and_walking_data_request.ipynb,sha256=51Ry2vy7dbK6lLFsO4fjldXdR3TMP3zTzdOpA9lQGNI,142409
|
|
14
|
+
data_request_api/stable/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
+
data_request_api/stable/content/README.MD,sha256=Fl7NpNlxEAP4xXTENPXLyPavaRfHsz04akGgW87aQ8I,3884
|
|
16
|
+
data_request_api/stable/content/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
+
data_request_api/stable/content/dump_transformation.py,sha256=yWkQN4nvICrTcm08ISsR5DTKssl6EWd-Kpv1wKruJ6M,32211
|
|
18
|
+
data_request_api/stable/content/dreq_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
+
data_request_api/stable/content/dreq_api/consolidate_export.py,sha256=ZGaYqKPibA8XkrItIgZpbbcZJ8a08RO2kLqbsNeo59g,21382
|
|
20
|
+
data_request_api/stable/content/dreq_api/dreq_content.py,sha256=LWawxzlxr6_1Fe4IvNyUayu1pea2s_3hy4RIBMiAMcs,20459
|
|
21
|
+
data_request_api/stable/content/dreq_api/mapping_table.py,sha256=Q5vfRKCgQCMGll1hCYFg7qaFBs-I3fI9toEMSF5znDk,12241
|
|
22
|
+
data_request_api/stable/content/dreq_api/test_dreq_content.py,sha256=JqktWhOAoCXTj3_ASQy3n64pZ9idv_QdCdU9lWuELlA,6488
|
|
23
|
+
data_request_api/stable/query/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
|
+
data_request_api/stable/query/data_request.py,sha256=DazgdQ815Agwv_Cz2ypzBgLIHZtN7n2Yhi4rQleU3jw,48219
|
|
25
|
+
data_request_api/stable/query/dreq_classes.py,sha256=ineO9CnHU0QsTys8_DNuPfQ_wkHeUIUxbK7kWsp1KBY,16280
|
|
26
|
+
data_request_api/stable/query/dreq_query.py,sha256=qrd3F9b4rkYCNEA89BU-iqBwztohSO8TdIypPyH7w0A,40269
|
|
27
|
+
data_request_api/stable/query/vocabulary_server.py,sha256=uB27mnG9yy1zRykDt1dwymXStxhcHLW29uk3Imbddzo,7193
|
|
28
|
+
data_request_api/stable/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
+
data_request_api/stable/utilities/logger.py,sha256=85qGdfVa5hsssh-rseiQP1c_ABvQ22b81njvjFRLYUY,1772
|
|
30
|
+
data_request_api/stable/utilities/tools.py,sha256=6OLuZoKeQn_LTb5Qx6548jh0JvDXCLk7IbE9gw_zXDc,1408
|
|
31
|
+
CMIP7_data_request_api-1.1.2.dist-info/LICENSE,sha256=eQ82CZRtA1kendI-gjZRrxjYdX8WqS8m2OsHhz2ayqw,1070
|
|
32
|
+
CMIP7_data_request_api-1.1.2.dist-info/METADATA,sha256=QvqLDsZYLP9mJFD52goC9raKiAmXtoHuoSC-s7MvSHs,11691
|
|
33
|
+
CMIP7_data_request_api-1.1.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
34
|
+
CMIP7_data_request_api-1.1.2.dist-info/entry_points.txt,sha256=L4ZgviM_N485tZsGXAg8HJKCedfN9QVTckgf_wARuk4,101
|
|
35
|
+
CMIP7_data_request_api-1.1.2.dist-info/top_level.txt,sha256=9pmO7hEsU_5ytqR82jRH01BvuSlLC2_dRNG6izwsOWE,17
|
|
36
|
+
CMIP7_data_request_api-1.1.2.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
data_request_api
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .version import *
|
|
File without changes
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
Command line interface for retrieving simple variable lists from the data request.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import sys
|
|
7
|
+
import json
|
|
8
|
+
import os
|
|
9
|
+
import argparse
|
|
10
|
+
from collections import OrderedDict
|
|
11
|
+
|
|
12
|
+
# import data_request_api.stable.content.dreq_api as dreq_api
|
|
13
|
+
import data_request_api
|
|
14
|
+
import data_request_api.stable.content.dreq_api.dreq_content as dc
|
|
15
|
+
import data_request_api.stable.query.dreq_query as dq
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def parse_args():
|
|
19
|
+
"""
|
|
20
|
+
Parse command line arguments
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
parser = argparse.ArgumentParser()
|
|
24
|
+
parser.add_argument('dreq_version', choices=dc.get_versions(), help="data request version")
|
|
25
|
+
parser.add_argument('--opportunities_file', type=str, help="path to JSON file listing opportunities to respond to. If it doesn't exist a template will be created")
|
|
26
|
+
parser.add_argument('--all_opportunities', action='store_true', help="respond to all opportunities")
|
|
27
|
+
parser.add_argument('--experiments', nargs='+', type=str, help='limit output to the specified experiments (space-delimited list, case sensitive)')
|
|
28
|
+
parser.add_argument('--priority_cutoff', default='low', choices=dq.PRIORITY_LEVELS, help="discard variables that are requested at lower priority than this cutoff priority")
|
|
29
|
+
parser.add_argument('output_file', help='file to write JSON output to')
|
|
30
|
+
parser.add_argument('--version', action='store_true', help='Return version information and exit')
|
|
31
|
+
return parser.parse_args()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def main():
|
|
35
|
+
"""
|
|
36
|
+
main routine
|
|
37
|
+
"""
|
|
38
|
+
args = parse_args()
|
|
39
|
+
|
|
40
|
+
if args.version:
|
|
41
|
+
print("CMIP7 data request api version {}".format(data_request_api.version))
|
|
42
|
+
sys.exit(0)
|
|
43
|
+
use_dreq_version = args.dreq_version
|
|
44
|
+
|
|
45
|
+
# Download specified version of data request content (if not locally cached)
|
|
46
|
+
dc.retrieve(use_dreq_version)
|
|
47
|
+
# Load content into python dict
|
|
48
|
+
content = dc.load(use_dreq_version)
|
|
49
|
+
# Render data request tables as dreq_table objects
|
|
50
|
+
base = dq.create_dreq_tables_for_request(content)
|
|
51
|
+
|
|
52
|
+
# Deal with opportunities
|
|
53
|
+
if args.opportunities_file:
|
|
54
|
+
opportunities_file = args.opportunities_file
|
|
55
|
+
Opps = base['Opportunity']
|
|
56
|
+
if not os.path.exists(opportunities_file):
|
|
57
|
+
# create opportunities file template
|
|
58
|
+
use_opps = sorted([opp.title for opp in Opps.records.values()], key=str.lower)
|
|
59
|
+
default_opportunity_dict = OrderedDict({
|
|
60
|
+
'Header' : OrderedDict({
|
|
61
|
+
'Description' : 'Opportunities template file for use with export_dreq_lists_json. Set supported/unsupported Opportunities to true/false.',
|
|
62
|
+
'dreq content version': use_dreq_version,
|
|
63
|
+
'dreq api version' : data_request_api.version,
|
|
64
|
+
}),
|
|
65
|
+
'Opportunity' : OrderedDict({title : True for title in use_opps})
|
|
66
|
+
})
|
|
67
|
+
with open(opportunities_file, 'w') as fh:
|
|
68
|
+
json.dump(default_opportunity_dict, fh, indent=4)
|
|
69
|
+
print("written opportunities dict to {}. Please edit and re-run".format(opportunities_file))
|
|
70
|
+
sys.exit(0)
|
|
71
|
+
else:
|
|
72
|
+
# load existing opportunities file
|
|
73
|
+
with open(opportunities_file, 'r') as fh:
|
|
74
|
+
opportunity_dict = json.load(fh)
|
|
75
|
+
|
|
76
|
+
dreq_version = opportunity_dict['Header']['dreq content version']
|
|
77
|
+
if dreq_version != use_dreq_version:
|
|
78
|
+
raise ValueError('Data request version mismatch!' + \
|
|
79
|
+
f'\nOpportunities file was generated for data request version {dreq_version}' + \
|
|
80
|
+
f'\nPlease regenerate the file using version {use_dreq_version}')
|
|
81
|
+
|
|
82
|
+
opportunity_dict = opportunity_dict['Opportunity']
|
|
83
|
+
|
|
84
|
+
# validate opportunities
|
|
85
|
+
# (mismatches can occur if an opportunities file created with an earlier data request version is loaded)
|
|
86
|
+
valid_opps = [opp.title for opp in Opps.records.values()]
|
|
87
|
+
invalid_opps = [title for title in opportunity_dict if title not in valid_opps]
|
|
88
|
+
if invalid_opps:
|
|
89
|
+
raise ValueError(f'\nInvalid opportunities were found in {opportunities_file}:\n' + '\n'.join(sorted(invalid_opps, key=str.lower)))
|
|
90
|
+
|
|
91
|
+
# filter opportunities
|
|
92
|
+
use_opps = [title for title in opportunity_dict if opportunity_dict[title]]
|
|
93
|
+
|
|
94
|
+
elif args.all_opportunities:
|
|
95
|
+
use_opps = 'all'
|
|
96
|
+
else:
|
|
97
|
+
print("Please use one of the opportunities arguments")
|
|
98
|
+
sys.exit(1)
|
|
99
|
+
|
|
100
|
+
# Get consolidated list of requested variables that supports these opportunities
|
|
101
|
+
dq.DREQ_VERSION = use_dreq_version
|
|
102
|
+
expt_vars = dq.get_requested_variables(base, use_opps, priority_cutoff=args.priority_cutoff, verbose=False)
|
|
103
|
+
|
|
104
|
+
# filter output by requested experiments
|
|
105
|
+
if args.experiments:
|
|
106
|
+
experiments = list(expt_vars['experiment'].keys()) # names of experiments requested by opportunities in use_opps
|
|
107
|
+
|
|
108
|
+
# validate the requested experiment names
|
|
109
|
+
Expts = base['Experiments']
|
|
110
|
+
valid_experiments = [expt.experiment for expt in Expts.records.values()] # all valid experiment names in data request
|
|
111
|
+
invalid_experiments = [entry for entry in args.experiments if entry not in valid_experiments]
|
|
112
|
+
if invalid_experiments:
|
|
113
|
+
raise ValueError('\nInvalid experiments: ' + ', '.join(sorted(invalid_experiments, key=str.lower)) + \
|
|
114
|
+
'\nValid experiment names: ' + ', '.join(sorted(valid_experiments, key=str.lower)))
|
|
115
|
+
|
|
116
|
+
# discard experiments that aren't requested
|
|
117
|
+
for entry in experiments:
|
|
118
|
+
if entry not in args.experiments:
|
|
119
|
+
del expt_vars['experiment'][entry]
|
|
120
|
+
|
|
121
|
+
# Construct output
|
|
122
|
+
if len(expt_vars['experiment']) > 0:
|
|
123
|
+
|
|
124
|
+
# Show user what was found
|
|
125
|
+
dq.show_requested_vars_summary(expt_vars, use_dreq_version)
|
|
126
|
+
|
|
127
|
+
# Write json file with the variable lists
|
|
128
|
+
content_path = dc._dreq_content_loaded['json_path']
|
|
129
|
+
outfile = args.output_file
|
|
130
|
+
dq.write_requested_vars_json(outfile, expt_vars, use_dreq_version, args.priority_cutoff, content_path)
|
|
131
|
+
|
|
132
|
+
else:
|
|
133
|
+
print(f'\nFor data request version {use_dreq_version}, no requested variables were found')
|
|
134
|
+
|
|
135
|
+
if __name__ == '__main__':
|
|
136
|
+
main()
|
|
File without changes
|