Hydro-Quebec-API-Wrapper 4.0.0__tar.gz → 4.2.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.
Files changed (108) hide show
  1. hydro_quebec_api_wrapper-4.2.0/.devcontainer/Dockerfile +11 -0
  2. hydro_quebec_api_wrapper-4.2.0/.devcontainer/devcontainer.json +20 -0
  3. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/.gitlab-ci.yml +8 -5
  4. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/.pre-commit-config.yaml +12 -12
  5. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/Hydro_Quebec_API_Wrapper.egg-info/PKG-INFO +6 -5
  6. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/Hydro_Quebec_API_Wrapper.egg-info/SOURCES.txt +1 -0
  7. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/Hydro_Quebec_API_Wrapper.egg-info/requires.txt +2 -2
  8. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/PKG-INFO +6 -5
  9. hydro_quebec_api_wrapper-4.2.0/conflict_test_requirements.txt +1 -0
  10. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/account.py +1 -0
  11. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/contract/common.py +25 -19
  12. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/contract/contract_d.py +5 -4
  13. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/contract/contract_d_cpc.py +8 -7
  14. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/contract/contract_dpc.py +71 -22
  15. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/contract/contract_dt.py +5 -4
  16. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/contract/contract_m.py +15 -14
  17. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/contract/contract_m_gdp.py +5 -4
  18. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/contract/contract_residential.py +10 -9
  19. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/customer.py +9 -8
  20. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/hydro_api/client.py +34 -6
  21. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/hydro_api/consts.py +2 -2
  22. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/peak/basepeakhandler.py +1 -0
  23. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/peak/cpc/consts.py +5 -3
  24. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/peak/cpc/handler.py +4 -3
  25. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/peak/cpc/peak.py +22 -5
  26. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/peak/dpc/consts.py +1 -3
  27. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/peak/dpc/handler.py +4 -3
  28. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/public_client.py +11 -2
  29. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/types/__init__.py +2 -2
  30. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/types/common.py +6 -6
  31. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/types/consump.py +0 -17
  32. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/types/dpc.py +27 -10
  33. hydro_quebec_api_wrapper-4.2.0/hydroqc/types/dt.py +25 -0
  34. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/webuser.py +5 -4
  35. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/pyproject.toml +4 -4
  36. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/setup.cfg +2 -2
  37. hydro_quebec_api_wrapper-4.2.0/test_requirements.txt +14 -0
  38. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/tests/subtest_common.py +7 -1
  39. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/tests/subtest_contract_dpc.py +2 -1
  40. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/tox.ini +1 -1
  41. hydro_quebec_api_wrapper-4.0.0/.devcontainer/devcontainer.json +0 -10
  42. hydro_quebec_api_wrapper-4.0.0/conflict_test_requirements.txt +0 -1
  43. hydro_quebec_api_wrapper-4.0.0/hydroqc/types/dt.py +0 -15
  44. hydro_quebec_api_wrapper-4.0.0/test_requirements.txt +0 -14
  45. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/.coveragerc +0 -0
  46. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/.flake8 +0 -0
  47. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/.gitignore +0 -0
  48. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/.pylintrc +0 -0
  49. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/Hydro_Quebec_API_Wrapper.egg-info/dependency_links.txt +0 -0
  50. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/Hydro_Quebec_API_Wrapper.egg-info/entry_points.txt +0 -0
  51. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/Hydro_Quebec_API_Wrapper.egg-info/top_level.txt +0 -0
  52. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/LICENSE +0 -0
  53. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/MANIFEST.in +0 -0
  54. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/README.md +0 -0
  55. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/config.default.yaml +0 -0
  56. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/Makefile +0 -0
  57. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/make.bat +0 -0
  58. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/source/_static/custom.css +0 -0
  59. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/source/_static/hydroqc-logo-128.png +0 -0
  60. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/source/_static/hydroqc-logo.svg +0 -0
  61. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/source/conf.py +0 -0
  62. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/source/external/description-des-codes-interruption.pdf +0 -0
  63. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/source/index.rst +0 -0
  64. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/source/reference/hydroqc.contract.rst +0 -0
  65. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/source/reference/hydroqc.hydro_api.rst +0 -0
  66. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/source/reference/hydroqc.peak.cpc.rst +0 -0
  67. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/source/reference/hydroqc.peak.dpc.rst +0 -0
  68. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/source/reference/hydroqc.peak.rst +0 -0
  69. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/source/reference/hydroqc.rst +0 -0
  70. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/source/reference/hydroqc.types.rst +0 -0
  71. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/source/reference/modules.rst +0 -0
  72. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/docs/source/todo.rst +0 -0
  73. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/examples/hydro.py +0 -0
  74. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/__init__.py +0 -0
  75. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/consts.py +0 -0
  76. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/contract/__init__.py +0 -0
  77. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/contract/outage.py +0 -0
  78. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/diagnostic.py +0 -0
  79. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/error.py +0 -0
  80. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/hydro_api/__init__.py +0 -0
  81. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/hydro_api/cache.py +0 -0
  82. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/logger.py +0 -0
  83. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/peak/__init__.py +0 -0
  84. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/peak/basepeak.py +0 -0
  85. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/peak/consts.py +0 -0
  86. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/peak/cpc/__init__.py +0 -0
  87. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/peak/dpc/__init__.py +0 -0
  88. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/peak/dpc/peak.py +0 -0
  89. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/py.typed +0 -0
  90. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/timerange.py +0 -0
  91. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/types/account.py +0 -0
  92. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/types/contract.py +0 -0
  93. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/types/cpc.py +0 -0
  94. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/types/outage.py +0 -0
  95. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/hydroqc/utils.py +0 -0
  96. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/logo/hydroqc-logo-128.png +0 -0
  97. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/logo/hydroqc-logo.svg +0 -0
  98. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/renovate.json5 +0 -0
  99. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/tests/__init__.py +0 -0
  100. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/tests/conftest.py +0 -0
  101. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/tests/subtest_contract_d.py +0 -0
  102. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/tests/subtest_contract_d_cpc.py +0 -0
  103. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/tests/subtest_contract_dt.py +0 -0
  104. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/tests/subtest_contract_m.py +0 -0
  105. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/tests/subtest_contract_m_gdp.py +0 -0
  106. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/tests/test_basic.py +0 -0
  107. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/tests/test_timerange.py +0 -0
  108. {hydro_quebec_api_wrapper-4.0.0 → hydro_quebec_api_wrapper-4.2.0}/tests/tools.py +0 -0
@@ -0,0 +1,11 @@
1
+ FROM registry.gitlab.com/hydroqc/hydroqc-base-container/3.13:latest
2
+
3
+ # Create devcontainer user with home directory and bash shell, install sudo, and configure passwordless sudo
4
+ RUN useradd -m -s /bin/bash devcontainer \
5
+ && apt-get update && apt-get install -y sudo gnulib locales \
6
+ && echo "devcontainer ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/devcontainer
7
+
8
+ WORKDIR /home/devcontainer
9
+ USER devcontainer
10
+ RUN mkdir -p /home/devcontainer/.local/bin \
11
+ && export PATH=$PATH:/home/devcontainer/.local/bin
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "hydroqc",
3
+ "build": {
4
+ "dockerfile": "Dockerfile"
5
+ },
6
+ "features": {
7
+ "ghcr.io/devcontainers/features/docker-in-docker:2": {},
8
+ "ghcr.io/msclock/features/gitlab-ci-local:0": {
9
+ "version": "latest"
10
+ }
11
+ },
12
+ "customizations": {
13
+ "vscode": {
14
+ "extensions": [
15
+ "GitLab.gitlab-workflow"
16
+ ]
17
+ }
18
+ },
19
+ "remoteUser": "devcontainer"
20
+ }
@@ -31,7 +31,7 @@ test:
31
31
  stage: test
32
32
  tags:
33
33
  - hydroqc
34
- image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.12@sha256:d8985672e512080c541beeab0da37aa166a41b24ab9f0cf86bed4944cd743fae
34
+ image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.13:latest
35
35
  script:
36
36
  - tox -e pylint,flake8,pydocstyle,typing,black,deps-conflict --parallel auto
37
37
  - cat mypy-txt-report/index.txt
@@ -70,7 +70,7 @@ test:
70
70
  # Run on shared runners to lighten the load on the private runners
71
71
  # tags:
72
72
  # - hydroqc
73
- image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.12@sha256:d8985672e512080c541beeab0da37aa166a41b24ab9f0cf86bed4944cd743fae
73
+ image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.13:latest
74
74
  script:
75
75
  - >
76
76
  OUTPUT=$(curl
@@ -257,7 +257,7 @@ private_tests_done:
257
257
  stage: private_tests_done
258
258
  tags:
259
259
  - hydroqc
260
- image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.12@sha256:d8985672e512080c541beeab0da37aa166a41b24ab9f0cf86bed4944cd743fae
260
+ image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.13:latest
261
261
  script:
262
262
  #- apt-get update && apt-get install --no-install-recommends -y python3.10 python3-venv python3-pip --no-install-recommends git
263
263
  - echo "Private Tests done"
@@ -299,7 +299,7 @@ package:
299
299
  stage: test
300
300
  tags:
301
301
  - hydroqc
302
- image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.12@sha256:d8985672e512080c541beeab0da37aa166a41b24ab9f0cf86bed4944cd743fae
302
+ image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.13:latest
303
303
  script:
304
304
  # Build a package with a version based on the commmit short sha
305
305
  - pip install --upgrade pip
@@ -314,6 +314,9 @@ package:
314
314
  # Disable if it's a tag pipeline
315
315
  - if: "$CI_COMMIT_TAG"
316
316
  when: never
317
+ # Disable if it's a scheduled pipeline
318
+ - if: "$CI_PIPELINE_SOURCE == 'schedule'"
319
+ when: never
317
320
  # Enabled for main branch
318
321
  - if: "$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH"
319
322
  when: on_success
@@ -329,7 +332,7 @@ promote2pypi:
329
332
  stage: pypi
330
333
  tags:
331
334
  - hydroqc
332
- image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.12@sha256:d8985672e512080c541beeab0da37aa166a41b24ab9f0cf86bed4944cd743fae
335
+ image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.13:latest
333
336
  script:
334
337
  # TODO: try to pull the good package from gitlab pypi repo
335
338
  # then change the version (promote)
@@ -1,6 +1,6 @@
1
1
  repos:
2
2
  - repo: https://github.com/pre-commit/pre-commit-hooks
3
- rev: v5.0.0
3
+ rev: v6.0.0
4
4
  hooks:
5
5
  - id: trailing-whitespace
6
6
  - id: end-of-file-fixer
@@ -16,40 +16,40 @@ repos:
16
16
  - id: check-ast
17
17
 
18
18
  - repo: https://github.com/psf/black
19
- rev: 24.10.0
19
+ rev: 25.11.0
20
20
  hooks:
21
21
  - id: black
22
22
  language_version: python3
23
23
 
24
24
  - repo: https://github.com/PyCQA/flake8/
25
- rev: 7.1.1
25
+ rev: 7.3.0
26
26
  hooks:
27
27
  - id: flake8
28
28
  additional_dependencies: [flake8-docstrings]
29
29
 
30
30
  - repo: https://github.com/PyCQA/isort
31
- rev: 5.13.2
31
+ rev: 7.0.0
32
32
  hooks:
33
33
  - id: isort
34
34
  args: ["--profile", "black", "--filter-files"]
35
35
  # additional_dependencies: [toml]
36
36
 
37
37
  - repo: https://github.com/PyCQA/doc8
38
- rev: v1.1.2
38
+ rev: v2.0.0
39
39
  hooks:
40
40
  - id: doc8
41
41
 
42
42
  - repo: https://github.com/pre-commit/mirrors-mypy
43
- rev: v1.14.1
43
+ rev: v1.18.2
44
44
  hooks:
45
45
  - id: mypy
46
46
  args: [--strict, --pretty, --show-error-codes]
47
47
  additional_dependencies:
48
- - "types-pytz==2024.1.0.20240417"
49
- - "types-PyYAML==6.0.12.20240311"
50
- - "types-python-dateutil==2.9.0.20240316"
48
+ - "types-pytz==2025.2.0.20251108"
49
+ - "types-PyYAML==6.0.12.20250915"
50
+ - "types-python-dateutil==2.9.0.20251108"
51
51
  - "pytest-stub==1.1.0"
52
- - "aiohttp==3.10.10"
53
- - "aiocache==0.12.2"
52
+ - "aiohttp==3.13.2"
53
+ - "aiocache==0.12.3"
54
54
  - "pkce==1.0.3"
55
- - "pytest-asyncio==0.25.0"
55
+ - "pytest-asyncio==1.3.0"
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: Hydro-Quebec-API-Wrapper
3
- Version: 4.0.0
3
+ Version: 4.2.0
4
4
  Summary: A wrapper library to access hydro quebec API and more
5
5
  Home-page: https://hydroqc.ca
6
6
  Author-email: Hydroqc Team <info@hydroqc.ca>
@@ -12,14 +12,15 @@ Keywords: hydroquebec,lib
12
12
  Platform: any
13
13
  Classifier: Programming Language :: Python :: 3
14
14
  Classifier: Operating System :: OS Independent
15
- Requires-Python: >=3.10.0
15
+ Requires-Python: >=3.13.0
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: aiohttp==3.10.10
18
+ Requires-Dist: aiohttp==3.13.2
19
19
  Requires-Dist: python-dateutil==2.9.0.post0
20
- Requires-Dist: pytz==2024.2
20
+ Requires-Dist: pytz==2025.2
21
21
  Requires-Dist: aiocache==0.12.3
22
22
  Requires-Dist: pkce==1.0.3
23
+ Dynamic: license-file
23
24
 
24
25
  # HydroQC - Hydro Quebec API wrapper
25
26
 
@@ -14,6 +14,7 @@ renovate.json5
14
14
  setup.cfg
15
15
  test_requirements.txt
16
16
  tox.ini
17
+ .devcontainer/Dockerfile
17
18
  .devcontainer/devcontainer.json
18
19
  Hydro_Quebec_API_Wrapper.egg-info/PKG-INFO
19
20
  Hydro_Quebec_API_Wrapper.egg-info/SOURCES.txt
@@ -1,5 +1,5 @@
1
- aiohttp==3.10.10
1
+ aiohttp==3.13.2
2
2
  python-dateutil==2.9.0.post0
3
- pytz==2024.2
3
+ pytz==2025.2
4
4
  aiocache==0.12.3
5
5
  pkce==1.0.3
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: Hydro-Quebec-API-Wrapper
3
- Version: 4.0.0
3
+ Version: 4.2.0
4
4
  Summary: A wrapper library to access hydro quebec API and more
5
5
  Home-page: https://hydroqc.ca
6
6
  Author-email: Hydroqc Team <info@hydroqc.ca>
@@ -12,14 +12,15 @@ Keywords: hydroquebec,lib
12
12
  Platform: any
13
13
  Classifier: Programming Language :: Python :: 3
14
14
  Classifier: Operating System :: OS Independent
15
- Requires-Python: >=3.10.0
15
+ Requires-Python: >=3.13.0
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: aiohttp==3.10.10
18
+ Requires-Dist: aiohttp==3.13.2
19
19
  Requires-Dist: python-dateutil==2.9.0.post0
20
- Requires-Dist: pytz==2024.2
20
+ Requires-Dist: pytz==2025.2
21
21
  Requires-Dist: aiocache==0.12.3
22
22
  Requires-Dist: pkce==1.0.3
23
+ Dynamic: license-file
23
24
 
24
25
  # HydroQC - Hydro Quebec API wrapper
25
26
 
@@ -0,0 +1 @@
1
+ mqtt-hass-base==4.4.1
@@ -21,6 +21,7 @@ class Account:
21
21
  self,
22
22
  applicant_id: str,
23
23
  customer_id: str,
24
+ *,
24
25
  account_id: str,
25
26
  contracts: list[Contract],
26
27
  hydro_client: HydroClient,
@@ -27,7 +27,7 @@ P = ParamSpec("P")
27
27
 
28
28
 
29
29
  def check_period_data_present(
30
- method: Callable[..., None | str | bool | float | PeriodDataTyping]
30
+ method: Callable[..., None | str | bool | float | PeriodDataTyping],
31
31
  ) -> Callable[..., None | str | bool | float | PeriodDataTyping]:
32
32
  """Check if contract's data are present."""
33
33
 
@@ -47,7 +47,7 @@ def check_period_data_present(
47
47
 
48
48
 
49
49
  def check_info_data_present(
50
- method: Callable[..., None | str | bool | float | date]
50
+ method: Callable[..., None | str | bool | float | date],
51
51
  ) -> Callable[..., None | str | bool | float | date]:
52
52
  """Check if contract's data are present."""
53
53
 
@@ -67,7 +67,7 @@ def check_info_data_present(
67
67
 
68
68
 
69
69
  def check_annual_data_present(
70
- method: Callable[..., None | str | bool | float | date]
70
+ method: Callable[..., None | str | bool | float | date],
71
71
  ) -> Callable[..., None | str | bool | float | date]:
72
72
  """Check if contract's data are present."""
73
73
 
@@ -124,6 +124,7 @@ class Contract(ABC):
124
124
  self,
125
125
  applicant_id: str,
126
126
  customer_id: str,
127
+ *,
127
128
  account_id: str,
128
129
  contract_id: str,
129
130
  hydro_client: HydroClient,
@@ -273,7 +274,11 @@ class Contract(ABC):
273
274
  ) -> ConsumpDailyTyping:
274
275
  """Fetch daily consumption."""
275
276
  return await self._hydro_client.get_daily_consumption(
276
- self.applicant_id, self.customer_id, self.contract_id, start_date, end_date
277
+ self.applicant_id,
278
+ self.customer_id,
279
+ contract_id=self.contract_id,
280
+ start_date=start_date,
281
+ end_date=end_date,
277
282
  )
278
283
 
279
284
  async def get_today_daily_consumption(self) -> ConsumpDailyTyping:
@@ -313,11 +318,11 @@ class Contract(ABC):
313
318
  data_csv = await self._hydro_client.get_consumption_csv(
314
319
  self.applicant_id,
315
320
  self.customer_id,
316
- self.contract_id,
317
- start_date,
318
- end_date,
319
- "energie-jour",
320
- raw_output,
321
+ contract_id=self.contract_id,
322
+ start_date=start_date,
323
+ end_date=end_date,
324
+ option="energie-jour",
325
+ raw_output=raw_output,
321
326
  )
322
327
  return data_csv
323
328
 
@@ -334,11 +339,11 @@ class Contract(ABC):
334
339
  data_csv = await self._hydro_client.get_consumption_csv(
335
340
  self.applicant_id,
336
341
  self.customer_id,
337
- self.contract_id,
338
- start_date,
339
- end_date,
340
- "energie-heure",
341
- raw_output,
342
+ contract_id=self.contract_id,
343
+ start_date=start_date,
344
+ end_date=end_date,
345
+ option="energie-heure",
346
+ raw_output=raw_output,
342
347
  )
343
348
  return data_csv
344
349
 
@@ -379,7 +384,7 @@ class Contract(ABC):
379
384
  @check_period_data_present
380
385
  def cp_projected_bill(self) -> float:
381
386
  """Projected bill of the current period."""
382
- return self._all_period_data[0]["montantProjetePeriode"]
387
+ return float(self._all_period_data[0]["montantProjetePeriode"])
383
388
 
384
389
  @property
385
390
  @check_period_data_present
@@ -453,6 +458,7 @@ class ContractFallBack(Contract):
453
458
  self,
454
459
  applicant_id: str,
455
460
  customer_id: str,
461
+ *,
456
462
  account_id: str,
457
463
  contract_id: str,
458
464
  hydro_client: HydroClient,
@@ -463,8 +469,8 @@ class ContractFallBack(Contract):
463
469
  self,
464
470
  applicant_id,
465
471
  customer_id,
466
- account_id,
467
- contract_id,
468
- hydro_client,
469
- log_level,
472
+ account_id=account_id,
473
+ contract_id=contract_id,
474
+ hydro_client=hydro_client,
475
+ log_level=log_level,
470
476
  )
@@ -17,6 +17,7 @@ class ContractD(ContractResidential):
17
17
  self,
18
18
  applicant_id: str,
19
19
  customer_id: str,
20
+ *,
20
21
  account_id: str,
21
22
  contract_id: str,
22
23
  hydro_client: HydroClient,
@@ -27,8 +28,8 @@ class ContractD(ContractResidential):
27
28
  self,
28
29
  applicant_id,
29
30
  customer_id,
30
- account_id,
31
- contract_id,
32
- hydro_client,
33
- log_level,
31
+ account_id=account_id,
32
+ contract_id=contract_id,
33
+ hydro_client=hydro_client,
34
+ log_level=log_level,
34
35
  )
@@ -17,6 +17,7 @@ class ContractDCPC(ContractD):
17
17
  self,
18
18
  applicant_id: str,
19
19
  customer_id: str,
20
+ *,
20
21
  account_id: str,
21
22
  contract_id: str,
22
23
  hydro_client: HydroClient,
@@ -27,18 +28,18 @@ class ContractDCPC(ContractD):
27
28
  self,
28
29
  applicant_id,
29
30
  customer_id,
30
- account_id,
31
- contract_id,
32
- hydro_client,
33
- log_level,
31
+ account_id=account_id,
32
+ contract_id=contract_id,
33
+ hydro_client=hydro_client,
34
+ log_level=log_level,
34
35
  )
35
36
  wch_logger = self._logger.getChild("wch")
36
37
  self._wch: CPCPeakHandler = CPCPeakHandler(
37
38
  self.applicant_id,
38
39
  self.customer_id,
39
- self.contract_id,
40
- hydro_client,
41
- wch_logger,
40
+ contract_id=self.contract_id,
41
+ hydro_client=hydro_client,
42
+ logger=wch_logger,
42
43
  )
43
44
 
44
45
  @property
@@ -1,7 +1,8 @@
1
1
  """Hydroquebec contract module."""
2
2
 
3
3
  from collections.abc import Callable
4
- from datetime import date
4
+ from datetime import date, datetime
5
+ from enum import Enum
5
6
 
6
7
  from hydroqc.contract.common import check_period_data_present
7
8
  from hydroqc.contract.contract_residential import ContractResidential
@@ -10,8 +11,15 @@ from hydroqc.peak.dpc.handler import DPCPeakHandler
10
11
  from hydroqc.types import DPCDataTyping
11
12
 
12
13
 
14
+ class WinterState(str, Enum):
15
+ """Winter period state."""
16
+
17
+ CURRENT = "C" # Current/Active (within winter period)
18
+ FINISHED = "F" # Finished (past winter period)
19
+
20
+
13
21
  def check_dpc_data_present(
14
- method: Callable[..., None | str | bool | float | date]
22
+ method: Callable[..., None | str | bool | float | date],
15
23
  ) -> Callable[..., None | str | bool | float | date]:
16
24
  """Check if contractDPC's data are present."""
17
25
 
@@ -26,6 +34,20 @@ def check_dpc_data_present(
26
34
  "Maybe you did a rate change recently. "
27
35
  "This message should disappear at the beginning of the next bill period."
28
36
  )
37
+ return None
38
+
39
+ # Check if winter period data is available
40
+ if (
41
+ "periodesHiver" not in contract._dpc_data
42
+ or not contract._dpc_data.get("periodesHiver")
43
+ or len(contract._dpc_data["periodesHiver"]) == 0
44
+ ):
45
+ contract._logger.info(
46
+ "DPC data is empty or incomplete. "
47
+ "This may occur outside the winter period or during a rate transition."
48
+ )
49
+ return None
50
+
29
51
  return method(contract)
30
52
 
31
53
  return wrapper
@@ -45,6 +67,7 @@ class ContractDPC(ContractResidential):
45
67
  self,
46
68
  applicant_id: str,
47
69
  customer_id: str,
70
+ *,
48
71
  account_id: str,
49
72
  contract_id: str,
50
73
  hydro_client: HydroClient,
@@ -55,18 +78,18 @@ class ContractDPC(ContractResidential):
55
78
  self,
56
79
  applicant_id,
57
80
  customer_id,
58
- account_id,
59
- contract_id,
60
- hydro_client,
61
- log_level,
81
+ account_id=account_id,
82
+ contract_id=contract_id,
83
+ hydro_client=hydro_client,
84
+ log_level=log_level,
62
85
  )
63
86
  peaks_logger = self._logger.getChild("peaks")
64
87
  self._peakh: DPCPeakHandler = DPCPeakHandler(
65
88
  self.applicant_id,
66
89
  self.customer_id,
67
- self.contract_id,
68
- hydro_client,
69
- peaks_logger,
90
+ contract_id=self.contract_id,
91
+ hydro_client=hydro_client,
92
+ logger=peaks_logger,
70
93
  )
71
94
 
72
95
  @property
@@ -85,6 +108,13 @@ class ContractDPC(ContractResidential):
85
108
  )
86
109
  return self._dpc_data
87
110
 
111
+ def _get_dpc_field(self, field_name: str) -> str | float | int:
112
+ """Get DPC field from periodesHiver data."""
113
+ winter_period = self._dpc_data["periodesHiver"][0]
114
+ if field_name in winter_period:
115
+ return winter_period[field_name] # type: ignore
116
+ raise KeyError(f"Field {field_name} not found in DPC data")
117
+
88
118
  @property
89
119
  @check_period_data_present
90
120
  def cp_lower_price_consumption(self) -> float:
@@ -110,44 +140,63 @@ class ContractDPC(ContractResidential):
110
140
  @check_dpc_data_present
111
141
  def last_update_date(self) -> date:
112
142
  """DPC data last update."""
113
- return date.fromisoformat(self._dpc_data["results"][0]["dateDernMaj"])
143
+ date_str = str(self._get_dpc_field("dateMaj"))
144
+ # Handle ISO format with timezone
145
+ if "T" in date_str:
146
+ return date.fromisoformat(date_str.split("T", maxsplit=1)[0])
147
+ return date.fromisoformat(date_str)
114
148
 
115
149
  @property
116
150
  @check_dpc_data_present
117
151
  def critical_called_hours(self) -> int:
118
152
  """Get number of critical hours."""
119
- return int(self._dpc_data["results"][0]["hrsCritiquesAppelees"])
153
+ return int(self._get_dpc_field("hrsCritiquesAppelees"))
120
154
 
121
155
  @property
122
156
  @check_dpc_data_present
123
157
  def max_critical_called_hours(self) -> int:
124
158
  """Get max number of critical hours."""
125
- return int(self._dpc_data["results"][0]["hrsCritiquesAppeleesMax"])
159
+ return int(self._get_dpc_field("hrsCritiquesAppeleesMax"))
126
160
 
127
161
  @property
128
162
  @check_dpc_data_present
129
163
  def amount_saved_vs_base_rate(self) -> float:
130
164
  """Amount saved or not versus the base rate."""
131
- return self._dpc_data["results"][0]["montantEconPerteVSTarifBase"]
165
+ return float(self._get_dpc_field("montantEconPerteVSTarifBase"))
132
166
 
133
167
  @property
134
168
  @check_dpc_data_present
135
169
  def winter_total_days(self) -> int:
136
- """Get number of winter days."""
137
- return self._dpc_data["results"][0]["nbJoursTotauxHiver"]
170
+ """Get number of winter days (calculated from period dates)."""
171
+ winter = self._dpc_data["periodesHiver"][0]
172
+ start = datetime.fromisoformat(winter["dateDebut"].replace("Z", "+00:00"))
173
+ end = datetime.fromisoformat(winter["dateFin"].replace("Z", "+00:00"))
174
+ return (end - start).days
138
175
 
139
176
  @property
140
177
  @check_dpc_data_present
141
178
  def winter_total_days_last_update(self) -> int:
142
- """Get number of days since winter starts."""
143
- return self._dpc_data["results"][0]["nbJoursDernMaj"]
179
+ """Get number of days since winter starts (calculated from dates)."""
180
+ winter = self._dpc_data["periodesHiver"][0]
181
+ start = datetime.fromisoformat(winter["dateDebut"].replace("Z", "+00:00"))
182
+ update = datetime.fromisoformat(winter["dateMaj"].replace("Z", "+00:00"))
183
+ return (update - start).days
144
184
 
145
185
  @property
146
186
  @check_dpc_data_present
147
- def winter_state(self) -> str:
148
- """Get winter state.
187
+ def winter_state(self) -> WinterState:
188
+ """Get winter state (computed from dates).
149
189
 
150
- C: started
151
- ?: ???????
190
+ Returns:
191
+ WinterState.CURRENT: Within winter period
192
+ WinterState.FINISHED: Past winter period
152
193
  """
153
- return self._dpc_data["results"][0]["etatHiver"]
194
+ winter = self._dpc_data["periodesHiver"][0]
195
+ now = datetime.now(
196
+ datetime.fromisoformat(winter["dateDebut"].replace("Z", "+00:00")).tzinfo
197
+ )
198
+ start = datetime.fromisoformat(winter["dateDebut"].replace("Z", "+00:00"))
199
+ end = datetime.fromisoformat(winter["dateFin"].replace("Z", "+00:00"))
200
+ if start <= now <= end:
201
+ return WinterState.CURRENT
202
+ return WinterState.FINISHED
@@ -18,6 +18,7 @@ class ContractDT(ContractResidential):
18
18
  self,
19
19
  applicant_id: str,
20
20
  customer_id: str,
21
+ *,
21
22
  account_id: str,
22
23
  contract_id: str,
23
24
  hydro_client: HydroClient,
@@ -28,10 +29,10 @@ class ContractDT(ContractResidential):
28
29
  self,
29
30
  applicant_id,
30
31
  customer_id,
31
- account_id,
32
- contract_id,
33
- hydro_client,
34
- log_level,
32
+ account_id=account_id,
33
+ contract_id=contract_id,
34
+ hydro_client=hydro_client,
35
+ log_level=log_level,
35
36
  )
36
37
 
37
38
  @property
@@ -21,6 +21,7 @@ class ContractM(Contract):
21
21
  self,
22
22
  applicant_id: str,
23
23
  customer_id: str,
24
+ *,
24
25
  account_id: str,
25
26
  contract_id: str,
26
27
  hydro_client: HydroClient,
@@ -31,10 +32,10 @@ class ContractM(Contract):
31
32
  self,
32
33
  applicant_id,
33
34
  customer_id,
34
- account_id,
35
- contract_id,
36
- hydro_client,
37
- log_level,
35
+ account_id=account_id,
36
+ contract_id=contract_id,
37
+ hydro_client=hydro_client,
38
+ log_level=log_level,
38
39
  )
39
40
 
40
41
  async def get_power_demand_per_15min(
@@ -47,11 +48,11 @@ class ContractM(Contract):
47
48
  data_csv = await self._hydro_client.get_consumption_csv(
48
49
  self.applicant_id,
49
50
  self.customer_id,
50
- self.contract_id,
51
- start_date,
52
- end_date,
53
- "puissance-min",
54
- raw_output,
51
+ contract_id=self.contract_id,
52
+ start_date=start_date,
53
+ end_date=end_date,
54
+ option="puissance-min",
55
+ raw_output=raw_output,
55
56
  )
56
57
  return data_csv
57
58
 
@@ -65,10 +66,10 @@ class ContractM(Contract):
65
66
  data_csv = await self._hydro_client.get_consumption_csv(
66
67
  self.applicant_id,
67
68
  self.customer_id,
68
- self.contract_id,
69
- start_date,
70
- end_date,
71
- "puissance-jour",
72
- raw_output,
69
+ contract_id=self.contract_id,
70
+ start_date=start_date,
71
+ end_date=end_date,
72
+ option="puissance-jour",
73
+ raw_output=raw_output,
73
74
  )
74
75
  return data_csv
@@ -16,6 +16,7 @@ class ContractMGDP(ContractM):
16
16
  self,
17
17
  applicant_id: str,
18
18
  customer_id: str,
19
+ *,
19
20
  account_id: str,
20
21
  contract_id: str,
21
22
  hydro_client: HydroClient,
@@ -26,8 +27,8 @@ class ContractMGDP(ContractM):
26
27
  self,
27
28
  applicant_id,
28
29
  customer_id,
29
- account_id,
30
- contract_id,
31
- hydro_client,
32
- log_level,
30
+ account_id=account_id,
31
+ contract_id=contract_id,
32
+ hydro_client=hydro_client,
33
+ log_level=log_level,
33
34
  )