ecmwf-datastores-client 0.1.0__tar.gz → 0.2.0__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 ecmwf-datastores-client might be problematic. Click here for more details.

Files changed (54) hide show
  1. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/.cruft.json +2 -2
  2. ecmwf_datastores_client-0.2.0/.github/workflows/on-pr-closed.yml +18 -0
  3. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/.github/workflows/on-push.yml +14 -3
  4. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/.pre-commit-config.yaml +7 -2
  5. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/Makefile +1 -0
  6. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/PKG-INFO +15 -29
  7. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/README.md +13 -27
  8. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ci/environment-ci.yml +3 -2
  9. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/docs/conf.py +1 -0
  10. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/docs/index.md +1 -0
  11. ecmwf_datastores_client-0.2.0/docs/notebooks/index.md +7 -0
  12. ecmwf_datastores_client-0.2.0/docs/notebooks/quick_start.ipynb +45 -0
  13. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ecmwf/datastores/catalogue.py +0 -11
  14. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ecmwf/datastores/client.py +2 -2
  15. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ecmwf/datastores/processing.py +0 -68
  16. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ecmwf/datastores/version.py +1 -1
  17. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ecmwf_datastores_client.egg-info/PKG-INFO +15 -29
  18. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ecmwf_datastores_client.egg-info/SOURCES.txt +3 -0
  19. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ecmwf_datastores_client.egg-info/requires.txt +1 -1
  20. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/pyproject.toml +1 -1
  21. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/tests/integration_test_20_processing.py +0 -8
  22. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/tests/integration_test_30_remote.py +0 -6
  23. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/tests/test_20_processing.py +0 -27
  24. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/.gitignore +0 -0
  25. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/.pre-commit-config-cruft.yaml +0 -0
  26. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/Dockerfile +0 -0
  27. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/LICENSE +0 -0
  28. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ci/environment-integration.yml +0 -0
  29. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/docs/Makefile +0 -0
  30. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/docs/_static/.gitkeep +0 -0
  31. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/docs/_templates/.gitkeep +0 -0
  32. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/docs/make.bat +0 -0
  33. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ecmwf/datastores/__init__.py +0 -0
  34. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ecmwf/datastores/config.py +0 -0
  35. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ecmwf/datastores/legacy_client.py +0 -0
  36. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ecmwf/datastores/profile.py +0 -0
  37. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ecmwf/datastores/py.typed +0 -0
  38. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ecmwf/datastores/utils.py +0 -0
  39. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ecmwf_datastores_client.egg-info/dependency_links.txt +0 -0
  40. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/ecmwf_datastores_client.egg-info/top_level.txt +0 -0
  41. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/environment.yml +0 -0
  42. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/setup.cfg +0 -0
  43. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/tests/conftest.py +0 -0
  44. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/tests/integration_test_10_catalogue.py +0 -0
  45. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/tests/integration_test_40_results.py +0 -0
  46. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/tests/integration_test_50_profile.py +0 -0
  47. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/tests/integration_test_60_api_client.py +0 -0
  48. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/tests/integration_test_70_legacy_api_client.py +0 -0
  49. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/tests/integration_test_80_adaptors.py +0 -0
  50. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/tests/integration_test_90_features.py +0 -0
  51. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/tests/test_00_version.py +0 -0
  52. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/tests/test_01_config.py +0 -0
  53. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/tests/test_10_catalogue.py +0 -0
  54. {ecmwf_datastores_client-0.1.0 → ecmwf_datastores_client-0.2.0}/tests/test_40_results.py +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "template": "https://github.com/ecmwf-projects/cookiecutter-conda-package",
3
- "commit": "18065cb3d40660d1b7d74ac1cbe285f08552e658",
3
+ "commit": "0b4d61da26c3aacfc1778716cb36749d16846c51",
4
4
  "checkout": null,
5
5
  "context": {
6
6
  "cookiecutter": {
@@ -13,7 +13,7 @@
13
13
  "integration_tests": "True",
14
14
  "pypi": true,
15
15
  "_template": "https://github.com/ecmwf-projects/cookiecutter-conda-package",
16
- "_commit": "18065cb3d40660d1b7d74ac1cbe285f08552e658"
16
+ "_commit": "0b4d61da26c3aacfc1778716cb36749d16846c51"
17
17
  }
18
18
  },
19
19
  "directory": null
@@ -0,0 +1,18 @@
1
+ name: on-pr-closed
2
+ on:
3
+ pull_request:
4
+ types:
5
+ - closed
6
+
7
+ jobs:
8
+ remove-preview:
9
+ runs-on: ubuntu-latest
10
+ permissions:
11
+ contents: write
12
+ pull-requests: write
13
+
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: rossjrw/pr-preview-action@v1
17
+ with:
18
+ action: "remove"
@@ -117,6 +117,7 @@ jobs:
117
117
  runs-on: macos-latest
118
118
  permissions:
119
119
  contents: write
120
+ pull-requests: write
120
121
 
121
122
  steps:
122
123
  - uses: actions/checkout@v4
@@ -140,16 +141,26 @@ jobs:
140
141
  run: |
141
142
  python -m pip install --no-deps -e .
142
143
  - name: Build documentation
144
+ timeout-minutes: 10
145
+ env:
146
+ ECMWF_DATASTORES_URL: ${{ secrets.ECMWF_DATASTORES_URL }}
147
+ ECMWF_DATASTORES_KEY: ${{ secrets.ECMWF_DATASTORES_KEY }}
148
+ ECMWF_DATASTORES_ANON_KEY: ${{ secrets.ECMWF_DATASTORES_ANON_KEY }}
143
149
  run: |
144
150
  make docs-build
151
+ - uses: rossjrw/pr-preview-action@v1
152
+ with:
153
+ source-dir: "docs/_build/html"
145
154
  - name: Deploy documentation
146
- uses: peaceiris/actions-gh-pages@v4
155
+ uses: JamesIves/github-pages-deploy-action@v4
147
156
  if: |
148
157
  github.event_name == 'push' &&
149
158
  startsWith(github.ref, 'refs/tags')
150
159
  with:
151
- github_token: ${{ secrets.GITHUB_TOKEN }}
152
- publish_dir: ./docs/_build/html/
160
+ folder: ./docs/_build/html/
161
+ # See: https://github.com/marketplace/actions/deploy-pr-preview#ensure-your-main-deployment-is-compatible
162
+ clean-exclude: pr-preview/
163
+ force: false
153
164
 
154
165
  integration-tests:
155
166
  needs: [combine-environments, unit-tests]
@@ -17,7 +17,7 @@ repos:
17
17
  - id: blackdoc
18
18
  additional_dependencies: [black==23.11.0]
19
19
  - repo: https://github.com/astral-sh/ruff-pre-commit
20
- rev: v0.11.8
20
+ rev: v0.11.12
21
21
  hooks:
22
22
  - id: ruff
23
23
  args: [--fix, --show-fixes]
@@ -34,6 +34,11 @@ repos:
34
34
  - id: pretty-format-toml
35
35
  args: [--autofix]
36
36
  - repo: https://github.com/gitleaks/gitleaks
37
- rev: v8.25.1
37
+ rev: v8.27.0
38
38
  hooks:
39
39
  - id: gitleaks
40
+ - repo: https://github.com/kynan/nbstripout
41
+ rev: 0.8.1
42
+ hooks:
43
+ - id: nbstripout
44
+ args: [--drop-empty-cells]
@@ -26,6 +26,7 @@ docker-run:
26
26
  docker run --rm -ti -v $(PWD):/srv $(PROJECT)
27
27
 
28
28
  template-update:
29
+ pre-commit autoupdate --repo https://github.com/kynan/nbstripout
29
30
  pre-commit run --all-files cruft -c .pre-commit-config-cruft.yaml
30
31
 
31
32
  docs-build:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ecmwf-datastores-client
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: ECMWF Data Stores Service (DSS) API Python client
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -228,25 +228,20 @@ Requires-Dist: multiurl>=0.3.2
228
228
  Requires-Dist: requests
229
229
  Requires-Dist: typing-extensions
230
230
  Provides-Extra: legacy
231
- Requires-Dist: cdsapi>=0.7.5; extra == "legacy"
231
+ Requires-Dist: cdsapi>=0.7.6; extra == "legacy"
232
232
  Dynamic: license-file
233
233
 
234
234
  <p align="center">
235
235
  <a href="https://github.com/ecmwf/codex/raw/refs/heads/main/ESEE">
236
- <img src="https://github.com/ecmwf/codex/raw/refs/heads/main/ESEE/data_provision_badge.svg" alt="ECMWF Software EnginE">
237
- </a>
236
+ <img src="https://github.com/ecmwf/codex/raw/refs/heads/main/ESEE/data_provision_badge.svg" alt="ECMWF Software EnginE"></a>
238
237
  <a href="https://github.com/ecmwf/codex/raw/refs/heads/main/Project Maturity">
239
- <img src="https://github.com/ecmwf/codex/raw/refs/heads/main/Project Maturity/incubating_badge.svg" alt="Maturity Level">
240
- </a>
241
- <!-- <a href="https://codecov.io/gh/ecmwf/earthkit">
242
- <img src="https://codecov.io/gh/ecmwf/ecmwf-datastores-client/branch/main/graph/badge.svg" alt="Code Coverage">
243
- </a> -->
238
+ <img src="https://github.com/ecmwf/codex/raw/refs/heads/main/Project Maturity/incubating_badge.svg" alt="Maturity Level"></a>
239
+ <!-- <a href="https://codecov.io/gh/ecmwf/ecmwf-datastores-client">
240
+ <img src="https://codecov.io/gh/ecmwf/ecmwf-datastores-client/branch/main/graph/badge.svg" alt="Code Coverage"></a> -->
244
241
  <a href="https://opensource.org/licenses/apache-2-0">
245
- <img src="https://img.shields.io/badge/Licence-Apache 2.0-blue.svg" alt="Licence">
246
- </a>
247
- <a href="https://github.com/ecmwf/earthkit/releases">
248
- <img src="https://img.shields.io/github/v/release/ecmwf/ecmwf-datastores-client?color=purple&label=Release" alt="Latest Release">
249
- </a>
242
+ <img src="https://img.shields.io/badge/Licence-Apache 2.0-blue.svg" alt="Licence"></a>
243
+ <a href="https://github.com/ecmwf/ecmwf-datastores-client/releases">
244
+ <img src="https://img.shields.io/github/v/release/ecmwf/ecmwf-datastores-client?color=purple&label=Release" alt="Latest Release"></a>
250
245
  </p>
251
246
 
252
247
  <p align="center">
@@ -282,8 +277,11 @@ $ pip install ecmwf-datastores-client
282
277
 
283
278
  ## Configuration
284
279
 
285
- The `Client` requires the `url` to the API root and a valid API `key`. You can also set the `ECMWF_DATASTORES_URL` and `ECMWF_DATASTORES_KEY` environment variables, or use a configuration file.
286
- The configuration file must be located at `~/.ecmwfdatastoresrc`, or at the path specified by the `ECMWF_DATASTORES_RC_FILE` environment variable.
280
+ The `Client` requires the `url` to the API root and a valid API `key`. These can be provided in three ways, in order of precedence:
281
+
282
+ 1. As keyword arguments when instantiating the `Client`.
283
+ 1. Via the `ECMWF_DATASTORES_URL` and `ECMWF_DATASTORES_KEY` environment variables.
284
+ 1. From a configuration file, which must be located at `~/.ecmwfdatastoresrc` or at the path specified by the `ECMWF_DATASTORES_RC_FILE` environment variable.
287
285
 
288
286
  ```
289
287
  $ cat $HOME/.ecmwfdatastoresrc
@@ -291,14 +289,6 @@ url: https://cds.climate.copernicus.eu/api
291
289
  key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
292
290
  ```
293
291
 
294
- It is possible (though not recommended) to use the API key of one of the test users:
295
-
296
- ```
297
- 00112233-4455-6677-c899-aabbccddeeff
298
- ```
299
-
300
- This key is used for anonymous tests and is designed to be the least performant option for accessing the system.
301
-
302
292
  ## Quick Start
303
293
 
304
294
  Configure the logging level to display INFO messages:
@@ -312,12 +302,8 @@ Configure the logging level to display INFO messages:
312
302
  Instantiate the API client and optionally verify authentication:
313
303
 
314
304
  ```python
315
- >>> import os
316
305
  >>> from ecmwf.datastores import Client
317
- >>> client = Client(
318
- ... url=os.getenv("ECMWF_DATASTORES_URL"),
319
- ... key=os.getenv("ECMWF_DATASTORES_KEY"),
320
- ... )
306
+ >>> client = Client()
321
307
  >>> client.check_authentication() # optional check
322
308
  {...}
323
309
 
@@ -1,19 +1,14 @@
1
1
  <p align="center">
2
2
  <a href="https://github.com/ecmwf/codex/raw/refs/heads/main/ESEE">
3
- <img src="https://github.com/ecmwf/codex/raw/refs/heads/main/ESEE/data_provision_badge.svg" alt="ECMWF Software EnginE">
4
- </a>
3
+ <img src="https://github.com/ecmwf/codex/raw/refs/heads/main/ESEE/data_provision_badge.svg" alt="ECMWF Software EnginE"></a>
5
4
  <a href="https://github.com/ecmwf/codex/raw/refs/heads/main/Project Maturity">
6
- <img src="https://github.com/ecmwf/codex/raw/refs/heads/main/Project Maturity/incubating_badge.svg" alt="Maturity Level">
7
- </a>
8
- <!-- <a href="https://codecov.io/gh/ecmwf/earthkit">
9
- <img src="https://codecov.io/gh/ecmwf/ecmwf-datastores-client/branch/main/graph/badge.svg" alt="Code Coverage">
10
- </a> -->
5
+ <img src="https://github.com/ecmwf/codex/raw/refs/heads/main/Project Maturity/incubating_badge.svg" alt="Maturity Level"></a>
6
+ <!-- <a href="https://codecov.io/gh/ecmwf/ecmwf-datastores-client">
7
+ <img src="https://codecov.io/gh/ecmwf/ecmwf-datastores-client/branch/main/graph/badge.svg" alt="Code Coverage"></a> -->
11
8
  <a href="https://opensource.org/licenses/apache-2-0">
12
- <img src="https://img.shields.io/badge/Licence-Apache 2.0-blue.svg" alt="Licence">
13
- </a>
14
- <a href="https://github.com/ecmwf/earthkit/releases">
15
- <img src="https://img.shields.io/github/v/release/ecmwf/ecmwf-datastores-client?color=purple&label=Release" alt="Latest Release">
16
- </a>
9
+ <img src="https://img.shields.io/badge/Licence-Apache 2.0-blue.svg" alt="Licence"></a>
10
+ <a href="https://github.com/ecmwf/ecmwf-datastores-client/releases">
11
+ <img src="https://img.shields.io/github/v/release/ecmwf/ecmwf-datastores-client?color=purple&label=Release" alt="Latest Release"></a>
17
12
  </p>
18
13
 
19
14
  <p align="center">
@@ -49,8 +44,11 @@ $ pip install ecmwf-datastores-client
49
44
 
50
45
  ## Configuration
51
46
 
52
- The `Client` requires the `url` to the API root and a valid API `key`. You can also set the `ECMWF_DATASTORES_URL` and `ECMWF_DATASTORES_KEY` environment variables, or use a configuration file.
53
- The configuration file must be located at `~/.ecmwfdatastoresrc`, or at the path specified by the `ECMWF_DATASTORES_RC_FILE` environment variable.
47
+ The `Client` requires the `url` to the API root and a valid API `key`. These can be provided in three ways, in order of precedence:
48
+
49
+ 1. As keyword arguments when instantiating the `Client`.
50
+ 1. Via the `ECMWF_DATASTORES_URL` and `ECMWF_DATASTORES_KEY` environment variables.
51
+ 1. From a configuration file, which must be located at `~/.ecmwfdatastoresrc` or at the path specified by the `ECMWF_DATASTORES_RC_FILE` environment variable.
54
52
 
55
53
  ```
56
54
  $ cat $HOME/.ecmwfdatastoresrc
@@ -58,14 +56,6 @@ url: https://cds.climate.copernicus.eu/api
58
56
  key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
59
57
  ```
60
58
 
61
- It is possible (though not recommended) to use the API key of one of the test users:
62
-
63
- ```
64
- 00112233-4455-6677-c899-aabbccddeeff
65
- ```
66
-
67
- This key is used for anonymous tests and is designed to be the least performant option for accessing the system.
68
-
69
59
  ## Quick Start
70
60
 
71
61
  Configure the logging level to display INFO messages:
@@ -79,12 +69,8 @@ Configure the logging level to display INFO messages:
79
69
  Instantiate the API client and optionally verify authentication:
80
70
 
81
71
  ```python
82
- >>> import os
83
72
  >>> from ecmwf.datastores import Client
84
- >>> client = Client(
85
- ... url=os.getenv("ECMWF_DATASTORES_URL"),
86
- ... key=os.getenv("ECMWF_DATASTORES_KEY"),
87
- ... )
73
+ >>> client = Client()
88
74
  >>> client.check_authentication() # optional check
89
75
  {...}
90
76
 
@@ -14,8 +14,9 @@ dependencies:
14
14
  - sphinx
15
15
  - sphinx-autoapi
16
16
  # DO NOT EDIT ABOVE THIS LINE, ADD DEPENDENCIES BELOW
17
+ - ipykernel
18
+ - nbsphinx
17
19
  - types-requests
18
20
  - pip:
19
- # TODO: install from pypi or conda when available
20
- - git+https://github.com/bopen/cdsapi.git@COPDS-2640
21
+ - cdsapi >= 0.7.6
21
22
  - responses
@@ -29,6 +29,7 @@ release = ecmwf.datastores.__version__
29
29
  extensions = [
30
30
  "autoapi.extension",
31
31
  "myst_parser",
32
+ "nbsphinx",
32
33
  "sphinx.ext.autodoc",
33
34
  "sphinx.ext.napoleon",
34
35
  ]
@@ -11,6 +11,7 @@ Knowledge Base.
11
11
  :maxdepth: 2
12
12
 
13
13
  README.md
14
+ notebooks/index
14
15
  API Reference <_api/datastores/index>
15
16
  ```
16
17
 
@@ -0,0 +1,7 @@
1
+ # Notebooks
2
+
3
+ ```{toctree}
4
+ :maxdepth: 1
5
+
6
+ quick_start
7
+ ```
@@ -0,0 +1,45 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "id": "0",
6
+ "metadata": {},
7
+ "source": [
8
+ "# Quick start"
9
+ ]
10
+ },
11
+ {
12
+ "cell_type": "code",
13
+ "execution_count": null,
14
+ "id": "1",
15
+ "metadata": {},
16
+ "outputs": [],
17
+ "source": [
18
+ "from ecmwf.datastores import Client\n",
19
+ "\n",
20
+ "client = Client()"
21
+ ]
22
+ }
23
+ ],
24
+ "metadata": {
25
+ "kernelspec": {
26
+ "display_name": "Python 3 (ipykernel)",
27
+ "language": "python",
28
+ "name": "python3"
29
+ },
30
+ "language_info": {
31
+ "codemirror_mode": {
32
+ "name": "ipython",
33
+ "version": 3
34
+ },
35
+ "file_extension": ".py",
36
+ "mimetype": "text/x-python",
37
+ "name": "python",
38
+ "nbconvert_exporter": "python",
39
+ "pygments_lexer": "ipython3",
40
+ "version": "3.11.11"
41
+ }
42
+ },
43
+ "nbformat": 4,
44
+ "nbformat_minor": 5
45
+ }
@@ -15,7 +15,6 @@
15
15
  from __future__ import annotations
16
16
 
17
17
  import datetime
18
- import warnings
19
18
  from typing import Any, Callable
20
19
 
21
20
  import attrs
@@ -93,16 +92,6 @@ class Collection(ApiResponse):
93
92
  url = self._get_link_href(rel="retrieve")
94
93
  return datastores.Process.from_request("get", url, **self._request_kwargs)
95
94
 
96
- @property
97
- def process(self) -> datastores.Process:
98
- warnings.warn(
99
- "`process` has been deprecated, and in the future will raise an error."
100
- "Please use `submit` and `apply_constraints` from now on.",
101
- DeprecationWarning,
102
- stacklevel=2,
103
- )
104
- return self._process
105
-
106
95
  @property
107
96
  def form(self) -> list[dict[str, Any]]:
108
97
  url = f"{self.url}/form.json"
@@ -234,7 +234,7 @@ class Client:
234
234
  Parameters
235
235
  ----------
236
236
  limit: int | None
237
- Number of processes per page.
237
+ Number of collections per page.
238
238
  sortby: {None, 'id', 'relevance', 'title', 'update'}
239
239
  Field to sort results by.
240
240
  query: str or None
@@ -266,7 +266,7 @@ class Client:
266
266
  Parameters
267
267
  ----------
268
268
  limit: int or None
269
- Number of processes per page.
269
+ Number of jobs per page.
270
270
  sortby: {None, 'created', '-created'}
271
271
  Field to sort results by.
272
272
  status: {None, 'accepted', 'running', 'successful', 'failed'}
@@ -400,16 +400,6 @@ class Remote:
400
400
  """Request ID."""
401
401
  return self.url.rpartition("/")[2]
402
402
 
403
- @property
404
- def request_uid(self) -> str:
405
- warnings.warn(
406
- "`request_uid` has been deprecated, and in the future will raise an error."
407
- "Please use `request_id` from now on.",
408
- DeprecationWarning,
409
- stacklevel=2,
410
- )
411
- return self.request_id
412
-
413
403
  @property
414
404
  def json(self) -> dict[str, Any]:
415
405
  """Content of the response."""
@@ -450,48 +440,18 @@ class Remote:
450
440
  """When the job was created."""
451
441
  return utils.string_to_datetime(self.json["created"])
452
442
 
453
- @property
454
- def creation_datetime(self) -> datetime.datetime:
455
- warnings.warn(
456
- "`creation_datetime` has been deprecated, and in the future will raise an error."
457
- "Please use `created_at` from now on.",
458
- DeprecationWarning,
459
- stacklevel=2,
460
- )
461
- return self.created_at
462
-
463
443
  @property
464
444
  def started_at(self) -> datetime.datetime | None:
465
445
  """When the job started. If None, the job has not started."""
466
446
  value = self.json.get("started")
467
447
  return value if value is None else utils.string_to_datetime(value)
468
448
 
469
- @property
470
- def start_datetime(self) -> datetime.datetime | None:
471
- warnings.warn(
472
- "`start_datetime` has been deprecated, and in the future will raise an error."
473
- "Please use `started_at` from now on.",
474
- DeprecationWarning,
475
- stacklevel=2,
476
- )
477
- return self.started_at
478
-
479
449
  @property
480
450
  def finished_at(self) -> datetime.datetime | None:
481
451
  """When the job finished. If None, the job has not finished."""
482
452
  value = self.json.get("finished")
483
453
  return value if value is None else utils.string_to_datetime(value)
484
454
 
485
- @property
486
- def end_datetime(self) -> datetime.datetime | None:
487
- warnings.warn(
488
- "`end_datetime` has been deprecated, and in the future will raise an error."
489
- "Please use `finished_at` from now on.",
490
- DeprecationWarning,
491
- stacklevel=2,
492
- )
493
- return self.finished_at
494
-
495
455
  def _wait_on_results(self) -> None:
496
456
  sleep = 1.0
497
457
  while not self.results_ready:
@@ -525,15 +485,6 @@ class Remote:
525
485
  results = Results.from_request("get", results_url, **self._request_kwargs)
526
486
  return results
527
487
 
528
- def make_results(self, wait: bool = True) -> Results:
529
- warnings.warn(
530
- "`make_results` has been deprecated, and in the future will raise an error."
531
- "Please use `get_results` from now on.",
532
- DeprecationWarning,
533
- stacklevel=2,
534
- )
535
- return self._make_results(wait)
536
-
537
488
  def get_results(self) -> Results:
538
489
  """Retrieve results.
539
490
 
@@ -641,15 +592,6 @@ class Job(ApiResponse):
641
592
  url = self._get_link_href(rel="self")
642
593
  return Remote(url, **self._request_kwargs)
643
594
 
644
- def make_remote(self) -> Remote:
645
- warnings.warn(
646
- "`make_remote` has been deprecated, and in the future will raise an error."
647
- "Please use `get_remote` from now on.",
648
- DeprecationWarning,
649
- stacklevel=2,
650
- )
651
- return self.get_remote()
652
-
653
595
 
654
596
  @attrs.define
655
597
  class Jobs(ApiResponsePaginated):
@@ -660,16 +602,6 @@ class Jobs(ApiResponsePaginated):
660
602
  """List of request IDs."""
661
603
  return [job["jobID"] for job in self._json_dict["jobs"]]
662
604
 
663
- @property
664
- def request_uids(self) -> list[str]:
665
- warnings.warn(
666
- "`request_uids` has been deprecated, and in the future will raise an error."
667
- "Please use `request_ids` from now on.",
668
- DeprecationWarning,
669
- stacklevel=2,
670
- )
671
- return self.request_ids
672
-
673
605
 
674
606
  @attrs.define
675
607
  class Results(ApiResponse):
@@ -1,2 +1,2 @@
1
1
  # Do not change! Do not track in version control!
2
- __version__ = "0.1.0"
2
+ __version__ = "0.2.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ecmwf-datastores-client
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: ECMWF Data Stores Service (DSS) API Python client
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -228,25 +228,20 @@ Requires-Dist: multiurl>=0.3.2
228
228
  Requires-Dist: requests
229
229
  Requires-Dist: typing-extensions
230
230
  Provides-Extra: legacy
231
- Requires-Dist: cdsapi>=0.7.5; extra == "legacy"
231
+ Requires-Dist: cdsapi>=0.7.6; extra == "legacy"
232
232
  Dynamic: license-file
233
233
 
234
234
  <p align="center">
235
235
  <a href="https://github.com/ecmwf/codex/raw/refs/heads/main/ESEE">
236
- <img src="https://github.com/ecmwf/codex/raw/refs/heads/main/ESEE/data_provision_badge.svg" alt="ECMWF Software EnginE">
237
- </a>
236
+ <img src="https://github.com/ecmwf/codex/raw/refs/heads/main/ESEE/data_provision_badge.svg" alt="ECMWF Software EnginE"></a>
238
237
  <a href="https://github.com/ecmwf/codex/raw/refs/heads/main/Project Maturity">
239
- <img src="https://github.com/ecmwf/codex/raw/refs/heads/main/Project Maturity/incubating_badge.svg" alt="Maturity Level">
240
- </a>
241
- <!-- <a href="https://codecov.io/gh/ecmwf/earthkit">
242
- <img src="https://codecov.io/gh/ecmwf/ecmwf-datastores-client/branch/main/graph/badge.svg" alt="Code Coverage">
243
- </a> -->
238
+ <img src="https://github.com/ecmwf/codex/raw/refs/heads/main/Project Maturity/incubating_badge.svg" alt="Maturity Level"></a>
239
+ <!-- <a href="https://codecov.io/gh/ecmwf/ecmwf-datastores-client">
240
+ <img src="https://codecov.io/gh/ecmwf/ecmwf-datastores-client/branch/main/graph/badge.svg" alt="Code Coverage"></a> -->
244
241
  <a href="https://opensource.org/licenses/apache-2-0">
245
- <img src="https://img.shields.io/badge/Licence-Apache 2.0-blue.svg" alt="Licence">
246
- </a>
247
- <a href="https://github.com/ecmwf/earthkit/releases">
248
- <img src="https://img.shields.io/github/v/release/ecmwf/ecmwf-datastores-client?color=purple&label=Release" alt="Latest Release">
249
- </a>
242
+ <img src="https://img.shields.io/badge/Licence-Apache 2.0-blue.svg" alt="Licence"></a>
243
+ <a href="https://github.com/ecmwf/ecmwf-datastores-client/releases">
244
+ <img src="https://img.shields.io/github/v/release/ecmwf/ecmwf-datastores-client?color=purple&label=Release" alt="Latest Release"></a>
250
245
  </p>
251
246
 
252
247
  <p align="center">
@@ -282,8 +277,11 @@ $ pip install ecmwf-datastores-client
282
277
 
283
278
  ## Configuration
284
279
 
285
- The `Client` requires the `url` to the API root and a valid API `key`. You can also set the `ECMWF_DATASTORES_URL` and `ECMWF_DATASTORES_KEY` environment variables, or use a configuration file.
286
- The configuration file must be located at `~/.ecmwfdatastoresrc`, or at the path specified by the `ECMWF_DATASTORES_RC_FILE` environment variable.
280
+ The `Client` requires the `url` to the API root and a valid API `key`. These can be provided in three ways, in order of precedence:
281
+
282
+ 1. As keyword arguments when instantiating the `Client`.
283
+ 1. Via the `ECMWF_DATASTORES_URL` and `ECMWF_DATASTORES_KEY` environment variables.
284
+ 1. From a configuration file, which must be located at `~/.ecmwfdatastoresrc` or at the path specified by the `ECMWF_DATASTORES_RC_FILE` environment variable.
287
285
 
288
286
  ```
289
287
  $ cat $HOME/.ecmwfdatastoresrc
@@ -291,14 +289,6 @@ url: https://cds.climate.copernicus.eu/api
291
289
  key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
292
290
  ```
293
291
 
294
- It is possible (though not recommended) to use the API key of one of the test users:
295
-
296
- ```
297
- 00112233-4455-6677-c899-aabbccddeeff
298
- ```
299
-
300
- This key is used for anonymous tests and is designed to be the least performant option for accessing the system.
301
-
302
292
  ## Quick Start
303
293
 
304
294
  Configure the logging level to display INFO messages:
@@ -312,12 +302,8 @@ Configure the logging level to display INFO messages:
312
302
  Instantiate the API client and optionally verify authentication:
313
303
 
314
304
  ```python
315
- >>> import os
316
305
  >>> from ecmwf.datastores import Client
317
- >>> client = Client(
318
- ... url=os.getenv("ECMWF_DATASTORES_URL"),
319
- ... key=os.getenv("ECMWF_DATASTORES_KEY"),
320
- ... )
306
+ >>> client = Client()
321
307
  >>> client.check_authentication() # optional check
322
308
  {...}
323
309
 
@@ -8,6 +8,7 @@ Makefile
8
8
  README.md
9
9
  environment.yml
10
10
  pyproject.toml
11
+ .github/workflows/on-pr-closed.yml
11
12
  .github/workflows/on-push.yml
12
13
  ci/environment-ci.yml
13
14
  ci/environment-integration.yml
@@ -17,6 +18,8 @@ docs/index.md
17
18
  docs/make.bat
18
19
  docs/_static/.gitkeep
19
20
  docs/_templates/.gitkeep
21
+ docs/notebooks/index.md
22
+ docs/notebooks/quick_start.ipynb
20
23
  ecmwf/datastores/__init__.py
21
24
  ecmwf/datastores/catalogue.py
22
25
  ecmwf/datastores/client.py
@@ -4,4 +4,4 @@ requests
4
4
  typing-extensions
5
5
 
6
6
  [legacy]
7
- cdsapi>=0.7.5
7
+ cdsapi>=0.7.6
@@ -32,7 +32,7 @@ readme = "README.md"
32
32
  requires-python = ">=3.8"
33
33
 
34
34
  [project.optional-dependencies]
35
- legacy = ["cdsapi >= 0.7.5"]
35
+ legacy = ["cdsapi >= 0.7.6"]
36
36
 
37
37
  [project.urls]
38
38
  documentation = "https://ecmwf.github.io/ecmwf-datastores-client/"
@@ -73,11 +73,3 @@ def test_processing_get_jobs_sortby(api_anon_client: Client) -> None:
73
73
  ids = api_anon_client.get_jobs(sortby="-created").request_ids
74
74
  assert ids.index(id2) < ids.index(id1)
75
75
  assert [id2] != api_anon_client.get_jobs(sortby="created", limit=1).request_ids
76
-
77
-
78
- def test_deprecation_warnings(api_anon_client: Client) -> None:
79
- with pytest.warns(DeprecationWarning):
80
- api_anon_client.submit("test-adaptor-dummy", {}).request_uid
81
-
82
- with pytest.warns(DeprecationWarning):
83
- api_anon_client.get_jobs().request_uids
@@ -106,9 +106,3 @@ def test_remote_datetimes(api_anon_client: Client) -> None:
106
106
  assert remote.finished_at is not None
107
107
  assert remote.created_at < remote.started_at < remote.finished_at
108
108
  assert remote.finished_at == remote.updated_at
109
-
110
-
111
- def test_make_results_deprecation(api_anon_client: Client) -> None:
112
- remote = api_anon_client.submit("test-adaptor-dummy", {})
113
- with pytest.warns(DeprecationWarning, match="`make_results` has been deprecated"):
114
- remote.make_results()
@@ -389,33 +389,6 @@ def test_submit(cat: catalogue.Catalogue) -> None:
389
389
  assert remote.finished_at.isoformat() == "2022-09-02T17:32:54.308120+00:00"
390
390
 
391
391
 
392
- @responses.activate
393
- def test_depracations(cat: catalogue.Catalogue) -> None:
394
- responses_add()
395
-
396
- collection = cat.get_collection(COLLECTION_ID)
397
- with pytest.warns(DeprecationWarning, match="`process` has been deprecated"):
398
- assert isinstance(collection.process, processing.Process)
399
-
400
- request = {"variable": "temperature", "year": "2022"}
401
- remote = collection.submit(request)
402
-
403
- with pytest.warns(
404
- DeprecationWarning, match="`creation_datetime` has been deprecated"
405
- ):
406
- assert (
407
- remote.creation_datetime.isoformat() == "2022-09-02T17:30:48.201213+00:00"
408
- )
409
-
410
- with pytest.warns(DeprecationWarning, match="`start_datetime` has been deprecated"):
411
- assert remote.start_datetime is not None
412
- assert remote.start_datetime.isoformat() == "2022-09-02T17:32:43.890617+00:00"
413
-
414
- with pytest.warns(DeprecationWarning, match="`end_datetime` has been deprecated"):
415
- assert remote.end_datetime is not None
416
- assert remote.end_datetime.isoformat() == "2022-09-02T17:32:54.308120+00:00"
417
-
418
-
419
392
  @responses.activate
420
393
  @pytest.mark.parametrize("method", ("submit", "apply_constraints", "estimate_costs"))
421
394
  def test_process_docstrings(cat: catalogue.Catalogue, method: str) -> None: