ecmwf-datastores-client 0.2.0__py3-none-any.whl → 0.4.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.

@@ -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
 
@@ -259,7 +276,7 @@ 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
 
@@ -269,7 +286,7 @@ class Client:
269
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
@@ -21,7 +21,7 @@ import os
21
21
  import time
22
22
  import urllib.parse
23
23
  import warnings
24
- from typing import Any, Callable, Type, TypedDict, TypeVar
24
+ from typing import Any, Callable, TypedDict, TypeVar
25
25
 
26
26
  try:
27
27
  from typing import Self
@@ -144,7 +144,7 @@ class ApiResponse:
144
144
 
145
145
  @classmethod
146
146
  def from_request(
147
- cls: Type[T_ApiResponse],
147
+ cls: type[T_ApiResponse],
148
148
  method: str,
149
149
  url: str,
150
150
  headers: dict[str, str],
@@ -467,7 +467,7 @@ class Remote:
467
467
  return True
468
468
  if status in ("accepted", "running"):
469
469
  return False
470
- if status == "failed":
470
+ if status in ("failed", "rejected"):
471
471
  results = self._make_results(wait=False)
472
472
  raise ProcessingFailedError(error_json_to_message(results._json_dict))
473
473
  if status in ("dismissed", "deleted"):
@@ -620,13 +620,16 @@ class Results(ApiResponse):
620
620
  def _download(self, url: str, target: str) -> requests.Response:
621
621
  download_options = {"stream": True, "resume_transfers": True}
622
622
  download_options.update(self.download_options)
623
- multiurl.download(
624
- url,
625
- target=target,
626
- **self.retry_options,
627
- **self.request_options,
628
- **download_options,
629
- )
623
+ try:
624
+ multiurl.download(
625
+ url,
626
+ target=target,
627
+ maximum_retries=0,
628
+ **self.request_options,
629
+ **download_options,
630
+ )
631
+ except requests.HTTPError as exc:
632
+ return exc.response
630
633
  return requests.Response() # mutliurl robust needs a response
631
634
 
632
635
  def download(
@@ -661,7 +664,7 @@ class Results(ApiResponse):
661
664
  @property
662
665
  def location(self) -> str:
663
666
  """File location."""
664
- result_href = self.asset["href"]
667
+ result_href: str = self.asset["href"]
665
668
  return urllib.parse.urljoin(self.response.url, result_href)
666
669
 
667
670
  @property
@@ -705,6 +708,13 @@ class Processing:
705
708
  log_callback=self.log_callback,
706
709
  )
707
710
 
711
+ def delete(self, *job_ids: str) -> dict[str, Any]:
712
+ url = f"{self.url}/jobs/delete"
713
+ response = ApiResponse.from_request(
714
+ "post", url, json={"job_ids": job_ids}, **self._request_kwargs
715
+ )
716
+ return response._json_dict
717
+
708
718
  def get_processes(self, **params: Any) -> Processes:
709
719
  url = f"{self.url}/processes"
710
720
  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.2.0"
2
+ __version__ = "0.4.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ecmwf-datastores-client
3
- Version: 0.2.0
3
+ Version: 0.4.0
4
4
  Summary: ECMWF Data Stores Service (DSS) API Python client
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -213,18 +213,17 @@ Classifier: License :: OSI Approved :: Apache Software License
213
213
  Classifier: Operating System :: OS Independent
214
214
  Classifier: Programming Language :: Python
215
215
  Classifier: Programming Language :: Python :: 3
216
- Classifier: Programming Language :: Python :: 3.8
217
216
  Classifier: Programming Language :: Python :: 3.9
218
217
  Classifier: Programming Language :: Python :: 3.10
219
218
  Classifier: Programming Language :: Python :: 3.11
220
219
  Classifier: Programming Language :: Python :: 3.12
221
220
  Classifier: Programming Language :: Python :: 3.13
222
221
  Classifier: Topic :: Scientific/Engineering
223
- Requires-Python: >=3.8
222
+ Requires-Python: >=3.9
224
223
  Description-Content-Type: text/markdown
225
224
  License-File: LICENSE
226
225
  Requires-Dist: attrs
227
- Requires-Dist: multiurl>=0.3.2
226
+ Requires-Dist: multiurl>=0.3.7
228
227
  Requires-Dist: requests
229
228
  Requires-Dist: typing-extensions
230
229
  Provides-Extra: legacy
@@ -322,8 +321,8 @@ Retrieve data:
322
321
  ... "time": ["00:00"],
323
322
  ... "pressure_level": ["1000"],
324
323
  ... "data_format": "grib",
325
- ... "download_format": "unarchived"
326
- ... }
324
+ ... "download_format": "unarchived",
325
+ ... }
327
326
 
328
327
  >>> client.retrieve(collection_id, request, target="target_1.grib") # blocks
329
328
  'target_1.grib'
@@ -359,6 +358,7 @@ List all collection IDs sorted by last update:
359
358
  >>> while collections is not None: # Loop over pages
360
359
  ... collection_ids.extend(collections.collection_ids)
361
360
  ... collections = collections.next # Move to the next page
361
+ ...
362
362
 
363
363
  >>> collection_ids
364
364
  [...]
@@ -425,6 +425,7 @@ List all successful jobs, sorted by newest first:
425
425
  >>> while jobs is not None: # Loop over pages
426
426
  ... request_ids.extend(jobs.request_ids)
427
427
  ... jobs = jobs.next # Move to the next page
428
+ ...
428
429
 
429
430
  >>> request_ids
430
431
  [...]
@@ -1,15 +1,15 @@
1
1
  ecmwf/datastores/__init__.py,sha256=RQ5WNfEjLQ1qlZxyvGv3S6zPcFO35UcgN4iiz_Uh06I,1243
2
2
  ecmwf/datastores/catalogue.py,sha256=I-ON4lxI13Y5dR7joU1qeQrWTxYBQMFGYoOrLa2oLic,6257
3
- ecmwf/datastores/client.py,sha256=x0NGrtuVtlS3VmKzAkwUpnhvZAlz0zfL2nmzGsduUFM,12643
3
+ ecmwf/datastores/client.py,sha256=bCXSb1q3T-kX7csOshi4z6qU54s8JrczPVbEPxa_UiA,13053
4
4
  ecmwf/datastores/config.py,sha256=45C4nvgk-uGucCAnN3bUtr_zv-_dm8IN_P5xl7LPqfs,1497
5
5
  ecmwf/datastores/legacy_client.py,sha256=UEkQNg9IA_zNnpZrc4I9O2X2h39NsaxYM0xpL2OKghA,9491
6
- ecmwf/datastores/processing.py,sha256=38rlgPnvQNfiyYxwa8NYU6er-qxDpofpp7_ppBwoPLM,21818
6
+ ecmwf/datastores/processing.py,sha256=KDV2rwNdWZHaXNqorSO-BRg8fuqxv5or3Z8s4-rDSYY,22204
7
7
  ecmwf/datastores/profile.py,sha256=VjT6GSoSZZyaDHXZh0SQbrzxSX3Ug2DOWhq7VIu-QX8,2974
8
8
  ecmwf/datastores/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  ecmwf/datastores/utils.py,sha256=fc6wma5qRpgAsX3dOmg0aoIc-qjWG6NY9PSHaWR8CpE,320
10
- ecmwf/datastores/version.py,sha256=Q6rYkA2w2NAZ1iqPYZyyi7rZkL-vTkoYSpVO5Rjzg4Q,72
11
- ecmwf_datastores_client-0.2.0.dist-info/licenses/LICENSE,sha256=e2Qp4JUZeHZZSYCADyp1B3siZB5aQE5MRCYRx7vqlNI,11346
12
- ecmwf_datastores_client-0.2.0.dist-info/METADATA,sha256=aL7FTRC3JA7guD1cnprBGKb1TaV7ZLK1GzPdXpKR6EE,21463
13
- ecmwf_datastores_client-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
- ecmwf_datastores_client-0.2.0.dist-info/top_level.txt,sha256=gvA9-Z3hRaFzijz-mf8v2t84s25ptpWeqhyuUomJoJk,6
15
- ecmwf_datastores_client-0.2.0.dist-info/RECORD,,
10
+ ecmwf/datastores/version.py,sha256=-UXII43tJWWG-Bw3-ObfEfbloOAVS2Clozd55E6zYvA,72
11
+ ecmwf_datastores_client-0.4.0.dist-info/licenses/LICENSE,sha256=e2Qp4JUZeHZZSYCADyp1B3siZB5aQE5MRCYRx7vqlNI,11346
12
+ ecmwf_datastores_client-0.4.0.dist-info/METADATA,sha256=6WXpiRL6szWCjZn8rHWa4OJkhhe0rAKXy_qZZioT64I,21418
13
+ ecmwf_datastores_client-0.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
+ ecmwf_datastores_client-0.4.0.dist-info/top_level.txt,sha256=gvA9-Z3hRaFzijz-mf8v2t84s25ptpWeqhyuUomJoJk,6
15
+ ecmwf_datastores_client-0.4.0.dist-info/RECORD,,