Hydro-Quebec-API-Wrapper 3.1.3__tar.gz → 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.
Files changed (106) hide show
  1. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/.gitlab-ci.yml +9 -11
  2. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/.pre-commit-config.yaml +10 -9
  3. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/.pylintrc +1 -1
  4. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/Hydro_Quebec_API_Wrapper.egg-info/PKG-INFO +5 -5
  5. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/Hydro_Quebec_API_Wrapper.egg-info/SOURCES.txt +4 -0
  6. hydro_quebec_api_wrapper-4.0.0/Hydro_Quebec_API_Wrapper.egg-info/requires.txt +5 -0
  7. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/PKG-INFO +5 -5
  8. hydro_quebec_api_wrapper-4.0.0/conflict_test_requirements.txt +1 -0
  9. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/examples/hydro.py +3 -1
  10. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/account.py +1 -0
  11. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/consts.py +1 -0
  12. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/contract/__init__.py +1 -0
  13. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/contract/common.py +1 -0
  14. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/contract/contract_d.py +1 -0
  15. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/contract/contract_d_cpc.py +1 -0
  16. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/contract/contract_dpc.py +1 -0
  17. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/contract/contract_dt.py +1 -0
  18. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/contract/contract_m.py +1 -0
  19. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/contract/contract_m_gdp.py +1 -0
  20. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/contract/contract_residential.py +1 -0
  21. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/contract/outage.py +1 -0
  22. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/customer.py +1 -0
  23. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/diagnostic.py +49 -5
  24. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/hydro_api/cache.py +1 -0
  25. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/hydro_api/client.py +41 -8
  26. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/hydro_api/consts.py +32 -25
  27. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/logger.py +1 -0
  28. hydro_quebec_api_wrapper-4.0.0/hydroqc/peak/basepeak.py +67 -0
  29. Hydro-Quebec-API-Wrapper-3.1.3/hydroqc/peak/dpc/handler.py → hydro_quebec_api_wrapper-4.0.0/hydroqc/peak/basepeakhandler.py +114 -107
  30. hydro_quebec_api_wrapper-4.0.0/hydroqc/peak/consts.py +3 -0
  31. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/peak/cpc/consts.py +1 -0
  32. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/peak/cpc/handler.py +75 -178
  33. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/peak/cpc/peak.py +14 -84
  34. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/peak/dpc/consts.py +1 -1
  35. hydro_quebec_api_wrapper-4.0.0/hydroqc/peak/dpc/handler.py +108 -0
  36. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/peak/dpc/peak.py +8 -21
  37. hydro_quebec_api_wrapper-4.0.0/hydroqc/public_client.py +79 -0
  38. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/timerange.py +1 -0
  39. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/types/__init__.py +9 -1
  40. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/types/account.py +1 -0
  41. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/types/common.py +33 -1
  42. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/types/consump.py +1 -0
  43. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/types/contract.py +1 -0
  44. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/types/cpc.py +1 -0
  45. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/types/dpc.py +1 -0
  46. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/types/dt.py +1 -0
  47. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/types/outage.py +1 -0
  48. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/webuser.py +8 -4
  49. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/pyproject.toml +6 -3
  50. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/renovate.json5 +7 -3
  51. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/setup.cfg +4 -4
  52. hydro_quebec_api_wrapper-4.0.0/test_requirements.txt +14 -0
  53. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/tests/conftest.py +1 -0
  54. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/tests/subtest_common.py +18 -46
  55. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/tests/subtest_contract_d.py +2 -1
  56. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/tests/subtest_contract_d_cpc.py +20 -1
  57. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/tests/subtest_contract_dpc.py +10 -4
  58. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/tests/subtest_contract_dt.py +2 -1
  59. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/tests/subtest_contract_m.py +2 -1
  60. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/tests/subtest_contract_m_gdp.py +2 -1
  61. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/tests/test_basic.py +1 -0
  62. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/tests/test_timerange.py +14 -5
  63. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/tests/tools.py +3 -2
  64. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/tox.ini +1 -1
  65. Hydro-Quebec-API-Wrapper-3.1.3/Hydro_Quebec_API_Wrapper.egg-info/requires.txt +0 -5
  66. Hydro-Quebec-API-Wrapper-3.1.3/conflict_test_requirements.txt +0 -1
  67. Hydro-Quebec-API-Wrapper-3.1.3/test_requirements.txt +0 -14
  68. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/.coveragerc +0 -0
  69. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/.devcontainer/devcontainer.json +0 -0
  70. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/.flake8 +0 -0
  71. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/.gitignore +0 -0
  72. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/Hydro_Quebec_API_Wrapper.egg-info/dependency_links.txt +0 -0
  73. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/Hydro_Quebec_API_Wrapper.egg-info/entry_points.txt +0 -0
  74. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/Hydro_Quebec_API_Wrapper.egg-info/top_level.txt +0 -0
  75. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/LICENSE +0 -0
  76. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/MANIFEST.in +0 -0
  77. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/README.md +0 -0
  78. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/config.default.yaml +0 -0
  79. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/Makefile +0 -0
  80. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/make.bat +0 -0
  81. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/source/_static/custom.css +0 -0
  82. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/source/_static/hydroqc-logo-128.png +0 -0
  83. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/source/_static/hydroqc-logo.svg +0 -0
  84. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/source/conf.py +0 -0
  85. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/source/external/description-des-codes-interruption.pdf +0 -0
  86. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/source/index.rst +0 -0
  87. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/source/reference/hydroqc.contract.rst +0 -0
  88. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/source/reference/hydroqc.hydro_api.rst +0 -0
  89. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/source/reference/hydroqc.peak.cpc.rst +0 -0
  90. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/source/reference/hydroqc.peak.dpc.rst +0 -0
  91. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/source/reference/hydroqc.peak.rst +0 -0
  92. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/source/reference/hydroqc.rst +0 -0
  93. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/source/reference/hydroqc.types.rst +0 -0
  94. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/source/reference/modules.rst +0 -0
  95. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/docs/source/todo.rst +0 -0
  96. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/__init__.py +0 -0
  97. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/error.py +0 -0
  98. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/hydro_api/__init__.py +0 -0
  99. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/peak/__init__.py +0 -0
  100. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/peak/cpc/__init__.py +0 -0
  101. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/peak/dpc/__init__.py +0 -0
  102. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/py.typed +0 -0
  103. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/hydroqc/utils.py +0 -0
  104. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/logo/hydroqc-logo-128.png +0 -0
  105. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/logo/hydroqc-logo.svg +0 -0
  106. {Hydro-Quebec-API-Wrapper-3.1.3 → hydro_quebec_api_wrapper-4.0.0}/tests/__init__.py +0 -0
@@ -30,10 +30,9 @@ renovate-config-validator:
30
30
  test:
31
31
  stage: test
32
32
  tags:
33
- - hydroqc
34
- image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.11@sha256:e6ef50dbb2f351fbd4e20c39512885bdcd62d202f05c8558a4d40ac2d9836763
33
+ - hydroqc
34
+ image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.12@sha256:d8985672e512080c541beeab0da37aa166a41b24ab9f0cf86bed4944cd743fae
35
35
  script:
36
- - pip install tox
37
36
  - tox -e pylint,flake8,pydocstyle,typing,black,deps-conflict --parallel auto
38
37
  - cat mypy-txt-report/index.txt
39
38
  artifacts:
@@ -68,11 +67,11 @@ test:
68
67
 
69
68
  .private_test_script: &private_test_script
70
69
  stage: private_tests
71
- tags:
72
- - hydroqc
73
- image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.11@sha256:e6ef50dbb2f351fbd4e20c39512885bdcd62d202f05c8558a4d40ac2d9836763
70
+ # Run on shared runners to lighten the load on the private runners
71
+ # tags:
72
+ # - hydroqc
73
+ image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.12@sha256:d8985672e512080c541beeab0da37aa166a41b24ab9f0cf86bed4944cd743fae
74
74
  script:
75
- #- apt update && apt install -y jq unzip curl
76
75
  - >
77
76
  OUTPUT=$(curl
78
77
  --globoff
@@ -258,11 +257,10 @@ private_tests_done:
258
257
  stage: private_tests_done
259
258
  tags:
260
259
  - hydroqc
261
- image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.11@sha256:e6ef50dbb2f351fbd4e20c39512885bdcd62d202f05c8558a4d40ac2d9836763
260
+ image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.12@sha256:d8985672e512080c541beeab0da37aa166a41b24ab9f0cf86bed4944cd743fae
262
261
  script:
263
262
  #- apt-get update && apt-get install --no-install-recommends -y python3.10 python3-venv python3-pip --no-install-recommends git
264
263
  - echo "Private Tests done"
265
- - pip install tox
266
264
  - find .
267
265
  - mv -v hydroqc/.coverage* .
268
266
  - mv -v hydroqc/*.xml .
@@ -301,7 +299,7 @@ package:
301
299
  stage: test
302
300
  tags:
303
301
  - hydroqc
304
- image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.11@sha256:e6ef50dbb2f351fbd4e20c39512885bdcd62d202f05c8558a4d40ac2d9836763
302
+ image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.12@sha256:d8985672e512080c541beeab0da37aa166a41b24ab9f0cf86bed4944cd743fae
305
303
  script:
306
304
  # Build a package with a version based on the commmit short sha
307
305
  - pip install --upgrade pip
@@ -331,7 +329,7 @@ promote2pypi:
331
329
  stage: pypi
332
330
  tags:
333
331
  - hydroqc
334
- image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.11@sha256:e6ef50dbb2f351fbd4e20c39512885bdcd62d202f05c8558a4d40ac2d9836763
332
+ image: registry.gitlab.com/hydroqc/hydroqc-base-container/3.12@sha256:d8985672e512080c541beeab0da37aa166a41b24ab9f0cf86bed4944cd743fae
335
333
  script:
336
334
  # TODO: try to pull the good package from gitlab pypi repo
337
335
  # 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: v4.5.0
3
+ rev: v5.0.0
4
4
  hooks:
5
5
  - id: trailing-whitespace
6
6
  - id: end-of-file-fixer
@@ -16,13 +16,13 @@ repos:
16
16
  - id: check-ast
17
17
 
18
18
  - repo: https://github.com/psf/black
19
- rev: 23.12.1
19
+ rev: 24.10.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.0.0
25
+ rev: 7.1.1
26
26
  hooks:
27
27
  - id: flake8
28
28
  additional_dependencies: [flake8-docstrings]
@@ -35,20 +35,21 @@ repos:
35
35
  # additional_dependencies: [toml]
36
36
 
37
37
  - repo: https://github.com/PyCQA/doc8
38
- rev: v1.1.1
38
+ rev: v1.1.2
39
39
  hooks:
40
40
  - id: doc8
41
41
 
42
42
  - repo: https://github.com/pre-commit/mirrors-mypy
43
- rev: v1.8.0
43
+ rev: v1.14.1
44
44
  hooks:
45
45
  - id: mypy
46
46
  args: [--strict, --pretty, --show-error-codes]
47
47
  additional_dependencies:
48
- - "types-pytz==2023.3.1.1"
49
- - "types-PyYAML==6.0.12.12"
50
- - "types-python-dateutil==2.8.19.20240106"
48
+ - "types-pytz==2024.1.0.20240417"
49
+ - "types-PyYAML==6.0.12.20240311"
50
+ - "types-python-dateutil==2.9.0.20240316"
51
51
  - "pytest-stub==1.1.0"
52
- - "aiohttp==3.9.1"
52
+ - "aiohttp==3.10.10"
53
53
  - "aiocache==0.12.2"
54
54
  - "pkce==1.0.3"
55
+ - "pytest-asyncio==0.25.0"
@@ -276,7 +276,7 @@ int-import-graph=
276
276
 
277
277
  # Exceptions that will emit a warning when being caught. Defaults to
278
278
  # "Exception"
279
- overgeneral-exceptions=Exception
279
+ overgeneral-exceptions=builtins.Exception
280
280
 
281
281
  max-nested-blocks=7
282
282
  max-bool-expr=10
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Hydro-Quebec-API-Wrapper
3
- Version: 3.1.3
3
+ Version: 4.0.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>
@@ -15,10 +15,10 @@ Classifier: Operating System :: OS Independent
15
15
  Requires-Python: >=3.10.0
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: aiohttp==3.9.1
19
- Requires-Dist: python-dateutil==2.8.2
20
- Requires-Dist: pytz==2023.3.post1
21
- Requires-Dist: aiocache==0.12.2
18
+ Requires-Dist: aiohttp==3.10.10
19
+ Requires-Dist: python-dateutil==2.9.0.post0
20
+ Requires-Dist: pytz==2024.2
21
+ Requires-Dist: aiocache==0.12.3
22
22
  Requires-Dist: pkce==1.0.3
23
23
 
24
24
  # HydroQC - Hydro Quebec API wrapper
@@ -46,6 +46,7 @@ hydroqc/customer.py
46
46
  hydroqc/diagnostic.py
47
47
  hydroqc/error.py
48
48
  hydroqc/logger.py
49
+ hydroqc/public_client.py
49
50
  hydroqc/py.typed
50
51
  hydroqc/timerange.py
51
52
  hydroqc/utils.py
@@ -65,6 +66,9 @@ hydroqc/hydro_api/cache.py
65
66
  hydroqc/hydro_api/client.py
66
67
  hydroqc/hydro_api/consts.py
67
68
  hydroqc/peak/__init__.py
69
+ hydroqc/peak/basepeak.py
70
+ hydroqc/peak/basepeakhandler.py
71
+ hydroqc/peak/consts.py
68
72
  hydroqc/peak/cpc/__init__.py
69
73
  hydroqc/peak/cpc/consts.py
70
74
  hydroqc/peak/cpc/handler.py
@@ -0,0 +1,5 @@
1
+ aiohttp==3.10.10
2
+ python-dateutil==2.9.0.post0
3
+ pytz==2024.2
4
+ aiocache==0.12.3
5
+ pkce==1.0.3
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Hydro-Quebec-API-Wrapper
3
- Version: 3.1.3
3
+ Version: 4.0.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>
@@ -15,10 +15,10 @@ Classifier: Operating System :: OS Independent
15
15
  Requires-Python: >=3.10.0
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
- Requires-Dist: aiohttp==3.9.1
19
- Requires-Dist: python-dateutil==2.8.2
20
- Requires-Dist: pytz==2023.3.post1
21
- Requires-Dist: aiocache==0.12.2
18
+ Requires-Dist: aiohttp==3.10.10
19
+ Requires-Dist: python-dateutil==2.9.0.post0
20
+ Requires-Dist: pytz==2024.2
21
+ Requires-Dist: aiocache==0.12.3
22
22
  Requires-Dist: pkce==1.0.3
23
23
 
24
24
  # HydroQC - Hydro Quebec API wrapper
@@ -0,0 +1 @@
1
+ mqtt-hass-base==4.4.0
@@ -65,7 +65,9 @@ async def async_func():
65
65
  print(data)
66
66
  data = await contract.get_annual_consumption()
67
67
  print(data)
68
- data = await contract.get_daily_consumption(date.fromisoformat("2022-01-10"), date.fromisoformat("2022-01-20"))
68
+ data = await contract.get_daily_consumption(
69
+ date.fromisoformat("2022-01-10"), date.fromisoformat("2022-01-20")
70
+ )
69
71
  print(data)
70
72
 
71
73
 
@@ -1,4 +1,5 @@
1
1
  """Hydroquebec Account Module."""
2
+
2
3
  from hydroqc.contract.common import Contract
3
4
  from hydroqc.error import HydroQcError
4
5
  from hydroqc.hydro_api.client import HydroClient
@@ -1,4 +1,5 @@
1
1
  """Hydroqc Consts."""
2
+
2
3
  from dateutil import tz
3
4
 
4
5
  # Always get the time using HydroQuebec Local Time
@@ -1,4 +1,5 @@
1
1
  """Contracts module."""
2
+
2
3
  from hydroqc.contract.common import ContractFallBack
3
4
  from hydroqc.contract.contract_d import ContractD
4
5
  from hydroqc.contract.contract_d_cpc import ContractDCPC
@@ -1,4 +1,5 @@
1
1
  """Hydroquebec contract module."""
2
+
2
3
  import functools
3
4
  import logging
4
5
  from abc import ABC
@@ -1,4 +1,5 @@
1
1
  """Hydroquebec contract module."""
2
+
2
3
  from hydroqc.contract.contract_residential import ContractResidential
3
4
  from hydroqc.hydro_api.client import HydroClient
4
5
 
@@ -1,4 +1,5 @@
1
1
  """Hydroquebec contract module."""
2
+
2
3
  from hydroqc.contract.contract_d import ContractD
3
4
  from hydroqc.hydro_api.client import HydroClient
4
5
  from hydroqc.peak.cpc.handler import CPCPeakHandler
@@ -1,4 +1,5 @@
1
1
  """Hydroquebec contract module."""
2
+
2
3
  from collections.abc import Callable
3
4
  from datetime import date
4
5
 
@@ -1,4 +1,5 @@
1
1
  """Hydroquebec contract module."""
2
+
2
3
  from hydroqc.contract.common import check_annual_data_present, check_period_data_present
3
4
  from hydroqc.contract.contract_residential import ContractResidential
4
5
  from hydroqc.hydro_api.client import HydroClient
@@ -1,4 +1,5 @@
1
1
  """Hydroquebec contract module."""
2
+
2
3
  from collections.abc import Iterator
3
4
  from datetime import date
4
5
  from io import StringIO
@@ -1,4 +1,5 @@
1
1
  """Hydroquebec contract module."""
2
+
2
3
  from hydroqc.contract.contract_m import ContractM
3
4
  from hydroqc.hydro_api.client import HydroClient
4
5
 
@@ -1,4 +1,5 @@
1
1
  """Hydroquebec contract module."""
2
+
2
3
  from collections.abc import Iterator
3
4
  from datetime import date
4
5
  from io import StringIO
@@ -5,6 +5,7 @@ See:
5
5
  * https://infopannes.solutions.hydroquebec.com/statut-adresse/
6
6
  * https://www.hydroquebec.com/data/loi-sur-acces/pdf/description-des-codes-interruption.pdf
7
7
  """
8
+
8
9
  import datetime
9
10
  import logging
10
11
 
@@ -1,4 +1,5 @@
1
1
  """Hydroquebec customer module."""
2
+
2
3
  import logging
3
4
 
4
5
  from hydroqc import contract as contractModule
@@ -1,4 +1,5 @@
1
1
  """Diagnostic module to help users to send debug to devs."""
2
+
2
3
  import argparse
3
4
  import asyncio
4
5
  import copy
@@ -19,6 +20,7 @@ from dateutil.relativedelta import relativedelta
19
20
  from hydroqc.contract import ContractDCPC, ContractDPC, ContractM
20
21
  from hydroqc.error import HydroQcError
21
22
  from hydroqc.logger import get_logger
23
+ from hydroqc.public_client import PublicClient
22
24
  from hydroqc.webuser import WebUser
23
25
 
24
26
  LOG_LEVEL = (
@@ -38,10 +40,12 @@ class Diagnostic:
38
40
  """Contructor."""
39
41
  # Get base settings
40
42
  self.diagnostic_folder = cli_settings.output_folder
43
+ self.diagnostic_folder_public = os.path.join(self.diagnostic_folder, "public")
41
44
  # Prepare output folder
42
45
  if os.path.exists(self.diagnostic_folder):
43
46
  shutil.rmtree(self.diagnostic_folder)
44
47
  os.makedirs(self.diagnostic_folder)
48
+ os.makedirs(self.diagnostic_folder_public)
45
49
  # Prepare logger
46
50
  self._log_file = os.path.join(self.diagnostic_folder, "diagnostic.log")
47
51
  log_level = cli_settings.log_level
@@ -50,6 +54,7 @@ class Diagnostic:
50
54
  file_handler.setFormatter(self.logger.handlers[0].formatter)
51
55
  file_handler.setLevel(self.logger.level)
52
56
  self.logger.addHandler(file_handler)
57
+ self.logger_public = self.logger.getChild("public")
53
58
  http_log_level = cli_settings.http_log_level
54
59
 
55
60
  # Get settings
@@ -68,6 +73,15 @@ class Diagnostic:
68
73
  log_file=self._log_file,
69
74
  diag_folder=self.diagnostic_folder,
70
75
  )
76
+ self.public_client = PublicClient(
77
+ rate_code="DPC",
78
+ # rate_option_code="CPC",
79
+ verify_ssl=True,
80
+ log_level=log_level,
81
+ http_log_level=http_log_level,
82
+ log_file=self._log_file,
83
+ diag_folder=self.diagnostic_folder_public,
84
+ )
71
85
 
72
86
  def zip(self) -> None:
73
87
  """Archive all generated files."""
@@ -86,6 +100,11 @@ class Diagnostic:
86
100
  """Get diagnostic http ID."""
87
101
  return self.webuser._hydro_client._diag_id
88
102
 
103
+ @property
104
+ def public_diag_id(self) -> int:
105
+ """Get diagnostic http ID."""
106
+ return self.public_client._hydro_client._diag_id
107
+
89
108
  async def run(self) -> None: # pylint: disable=too-many-statements
90
109
  """Run diagnostic."""
91
110
  today = datetime.date.today()
@@ -93,6 +112,24 @@ class Diagnostic:
93
112
  day_2 = today - datetime.timedelta(days=2)
94
113
 
95
114
  try:
115
+ self.logger_public.info(
116
+ "%02d - Checking HQ portal status", self.public_diag_id
117
+ )
118
+ hq_status = await self.public_client.check_hq_portal_status()
119
+ self.logger_public.info(
120
+ "%02d - HQ portal available: %s", self.public_diag_id - 1, hq_status
121
+ )
122
+
123
+ self.logger_public.info(
124
+ "%02d - Fetch peak using open data", self.public_diag_id
125
+ )
126
+ await self.public_client.fetch_peak_data()
127
+ self.logger_public.info(
128
+ "%02d - Peak found: %s",
129
+ self.public_diag_id - 1,
130
+ len(self.public_client.peaks),
131
+ )
132
+
96
133
  self.logger.info("%02d - Checking HQ portal status", self.diag_id)
97
134
  hq_status = await self.webuser.check_hq_portal_status()
98
135
  self.logger.info(
@@ -266,6 +303,10 @@ class Diagnostic:
266
303
  await contract_dcpc.peak_handler.refresh_data()
267
304
  self.logger.info("%02d - Got cpc data", self.diag_id - 1)
268
305
 
306
+ self.logger.info("%02d - Trying to get opn data", self.diag_id)
307
+ await contract_dcpc.peak_handler.refresh_open_data()
308
+ self.logger.info("%02d - Got open data", self.diag_id - 1)
309
+
269
310
  # DCP/FlexD
270
311
  elif self.contract.rate == "DPC":
271
312
  self.logger.info("%02d - Trying to get flexD data", self.diag_id)
@@ -288,6 +329,10 @@ class Diagnostic:
288
329
  await contract_dpc.peak_handler.refresh_data()
289
330
  self.logger.info("%02d - Got flexD data", self.diag_id - 1)
290
331
 
332
+ self.logger.info("%02d - Trying to get opn data", self.diag_id)
333
+ await contract_dcpc.peak_handler.refresh_open_data()
334
+ self.logger.info("%02d - Got open data", self.diag_id - 1)
335
+
291
336
  # DT
292
337
  if self.contract.rate == "DT":
293
338
  low_price = contract_dpc.cp_lower_price_consumption
@@ -329,6 +374,9 @@ class Diagnostic:
329
374
  traceback.print_exception(exp, file=fhtb)
330
375
  fhtb.seek(0)
331
376
  self.logger.error(fhtb.read())
377
+ finally:
378
+ await self.webuser.close_session()
379
+ await self.public_client.close_session()
332
380
 
333
381
 
334
382
  def parse_args() -> argparse.Namespace:
@@ -379,14 +427,10 @@ def main() -> None:
379
427
  """Run diagnostic."""
380
428
  cli_settings = parse_args()
381
429
 
382
- loop = asyncio.get_event_loop()
383
430
  diag = Diagnostic(cli_settings)
384
431
 
385
432
  # Fetch data
386
- loop.run_until_complete(diag.run())
387
- close_fut = asyncio.gather(diag.webuser.close_session())
388
- loop.run_until_complete(close_fut)
389
- loop.close()
433
+ asyncio.run(diag.run())
390
434
  # zip
391
435
  diag.zip()
392
436
 
@@ -1,4 +1,5 @@
1
1
  """Custon cache module."""
2
+
2
3
  import functools
3
4
  from collections.abc import Callable
4
5
  from typing import ParamSpec, TypeVar, cast
@@ -1,4 +1,5 @@
1
1
  """HydroQc Client Module."""
2
+
2
3
  import base64
3
4
  import csv
4
5
  import json
@@ -13,11 +14,11 @@ from datetime import date, datetime, timedelta
13
14
  from importlib.metadata import PackageNotFoundError, version
14
15
  from io import StringIO
15
16
  from json import dumps as json_dumps
16
- from typing import Any
17
- from pkce import generate_pkce_pair
17
+ from typing import Any, cast
18
18
 
19
19
  import aiohttp
20
20
  import yarl
21
+ from pkce import generate_pkce_pair
21
22
 
22
23
  from hydroqc.error import HydroQcError, HydroQcHTTPError
23
24
  from hydroqc.hydro_api.cache import CCached
@@ -42,6 +43,7 @@ from hydroqc.hydro_api.consts import (
42
43
  HOURLY_CONSUMPTION_API_URL,
43
44
  IS_HYDRO_PORTAL_UP_URL,
44
45
  MONTHLY_DATA_URL,
46
+ OPEN_DATA_PEAK_URL,
45
47
  OUTAGES,
46
48
  PERIOD_DATA_URL,
47
49
  PORTRAIT_URL,
@@ -66,6 +68,8 @@ from hydroqc.types import (
66
68
  InfoAccountTyping,
67
69
  ListAccountsContractsTyping,
68
70
  ListContractsTyping,
71
+ OpenDataPeakEvent,
72
+ OpenDataPeakEventOffer,
69
73
  OutageListTyping,
70
74
  PeriodDataTyping,
71
75
  )
@@ -75,6 +79,8 @@ from hydroqc.utils import EST_TIMEZONE
75
79
  class HydroClient:
76
80
  """HydroQc HTTP Client."""
77
81
 
82
+ _cookie_jar: aiohttp.CookieJar
83
+
78
84
  def __init__(
79
85
  self,
80
86
  username: str,
@@ -90,7 +96,6 @@ class HydroClient:
90
96
  self.password: str = password
91
97
  self._timeout: int = timeout
92
98
  self._session: aiohttp.ClientSession | None = session
93
- self._cookie_jar: aiohttp.CookieJar = aiohttp.CookieJar()
94
99
  self._verify_ssl: bool = verify_ssl
95
100
 
96
101
  # OAuth handling variables
@@ -118,7 +123,7 @@ class HydroClient:
118
123
  self.refresh_token = ""
119
124
  self.refresh_token_expiry = datetime.now()
120
125
  self.web_session_expiry = datetime.now()
121
- self._cookie_jar = aiohttp.CookieJar()
126
+ # self._cookie_jar = aiohttp.CookieJar()
122
127
  self._selected_customer = ""
123
128
  self._selected_contract = ""
124
129
 
@@ -233,16 +238,20 @@ class HydroClient:
233
238
  self._logger.debug("JSON received : ", data)
234
239
  raise HydroQcHTTPError("Bad JSON format") from exp
235
240
 
236
- def get_token_data(self) -> IDTokenTyping:
241
+ def get_token_data(self) -> IDTokenTyping | None:
237
242
  """Decode id token data."""
243
+ if not self._id_token:
244
+ return None
238
245
  raw_token_data = self._id_token.split(".")[1]
239
246
  # In some cases padding get lost, adding it to avoid issues with base64 decode
240
247
  raw_token_data += "=" * ((4 - len(raw_token_data) % 4) % 4)
241
248
  token_data: IDTokenTyping = self._load_json(base64.b64decode(raw_token_data))
242
249
  return token_data
243
250
 
244
- def _get_httpsession(self) -> None:
251
+ async def _get_httpsession(self) -> None:
245
252
  """Set http session."""
253
+ if not hasattr(self, "_cookie_jar"):
254
+ self._cookie_jar = aiohttp.CookieJar()
246
255
  if self._session is None:
247
256
  self._logger.debug("Creating new http session")
248
257
  self._session = aiohttp.ClientSession(
@@ -275,7 +284,7 @@ class HydroClient:
275
284
  async def check_portal_status(self) -> bool:
276
285
  """Check if Hydro Quebec portal is UP."""
277
286
  # Get http session
278
- self._get_httpsession()
287
+ await self._get_httpsession()
279
288
  self._logger.info("Checking if the Hydro Quebec portal is UP")
280
289
  api_call_response = await self.http_request(
281
290
  IS_HYDRO_PORTAL_UP_URL,
@@ -300,7 +309,7 @@ class HydroClient:
300
309
  code_verifier, code_challenge = generate_pkce_pair()
301
310
 
302
311
  # Get http session
303
- self._get_httpsession()
312
+ await self._get_httpsession()
304
313
 
305
314
  url = f"{AUTHORIZE_URL}"
306
315
  headers = {
@@ -911,3 +920,27 @@ class HydroClient:
911
920
  return content
912
921
  data_csv: Iterator[Any] = csv.reader(content, delimiter=";")
913
922
  return data_csv
923
+
924
+ @CCached(ttl=300)
925
+ async def get_open_data_peaks(
926
+ self,
927
+ offer: OpenDataPeakEventOffer | None = None,
928
+ ) -> list[OpenDataPeakEvent]:
929
+ """Get the list of peak event from open data url."""
930
+ await self._get_httpsession()
931
+ res = await self.http_request(OPEN_DATA_PEAK_URL, "get")
932
+ content = await res.text()
933
+ try:
934
+ raw_res_json = json.loads(content)
935
+ except json.JSONDecodeError:
936
+ # Try to clean up json removing comments
937
+ cleaned_json = ""
938
+ res_text = await res.text()
939
+ for line in res_text.splitlines():
940
+ if not line.startswith("/") and not line.startswith("#"):
941
+ cleaned_json += line
942
+ raw_res_json = json.loads(cleaned_json)
943
+ res_json = cast(list[OpenDataPeakEvent], raw_res_json.get("evenements", []))
944
+ if not offer:
945
+ return res_json
946
+ return [e for e in res_json if e["offre"] == offer]