Skip to content
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
13 changes: 11 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ jobs:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.14"
platform:
- ubuntu-latest
- macos-latest
Expand Down Expand Up @@ -82,16 +84,23 @@ jobs:

test-s2:
needs: check
strategy:
fail-fast: false
matrix:
python:
# Oldest and newest supported Python; 3.14 is what Home Assistant runs on.
- "3.10"
- "3.14"
runs-on: ubuntu-latest
name: "Test S2 (on Python 3.12)"
name: "Test S2 (on Python ${{ matrix.python }})"
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
version: "0.10.9"
python-version-file: ".python-version"
python-version: ${{ matrix.python }}
- name: Install dependencies
run: uv sync --frozen --extra s2 --group test
- name: Run S2 tests
Expand Down
20 changes: 12 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build-backend = "hatchling.build"
name = "flexmeasures-client"
description = "Async client to connect to the FlexMeasures API"
readme = "README.rst"
requires-python = ">=3.10, <3.13"
requires-python = ">=3.10"
license = "Apache-2.0"
license-files = ["LICENSE"]
authors = [
Expand All @@ -20,15 +20,19 @@ classifiers = [
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dynamic = ["version"]
# Keep the floors below permissive: Home Assistant pins these packages to
# exact versions (homeassistant/package_constraints.txt), so every floor we
# raise here shrinks the range of HA versions the FlexMeasures HA integration
# can be installed on. E.g. HA 2026.7 pins async-timeout==4.0.3.
dependencies = [
"aiohttp>=3.13.3",
"aiohttp>=3.8.1",
"pandas>=2.1.4",
"async-timeout>=5.0.1",
"packaging>=26.0",
# Below: minimum requirements solely here for security reasons
"urllib3>=2.7.0", # https://github.com/FlexMeasures/flexmeasures-client/security/dependabot/16
"async-timeout>=4.0.1",
"packaging>=23.1",
]

[project.urls]
Expand All @@ -38,10 +42,10 @@ Documentation = "https://flexmeasures-client.readthedocs.io/"

[project.optional-dependencies]
s2 = [
"requests>=2.32.5",
"requests>=2.31.0",
"s2-python>=0.8.1",
"semver>=3.0.4",
"tzdata>=2025.3",
"tzdata>=2023.3",
]

[dependency-groups]
Expand Down
16 changes: 15 additions & 1 deletion tests/client/test_sensor.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from __future__ import annotations

import os
import re
from unittest.mock import patch
from urllib.parse import unquote

import pandas as pd
import pytest
from aioresponses import aioresponses

Expand Down Expand Up @@ -559,7 +562,7 @@ async def test_get_sensor_data() -> None:

sensor_id = 2
m.get(
f"http://localhost:5000/api/v3_0/sensors/{sensor_id}/data?duration=P0DT0H45M0S&resolution=P0DT0H15M0S&start=2023-06-01T10%253A00%253A00%252B02%253A00&unit=MW", # noqa: E501
re.compile(rf"http://localhost:5000/api/v3_0/sensors/{sensor_id}/data\?.*"),
status=200,
payload={
"duration": "PT45M",
Expand All @@ -585,6 +588,17 @@ async def test_get_sensor_data() -> None:
resolution=resolution,
)
assert sensor_data["values"] == [8.5, 8.5, 8.5]

# Check the requested query params. Durations are compared as
# timedeltas, because pandas renders "PT45M" as "P0DT0H45M0S" on
# some versions, and both are valid ISO 8601. The start param is
# unquoted first, because yarl versions differ in requote behavior.
((request_key, _),) = m.requests.items()
query = request_key[1].query
assert pd.Timedelta(query["duration"]) == pd.Timedelta(duration)
assert pd.Timedelta(query["resolution"]) == pd.Timedelta(resolution)
assert unquote(query["start"]) == start
assert query["unit"] == unit
await flexmeasures_client.close()


Expand Down
Loading
Loading