Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

releasing 0.4.6 #50

Merged
merged 14 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions .github/workflows/changelog-release-update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
name: "Update Changelog"

on:
release:
types: [released]
workflow_dispatch: ~
workflow_run:
workflows:
- Upload Python Package
types:
- completed

permissions:
pull-requests: write
Expand All @@ -13,6 +15,7 @@ permissions:
jobs:
update:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}

steps:
- name: Checkout code
Expand All @@ -31,6 +34,12 @@ jobs:
uses: peter-evans/create-pull-request@v6
with:
branch: docs/changelog-update-${{ github.event.release.tag_name }}
base: develop
title: '[Changelog] Update to ${{ github.event.release.tag_name }}'
body: |
This PR updates the changelog to include the changes in the latest release.

> [!CAUTION]
> Merge DO NOT squash to correctly update the tag version of `develop` branch.
add-paths: |
CHANGELOG.md
31 changes: 23 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,28 @@ jobs:
with:
anemoi-utils: ecmwf/anemoi-utils@${{ github.event.pull_request.head.sha || github.sha }}
codecov_upload: true
skip_matrix_jobs: |
gnu@debian-11
[email protected]
gnu@debian-11
[email protected]
[email protected]
gnu@fedora-37
secrets: inherit

# Build downstream packages on HPC
downstream-ci-hpc:
name: downstream-ci-hpc
if: ${{ !github.event.pull_request.head.repo.fork && github.event.action != 'labeled' || github.event.label.name == 'approved-for-ci' }}
uses: ecmwf-actions/downstream-ci/.github/workflows/downstream-ci-hpc.yml@main
with:
anemoi-utils: ecmwf/anemoi-utils@${{ github.event.pull_request.head.sha || github.sha }}
secrets: inherit
# # Build downstream packages on HPC
# downstream-ci-hpc:
# name: downstream-ci-hpc
# if: ${{ !github.event.pull_request.head.repo.fork && github.event.action != 'labeled' || github.event.label.name == 'approved-for-ci' }}
# uses: ecmwf-actions/downstream-ci/.github/workflows/downstream-ci.yml@main
# with:
# anemoi-utils: ecmwf/anemoi-utils@${{ github.event.pull_request.head.sha || github.sha }}
# codecov_upload: true
# skip_matrix_jobs: |
# gnu@debian-11
# [email protected]
# gnu@debian-11
# [email protected]
# [email protected]
# gnu@fedora-37
# secrets: inherit
11 changes: 8 additions & 3 deletions .github/workflows/python-pull-request.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries

name: Code Quality checks for PRs
name: Test PR

on:
push:
pull_request:
types: [opened, synchronize, reopened]
push:
branches:
- develop
schedule:
- cron: "9 2 * * 0" # at 9:02 on sunday


jobs:
quality:
Expand All @@ -17,7 +22,7 @@ jobs:
checks:
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: ["3.11"]
uses: ecmwf-actions/reusable-workflows/.github/workflows/qa-pytest-pyproject.yml@v2
with:
python-version: ${{ matrix.python-version }}
5 changes: 0 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,6 @@ repos:
hooks:
- id: rstfmt
exclude: 'cli/.*' # Because we use argparse
- repo: https://github.com/b8raoult/pre-commit-docconvert
rev: "0.1.5"
hooks:
- id: docconvert
args: ["numpy"]
- repo: https://github.com/tox-dev/pyproject-fmt
rev: "v2.5.0"
hooks:
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Please add your functional changes to the appropriate section in the PR.
Keep it human-readable, your future self will thank you!

## [0.4.5](https://github.com/ecmwf/anemoi-utils/compare/0.4.4...0.4.5) - 2024-11-06

### What's Changed

* upload with ssh by @floriankrb in https://github.com/ecmwf/anemoi-utils/pull/25
* feat: Add aliases decorator by @HCookie in https://github.com/ecmwf/anemoi-utils/pull/40

**Full Changelog**: https://github.com/ecmwf/anemoi-utils/compare/0.4.4...0.4.5

## [0.4.4](https://github.com/ecmwf/anemoi-utils/compare/0.4.3...0.4.4) - 2024-11-01

## [0.4.3](https://github.com/ecmwf/anemoi-utils/compare/0.4.1...0.4.3) - 2024-10-26

## [0.4.2](https://github.com/ecmwf/anemoi-utils/compare/0.4.1...0.4.2) - 2024-10-25

### Added

- Add supporting_arrays to checkpoints
- Add factories registry
- Optional renaming of subcommands via `command` attribute [#34](https://github.com/ecmwf/anemoi-utils/pull/34)
Expand Down
18 changes: 9 additions & 9 deletions src/anemoi/utils/hindcasts.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ def __init__(self, reference_dates, years=20):

self.reference_dates = reference_dates

if isinstance(years, list):
self.years = years
else:
self.years = range(1, years + 1)
assert isinstance(years, int), f"years must be an integer, got {years}"
assert years > 0, f"years must be greater than 0, got {years}"
self.years = years

def __iter__(self):
for reference_date in self.reference_dates:
for year in self.years:
if reference_date.month == 2 and reference_date.day == 29:
date = datetime.datetime(reference_date.year - year, 2, 28)
else:
date = datetime.datetime(reference_date.year - year, reference_date.month, reference_date.day)
year, month, day = reference_date.year, reference_date.month, reference_date.day
if (month, day) == (2, 29):
day = 28

for i in range(1, self.years + 1):
date = datetime.datetime(year - i, month, day)
yield (date, reference_date)
25 changes: 21 additions & 4 deletions src/anemoi/utils/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ def __call__(self, factory):
return factory


_BY_KIND = {}


class Registry:
"""A registry of factories"""

Expand All @@ -39,6 +42,11 @@ def __init__(self, package, key="_type"):
self.registered = {}
self.kind = package.split(".")[-1]
self.key = key
_BY_KIND[self.kind] = self

@classmethod
def lookup_kind(cls, kind: str):
return _BY_KIND.get(kind)

def register(self, name: str, factory: callable = None):

Expand All @@ -47,14 +55,19 @@ def register(self, name: str, factory: callable = None):

self.registered[name] = factory

# def registered(self, name: str):
# return name in self.registered

def _load(self, file):
name, _ = os.path.splitext(file)
try:
importlib.import_module(f".{name}", package=self.package)
except Exception:
LOG.warning(f"Error loading filter '{self.package}.{name}'", exc_info=True)

def lookup(self, name: str) -> callable:
def lookup(self, name: str, *, return_none=False) -> callable:

# print('✅✅✅✅✅✅✅✅✅✅✅✅✅', name, self.registered)
if name in self.registered:
return self.registered[name]

Expand Down Expand Up @@ -87,8 +100,12 @@ def lookup(self, name: str) -> callable:
self.registered[name] = entry_point.load()

if name not in self.registered:
if return_none:
return None

for e in self.registered:
LOG.info(f"Registered: {e}")

raise ValueError(f"Cannot load '{name}' from {self.package}")

return self.registered[name]
Expand All @@ -97,8 +114,8 @@ def create(self, name: str, *args, **kwargs):
factory = self.lookup(name)
return factory(*args, **kwargs)

def __call__(self, name: str, *args, **kwargs):
return self.create(name, *args, **kwargs)
# def __call__(self, name: str, *args, **kwargs):
# return self.create(name, *args, **kwargs)

def from_config(self, config, *args, **kwargs):
if isinstance(config, str):
Expand All @@ -125,5 +142,5 @@ def from_config(self, config, *args, **kwargs):
return self.create(key, *args, value, **kwargs)

raise ValueError(
f"Entry '{config}' must either be a string, a dictionray with a single entry, or a dictionary with a '{self.key}' key"
f"Entry '{config}' must either be a string, a dictionary with a single entry, or a dictionary with a '{self.key}' key"
)
30 changes: 0 additions & 30 deletions tests/test_dates.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,36 +83,6 @@ def test_date_hindcast_1():
assert len(list(d)) == 60


def test_date_hindcast_2():
d = _(
"""
- name: hindcast
reference_dates:
start: 2023-01-01
end: 2023-01-03
frequency: 24
years: [2018, 2019, 2020, 2021]
"""
)
assert len(list(d)) == 12


def test_date_hindcast_3():
d = _(
"""
- name: hindcast
reference_dates:
start: 2022-12-25 00:00:00
end: 2022-12-31 12:00:00
frequency: 12h
day_of_week: tuesday
years: [2018, 2019, 2020, 2021]
"""
)
print(list(d))
assert len(list(d)) == 8


if __name__ == "__main__":
for name, obj in list(globals().items()):
if name.startswith("test_") and callable(obj):
Expand Down
Loading