ecmwf-datastores-client 0.1.0__py3-none-any.whl → 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ecmwf-datastores-client might be problematic. Click here for more details.

@@ -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"
@@ -28,6 +28,8 @@ from ecmwf.datastores.catalogue import Catalogue
28
28
  from ecmwf.datastores.processing import Processing, RequestKwargs
29
29
  from ecmwf.datastores.profile import Profile
30
30
 
31
+ T_STATUS = Literal["accepted", "running", "successful", "failed", "rejected"]
32
+
31
33
 
32
34
  @attrs.define(slots=False)
33
35
  class Client:
@@ -179,6 +181,21 @@ class Client:
179
181
  """
180
182
  return self._profile_api.check_authentication()
181
183
 
184
+ def delete(self, *request_ids: str) -> dict[str, Any]:
185
+ """Delete requests.
186
+
187
+ Parameters
188
+ ----------
189
+ *request_ids: str
190
+ Request IDs.
191
+
192
+ Returns
193
+ -------
194
+ dict[str,Any]
195
+ Content of the response.
196
+ """
197
+ return self._retrieve_api.delete(*request_ids)
198
+
182
199
  def download_results(self, request_id: str, target: str | None = None) -> str:
183
200
  """Download the results of a request.
184
201
 
@@ -234,7 +251,7 @@ class Client:
234
251
  Parameters
235
252
  ----------
236
253
  limit: int | None
237
- Number of processes per page.
254
+ Number of collections per page.
238
255
  sortby: {None, 'id', 'relevance', 'title', 'update'}
239
256
  Field to sort results by.
240
257
  query: str or None
@@ -259,17 +276,17 @@ class Client:
259
276
  self,
260
277
  limit: int | None = None,
261
278
  sortby: Literal[None, "created", "-created"] = None,
262
- status: Literal[None, "accepted", "running", "successful", "failed"] = None,
279
+ status: None | T_STATUS | list[T_STATUS] = None,
263
280
  ) -> datastores.Jobs:
264
281
  """Retrieve submitted jobs.
265
282
 
266
283
  Parameters
267
284
  ----------
268
285
  limit: int or None
269
- Number of processes per page.
286
+ Number of jobs per page.
270
287
  sortby: {None, 'created', '-created'}
271
288
  Field to sort results by.
272
- status: {None, 'accepted', 'running', 'successful', 'failed'}
289
+ status: None or {'accepted', 'running', 'successful', 'failed', 'rejected'} or list
273
290
  Status of the results.
274
291
 
275
292
  Returns
@@ -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:
@@ -507,7 +467,7 @@ class Remote:
507
467
  return True
508
468
  if status in ("accepted", "running"):
509
469
  return False
510
- if status == "failed":
470
+ if status in ("failed", "rejected"):
511
471
  results = self._make_results(wait=False)
512
472
  raise ProcessingFailedError(error_json_to_message(results._json_dict))
513
473
  if status in ("dismissed", "deleted"):
@@ -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):
@@ -773,6 +705,13 @@ class Processing:
773
705
  log_callback=self.log_callback,
774
706
  )
775
707
 
708
+ def delete(self, *job_ids: str) -> dict[str, Any]:
709
+ url = f"{self.url}/jobs/delete"
710
+ response = ApiResponse.from_request(
711
+ "post", url, json={"job_ids": job_ids}, **self._request_kwargs
712
+ )
713
+ return response._json_dict
714
+
776
715
  def get_processes(self, **params: Any) -> Processes:
777
716
  url = f"{self.url}/processes"
778
717
  return Processes.from_request("get", url, params=params, **self._request_kwargs)
@@ -1,2 +1,2 @@
1
1
  # Do not change! Do not track in version control!
2
- __version__ = "0.1.0"
2
+ __version__ = "0.3.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.3.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
 
@@ -0,0 +1,15 @@
1
+ ecmwf/datastores/__init__.py,sha256=RQ5WNfEjLQ1qlZxyvGv3S6zPcFO35UcgN4iiz_Uh06I,1243
2
+ ecmwf/datastores/catalogue.py,sha256=I-ON4lxI13Y5dR7joU1qeQrWTxYBQMFGYoOrLa2oLic,6257
3
+ ecmwf/datastores/client.py,sha256=bCXSb1q3T-kX7csOshi4z6qU54s8JrczPVbEPxa_UiA,13053
4
+ ecmwf/datastores/config.py,sha256=45C4nvgk-uGucCAnN3bUtr_zv-_dm8IN_P5xl7LPqfs,1497
5
+ ecmwf/datastores/legacy_client.py,sha256=UEkQNg9IA_zNnpZrc4I9O2X2h39NsaxYM0xpL2OKghA,9491
6
+ ecmwf/datastores/processing.py,sha256=C6nMsPCQGVWGN0gCHU59Q2C1QfbGGwEbOscv0GgqLaw,22093
7
+ ecmwf/datastores/profile.py,sha256=VjT6GSoSZZyaDHXZh0SQbrzxSX3Ug2DOWhq7VIu-QX8,2974
8
+ ecmwf/datastores/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ ecmwf/datastores/utils.py,sha256=fc6wma5qRpgAsX3dOmg0aoIc-qjWG6NY9PSHaWR8CpE,320
10
+ ecmwf/datastores/version.py,sha256=3h8WahDhaqqG0csM7Cbye1f4Rwme9vn3Dz_DYKtqceo,72
11
+ ecmwf_datastores_client-0.3.0.dist-info/licenses/LICENSE,sha256=e2Qp4JUZeHZZSYCADyp1B3siZB5aQE5MRCYRx7vqlNI,11346
12
+ ecmwf_datastores_client-0.3.0.dist-info/METADATA,sha256=ulKbZeg6q4nUICkZ_A2P2tWSB-eekToBmUnim-HzJHk,21463
13
+ ecmwf_datastores_client-0.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
+ ecmwf_datastores_client-0.3.0.dist-info/top_level.txt,sha256=gvA9-Z3hRaFzijz-mf8v2t84s25ptpWeqhyuUomJoJk,6
15
+ ecmwf_datastores_client-0.3.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.3.1)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,15 +0,0 @@
1
- ecmwf/datastores/__init__.py,sha256=RQ5WNfEjLQ1qlZxyvGv3S6zPcFO35UcgN4iiz_Uh06I,1243
2
- ecmwf/datastores/catalogue.py,sha256=Mj5myLRkk_NcjWSZISuZxU-jJIhSAATFhsJJveiyiHo,6609
3
- ecmwf/datastores/client.py,sha256=0hRAHOV-i5Cbu6z_VL7nyMzx_qjCAtxVzhuxexiciGI,12646
4
- ecmwf/datastores/config.py,sha256=45C4nvgk-uGucCAnN3bUtr_zv-_dm8IN_P5xl7LPqfs,1497
5
- ecmwf/datastores/legacy_client.py,sha256=UEkQNg9IA_zNnpZrc4I9O2X2h39NsaxYM0xpL2OKghA,9491
6
- ecmwf/datastores/processing.py,sha256=FrDBoO8HfQ_dlqo15xe_SK_AHiPBQ9fvJ5UYbaeLxsE,24095
7
- ecmwf/datastores/profile.py,sha256=VjT6GSoSZZyaDHXZh0SQbrzxSX3Ug2DOWhq7VIu-QX8,2974
8
- ecmwf/datastores/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- ecmwf/datastores/utils.py,sha256=fc6wma5qRpgAsX3dOmg0aoIc-qjWG6NY9PSHaWR8CpE,320
10
- ecmwf/datastores/version.py,sha256=FGsmFbZ942cZk42U_qHqxgRCbsD--5Vld_eR6xKJ-mQ,72
11
- ecmwf_datastores_client-0.1.0.dist-info/licenses/LICENSE,sha256=e2Qp4JUZeHZZSYCADyp1B3siZB5aQE5MRCYRx7vqlNI,11346
12
- ecmwf_datastores_client-0.1.0.dist-info/METADATA,sha256=iWh4WP7qUyNI2kxFJJmj9kxo9a-c_rwIQkhE3o2NiEA,21715
13
- ecmwf_datastores_client-0.1.0.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
14
- ecmwf_datastores_client-0.1.0.dist-info/top_level.txt,sha256=gvA9-Z3hRaFzijz-mf8v2t84s25ptpWeqhyuUomJoJk,6
15
- ecmwf_datastores_client-0.1.0.dist-info/RECORD,,