anemoi-utils 0.4.5__tar.gz → 0.4.6__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 (79) hide show
  1. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/.github/workflows/changelog-release-update.yml +12 -3
  2. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/.github/workflows/ci.yml +23 -8
  3. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/.github/workflows/python-pull-request.yml +8 -3
  4. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/.pre-commit-config.yaml +0 -5
  5. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/CHANGELOG.md +10 -0
  6. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/PKG-INFO +1 -1
  7. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/_version.py +2 -2
  8. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/hindcasts.py +9 -9
  9. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/registry.py +21 -4
  10. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi_utils.egg-info/PKG-INFO +1 -1
  11. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/tests/test_dates.py +0 -30
  12. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/.gitattributes +0 -0
  13. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/.github/CODEOWNERS +0 -0
  14. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/.github/ci-hpc-config.yml +0 -0
  15. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/.github/workflows/changelog-pr-update.yml +0 -0
  16. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/.github/workflows/label-public-pr.yml +0 -0
  17. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/.github/workflows/python-publish.yml +0 -0
  18. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/.github/workflows/readthedocs-pr-update.yml +0 -0
  19. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/.gitignore +0 -0
  20. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/.readthedocs.yaml +0 -0
  21. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/CONTRIBUTORS.md +0 -0
  22. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/LICENSE +0 -0
  23. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/README.md +0 -0
  24. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/docs/Makefile +0 -0
  25. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/docs/_static/logo.png +0 -0
  26. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/docs/_static/style.css +0 -0
  27. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/docs/_templates/.gitkeep +0 -0
  28. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/docs/conf.py +0 -0
  29. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/docs/index.rst +0 -0
  30. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/docs/installing.rst +0 -0
  31. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/docs/modules/checkpoints.rst +0 -0
  32. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/docs/modules/config.rst +0 -0
  33. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/docs/modules/dates.rst +0 -0
  34. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/docs/modules/grib.rst +0 -0
  35. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/docs/modules/humanize.rst +0 -0
  36. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/docs/modules/provenance.rst +0 -0
  37. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/docs/modules/s3.rst +0 -0
  38. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/docs/modules/text.rst +0 -0
  39. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/pyproject.toml +0 -0
  40. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/setup.cfg +0 -0
  41. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/__init__.py +0 -0
  42. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/__main__.py +0 -0
  43. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/caching.py +0 -0
  44. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/checkpoints.py +0 -0
  45. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/cli.py +0 -0
  46. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/commands/__init__.py +0 -0
  47. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/commands/config.py +0 -0
  48. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/compatibility.py +0 -0
  49. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/config.py +0 -0
  50. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/dates.py +0 -0
  51. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/grib.py +0 -0
  52. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/humanize.py +0 -0
  53. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/mars/__init__.py +0 -0
  54. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/mars/mars.yaml +0 -0
  55. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/provenance.py +0 -0
  56. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/remote/__init__.py +0 -0
  57. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/remote/s3.py +0 -0
  58. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/remote/ssh.py +0 -0
  59. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/s3.py +0 -0
  60. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/sanitise.py +0 -0
  61. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/sanitize.py +0 -0
  62. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/text.py +0 -0
  63. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi/utils/timer.py +0 -0
  64. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi_utils.egg-info/SOURCES.txt +0 -0
  65. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi_utils.egg-info/dependency_links.txt +0 -0
  66. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi_utils.egg-info/entry_points.txt +0 -0
  67. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi_utils.egg-info/requires.txt +0 -0
  68. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/src/anemoi_utils.egg-info/top_level.txt +0 -0
  69. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/tests/test-transfer-data/directory/b/c/x +0 -0
  70. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/tests/test-transfer-data/directory/b/y +0 -0
  71. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/tests/test-transfer-data/directory/exotic filename ;^/"'[=.,#]()/303/252/303/274/303/247/303/262/342/234/205.txt" +0 -0
  72. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/tests/test-transfer-data/directory/z +0 -0
  73. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/tests/test-transfer-data/file +0 -0
  74. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/tests/test_compatibility.py +0 -0
  75. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/tests/test_frequency.py +0 -0
  76. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/tests/test_provenance.py +0 -0
  77. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/tests/test_remote.py +0 -0
  78. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/tests/test_sanetise.py +0 -0
  79. {anemoi_utils-0.4.5 → anemoi_utils-0.4.6}/tests/test_utils.py +0 -0
@@ -2,9 +2,11 @@
2
2
  name: "Update Changelog"
3
3
 
4
4
  on:
5
- release:
6
- types: [released]
7
- workflow_dispatch: ~
5
+ workflow_run:
6
+ workflows:
7
+ - Upload Python Package
8
+ types:
9
+ - completed
8
10
 
9
11
  permissions:
10
12
  pull-requests: write
@@ -13,6 +15,7 @@ permissions:
13
15
  jobs:
14
16
  update:
15
17
  runs-on: ubuntu-latest
18
+ if: ${{ github.event.workflow_run.conclusion == 'success' }}
16
19
 
17
20
  steps:
18
21
  - name: Checkout code
@@ -31,6 +34,12 @@ jobs:
31
34
  uses: peter-evans/create-pull-request@v6
32
35
  with:
33
36
  branch: docs/changelog-update-${{ github.event.release.tag_name }}
37
+ base: develop
34
38
  title: '[Changelog] Update to ${{ github.event.release.tag_name }}'
39
+ body: |
40
+ This PR updates the changelog to include the changes in the latest release.
41
+
42
+ > [!CAUTION]
43
+ > Merge DO NOT squash to correctly update the tag version of `develop` branch.
35
44
  add-paths: |
36
45
  CHANGELOG.md
@@ -31,13 +31,28 @@ jobs:
31
31
  with:
32
32
  anemoi-utils: ecmwf/anemoi-utils@${{ github.event.pull_request.head.sha || github.sha }}
33
33
  codecov_upload: true
34
+ skip_matrix_jobs: |
35
+ gnu@debian-11
36
+ clang@rocky-8.6
37
+ gnu@debian-11
38
+ gnu@rocky-8.6
39
+ clang@rocky-8.6
40
+ gnu@fedora-37
34
41
  secrets: inherit
35
42
 
36
- # Build downstream packages on HPC
37
- downstream-ci-hpc:
38
- name: downstream-ci-hpc
39
- if: ${{ !github.event.pull_request.head.repo.fork && github.event.action != 'labeled' || github.event.label.name == 'approved-for-ci' }}
40
- uses: ecmwf-actions/downstream-ci/.github/workflows/downstream-ci-hpc.yml@main
41
- with:
42
- anemoi-utils: ecmwf/anemoi-utils@${{ github.event.pull_request.head.sha || github.sha }}
43
- secrets: inherit
43
+ # # Build downstream packages on HPC
44
+ # downstream-ci-hpc:
45
+ # name: downstream-ci-hpc
46
+ # if: ${{ !github.event.pull_request.head.repo.fork && github.event.action != 'labeled' || github.event.label.name == 'approved-for-ci' }}
47
+ # uses: ecmwf-actions/downstream-ci/.github/workflows/downstream-ci.yml@main
48
+ # with:
49
+ # anemoi-utils: ecmwf/anemoi-utils@${{ github.event.pull_request.head.sha || github.sha }}
50
+ # codecov_upload: true
51
+ # skip_matrix_jobs: |
52
+ # gnu@debian-11
53
+ # clang@rocky-8.6
54
+ # gnu@debian-11
55
+ # gnu@rocky-8.6
56
+ # clang@rocky-8.6
57
+ # gnu@fedora-37
58
+ # secrets: inherit
@@ -1,12 +1,17 @@
1
1
  # This workflow will upload a Python Package using Twine when a release is created
2
2
  # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
3
3
 
4
- name: Code Quality checks for PRs
4
+ name: Test PR
5
5
 
6
6
  on:
7
- push:
8
7
  pull_request:
9
8
  types: [opened, synchronize, reopened]
9
+ push:
10
+ branches:
11
+ - develop
12
+ schedule:
13
+ - cron: "9 2 * * 0" # at 9:02 on sunday
14
+
10
15
 
11
16
  jobs:
12
17
  quality:
@@ -17,7 +22,7 @@ jobs:
17
22
  checks:
18
23
  strategy:
19
24
  matrix:
20
- python-version: ["3.9", "3.10", "3.11", "3.12"]
25
+ python-version: ["3.11"]
21
26
  uses: ecmwf-actions/reusable-workflows/.github/workflows/qa-pytest-pyproject.yml@v2
22
27
  with:
23
28
  python-version: ${{ matrix.python-version }}
@@ -59,11 +59,6 @@ repos:
59
59
  hooks:
60
60
  - id: rstfmt
61
61
  exclude: 'cli/.*' # Because we use argparse
62
- - repo: https://github.com/b8raoult/pre-commit-docconvert
63
- rev: "0.1.5"
64
- hooks:
65
- - id: docconvert
66
- args: ["numpy"]
67
62
  - repo: https://github.com/tox-dev/pyproject-fmt
68
63
  rev: "v2.5.0"
69
64
  hooks:
@@ -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.5](https://github.com/ecmwf/anemoi-utils/compare/0.4.4...0.4.5) - 2024-11-06
12
+
13
+ ### What's Changed
14
+
15
+ * upload with ssh by @floriankrb in https://github.com/ecmwf/anemoi-utils/pull/25
16
+ * feat: Add aliases decorator by @HCookie in https://github.com/ecmwf/anemoi-utils/pull/40
17
+
18
+ **Full Changelog**: https://github.com/ecmwf/anemoi-utils/compare/0.4.4...0.4.5
19
+
11
20
  ## [0.4.4](https://github.com/ecmwf/anemoi-utils/compare/0.4.3...0.4.4) - 2024-11-01
12
21
 
13
22
  ## [0.4.3](https://github.com/ecmwf/anemoi-utils/compare/0.4.1...0.4.3) - 2024-10-26
@@ -15,6 +24,7 @@ Keep it human-readable, your future self will thank you!
15
24
  ## [0.4.2](https://github.com/ecmwf/anemoi-utils/compare/0.4.1...0.4.2) - 2024-10-25
16
25
 
17
26
  ### Added
27
+
18
28
  - Add supporting_arrays to checkpoints
19
29
  - Add factories registry
20
30
  - Optional renaming of subcommands via `command` attribute [#34](https://github.com/ecmwf/anemoi-utils/pull/34)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: anemoi-utils
3
- Version: 0.4.5
3
+ Version: 0.4.6
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
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.4.5'
16
- __version_tuple__ = version_tuple = (0, 4, 5)
15
+ __version__ = version = '0.4.6'
16
+ __version_tuple__ = version_tuple = (0, 4, 6)
@@ -27,16 +27,16 @@ class HindcastDatesTimes:
27
27
 
28
28
  self.reference_dates = reference_dates
29
29
 
30
- if isinstance(years, list):
31
- self.years = years
32
- else:
33
- self.years = range(1, years + 1)
30
+ assert isinstance(years, int), f"years must be an integer, got {years}"
31
+ assert years > 0, f"years must be greater than 0, got {years}"
32
+ self.years = years
34
33
 
35
34
  def __iter__(self):
36
35
  for reference_date in self.reference_dates:
37
- for year in self.years:
38
- if reference_date.month == 2 and reference_date.day == 29:
39
- date = datetime.datetime(reference_date.year - year, 2, 28)
40
- else:
41
- date = datetime.datetime(reference_date.year - year, reference_date.month, reference_date.day)
36
+ year, month, day = reference_date.year, reference_date.month, reference_date.day
37
+ if (month, day) == (2, 29):
38
+ day = 28
39
+
40
+ for i in range(1, self.years + 1):
41
+ date = datetime.datetime(year - i, month, day)
42
42
  yield (date, reference_date)
@@ -30,6 +30,9 @@ class Wrapper:
30
30
  return factory
31
31
 
32
32
 
33
+ _BY_KIND = {}
34
+
35
+
33
36
  class Registry:
34
37
  """A registry of factories"""
35
38
 
@@ -39,6 +42,11 @@ class Registry:
39
42
  self.registered = {}
40
43
  self.kind = package.split(".")[-1]
41
44
  self.key = key
45
+ _BY_KIND[self.kind] = self
46
+
47
+ @classmethod
48
+ def lookup_kind(cls, kind: str):
49
+ return _BY_KIND.get(kind)
42
50
 
43
51
  def register(self, name: str, factory: callable = None):
44
52
 
@@ -47,6 +55,9 @@ class Registry:
47
55
 
48
56
  self.registered[name] = factory
49
57
 
58
+ # def registered(self, name: str):
59
+ # return name in self.registered
60
+
50
61
  def _load(self, file):
51
62
  name, _ = os.path.splitext(file)
52
63
  try:
@@ -54,7 +65,9 @@ class Registry:
54
65
  except Exception:
55
66
  LOG.warning(f"Error loading filter '{self.package}.{name}'", exc_info=True)
56
67
 
57
- def lookup(self, name: str) -> callable:
68
+ def lookup(self, name: str, *, return_none=False) -> callable:
69
+
70
+ # print('✅✅✅✅✅✅✅✅✅✅✅✅✅', name, self.registered)
58
71
  if name in self.registered:
59
72
  return self.registered[name]
60
73
 
@@ -87,8 +100,12 @@ class Registry:
87
100
  self.registered[name] = entry_point.load()
88
101
 
89
102
  if name not in self.registered:
103
+ if return_none:
104
+ return None
105
+
90
106
  for e in self.registered:
91
107
  LOG.info(f"Registered: {e}")
108
+
92
109
  raise ValueError(f"Cannot load '{name}' from {self.package}")
93
110
 
94
111
  return self.registered[name]
@@ -97,8 +114,8 @@ class Registry:
97
114
  factory = self.lookup(name)
98
115
  return factory(*args, **kwargs)
99
116
 
100
- def __call__(self, name: str, *args, **kwargs):
101
- return self.create(name, *args, **kwargs)
117
+ # def __call__(self, name: str, *args, **kwargs):
118
+ # return self.create(name, *args, **kwargs)
102
119
 
103
120
  def from_config(self, config, *args, **kwargs):
104
121
  if isinstance(config, str):
@@ -125,5 +142,5 @@ class Registry:
125
142
  return self.create(key, *args, value, **kwargs)
126
143
 
127
144
  raise ValueError(
128
- f"Entry '{config}' must either be a string, a dictionray with a single entry, or a dictionary with a '{self.key}' key"
145
+ f"Entry '{config}' must either be a string, a dictionary with a single entry, or a dictionary with a '{self.key}' key"
129
146
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: anemoi-utils
3
- Version: 0.4.5
3
+ Version: 0.4.6
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
@@ -83,36 +83,6 @@ def test_date_hindcast_1():
83
83
  assert len(list(d)) == 60
84
84
 
85
85
 
86
- def test_date_hindcast_2():
87
- d = _(
88
- """
89
- - name: hindcast
90
- reference_dates:
91
- start: 2023-01-01
92
- end: 2023-01-03
93
- frequency: 24
94
- years: [2018, 2019, 2020, 2021]
95
- """
96
- )
97
- assert len(list(d)) == 12
98
-
99
-
100
- def test_date_hindcast_3():
101
- d = _(
102
- """
103
- - name: hindcast
104
- reference_dates:
105
- start: 2022-12-25 00:00:00
106
- end: 2022-12-31 12:00:00
107
- frequency: 12h
108
- day_of_week: tuesday
109
- years: [2018, 2019, 2020, 2021]
110
- """
111
- )
112
- print(list(d))
113
- assert len(list(d)) == 8
114
-
115
-
116
86
  if __name__ == "__main__":
117
87
  for name, obj in list(globals().items()):
118
88
  if name.startswith("test_") and callable(obj):
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes