ukceh-time-stream 4.0.0__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.
- ukceh_time_stream-4.0.0/.editorconfig +33 -0
- ukceh_time_stream-4.0.0/.githooks/pre-commit +47 -0
- ukceh_time_stream-4.0.0/.github/ISSUE_TEMPLATE/bug_report.yml +61 -0
- ukceh_time_stream-4.0.0/.github/ISSUE_TEMPLATE/config.yml +1 -0
- ukceh_time_stream-4.0.0/.github/ISSUE_TEMPLATE/feature_request.yml +30 -0
- ukceh_time_stream-4.0.0/.github/dependabot.yml +23 -0
- ukceh_time_stream-4.0.0/.github/pull_request_template.md +9 -0
- ukceh_time_stream-4.0.0/.github/workflows/pipeline.yml +151 -0
- ukceh_time_stream-4.0.0/.gitignore +168 -0
- ukceh_time_stream-4.0.0/CHANGELOG/1.0.0.md +45 -0
- ukceh_time_stream-4.0.0/CHANGELOG/1.1.0.md +28 -0
- ukceh_time_stream-4.0.0/CHANGELOG/1.1.1.md +10 -0
- ukceh_time_stream-4.0.0/CHANGELOG/1.2.0.md +19 -0
- ukceh_time_stream-4.0.0/CHANGELOG/1.2.1.md +8 -0
- ukceh_time_stream-4.0.0/CHANGELOG/2.0.0.md +46 -0
- ukceh_time_stream-4.0.0/CHANGELOG/2.0.1.md +22 -0
- ukceh_time_stream-4.0.0/CHANGELOG/3.0.0.md +100 -0
- ukceh_time_stream-4.0.0/CHANGELOG/4.0.0.md +139 -0
- ukceh_time_stream-4.0.0/CITATION.cff +39 -0
- ukceh_time_stream-4.0.0/CONTRIBUTING.md +151 -0
- ukceh_time_stream-4.0.0/LICENSE +21 -0
- ukceh_time_stream-4.0.0/Makefile +89 -0
- ukceh_time_stream-4.0.0/PKG-INFO +211 -0
- ukceh_time_stream-4.0.0/README.md +160 -0
- ukceh_time_stream-4.0.0/conftest.py +6 -0
- ukceh_time_stream-4.0.0/docs/Makefile +23 -0
- ukceh_time_stream-4.0.0/docs/source/_static/UKCEH_Logo_Master_Black.png +0 -0
- ukceh_time_stream-4.0.0/docs/source/_static/UKCEH_Logo_Tagline_Black_Data.png +0 -0
- ukceh_time_stream-4.0.0/docs/source/_static/css/custom.css +56 -0
- ukceh_time_stream-4.0.0/docs/source/_static/fdri_logo.png +0 -0
- ukceh_time_stream-4.0.0/docs/source/_static/fdri_logo_cropped.jpg +0 -0
- ukceh_time_stream-4.0.0/docs/source/_static/polars.png +0 -0
- ukceh_time_stream-4.0.0/docs/source/_templates/autosummary/attribute.rst +7 -0
- ukceh_time_stream-4.0.0/docs/source/_templates/autosummary/method.rst +7 -0
- ukceh_time_stream-4.0.0/docs/source/_templates/autosummary/property.rst +7 -0
- ukceh_time_stream-4.0.0/docs/source/_templates/partials/nav-socials.html +10 -0
- ukceh_time_stream-4.0.0/docs/source/api/aggregation.rst +38 -0
- ukceh_time_stream-4.0.0/docs/source/api/infilling.rst +35 -0
- ukceh_time_stream-4.0.0/docs/source/api/quality_control.rst +32 -0
- ukceh_time_stream-4.0.0/docs/source/api/time_frame.rst +89 -0
- ukceh_time_stream-4.0.0/docs/source/conf.py +123 -0
- ukceh_time_stream-4.0.0/docs/source/developer/contributing.rst +137 -0
- ukceh_time_stream-4.0.0/docs/source/developer/documentation.rst +130 -0
- ukceh_time_stream-4.0.0/docs/source/examples/__init__.py +0 -0
- ukceh_time_stream-4.0.0/docs/source/examples/aggregation.py +186 -0
- ukceh_time_stream-4.0.0/docs/source/examples/flagging.py +266 -0
- ukceh_time_stream-4.0.0/docs/source/examples/helpers.py +27 -0
- ukceh_time_stream-4.0.0/docs/source/examples/infilling.py +269 -0
- ukceh_time_stream-4.0.0/docs/source/examples/irregular.py +96 -0
- ukceh_time_stream-4.0.0/docs/source/examples/quality_control.py +186 -0
- ukceh_time_stream-4.0.0/docs/source/examples/rolling_aggregation.py +41 -0
- ukceh_time_stream-4.0.0/docs/source/examples/time_of_year_aggregation.py +59 -0
- ukceh_time_stream-4.0.0/docs/source/examples/timeseries_basics.py +273 -0
- ukceh_time_stream-4.0.0/docs/source/getting_started/concepts.rst +319 -0
- ukceh_time_stream-4.0.0/docs/source/getting_started/installation.rst +46 -0
- ukceh_time_stream-4.0.0/docs/source/getting_started/quick-start.rst +390 -0
- ukceh_time_stream-4.0.0/docs/source/index.rst +139 -0
- ukceh_time_stream-4.0.0/docs/source/user_guide/aggregation.rst +484 -0
- ukceh_time_stream-4.0.0/docs/source/user_guide/flagging.rst +538 -0
- ukceh_time_stream-4.0.0/docs/source/user_guide/infilling.rst +568 -0
- ukceh_time_stream-4.0.0/docs/source/user_guide/intro.rst +12 -0
- ukceh_time_stream-4.0.0/docs/source/user_guide/irregular.rst +161 -0
- ukceh_time_stream-4.0.0/docs/source/user_guide/quality_control.rst +330 -0
- ukceh_time_stream-4.0.0/docs/source/user_guide/rolling_aggregation.rst +224 -0
- ukceh_time_stream-4.0.0/docs/source/user_guide/time_of_year_aggregation.rst +148 -0
- ukceh_time_stream-4.0.0/pyproject.toml +171 -0
- ukceh_time_stream-4.0.0/scripts/bump.py +73 -0
- ukceh_time_stream-4.0.0/scripts/release.py +98 -0
- ukceh_time_stream-4.0.0/src/time_stream/__init__.py +32 -0
- ukceh_time_stream-4.0.0/src/time_stream/aggregation.py +1166 -0
- ukceh_time_stream-4.0.0/src/time_stream/base.py +1168 -0
- ukceh_time_stream-4.0.0/src/time_stream/exceptions.py +177 -0
- ukceh_time_stream-4.0.0/src/time_stream/flags/bitwise_flag_system.py +162 -0
- ukceh_time_stream-4.0.0/src/time_stream/flags/categorical_flag_system.py +213 -0
- ukceh_time_stream-4.0.0/src/time_stream/flags/flag_manager.py +899 -0
- ukceh_time_stream-4.0.0/src/time_stream/flags/flag_system.py +148 -0
- ukceh_time_stream-4.0.0/src/time_stream/formatting.py +243 -0
- ukceh_time_stream-4.0.0/src/time_stream/infill.py +908 -0
- ukceh_time_stream-4.0.0/src/time_stream/metadata.py +99 -0
- ukceh_time_stream-4.0.0/src/time_stream/operation.py +111 -0
- ukceh_time_stream-4.0.0/src/time_stream/py.typed +0 -0
- ukceh_time_stream-4.0.0/src/time_stream/qc.py +387 -0
- ukceh_time_stream-4.0.0/src/time_stream/time_manager.py +444 -0
- ukceh_time_stream-4.0.0/src/time_stream/types.py +19 -0
- ukceh_time_stream-4.0.0/src/time_stream/utils.py +566 -0
- ukceh_time_stream-4.0.0/tests/__init__.py +0 -0
- ukceh_time_stream-4.0.0/tests/time_stream/__init__.py +0 -0
- ukceh_time_stream-4.0.0/tests/time_stream/examples/test_examples.py +52 -0
- ukceh_time_stream-4.0.0/tests/time_stream/flags/test_bitwise_flag.py +561 -0
- ukceh_time_stream-4.0.0/tests/time_stream/flags/test_categorical_flag.py +599 -0
- ukceh_time_stream-4.0.0/tests/time_stream/flags/test_flag_manager.py +474 -0
- ukceh_time_stream-4.0.0/tests/time_stream/flags/test_flag_system.py +24 -0
- ukceh_time_stream-4.0.0/tests/time_stream/test_aggregation.py +3716 -0
- ukceh_time_stream-4.0.0/tests/time_stream/test_base.py +1727 -0
- ukceh_time_stream-4.0.0/tests/time_stream/test_formatting.py +444 -0
- ukceh_time_stream-4.0.0/tests/time_stream/test_infill.py +963 -0
- ukceh_time_stream-4.0.0/tests/time_stream/test_qc.py +1195 -0
- ukceh_time_stream-4.0.0/tests/time_stream/test_time_manager.py +1034 -0
- ukceh_time_stream-4.0.0/tests/time_stream/test_utils.py +2432 -0
- ukceh_time_stream-4.0.0/uv.lock +2719 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# https://editorconfig.org
|
|
2
|
+
root = true
|
|
3
|
+
|
|
4
|
+
[*]
|
|
5
|
+
charset = utf-8
|
|
6
|
+
end_of_line = lf
|
|
7
|
+
indent_style = space
|
|
8
|
+
indent_size = 4
|
|
9
|
+
trim_trailing_whitespace = true
|
|
10
|
+
insert_final_newline = true
|
|
11
|
+
|
|
12
|
+
[*.{html,css,js,json,sh,yml,yaml}]
|
|
13
|
+
indent_size = 2
|
|
14
|
+
|
|
15
|
+
[*.bat]
|
|
16
|
+
indent_style = tab
|
|
17
|
+
end_of_line = crlf
|
|
18
|
+
|
|
19
|
+
[LICENSE]
|
|
20
|
+
insert_final_newline = false
|
|
21
|
+
|
|
22
|
+
# Ignore binary or generated files
|
|
23
|
+
[*.{png,jpg,gif,ico,woff,woff2,ttf,eot,svg,pdf}]
|
|
24
|
+
charset = unset
|
|
25
|
+
end_of_line = unset
|
|
26
|
+
indent_style = unset
|
|
27
|
+
indent_size = unset
|
|
28
|
+
trim_trailing_whitespace = unset
|
|
29
|
+
insert_final_newline = unset
|
|
30
|
+
max_line_length = unset
|
|
31
|
+
|
|
32
|
+
[*.{diff,patch}]
|
|
33
|
+
trim_trailing_whitespace = false
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
#
|
|
3
|
+
# Pre-commit hook: runs ruff format and lint checks via uv.
|
|
4
|
+
# Requires uv on PATH: https://docs.astral.sh/uv/getting-started/installation/
|
|
5
|
+
#
|
|
6
|
+
# Installed automatically by post-generation hook via:
|
|
7
|
+
# git config core.hooksPath .githooks
|
|
8
|
+
#
|
|
9
|
+
# To install manually in an existing clone:
|
|
10
|
+
# make install-hooks
|
|
11
|
+
|
|
12
|
+
# Redirect output to stderr.
|
|
13
|
+
exec 1>&2
|
|
14
|
+
|
|
15
|
+
RED='\033[0;31m'
|
|
16
|
+
NC='\033[0m' # No Color
|
|
17
|
+
format_err=0
|
|
18
|
+
check_err=0
|
|
19
|
+
err=0
|
|
20
|
+
|
|
21
|
+
echo 'Running "uv run ruff format --check"'
|
|
22
|
+
uv run ruff format --check
|
|
23
|
+
|
|
24
|
+
if [ "$?" -eq 1 ]; then
|
|
25
|
+
format_err=1
|
|
26
|
+
err=1
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
echo 'Running "uv run ruff check"'
|
|
30
|
+
uv run ruff check
|
|
31
|
+
|
|
32
|
+
if [ "$?" -eq 1 ]; then
|
|
33
|
+
check_err=1
|
|
34
|
+
err=1
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
if [ "${format_err}" -eq 1 ] ; then
|
|
38
|
+
echo "${RED}Run \"ruff format\" before committing${NC}"
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
if [ "${check_err}" -eq 1 ] ; then
|
|
42
|
+
echo "${RED}Correct ruff errors before committing${NC}"
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
if [ "${err}" -eq 1 ] ; then
|
|
46
|
+
exit 1
|
|
47
|
+
fi
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
name: Bug Report
|
|
2
|
+
description: Something isn't working as expected.
|
|
3
|
+
title: "BUG: "
|
|
4
|
+
labels: [bug]
|
|
5
|
+
body:
|
|
6
|
+
- type: textarea
|
|
7
|
+
id: description
|
|
8
|
+
attributes:
|
|
9
|
+
label: Describe the bug
|
|
10
|
+
description: What happened? What did you expect to happen?
|
|
11
|
+
validations:
|
|
12
|
+
required: true
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: steps
|
|
15
|
+
attributes:
|
|
16
|
+
label: Steps to reproduce
|
|
17
|
+
description: Minimal steps to trigger the bug.
|
|
18
|
+
placeholder: |
|
|
19
|
+
1. Install with `uv pip install ukceh-time-stream`
|
|
20
|
+
2. Run `...`
|
|
21
|
+
3. See error
|
|
22
|
+
validations:
|
|
23
|
+
required: true
|
|
24
|
+
- type: textarea
|
|
25
|
+
id: expected
|
|
26
|
+
attributes:
|
|
27
|
+
label: Expected behavior
|
|
28
|
+
validations:
|
|
29
|
+
required: true
|
|
30
|
+
- type: input
|
|
31
|
+
id: version
|
|
32
|
+
attributes:
|
|
33
|
+
label: "My Package version"
|
|
34
|
+
placeholder: "0.1.0"
|
|
35
|
+
validations:
|
|
36
|
+
required: true
|
|
37
|
+
- type: input
|
|
38
|
+
id: python-version
|
|
39
|
+
attributes:
|
|
40
|
+
label: Python version
|
|
41
|
+
placeholder: "3.13"
|
|
42
|
+
validations:
|
|
43
|
+
required: true
|
|
44
|
+
- type: dropdown
|
|
45
|
+
id: os
|
|
46
|
+
attributes:
|
|
47
|
+
label: Operating system
|
|
48
|
+
options:
|
|
49
|
+
- macOS
|
|
50
|
+
- Linux
|
|
51
|
+
- Windows
|
|
52
|
+
- Other
|
|
53
|
+
validations:
|
|
54
|
+
required: true
|
|
55
|
+
- type: textarea
|
|
56
|
+
id: context
|
|
57
|
+
attributes:
|
|
58
|
+
label: Additional context
|
|
59
|
+
description: Logs, tracebacks, screenshots, or anything else that helps.
|
|
60
|
+
validations:
|
|
61
|
+
required: false
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
blank_issues_enabled: true
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Feature Request
|
|
2
|
+
description: Suggest something new.
|
|
3
|
+
title: "FEAT: "
|
|
4
|
+
labels: [enhancement]
|
|
5
|
+
body:
|
|
6
|
+
- type: textarea
|
|
7
|
+
id: description
|
|
8
|
+
attributes:
|
|
9
|
+
label: Describe the feature
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: motivation
|
|
14
|
+
attributes:
|
|
15
|
+
label: Motivation
|
|
16
|
+
description: What problem does this solve? What's the use case?
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: alternatives
|
|
21
|
+
attributes:
|
|
22
|
+
label: Alternatives considered
|
|
23
|
+
validations:
|
|
24
|
+
required: false
|
|
25
|
+
- type: textarea
|
|
26
|
+
id: context
|
|
27
|
+
attributes:
|
|
28
|
+
label: Additional context
|
|
29
|
+
validations:
|
|
30
|
+
required: false
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: github-actions
|
|
4
|
+
directory: /
|
|
5
|
+
schedule:
|
|
6
|
+
interval: weekly
|
|
7
|
+
cooldown:
|
|
8
|
+
default-days: 7
|
|
9
|
+
open-pull-requests-limit: 5
|
|
10
|
+
groups:
|
|
11
|
+
all-actions:
|
|
12
|
+
patterns:
|
|
13
|
+
- "*"
|
|
14
|
+
|
|
15
|
+
- package-ecosystem: uv
|
|
16
|
+
directory: /
|
|
17
|
+
schedule:
|
|
18
|
+
interval: weekly
|
|
19
|
+
open-pull-requests-limit: 5
|
|
20
|
+
groups:
|
|
21
|
+
all-dependencies:
|
|
22
|
+
patterns:
|
|
23
|
+
- "*"
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
name: Pipeline
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
- develop
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
actions: read
|
|
14
|
+
|
|
15
|
+
pages: write
|
|
16
|
+
id-token: write
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
|
|
21
|
+
test-python:
|
|
22
|
+
uses: NERC-CEH/dri-cicd/.github/workflows/test-python.yml@main
|
|
23
|
+
with:
|
|
24
|
+
use_uv: true
|
|
25
|
+
use_pyright: true
|
|
26
|
+
coverage_threshold: 90
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
build-docs:
|
|
30
|
+
uses: NERC-CEH/dri-cicd/.github/workflows/build-docs.yml@main
|
|
31
|
+
with:
|
|
32
|
+
use_uv: true
|
|
33
|
+
pages_artifact_name: pages-artifact
|
|
34
|
+
|
|
35
|
+
deploy-docs:
|
|
36
|
+
needs: [build-docs]
|
|
37
|
+
if: github.ref == 'refs/heads/main'
|
|
38
|
+
uses: NERC-CEH/dri-cicd/.github/workflows/deploy-docs.yml@main
|
|
39
|
+
with:
|
|
40
|
+
pages_artifact_name: pages-artifact
|
|
41
|
+
|
|
42
|
+
release-ready:
|
|
43
|
+
if: github.event_name == 'pull_request' && github.base_ref == 'main'
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/checkout@v7.0.1
|
|
47
|
+
with:
|
|
48
|
+
fetch-depth: 0
|
|
49
|
+
|
|
50
|
+
- name: Check version bump and changelog
|
|
51
|
+
run: |
|
|
52
|
+
BASE_VER=$(git show origin/main:pyproject.toml | grep '^version' | sed 's/.*"\(.*\)"/\1/')
|
|
53
|
+
NEW_VER=$(grep '^version' pyproject.toml | sed 's/.*"\(.*\)"/\1/')
|
|
54
|
+
|
|
55
|
+
if [ "$BASE_VER" = "$NEW_VER" ]; then
|
|
56
|
+
echo "ERROR: merges to main require a version bump (current: $NEW_VER)"
|
|
57
|
+
exit 1
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
echo "Version bumped: $BASE_VER -> $NEW_VER"
|
|
61
|
+
|
|
62
|
+
CHANGELOG="CHANGELOG/${NEW_VER}.md"
|
|
63
|
+
|
|
64
|
+
if [ ! -f "$CHANGELOG" ]; then
|
|
65
|
+
echo "ERROR: $CHANGELOG not found"
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
if grep -q "<!-- Add release notes here -->" "$CHANGELOG"; then
|
|
70
|
+
echo "ERROR: $CHANGELOG still contains the stub placeholder"
|
|
71
|
+
exit 1
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
LINES=$(tail -n +2 "$CHANGELOG" | grep -vc '^$')
|
|
75
|
+
if [ "$LINES" -eq 0 ]; then
|
|
76
|
+
echo "ERROR: $CHANGELOG has no content beyond the heading"
|
|
77
|
+
exit 1
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
echo "Changelog looks good"
|
|
81
|
+
|
|
82
|
+
release:
|
|
83
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
84
|
+
needs: [test-python]
|
|
85
|
+
runs-on: ubuntu-latest
|
|
86
|
+
permissions:
|
|
87
|
+
contents: write
|
|
88
|
+
outputs:
|
|
89
|
+
released: ${{ steps.release.outputs.released }}
|
|
90
|
+
steps:
|
|
91
|
+
- uses: actions/checkout@v7.0.1
|
|
92
|
+
|
|
93
|
+
- uses: astral-sh/setup-uv@v10.3.0
|
|
94
|
+
|
|
95
|
+
- name: Configure git identity
|
|
96
|
+
run: |
|
|
97
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
98
|
+
git config user.name "github-actions[bot]"
|
|
99
|
+
|
|
100
|
+
- name: Release
|
|
101
|
+
id: release
|
|
102
|
+
env:
|
|
103
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
104
|
+
run: |
|
|
105
|
+
VERSION=$(grep '^version' pyproject.toml | sed 's/.*"\(.*\)"/\1/')
|
|
106
|
+
if git ls-remote --tags origin | grep -q "refs/tags/v$VERSION$"; then
|
|
107
|
+
echo "Tag v$VERSION already exists — skipping release"
|
|
108
|
+
exit 0
|
|
109
|
+
fi
|
|
110
|
+
make release
|
|
111
|
+
echo "released=true" >> "$GITHUB_OUTPUT"
|
|
112
|
+
|
|
113
|
+
build-dist:
|
|
114
|
+
needs: [release]
|
|
115
|
+
if: needs.release.outputs.released == 'true'
|
|
116
|
+
runs-on: ubuntu-latest
|
|
117
|
+
permissions:
|
|
118
|
+
contents: read
|
|
119
|
+
steps:
|
|
120
|
+
- uses: actions/checkout@v7.0.1
|
|
121
|
+
with:
|
|
122
|
+
persist-credentials: false
|
|
123
|
+
|
|
124
|
+
- uses: astral-sh/setup-uv@v10.3.0
|
|
125
|
+
with:
|
|
126
|
+
enable-cache: false
|
|
127
|
+
|
|
128
|
+
- name: Build
|
|
129
|
+
run: uv build
|
|
130
|
+
|
|
131
|
+
- uses: actions/upload-artifact@v7
|
|
132
|
+
with:
|
|
133
|
+
name: dist
|
|
134
|
+
path: dist/
|
|
135
|
+
|
|
136
|
+
publish-pypi:
|
|
137
|
+
needs: [build-dist]
|
|
138
|
+
runs-on: ubuntu-latest
|
|
139
|
+
permissions:
|
|
140
|
+
id-token: write
|
|
141
|
+
environment:
|
|
142
|
+
name: pypi
|
|
143
|
+
url: https://pypi.org/p/ukceh-time-stream
|
|
144
|
+
steps:
|
|
145
|
+
- uses: actions/download-artifact@v8
|
|
146
|
+
with:
|
|
147
|
+
name: dist
|
|
148
|
+
path: dist/
|
|
149
|
+
|
|
150
|
+
- name: Publish to PyPI
|
|
151
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py,cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
.benchmarks/
|
|
54
|
+
benchmark*.svg
|
|
55
|
+
|
|
56
|
+
# Translations
|
|
57
|
+
*.mo
|
|
58
|
+
*.pot
|
|
59
|
+
|
|
60
|
+
# Django stuff:
|
|
61
|
+
*.log
|
|
62
|
+
local_settings.py
|
|
63
|
+
db.sqlite3
|
|
64
|
+
db.sqlite3-journal
|
|
65
|
+
|
|
66
|
+
# Flask stuff:
|
|
67
|
+
instance/
|
|
68
|
+
.webassets-cache
|
|
69
|
+
|
|
70
|
+
# Scrapy stuff:
|
|
71
|
+
.scrapy
|
|
72
|
+
|
|
73
|
+
# Sphinx documentation
|
|
74
|
+
docs/_build/
|
|
75
|
+
# Using the plot directive from code in src/examples will copy outputs to docs/src/examples. No need to commit this.
|
|
76
|
+
docs/src
|
|
77
|
+
docs/source/api/_api/
|
|
78
|
+
|
|
79
|
+
# PyBuilder
|
|
80
|
+
.pybuilder/
|
|
81
|
+
target/
|
|
82
|
+
|
|
83
|
+
# Jupyter Notebook
|
|
84
|
+
.ipynb_checkpoints
|
|
85
|
+
|
|
86
|
+
# IPython
|
|
87
|
+
profile_default/
|
|
88
|
+
ipython_config.py
|
|
89
|
+
|
|
90
|
+
# pyenv
|
|
91
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
92
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
93
|
+
# .python-version
|
|
94
|
+
|
|
95
|
+
# pipenv
|
|
96
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
97
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
98
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
99
|
+
# install all needed dependencies.
|
|
100
|
+
#Pipfile.lock
|
|
101
|
+
|
|
102
|
+
# poetry
|
|
103
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
104
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
105
|
+
# commonly ignored for libraries.
|
|
106
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
107
|
+
#poetry.lock
|
|
108
|
+
|
|
109
|
+
# pdm
|
|
110
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
111
|
+
#pdm.lock
|
|
112
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
113
|
+
# in version control.
|
|
114
|
+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
|
115
|
+
.pdm.toml
|
|
116
|
+
.pdm-python
|
|
117
|
+
.pdm-build/
|
|
118
|
+
|
|
119
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
120
|
+
__pypackages__/
|
|
121
|
+
|
|
122
|
+
# Celery stuff
|
|
123
|
+
celerybeat-schedule
|
|
124
|
+
celerybeat.pid
|
|
125
|
+
|
|
126
|
+
# SageMath parsed files
|
|
127
|
+
*.sage.py
|
|
128
|
+
|
|
129
|
+
# Environments
|
|
130
|
+
.env
|
|
131
|
+
.venv
|
|
132
|
+
env/
|
|
133
|
+
venv/
|
|
134
|
+
ENV/
|
|
135
|
+
env.bak/
|
|
136
|
+
venv.bak/
|
|
137
|
+
|
|
138
|
+
# Spyder project settings
|
|
139
|
+
.spyderproject
|
|
140
|
+
.spyproject
|
|
141
|
+
|
|
142
|
+
# Rope project settings
|
|
143
|
+
.ropeproject
|
|
144
|
+
|
|
145
|
+
# mkdocs documentation
|
|
146
|
+
/site
|
|
147
|
+
|
|
148
|
+
# mypy
|
|
149
|
+
.mypy_cache/
|
|
150
|
+
.dmypy.json
|
|
151
|
+
dmypy.json
|
|
152
|
+
|
|
153
|
+
# Pyre type checker
|
|
154
|
+
.pyre/
|
|
155
|
+
|
|
156
|
+
# pytype static type analyzer
|
|
157
|
+
.pytype/
|
|
158
|
+
|
|
159
|
+
# Cython debug symbols
|
|
160
|
+
cython_debug/
|
|
161
|
+
|
|
162
|
+
# PyCharm
|
|
163
|
+
.idea/
|
|
164
|
+
|
|
165
|
+
# VSCode
|
|
166
|
+
.vscode
|
|
167
|
+
|
|
168
|
+
CLAUDE.md
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# 1.0.0
|
|
2
|
+
|
|
3
|
+
## 24/06/2026
|
|
4
|
+
|
|
5
|
+
After over a year of active development within UKCEH's FDRI programme, time-stream 1.0.0 marks the first stable,
|
|
6
|
+
versioned public release. The library provides a high-level API for working with environmental time series data
|
|
7
|
+
built on [Polars](https://pola.rs/), with a focus maintaining the integrity of the temporal properties time series data.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
### Core
|
|
12
|
+
|
|
13
|
+
- **`TimeFrame`** - the central data structure wrapping a Polars DataFrame with an associated periodicity and
|
|
14
|
+
time anchor, enforcing a consistent schema for time series operations.
|
|
15
|
+
- **`Period`** - a rich period/frequency abstraction supporting both fixed-duration (sub-daily through multi-year)
|
|
16
|
+
and calendar-aligned (monthly, annual) periods, with ISO 8601 duration support.
|
|
17
|
+
|
|
18
|
+
### Flagging
|
|
19
|
+
|
|
20
|
+
- Bitwise and categorical flag systems for recording QC and processing decisions alongside the data.
|
|
21
|
+
- Flag columns can be attached to any `TimeFrame` column.
|
|
22
|
+
- Support for encoding and decoding flag values, and auto-generation of bitwise flag integers from a list of named
|
|
23
|
+
categories.
|
|
24
|
+
- Filter a `TimeFrame` by flag values to subset data based on QC or processing state.
|
|
25
|
+
|
|
26
|
+
### Aggregation
|
|
27
|
+
|
|
28
|
+
- Standard temporal aggregation via `TimeFrame.aggregate()`, with support for custom time windows, time anchoring,
|
|
29
|
+
and configurable missing-data criteria.
|
|
30
|
+
- Rolling aggregation via `TimeFrame.rolling_aggregate()` with trailing, leading, and centre alignment.
|
|
31
|
+
- Built-in aggregation functions, including: mean, sum, min, max, standard deviation, angular mean, and count.
|
|
32
|
+
|
|
33
|
+
### Quality Control
|
|
34
|
+
|
|
35
|
+
- Extensible QC framework (`QCCheck`) with a registration system allowing custom checks to be defined and reused by
|
|
36
|
+
name.
|
|
37
|
+
- Built-in checks, including: range, flatline, and spike detection.
|
|
38
|
+
- QC results returned as a Polars `Series` or written directly into a flag column on the `TimeFrame`.
|
|
39
|
+
|
|
40
|
+
### Infilling
|
|
41
|
+
|
|
42
|
+
- Infill framework (`InfillMethod`) for filling gaps in time series, with a registration system for custom methods.
|
|
43
|
+
- Built-in interpolation methods, including: linear, quadratic, cubic, B-spline, Akima, and PCHIP.
|
|
44
|
+
- Alternative-data infill from a secondary column or DataFrame, with an optional correction factor.
|
|
45
|
+
- Configurable maximum gap size and observation interval constraints to limit where infilling is applied.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# 1.1.0
|
|
2
|
+
|
|
3
|
+
This release adds a new dynamic alternative-data infilling method, a helper for renaming the time column, and
|
|
4
|
+
simplifies the public API by replacing enums with string literals. It also includes routine dependency updates.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
|
|
8
|
+
### Infilling
|
|
9
|
+
|
|
10
|
+
- **`AltDataDynamic`** - a new alternative-data infill method that derives a *dynamic* correction factor from data
|
|
11
|
+
windows either side of each gap, rather than a single static factor.
|
|
12
|
+
|
|
13
|
+
### Core
|
|
14
|
+
|
|
15
|
+
- **`TimeFrame.rename_time_column()`** - rename the time column on a `TimeFrame` while preserving its temporal
|
|
16
|
+
properties.
|
|
17
|
+
|
|
18
|
+
## Changes
|
|
19
|
+
|
|
20
|
+
- Public API enums (e.g. time anchor, closed interval, missing criteria, duplicate options, alignment) have been
|
|
21
|
+
replaced by `Literal[...]` string values, simplifying usage.
|
|
22
|
+
|
|
23
|
+
## Maintenance
|
|
24
|
+
|
|
25
|
+
- Added automated `uv` dependency updates via Dependabot.
|
|
26
|
+
- Numerous dependency bumps across the project and documentation.
|
|
27
|
+
- Resolved deprecation warnings in Sphinx documentation builds and fixed pyright type-checking issues following
|
|
28
|
+
dependency updates.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# 1.1.1
|
|
2
|
+
|
|
3
|
+
This release fixes incorrect type hints on the `missing_criteria` parameter.
|
|
4
|
+
|
|
5
|
+
## Bug fixes
|
|
6
|
+
|
|
7
|
+
- **`missing_criteria` type hints** - the first element of the `missing_criteria` tuple in `TimeFrame.aggregate()`,
|
|
8
|
+
`TimeFrame.rolling_aggregate()`, and the internal pipeline classes (`AggregationPipeline`,
|
|
9
|
+
`StandardAggregationPipeline`, `RollingAggregationPipeline`) was incorrectly typed as `str`. It is now correctly typed
|
|
10
|
+
as `MissingCriteria`.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# 1.2.0
|
|
2
|
+
|
|
3
|
+
This release adds a new `nth` aggregation method for selecting a value at a fixed position within an aggregation
|
|
4
|
+
period or rolling window. It also includes a code fix for deprecation warnings raised by updated dependencies,
|
|
5
|
+
alongside routine dependency updates.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
### Aggregation
|
|
10
|
+
|
|
11
|
+
- **`Nth`** - a new aggregation function that selects the value (and its timestamp) at a fixed 1-based position
|
|
12
|
+
within each aggregation period, e.g. always taking the reading at a particular time of day. Also usable with
|
|
13
|
+
`TimeFrame.rolling_aggregate()` to pull a value from a fixed position relative to each timestamp.
|
|
14
|
+
|
|
15
|
+
## Maintenance
|
|
16
|
+
|
|
17
|
+
- Updated code in the flags and infill modules to resolve deprecation warnings raised by updated dependencies.
|
|
18
|
+
- Added automated `uv` dependency updates via Dependabot.
|
|
19
|
+
- Numerous dependency and GitHub Actions bumps across the project.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# 1.2.1
|
|
2
|
+
|
|
3
|
+
This is a small release with a documentation branding update and routine dependency updates.
|
|
4
|
+
|
|
5
|
+
## Maintenance
|
|
6
|
+
|
|
7
|
+
- Updated the UKCEH logo and related branding assets used in the documentation site.
|
|
8
|
+
- Bumped `uv` dependencies and GitHub Actions across the project.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# 2.0.0
|
|
2
|
+
|
|
3
|
+
This release extracts the period/frequency handling into a standalone package, [`isoperiod`](https://github.com/NERC-CEH/isoperiod),
|
|
4
|
+
and Time-Stream now depends on it rather than shipping its own `Period` implementation. This removes `Period`
|
|
5
|
+
from the `time_stream` namespace and tightens the accepted duration/offset string syntax, so it is a breaking
|
|
6
|
+
release. Runtime dependencies have also been trimmed to just Polars, NumPy, SciPy, and `isoperiod`.
|
|
7
|
+
|
|
8
|
+
## Breaking changes
|
|
9
|
+
|
|
10
|
+
### Period moved to `isoperiod`
|
|
11
|
+
|
|
12
|
+
- The `Period` class and all period parsing/arithmetic have been removed from Time-Stream and are now provided
|
|
13
|
+
by the separate `isoperiod` package. Replace `from time_stream import Period` with `from isoperiod import Period`.
|
|
14
|
+
- `TimeFrame.resolution`, `TimeFrame.alignment` and `TimeFrame.periodicity` now return `isoperiod.Period`
|
|
15
|
+
objects. The public behaviour is the same; only the import path of the type has changed.
|
|
16
|
+
- The period exceptions have been removed from `time_stream.exceptions`: `PeriodError`, `PeriodParsingError`
|
|
17
|
+
and `PeriodValidationError` now live in `isoperiod.exceptions` (and re-exported from `isoperiod`).
|
|
18
|
+
`PeriodConfigError` has been removed entirely.
|
|
19
|
+
|
|
20
|
+
### Duration and offset string syntax
|
|
21
|
+
|
|
22
|
+
- Time components in a duration or offset string must now be preceded by `T`, following ISO 8601 strictly.
|
|
23
|
+
`TimeFrame(df, "time", resolution="P1D", offset="+9H")` must become `offset="+T9H"`; `"P1Y+9M9H"` must become
|
|
24
|
+
`"P1Y+9MT9H"`. Strings that only use date components (e.g. `"+9M"`) are unaffected.
|
|
25
|
+
- `Period.count()` now returns `int | None` (`None` when there is no fixed count, e.g. days in a month) instead
|
|
26
|
+
of `0`. Code that compared the result with `> 0` should check `is not None` first.
|
|
27
|
+
|
|
28
|
+
### Dependencies
|
|
29
|
+
|
|
30
|
+
- Removed unused runtime dependencies: `config`, `pydantic`, `isodate` and `altair`.
|
|
31
|
+
- `pandas`, `matplotlib` and `pyarrow` are no longer runtime dependencies. They are only used by the
|
|
32
|
+
documentation examples and are now in the `examples` dependency group. Installing `time-stream` no longer pulls
|
|
33
|
+
them in transitively.
|
|
34
|
+
|
|
35
|
+
## Changes
|
|
36
|
+
|
|
37
|
+
- API reference docstrings now contain runnable, checked examples (`>>>` doctests) in place of illustrative
|
|
38
|
+
snippets.
|
|
39
|
+
|
|
40
|
+
## Maintenance
|
|
41
|
+
|
|
42
|
+
- The user guide's example code has moved from `src/time_stream/examples/` to `docs/source/examples/`, so it is
|
|
43
|
+
no longer shipped in the wheel. Examples are executed as part of the test suite
|
|
44
|
+
- (`tests/time_stream/examples/test_examples.py`) and the docstring examples run under pytest's `--doctest-modules`.
|
|
45
|
+
- Fixed several stale period strings and a typo in the `TimeFrame` docstring examples.
|
|
46
|
+
- Numerous dependency and GitHub Actions bumps across the project.
|