anemoi-utils 0.4.22__tar.gz → 0.4.23__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 anemoi-utils might be problematic. Click here for more details.

Files changed (102) hide show
  1. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.pre-commit-config.yaml +1 -1
  2. anemoi_utils-0.4.23/.release-please-manifest.json +3 -0
  3. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/CHANGELOG.md +9 -0
  4. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/PKG-INFO +2 -2
  5. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/pyproject.toml +1 -1
  6. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/_version.py +2 -2
  7. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/provenance.py +5 -2
  8. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/remote/s3.py +42 -9
  9. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/testing.py +4 -4
  10. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi_utils.egg-info/PKG-INFO +2 -2
  11. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi_utils.egg-info/requires.txt +1 -1
  12. anemoi_utils-0.4.22/.release-please-manifest.json +0 -3
  13. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.gitattributes +0 -0
  14. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.github/CODEOWNERS +0 -0
  15. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.github/ci-hpc-config.yml +0 -0
  16. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.github/dependabot.yml +0 -0
  17. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.github/labeler.yml +0 -0
  18. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.github/pull_request_template.md +0 -0
  19. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.github/release.yml +0 -0
  20. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.github/workflows/downstream-ci-hpc.yml +0 -0
  21. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.github/workflows/pr-conventional-commit.yml +0 -0
  22. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.github/workflows/pr-label-conventional-commits.yml +0 -0
  23. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.github/workflows/pr-label-file-based.yml +0 -0
  24. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.github/workflows/pr-label-public.yml +0 -0
  25. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.github/workflows/python-publish.yml +0 -0
  26. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.github/workflows/python-pull-request.yml +0 -0
  27. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.github/workflows/readthedocs-pr-update.yml +0 -0
  28. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.github/workflows/release-please.yml +0 -0
  29. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.gitignore +0 -0
  30. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.readthedocs.yaml +0 -0
  31. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/.release-please-config.json +0 -0
  32. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/CONTRIBUTORS.md +0 -0
  33. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/LICENSE +0 -0
  34. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/README.md +0 -0
  35. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/Makefile +0 -0
  36. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/_static/logo.png +0 -0
  37. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/_static/style.css +0 -0
  38. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/_templates/.gitkeep +0 -0
  39. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/_templates/apidoc/package.rst.jinja +0 -0
  40. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/conf.py +0 -0
  41. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/index.rst +0 -0
  42. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/installing.rst +0 -0
  43. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/modules/checkpoints.rst +0 -0
  44. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/modules/config.rst +0 -0
  45. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/modules/dates.rst +0 -0
  46. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/modules/grib.rst +0 -0
  47. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/modules/humanize.rst +0 -0
  48. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/modules/provenance.rst +0 -0
  49. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/modules/s3.rst +0 -0
  50. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/modules/testing.rst +0 -0
  51. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/modules/text.rst +0 -0
  52. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/docs/scripts/api_build.sh +0 -0
  53. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/setup.cfg +0 -0
  54. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/__init__.py +0 -0
  55. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/__main__.py +0 -0
  56. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/caching.py +0 -0
  57. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/checkpoints.py +0 -0
  58. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/cli.py +0 -0
  59. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/commands/__init__.py +0 -0
  60. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/commands/config.py +0 -0
  61. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/commands/requests.py +0 -0
  62. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/compatibility.py +0 -0
  63. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/config.py +0 -0
  64. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/dates.py +0 -0
  65. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/devtools.py +0 -0
  66. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/grib.py +0 -0
  67. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/grids.py +0 -0
  68. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/hindcasts.py +0 -0
  69. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/humanize.py +0 -0
  70. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/logs.py +0 -0
  71. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/mars/__init__.py +0 -0
  72. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/mars/mars.yaml +0 -0
  73. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/mars/requests.py +0 -0
  74. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/registry.py +0 -0
  75. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/remote/__init__.py +0 -0
  76. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/remote/ssh.py +0 -0
  77. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/rules.py +0 -0
  78. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/s3.py +0 -0
  79. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/sanitise.py +0 -0
  80. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/sanitize.py +0 -0
  81. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/schemas/__init__.py +0 -0
  82. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/schemas/errors.py +0 -0
  83. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/text.py +0 -0
  84. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi/utils/timer.py +0 -0
  85. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi_utils.egg-info/SOURCES.txt +0 -0
  86. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi_utils.egg-info/dependency_links.txt +0 -0
  87. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi_utils.egg-info/entry_points.txt +0 -0
  88. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/src/anemoi_utils.egg-info/top_level.txt +0 -0
  89. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/tests/test-transfer-data/directory/b/c/x +0 -0
  90. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/tests/test-transfer-data/directory/b/y +0 -0
  91. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/tests/test-transfer-data/directory/exotic filename ;^/"'[=.,#]()/303/252/303/274/303/247/303/262/342/234/205.txt" +0 -0
  92. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/tests/test-transfer-data/directory/z +0 -0
  93. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/tests/test-transfer-data/file +0 -0
  94. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/tests/test_caching.py +0 -0
  95. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/tests/test_compatibility.py +0 -0
  96. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/tests/test_dates.py +0 -0
  97. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/tests/test_frequency.py +0 -0
  98. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/tests/test_grids.py +0 -0
  99. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/tests/test_provenance.py +0 -0
  100. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/tests/test_remote.py +0 -0
  101. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/tests/test_sanetise.py +0 -0
  102. {anemoi_utils-0.4.22 → anemoi_utils-0.4.23}/tests/test_utils.py +0 -0
@@ -40,7 +40,7 @@ repos:
40
40
  - --force-single-line-imports
41
41
  - --profile black
42
42
  - repo: https://github.com/astral-sh/ruff-pre-commit
43
- rev: v0.11.4
43
+ rev: v0.11.8
44
44
  hooks:
45
45
  - id: ruff
46
46
  args:
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.4.23"
3
+ }
@@ -8,6 +8,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
  Please add your functional changes to the appropriate section in the PR.
9
9
  Keep it human-readable, your future self will thank you!
10
10
 
11
+ ## [0.4.23](https://github.com/ecmwf/anemoi-utils/compare/0.4.22...0.4.23) (2025-05-20)
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * fix list_folder on s3 ([#154](https://github.com/ecmwf/anemoi-utils/issues/154)) ([3ceb42c](https://github.com/ecmwf/anemoi-utils/commit/3ceb42c5185290d4c12e3fe90c3c331e3d8c7a5f))
17
+ * Remove the requirment to have git installed ([#149](https://github.com/ecmwf/anemoi-utils/issues/149)) ([88846e8](https://github.com/ecmwf/anemoi-utils/commit/88846e80be2927050a879ff953a78aecf39c3ac5))
18
+ * Use urllib to make _offline() aware of HTTP(s) proxies. ([#150](https://github.com/ecmwf/anemoi-utils/issues/150)) ([5c4d06f](https://github.com/ecmwf/anemoi-utils/commit/5c4d06f931590cc360eb4ffeeb8753a5d3d72bcb))
19
+
11
20
  ## [0.4.22](https://github.com/ecmwf/anemoi-utils/compare/0.4.21...0.4.22) (2025-04-10)
12
21
 
13
22
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: anemoi-utils
3
- Version: 0.4.22
3
+ Version: 0.4.23
4
4
  Summary: A package to hold various functions to support training of ML models on ECMWF data.
5
5
  Author-email: "European Centre for Medium-Range Weather Forecasts (ECMWF)" <software.support@ecmwf.int>
6
6
  License: Apache License
@@ -252,7 +252,7 @@ Provides-Extra: provenance
252
252
  Requires-Dist: gitpython; extra == "provenance"
253
253
  Requires-Dist: nvsmi; extra == "provenance"
254
254
  Provides-Extra: s3
255
- Requires-Dist: boto3<1.36; extra == "s3"
255
+ Requires-Dist: boto3>1.36; extra == "s3"
256
256
  Provides-Extra: tests
257
257
  Requires-Dist: pytest; extra == "tests"
258
258
  Provides-Extra: text
@@ -70,7 +70,7 @@ optional-dependencies.grib = [ "requests" ]
70
70
  optional-dependencies.provenance = [ "gitpython", "nvsmi" ]
71
71
 
72
72
  optional-dependencies.s3 = [
73
- "boto3<1.36",
73
+ "boto3>1.36",
74
74
  ]
75
75
 
76
76
  optional-dependencies.tests = [ "pytest" ]
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.4.22'
21
- __version_tuple__ = version_tuple = (0, 4, 22)
20
+ __version__ = version = '0.4.23'
21
+ __version_tuple__ = version_tuple = (0, 4, 23)
@@ -47,8 +47,11 @@ def lookup_git_repo(path: str) -> Optional[Any]:
47
47
  Repo, optional
48
48
  The git repository if found, otherwise None.
49
49
  """
50
- from git import InvalidGitRepositoryError
51
- from git import Repo
50
+ try:
51
+ from git import InvalidGitRepositoryError
52
+ from git import Repo
53
+ except ImportError:
54
+ return None
52
55
 
53
56
  while path != "/":
54
57
  try:
@@ -1,10 +1,13 @@
1
- # (C) Copyright 2024 European Centre for Medium-Range Weather Forecasts.
1
+ # (C) Copyright 2024-2025 Anemoi contributors.
2
+ #
2
3
  # This software is licensed under the terms of the Apache Licence Version 2.0
3
4
  # which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5
+ #
4
6
  # In applying this licence, ECMWF does not waive the privileges and immunities
5
7
  # granted to it by virtue of its status as an intergovernmental organisation
6
8
  # nor does it submit to any jurisdiction.
7
9
 
10
+
8
11
  """This module provides functions to upload, download, list and delete files and folders on S3.
9
12
  The functions of this package expect that the AWS credentials are set up in the environment
10
13
  typicaly by setting the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables or
@@ -67,12 +70,14 @@ def s3_client(bucket: str, region: str = None) -> Any:
67
70
 
68
71
  key = f"{bucket}-{region}"
69
72
 
70
- boto3_config = dict(max_pool_connections=25)
71
-
72
73
  if key in thread_local.s3_clients:
73
74
  return thread_local.s3_clients[key]
74
75
 
75
- boto3_config = dict(max_pool_connections=25)
76
+ boto3_config = dict(
77
+ max_pool_connections=25,
78
+ request_checksum_calculation="when_required",
79
+ response_checksum_validation="when_required",
80
+ )
76
81
 
77
82
  if region:
78
83
  # This is using AWS
@@ -162,7 +167,14 @@ class S3Upload(BaseUpload):
162
167
  # delete(target)
163
168
 
164
169
  def _transfer_file(
165
- self, source: str, target: str, overwrite: bool, resume: bool, verbosity: int, threads: int, config: dict = None
170
+ self,
171
+ source: str,
172
+ target: str,
173
+ overwrite: bool,
174
+ resume: bool,
175
+ verbosity: int,
176
+ threads: int,
177
+ config: dict = None,
166
178
  ) -> int:
167
179
  """Transfer a file to S3.
168
180
 
@@ -227,7 +239,13 @@ class S3Upload(BaseUpload):
227
239
 
228
240
  if verbosity > 0:
229
241
  with tqdm.tqdm(total=size, unit="B", unit_scale=True, unit_divisor=1024, leave=False) as pbar:
230
- s3.upload_file(source, bucket, key, Callback=lambda x: pbar.update(x), Config=config)
242
+ s3.upload_file(
243
+ source,
244
+ bucket,
245
+ key,
246
+ Callback=lambda x: pbar.update(x),
247
+ Config=config,
248
+ )
231
249
  else:
232
250
  s3.upload_file(source, bucket, key, Config=config)
233
251
 
@@ -326,7 +344,14 @@ class S3Download(BaseDownload):
326
344
  return s3_object["Size"]
327
345
 
328
346
  def _transfer_file(
329
- self, source: str, target: str, overwrite: bool, resume: bool, verbosity: int, threads: int, config: dict = None
347
+ self,
348
+ source: str,
349
+ target: str,
350
+ overwrite: bool,
351
+ resume: bool,
352
+ verbosity: int,
353
+ threads: int,
354
+ config: dict = None,
330
355
  ) -> int:
331
356
  """Transfer a file from S3 to the local filesystem.
332
357
 
@@ -397,7 +422,13 @@ class S3Download(BaseDownload):
397
422
 
398
423
  if verbosity > 0:
399
424
  with tqdm.tqdm(total=size, unit="B", unit_scale=True, unit_divisor=1024, leave=False) as pbar:
400
- s3.download_file(bucket, key, target, Callback=lambda x: pbar.update(x), Config=config)
425
+ s3.download_file(
426
+ bucket,
427
+ key,
428
+ target,
429
+ Callback=lambda x: pbar.update(x),
430
+ Config=config,
431
+ )
401
432
  else:
402
433
  s3.download_file(bucket, key, target, Config=config)
403
434
 
@@ -524,7 +555,9 @@ def list_folder(folder: str) -> Iterable:
524
555
 
525
556
  for page in paginator.paginate(Bucket=bucket, Prefix=prefix, Delimiter="/"):
526
557
  if "CommonPrefixes" in page:
527
- yield from [folder + _["Prefix"] for _ in page.get("CommonPrefixes")]
558
+ yield from [folder + _["Prefix"] for _ in page.get("CommonPrefixes") if _["Prefix"] != "/"]
559
+ if "Contents" in page:
560
+ yield from [folder + _["Key"] for _ in page.get("Contents")]
528
561
 
529
562
 
530
563
  def object_info(target: str) -> dict:
@@ -261,12 +261,12 @@ def _run_slow_tests() -> bool:
261
261
  @lru_cache(maxsize=None)
262
262
  def _offline() -> bool:
263
263
  """Check if we are offline."""
264
-
265
- import socket
264
+ from urllib import request
266
265
 
267
266
  try:
268
- socket.create_connection(("anemoi.ecmwf.int", 443), timeout=5)
269
- except OSError:
267
+ request.urlopen("https://anemoi.ecmwf.int", timeout=1)
268
+ return False
269
+ except request.URLError:
270
270
  return True
271
271
 
272
272
  return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: anemoi-utils
3
- Version: 0.4.22
3
+ Version: 0.4.23
4
4
  Summary: A package to hold various functions to support training of ML models on ECMWF data.
5
5
  Author-email: "European Centre for Medium-Range Weather Forecasts (ECMWF)" <software.support@ecmwf.int>
6
6
  License: Apache License
@@ -252,7 +252,7 @@ Provides-Extra: provenance
252
252
  Requires-Dist: gitpython; extra == "provenance"
253
253
  Requires-Dist: nvsmi; extra == "provenance"
254
254
  Provides-Extra: s3
255
- Requires-Dist: boto3<1.36; extra == "s3"
255
+ Requires-Dist: boto3>1.36; extra == "s3"
256
256
  Provides-Extra: tests
257
257
  Requires-Dist: pytest; extra == "tests"
258
258
  Provides-Extra: text
@@ -36,7 +36,7 @@ gitpython
36
36
  nvsmi
37
37
 
38
38
  [s3]
39
- boto3<1.36
39
+ boto3>1.36
40
40
 
41
41
  [tests]
42
42
  pytest
@@ -1,3 +0,0 @@
1
- {
2
- ".": "0.4.22"
3
- }
File without changes
File without changes
File without changes
File without changes