pax_global_header00006660000000000000000000000064147471272700014525gustar00rootroot0000000000000052 comment=b5681f9285719ce41be08f41485887194e5b2a4a python-homewizard-energy-8.3.2/000077500000000000000000000000001474712727000165165ustar00rootroot00000000000000python-homewizard-energy-8.3.2/.flake8000066400000000000000000000001351474712727000176700ustar00rootroot00000000000000[flake8] max-line-length = 120 ignore = D202,W503 per-file-ignores = tests/*:DAR,S101,*/:DAR python-homewizard-energy-8.3.2/.github/000077500000000000000000000000001474712727000200565ustar00rootroot00000000000000python-homewizard-energy-8.3.2/.github/dependabot.yml000066400000000000000000000004621474712727000227100ustar00rootroot00000000000000--- version: 2 updates: - package-ecosystem: pip directory: "/" schedule: interval: monthly - package-ecosystem: pip directory: "/.github/workflows" schedule: interval: monthly - package-ecosystem: "github-actions" directory: "/" schedule: interval: monthly python-homewizard-energy-8.3.2/.github/workflows/000077500000000000000000000000001474712727000221135ustar00rootroot00000000000000python-homewizard-energy-8.3.2/.github/workflows/codeql.yaml000066400000000000000000000006721474712727000242530ustar00rootroot00000000000000--- name: "CodeQL" # yamllint disable-line rule:truthy on: pull_request: branches: [main] schedule: - cron: "30 1 * * 0" jobs: codeql: name: Scanning runs-on: ubuntu-latest steps: - name: Check out code from GitHub uses: actions/checkout@v4 - name: Initialize CodeQL uses: github/codeql-action/init@v3 - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 python-homewizard-energy-8.3.2/.github/workflows/dependabot-auto-merge.yml000066400000000000000000000013661474712727000270140ustar00rootroot00000000000000--- name: Dependabot auto-merge on: pull_request permissions: contents: write pull-requests: write jobs: dependabot: runs-on: ubuntu-latest if: ${{ github.actor == 'dependabot[bot]' }} steps: - name: Dependabot metadata id: metadata uses: dependabot/fetch-metadata@v2 with: github-token: "${{ secrets.GITHUB_TOKEN }}" - name: Enable auto-merge for Dependabot PRs if: ${{steps.metadata.outputs.update-type == 'version-update:semver-minor' || steps.metadata.outputs.update-type == 'version-update:semver-patch'}} run: gh pr merge --auto --squash "$PR_URL" env: PR_URL: ${{github.event.pull_request.html_url}} GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} python-homewizard-energy-8.3.2/.github/workflows/linting.yaml000066400000000000000000000067201474712727000244500ustar00rootroot00000000000000--- name: Linting # yamllint disable-line rule:truthy on: [pull_request] jobs: precommit: name: ${{ matrix.name }} runs-on: ubuntu-latest strategy: matrix: include: - id: bandit name: Check with bandit - id: ruff-check name: Check code style - id: ruff-format name: Format code style - id: check-ast name: Check Python AST - id: check-case-conflict name: Check for case conflicts - id: check-docstring-first name: Check docstring is first - id: check-executables-have-shebangs name: Check that executables have shebangs - id: check-json name: Check JSON files - id: check-merge-conflict name: Check for merge conflicts - id: check-symlinks name: Check for broken symlinks - id: check-toml name: Check TOML files - id: check-yaml name: Check YAML files - id: codespell name: Check code for common misspellings - id: debug-statements name: Debug Statements and imports (Python) - id: detect-private-key name: Detect Private Keys - id: end-of-file-fixer name: Check End of Files - id: fix-byte-order-marker name: Check UTF-8 byte order marker # - id: flake8 # name: Enforcing style guide with flake8 - id: isort name: Check imports are sorted - id: poetry name: Check pyproject file - id: pylint name: Check with pylint - id: pyupgrade name: Check for upgradable syntax - id: trailing-whitespace name: Trim Trailing Whitespace - id: vulture name: Check for unused Python code - id: yamllint name: Check YAML style steps: - name: Check out code from GitHub uses: actions/checkout@v4 - name: Set up Python 3.13 id: python uses: actions/setup-python@v5 with: python-version: 3.13 - name: Get pip cache dir id: pip-cache run: | echo "::set-output name=dir::$(pip cache dir)" - name: Restore cached Python PIP packages uses: actions/cache@v4 with: path: ${{ steps.pip-cache.outputs.dir }} key: pip-${{ runner.os }}-v1-${{ steps.python.outputs.python-version }}-${{ hashFiles('.github/workflows/requirements.txt') }} restore-keys: | pip-${{ runner.os }}-v1-${{ steps.python.outputs.python-version }}- - name: 🏗 Install workflow dependencies run: | pip install -r .github/workflows/requirements.txt poetry config virtualenvs.create true poetry config virtualenvs.in-project true - name: Restore cached Python virtual environment id: cached-poetry-dependencies uses: actions/cache@v4 with: path: .venv key: >- venv-${{ runner.os }}-v1-${{ steps.python.outputs.python-version }}-${{ hashFiles('poetry.lock') }} venv-${{ runner.os }}-v1-${{ steps.python.outputs.python-version }}- - name: Install Python dependencies run: poetry install --no-interaction - name: Run pre-commit for ${{ matrix.id }} run: poetry run pre-commit run ${{ matrix.id }} --all-files python-homewizard-energy-8.3.2/.github/workflows/release.yaml000066400000000000000000000040521474712727000244200ustar00rootroot00000000000000--- name: Release # yamllint disable-line rule:truthy on: release: types: - published jobs: release: name: Releasing to PyPi runs-on: ubuntu-latest steps: - name: Check out code from GitHub uses: actions/checkout@v4 - name: Set up Python 3.13 id: python uses: actions/setup-python@v5 with: python-version: 3.13 - name: Get pip cache dir id: pip-cache run: | echo "::set-output name=dir::$(pip cache dir)" - name: Restore cached Python PIP packages uses: actions/cache@v4 with: path: ${{ steps.pip-cache.outputs.dir }} key: pip-${{ runner.os }}-v1-${{ steps.python.outputs.python-version }}-${{ hashFiles('.github/workflows/requirements.txt') }} restore-keys: | pip-${{ runner.os }}-v1-${{ steps.python.outputs.python-version }}- - name: Install workflow dependencies run: | pip install -r .github/workflows/requirements.txt poetry config virtualenvs.create true poetry config virtualenvs.in-project true - name: Restore cached Python virtual environment id: cached-poetry-dependencies uses: actions/cache@v4 with: path: .venv key: >- venv-${{ runner.os }}-v1-${{ steps.python.outputs.python-version }}-${{ hashFiles('poetry.lock') }} venv-${{ runner.os }}-v1-${{ steps.python.outputs.python-version }}- - name: Install dependencies run: poetry install --no-interaction - name: Set package version run: | version="${{ github.event.release.tag_name }}" version="${version,,}" version="${version#v}" poetry version --no-interaction "${version}" - name: Build package run: poetry build --no-interaction - name: Publish to PyPi env: PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} run: | poetry config pypi-token.pypi "${PYPI_TOKEN}" poetry publish --no-interaction python-homewizard-energy-8.3.2/.github/workflows/requirements.txt000066400000000000000000000000321474712727000253720ustar00rootroot00000000000000pip==24.3.1 poetry==1.8.5 python-homewizard-energy-8.3.2/.github/workflows/tests.yaml000066400000000000000000000053071474712727000241460ustar00rootroot00000000000000--- name: Testing # yamllint disable-line rule:truthy on: pull_request: types: [opened, reopened, synchronize] push: branches: - main workflow_dispatch: jobs: pytest: name: Python ${{ matrix.python }} on ${{ matrix.os }} runs-on: ${{ matrix.os }}-latest strategy: matrix: os: [ubuntu] python: ['3.12', '3.13'] steps: - name: Check out code from GitHub uses: actions/checkout@v4 - name: 🏗 Set up Poetry run: pipx install poetry - name: Set up Python ${{ matrix.python }} id: python uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} cache: "poetry" - name: Install workflow dependencies run: | poetry config virtualenvs.create true poetry config virtualenvs.in-project true - name: Install dependencies run: poetry install --no-interaction - name: Run pytest run: poetry run pytest --cov homewizard_energy tests - name: Upload coverage artifact uses: actions/upload-artifact@v4 with: name: coverage-${{ matrix.python }}-${{ matrix.os }} include-hidden-files: true path: .coverage coverage: runs-on: ubuntu-latest needs: pytest steps: - name: Check out code from GitHub uses: actions/checkout@v4 with: fetch-depth: 0 - name: Download coverage data uses: actions/download-artifact@v4 - name: 🏗 Set up Poetry run: pipx install poetry - name: Set up Python 3.13 id: python uses: actions/setup-python@v5 with: python-version: 3.13 cache: "poetry" - name: Install workflow dependencies run: | pip install -r .github/workflows/requirements.txt poetry config virtualenvs.create true poetry config virtualenvs.in-project true - name: Restore cached Python virtual environment id: cached-poetry-dependencies uses: actions/cache@v4 with: path: .venv key: >- venv-${{ runner.os }}-v1-${{ steps.python.outputs.python-version }}-${{ hashFiles('poetry.lock') }} venv-${{ runner.os }}-v1-${{ steps.python.outputs.python-version }}- - name: Install dependencies run: poetry install --no-interaction - name: Process coverage results run: | poetry run coverage combine coverage*/.coverage* poetry run coverage xml -i - name: Upload coverage report uses: codecov/codecov-action@v5.1.2 with: fail_ci_if_error: true token: ${{ secrets.CODECOV_TOKEN }} python-homewizard-energy-8.3.2/.gitignore000066400000000000000000000004301474712727000205030ustar00rootroot00000000000000# general things to ignore build/ dist/ *.egg-info/ *.egg *.py[cod] __pycache__/ *.so *~ # due to using tox and pytest .tox .cache coverage.xml .coverage .coverage.* # PyCharm .idea/workspace.xml # VS Code .vscode/ # virtualenv .venv venv/ ENV/ # local test files example.py python-homewizard-energy-8.3.2/.pre-commit-config.yaml000066400000000000000000000113761474712727000230070ustar00rootroot00000000000000--- repos: - repo: local hooks: - id: ruff-check name: Ruff Linter language: system types: [python] entry: poetry run ruff check --fix require_serial: true stages: [commit, push, manual] - id: ruff-format name: Ruff Formatter language: system types: [python] entry: poetry run ruff format require_serial: true stages: [commit, push, manual] - id: bandit name: Checking using bandit language: system types: [python] entry: poetry run bandit files: ^homewizard_energy/ require_serial: true - id: check-ast name: Check Python AST language: system types: [python] entry: poetry run check-ast - id: check-case-conflict name: Check for case conflicts language: system entry: poetry run check-case-conflict - id: check-docstring-first name: Check docstring is first language: system types: [python] entry: poetry run check-docstring-first - id: check-executables-have-shebangs name: Check that executables have shebangs language: system types: [text, executable] entry: poetry run check-executables-have-shebangs stages: [commit, push, manual] - id: check-json name: Check JSON files language: system types: [json] entry: poetry run check-json - id: check-merge-conflict name: Check for merge conflicts language: system types: [text] entry: poetry run check-merge-conflict - id: check-symlinks name: Check for broken symlinks language: system types: [symlink] entry: poetry run check-symlinks - id: check-toml name: Check TOML files language: system types: [toml] entry: poetry run check-toml - id: check-yaml name: Check YAML files language: system types: [yaml] entry: poetry run check-yaml - id: codespell name: Check code for common misspellings language: system types: [text] exclude: ^poetry\.lock$ entry: poetry run codespell - id: debug-statements name: Debug Statements and imports (Python) language: system types: [python] entry: poetry run debug-statement-hook - id: detect-private-key name: Detect Private Keys language: system types: [text] entry: poetry run detect-private-key - id: end-of-file-fixer name: Fix End of Files language: system types: [text] entry: poetry run end-of-file-fixer stages: [commit, push, manual] - id: fix-byte-order-marker name: Fix UTF-8 byte order marker language: system types: [text] entry: poetry run fix-byte-order-marker # - id: flake8 # name: Enforcing style guide with flake8 # language: system # types: [python] # entry: poetry run flake8 # require_serial: true - id: isort name: Sort all imports with isort language: system types: [python] entry: poetry run isort - id: no-commit-to-branch name: Don't commit to main branch language: system entry: poetry run no-commit-to-branch pass_filenames: false always_run: true args: - --branch=main - id: poetry name: Check pyproject with Poetry language: system entry: poetry check pass_filenames: false always_run: true - id: pylint name: Starring code with pylint language: system types: [python] entry: poetry run pylint - id: pytest name: Running tests and test coverage with pytest language: system types: [python] entry: poetry run pytest pass_filenames: false - id: pyupgrade name: Checking for upgradable syntax with pyupgrade language: system types: [python] entry: poetry run pyupgrade args: [--py39-plus, --keep-runtime-typing] - id: trailing-whitespace name: Trim Trailing Whitespace language: system types: [text] entry: poetry run trailing-whitespace-fixer stages: [commit, push, manual] - id: vulture name: Find unused Python code with Vulture language: system types: [python] entry: poetry run vulture pass_filenames: false require_serial: true - id: yamllint name: Check YAML files with yamllint language: system types: [yaml] entry: poetry run yamllint python-homewizard-energy-8.3.2/.yamllint000066400000000000000000000024141474712727000203510ustar00rootroot00000000000000--- ignore: | .github/workflows rules: braces: level: error min-spaces-inside: 0 max-spaces-inside: 1 min-spaces-inside-empty: -1 max-spaces-inside-empty: -1 brackets: level: error min-spaces-inside: 0 max-spaces-inside: 0 min-spaces-inside-empty: -1 max-spaces-inside-empty: -1 colons: level: error max-spaces-before: 0 max-spaces-after: 1 commas: level: error max-spaces-before: 0 min-spaces-after: 1 max-spaces-after: 1 comments: level: error require-starting-space: true min-spaces-from-content: 2 comments-indentation: level: error document-end: level: error present: false document-start: level: error present: true empty-lines: level: error max: 1 max-start: 0 max-end: 1 hyphens: level: error max-spaces-after: 1 indentation: level: error spaces: 2 indent-sequences: true check-multi-line-strings: false key-duplicates: level: error line-length: level: warning max: 120 allow-non-breakable-words: true allow-non-breakable-inline-mappings: true new-line-at-end-of-file: level: error new-lines: level: error type: unix trailing-spaces: level: error truthy: level: error python-homewizard-energy-8.3.2/LICENSE000066400000000000000000000261221474712727000175260ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2018 Paulus Schoutsen Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. python-homewizard-energy-8.3.2/README.md000066400000000000000000000043771474712727000200100ustar00rootroot00000000000000# HomeWizard Energy: `python-homewizard-energy` Asyncio package to communicate with HomeWizard Energy devices This package is aimed at basic control of the device. Initial setup and configuration is assumed to done with the official HomeWizard Energy app. [![Testing](https://github.com/homewizard/python-homewizard-energy/actions/workflows/tests.yaml/badge.svg?branch=main)](https://github.com/homewizard/python-homewizard-energy/actions/workflows/tests.yaml) [![Codecov](https://img.shields.io/codecov/c/github/homewizard/python-homewizard-energy)](https://app.codecov.io/gh/homewizard/python-homewizard-energy) [![Release](https://img.shields.io/github/v/release/homewizard/python-homewizard-energy)](https://github.com/homewizard/python-homewizard-energy/releases) # Usage Instantiate the HomeWizard class and access the API. For more details on the API see the API documentation for HomeWizard Energy on https://api-documentation.homewizard.com ## Installation ```bash python3 -m pip install python-homewizard-energy ``` ## Example ### API v1 ```python import asyncio from homewizard_energy import HomeWizardEnergyV1V1 IP_ADDRESS = "192.168.1.123" async def main(): async with HomeWizardEnergyV1(host=IP_ADDRESS) as api: # Get device information, like firmware version print(await api.device()) # Get measurements, like energy or water usage measurement = await api.measurement() print(measurement.energy_import_kwh) # Get all data and remap v1 data to new v2 structure print(await api.combined()) # Turn on the Energy Socket outlet await api.state(power_on=True) asyncio.run(main()) ``` # Development and contribution Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. ## Requirements - Python 3.10 or higher - [Poetry](https://python-poetry.org/docs/#installing-with-pipx) ## Installation and setup ```bash poetry install poetry shell pre-commit install ``` You can now start developing. The pre-commit hooks will run automatically when you commit your changes. Please note that a failed pre-commit hook will prevent you from committing your changes. This is to make sure that the code is formatted correctly and that the tests pass. python-homewizard-energy-8.3.2/homewizard_energy/000077500000000000000000000000001474712727000222405ustar00rootroot00000000000000python-homewizard-energy-8.3.2/homewizard_energy/__init__.py000066400000000000000000000024211474712727000243500ustar00rootroot00000000000000"""HomeWizard Energy API library.""" from aiohttp import ClientSession from .errors import DisabledError, InvalidStateError, RequestError, UnsupportedError from .homewizard_energy import HomeWizardEnergy from .v1 import HomeWizardEnergyV1 from .v2 import HomeWizardEnergyV2 __all__ = [ "DisabledError", "HomeWizardEnergy", "HomeWizardEnergyV1", "HomeWizardEnergyV2", "InvalidStateError", "RequestError", "UnsupportedError", ] async def has_v2_api(host: str, websession: ClientSession | None = None) -> bool: """Check if the device has support for the v2 api.""" websession_provided = websession is not None if websession is None: websession = ClientSession() try: # v2 api is https only and returns a 401 Unauthorized when no key provided, # no connection can be made if the device is not v2 url = f"https://{host}/api" res = await websession.get(url, ssl=False, raise_for_status=False, timeout=5) res.close() return res.status == 401 except Exception: # pylint: disable=broad-except # all other status/exceptions means the device is not v2 or not reachable at this time return False finally: if not websession_provided: await websession.close() python-homewizard-energy-8.3.2/homewizard_energy/const.py000066400000000000000000000025211474712727000237400ustar00rootroot00000000000000"""Constants for HomeWizard Energy.""" import logging from enum import StrEnum LOGGER = logging.getLogger(__name__) class Model(StrEnum): """Model of the HomeWizard Energy device.""" P1_METER = "HWE-P1" ENERGY_SOCKET = "HWE-SKT" WATER_METER = "HWE-WTR" DISPLAY = "HWE-DSP" ENERGY_METER_1_PHASE = "HWE-KWH1" ENERGY_METER_3_PHASE = "HWE-KWH3" ENERGY_METER_EASTRON_SDM230 = "SDM230-wifi" ENERGY_METER_EASTRON_SDM630 = "SDM630-wifi" BATTERY = "HWE-BAT" MODEL_TO_ID = { Model.P1_METER: "p1dongle", Model.ENERGY_SOCKET: "energysocket", Model.WATER_METER: "watermeter", Model.DISPLAY: "display", Model.ENERGY_METER_1_PHASE: "energymeter", Model.ENERGY_METER_3_PHASE: "energymeter", Model.ENERGY_METER_EASTRON_SDM230: "energymeter", Model.ENERGY_METER_EASTRON_SDM630: "energymeter", Model.BATTERY: "battery", } MODEL_TO_NAME = { Model.P1_METER: "Wi-Fi P1 Meter", Model.ENERGY_SOCKET: "Wi-Fi Energy Socket", Model.WATER_METER: "Wi-Fi Watermeter", Model.DISPLAY: "Energy Display", Model.ENERGY_METER_1_PHASE: "Wi-Fi kWh Meter 1-phase", Model.ENERGY_METER_3_PHASE: "Wi-Fi kWh Meter 3-phase", Model.ENERGY_METER_EASTRON_SDM230: "Wi-Fi kWh Meter 1-phase", Model.ENERGY_METER_EASTRON_SDM630: "Wi-Fi kWh Meter 3-phase", Model.BATTERY: "Plug-In Battery", } python-homewizard-energy-8.3.2/homewizard_energy/errors.py000066400000000000000000000021231474712727000241240ustar00rootroot00000000000000"""python-homewizard-energy errors.""" class HomeWizardEnergyException(Exception): """Base error for python-homewizard-energy.""" class RequestError(HomeWizardEnergyException): """Unable to fulfill request. Raised when host or API cannot be reached. """ class InvalidUserNameError(HomeWizardEnergyException): """Invalid username. Raised when username is not valid, too short or too long. """ class ResponseError(HomeWizardEnergyException): """API responded unexpected.""" class NotFoundError(HomeWizardEnergyException): """Request not found. Raised when API responds with '404' """ class InvalidStateError(HomeWizardEnergyException): """Raised when the device is not in the correct state.""" class UnsupportedError(HomeWizardEnergyException): """Raised when the device is not supported from this library.""" class DisabledError(HomeWizardEnergyException): """Raised when device API is disabled. User has to enable API in app.""" class UnauthorizedError(HomeWizardEnergyException): """Raised when request is not authorized.""" python-homewizard-energy-8.3.2/homewizard_energy/homewizard_energy.py000066400000000000000000000076771474712727000263550ustar00rootroot00000000000000"""HomeWizard Energy base class""" from __future__ import annotations import asyncio from typing import Any from aiohttp.client import ClientSession, ClientTimeout, TCPConnector from .const import LOGGER from .errors import UnsupportedError from .models import CombinedModels, Device, Measurement, State, System class HomeWizardEnergy: """Base class for HomeWizard Energy API.""" _session: ClientSession | None = None _close_session: bool = False _request_timeout: int = 10 _host: str _device: Device | None = None _lock: asyncio.Lock def __init__( self, host: str, clientsession: ClientSession = None, timeout: int = 10, ): """Create a HomeWizard Energy object. Args: host: IP or URL for device. clientsession: The clientsession. timeout: Request timeout in seconds. """ self._host = host self._session = clientsession self._close_session = clientsession is None self._request_timeout = timeout self._lock = asyncio.Lock() @property def host(self) -> str: """Return the hostname of the device. Returns: host: The used host """ return self._host async def combined(self) -> CombinedModels: """Get all information.""" async def fetch_data(coroutine): try: return await coroutine except (UnsupportedError, NotImplementedError): return None device, measurement, system, state = await asyncio.gather( fetch_data(self.device()), fetch_data(self.measurement()), fetch_data(self.system()), fetch_data(self.state()), ) return CombinedModels( device=device, measurement=measurement, system=system, state=state ) async def device(self, reset_cache: bool = False) -> Device: """Get the device information.""" raise NotImplementedError async def measurement(self) -> Measurement: """Get the current measurement.""" raise NotImplementedError async def system( self, cloud_enabled: bool | None = None, status_led_brightness_pct: int | None = None, api_v1_enabled: bool | None = None, ) -> System: """Get/set the system.""" raise NotImplementedError async def state( self, power_on: bool | None = None, switch_lock: bool | None = None, brightness: int | None = None, ) -> State: """Get/set the state.""" raise UnsupportedError("State is not supported") async def identify( self, ) -> None: """Identify the device.""" raise NotImplementedError async def reboot( self, ) -> None: """Reboot the device.""" raise UnsupportedError("Reboot is not supported") async def close(self) -> None: """Close client session.""" LOGGER.debug("Closing clientsession") if self._session and self._close_session: await self._session.close() async def _create_clientsession(self) -> None: """Create a client session.""" LOGGER.debug("Creating clientsession") if self._session is not None: raise RuntimeError("Session already exists") connector = TCPConnector( enable_cleanup_closed=True, limit_per_host=1, ) self._close_session = True self._session = ClientSession( connector=connector, timeout=ClientTimeout(total=self._request_timeout) ) async def __aenter__(self) -> HomeWizardEnergy: """Async enter. Returns: The HomeWizardEnergy object. """ return self async def __aexit__(self, *_exc_info: Any) -> None: """Async exit. Args: _exc_info: Exec type. """ await self.close() python-homewizard-energy-8.3.2/homewizard_energy/models.py000066400000000000000000000414341474712727000241030ustar00rootroot00000000000000"""Common models for HomeWizard Energy API.""" from __future__ import annotations from dataclasses import dataclass, field from datetime import datetime from enum import StrEnum from typing import Any from awesomeversion import AwesomeVersion from mashumaro.config import BaseConfig from mashumaro.exceptions import MissingField from mashumaro.mixins.orjson import DataClassORJSONMixin from mashumaro.types import SerializationStrategy from .const import LOGGER, MODEL_TO_ID, MODEL_TO_NAME, Model from .utils import get_awesome_version class AwesomeVersionSerializationStrategy(SerializationStrategy, use_annotations=True): """Serialization strategy for AwesomeVersion objects.""" def serialize(self, value: AwesomeVersion) -> str: """Serialize AwesomeVersion object to string.""" return str(value) def deserialize(self, value: str) -> AwesomeVersion | None: """Deserialize string to AwesomeVersion object.""" version = get_awesome_version(value) return version class BaseModel(DataClassORJSONMixin): """Base model for all HomeWizard models.""" # pylint: disable-next=too-few-public-methods class Config(BaseConfig): """Mashumaro configuration.""" serialize_by_alias = True serialization_strategy = { # noqa: RUF012 AwesomeVersion: AwesomeVersionSerializationStrategy() } omit_none = True class UpdateBaseModel(BaseModel): """Base model for all 'update' models.""" def __post_serialize__(self, d: dict, context: dict | None = None): """Post serialize hook for UpdateBaseModel object.""" _ = context # Unused if not d: raise ValueError("No values to update") return d @dataclass(kw_only=True) class CombinedModels: """All values.""" device: Device measurement: Measurement state: State | None system: System | None def __init__( self, device: Device, measurement: Measurement, state: State | None, system: System | None, ): self.device = device self.measurement = measurement self.state = state self.system = system # Move things around for backwards compatibility ## measurement.wifi_ssid -> system.wifi_ssid if self.measurement is not None and self.measurement.wifi_ssid is not None: if self.system is None: self.system = System() self.system.wifi_ssid = self.measurement.wifi_ssid ## measurement.wifi_strength -> system.wifi_strength_pct if self.measurement is not None and self.measurement.wifi_strength is not None: if self.system is None: self.system = System() self.system.wifi_strength_pct = self.measurement.wifi_strength ## state.brightness -> system.status_led_brightness_pct if self.state is not None and self.state.brightness is not None: if self.system is None: self.system = System() self.system.status_led_brightness_pct = (self.state.brightness / 255) * 100 def get_verification_hostname(model: str, serial_number: str) -> str: """Helper method to convert device model and serial to identifier The identifier is used to verify the device in the HomeWizard Energy API via HTTPS. """ if model not in MODEL_TO_ID: raise ValueError(f"Unsupported model: {model}") return f"appliance/{MODEL_TO_ID[model]}/{serial_number}" @dataclass(kw_only=True) class Device(BaseModel): """Represent Device config.""" model_name: str | None = None id: str | None = None product_name: str = field() product_type: str = field() serial: str = field() api_version: AwesomeVersion = field() firmware_version: str = field() @classmethod def __post_deserialize__(cls, obj: Device) -> Device: """Post deserialize hook for Device object.""" _ = cls # Unused obj.model_name = MODEL_TO_NAME.get(obj.product_type) obj.id = get_verification_hostname(obj.product_type, obj.serial) return obj def supports_state(self) -> bool: """Return if the device supports state.""" return self.product_type == Model.ENERGY_SOCKET def supports_cloud_enable(self) -> bool: """Return if the device supports cloud enable/disable.""" return self.product_type != Model.BATTERY def supports_reboot(self) -> bool: """Return if the device supports reboot.""" return self.api_version.major >= 2 def supports_identify(self) -> bool: """Return if the device supports identify.""" return self.product_type not in ( Model.ENERGY_METER_1_PHASE, Model.ENERGY_METER_3_PHASE, Model.ENERGY_METER_EASTRON_SDM230, Model.ENERGY_METER_EASTRON_SDM630, ) @dataclass(kw_only=True) class Measurement(BaseModel): """Represent Measurement.""" # Deprecated, use 'System' wifi_ssid: str | None = field( default=None, ) wifi_strength: int | None = field( default=None, ) # Generic energy_import_kwh: float | None = field( default=None, ) energy_import_t1_kwh: float | None = field( default=None, ) energy_import_t2_kwh: float | None = field( default=None, ) energy_import_t3_kwh: float | None = field( default=None, ) energy_import_t4_kwh: float | None = field( default=None, ) energy_export_kwh: float | None = field( default=None, ) energy_export_t1_kwh: float | None = field( default=None, ) energy_export_t2_kwh: float | None = field( default=None, ) energy_export_t3_kwh: float | None = field( default=None, ) energy_export_t4_kwh: float | None = field( default=None, ) power_w: float | None = field( default=None, ) power_l1_w: float | None = field( default=None, ) power_l2_w: float | None = field( default=None, ) power_l3_w: float | None = field( default=None, ) voltage_v: float | None = field( default=None, ) voltage_l1_v: float | None = field( default=None, ) voltage_l2_v: float | None = field( default=None, ) voltage_l3_v: float | None = field( default=None, ) current_a: float | None = field( default=None, ) current_l1_a: float | None = field( default=None, ) current_l2_a: float | None = field( default=None, ) current_l3_a: float | None = field( default=None, ) apparent_power_va: float | None = field( default=None, ) apparent_power_l1_va: float | None = field( default=None, ) apparent_power_l2_va: float | None = field( default=None, ) apparent_power_l3_va: float | None = field( default=None, ) reactive_power_var: float | None = field( default=None, ) reactive_power_l1_var: float | None = field( default=None, ) reactive_power_l2_var: float | None = field( default=None, ) reactive_power_l3_var: float | None = field( default=None, ) power_factor: float | None = field( default=None, ) power_factor_l1: float | None = field( default=None, ) power_factor_l2: float | None = field( default=None, ) power_factor_l3: float | None = field( default=None, ) frequency_hz: float | None = field( default=None, ) # P1 Meter specific timestamp: datetime | None = field( default=None, metadata={"deserialize": lambda x: Measurement.to_datetime(x)}, ) protocol_version: int | None = field( default=None, ) meter_model: str | None = field( default=None, ) unique_id: str | None = field( default=None, metadata={"deserialize": lambda x: Measurement.hex_to_readable(x)}, ) tariff: int | None = field( default=None, ) voltage_sag_l1_count: int | None = field( default=None, ) voltage_sag_l2_count: int | None = field( default=None, ) voltage_sag_l3_count: int | None = field( default=None, ) voltage_swell_l1_count: int | None = field( default=None, ) voltage_swell_l2_count: int | None = field( default=None, ) voltage_swell_l3_count: int | None = field( default=None, ) any_power_fail_count: int | None = field( default=None, ) long_power_fail_count: int | None = field( default=None, ) average_power_15m_w: float | None = field( default=None, ) monthly_power_peak_w: float | None = field( default=None, ) monthly_power_peak_timestamp: datetime | None = field( default=None, metadata={"deserialize": lambda x: Measurement.to_datetime(x)}, ) external_devices: dict[str, ExternalDevice] | None = field( default=None, metadata={ "alias": "external", "deserialize": lambda list: Measurement.array_to_external_device_list(list), }, ) # Watermeter Specific active_liter_lpm: float | None = field( default=None, ) total_liter_m3: float | None = field( default=None, ) # Battery Specific cycles: int | None = field( default=None, ) state_of_charge_pct: float | None = field( default=None, ) @staticmethod def array_to_external_device_list(devices: list[dict]) -> dict[str, ExternalDevice]: """Convert external device dict to list of ExternalDevice objects.""" rv: dict[str, ExternalDevice] = {} for item in devices: try: device = ExternalDevice.from_dict(item) except MissingField as e: LOGGER.error("Error converting external device: %s", e) continue rv[f"{device.type}_{device.unique_id}"] = device return rv @staticmethod def to_datetime(timestamp: str | int) -> datetime: """Convert DSRM gas-timestamp to datetime object. Args: timestamp: Timestamp string, formatted as YYMMDDHHMMSS or YYYY-MM-DDTHH:MM:SS Returns: A datetime object. """ if isinstance(timestamp, int): # V1 API uses int for timestamp return datetime.strptime(str(timestamp), "%y%m%d%H%M%S") return datetime.fromisoformat(timestamp) @staticmethod def hex_to_readable(value: str | None) -> str | None: """Convert hex string to readable string, if possible. Args: value: String to convert, e.g. '4E47475955' Returns: A string formatted or original value when failed. """ try: return bytes.fromhex(value).decode("utf-8") except (TypeError, ValueError): return value @classmethod # pylint: disable=too-many-statements def __pre_deserialize__(cls, d: dict[Any, Any]) -> dict[Any, Any]: _ = cls # Unused if "wifi_ssid" not in d: # This is a v2 API response, no need to remap return d d["protocol_version"] = d.get("smr_version") d["tariff"] = d.get("active_tariff") d["energy_import_kwh"] = d.get( "total_power_import_kwh", d.get("total_power_import_t1_kwh") ) d["energy_import_t1_kwh"] = d.get("total_power_import_t1_kwh") d["energy_import_t2_kwh"] = d.get("total_power_import_t2_kwh") d["energy_import_t3_kwh"] = d.get("total_power_import_t3_kwh") d["energy_import_t4_kwh"] = d.get("total_power_import_t4_kwh") d["energy_export_kwh"] = d.get( "total_power_export_kwh", d.get("total_power_export_t1_kwh") ) d["energy_export_t1_kwh"] = d.get("total_power_export_t1_kwh") d["energy_export_t2_kwh"] = d.get("total_power_export_t2_kwh") d["energy_export_t3_kwh"] = d.get("total_power_export_t3_kwh") d["energy_export_t4_kwh"] = d.get("total_power_export_t4_kwh") d["power_w"] = d.get("active_power_w") d["power_l1_w"] = d.get("active_power_l1_w") d["power_l2_w"] = d.get("active_power_l2_w") d["power_l3_w"] = d.get("active_power_l3_w") d["voltage_v"] = d.get("active_voltage_v") d["voltage_l1_v"] = d.get("active_voltage_l1_v") d["voltage_l2_v"] = d.get("active_voltage_l2_v") d["voltage_l3_v"] = d.get("active_voltage_l3_v") d["current_a"] = d.get("active_current_a") d["current_l1_a"] = d.get("active_current_l1_a") d["current_l2_a"] = d.get("active_current_l2_a") d["current_l3_a"] = d.get("active_current_l3_a") d["apparent_power_va"] = d.get("active_apparent_power_va") d["apparent_power_l1_va"] = d.get("active_apparent_power_l1_va") d["apparent_power_l2_va"] = d.get("active_apparent_power_l2_va") d["apparent_power_l3_va"] = d.get("active_apparent_power_l3_va") d["reactive_power_var"] = d.get("active_reactive_power_var") d["reactive_power_l1_var"] = d.get("active_reactive_power_l1_var") d["reactive_power_l2_var"] = d.get("active_reactive_power_l2_var") d["reactive_power_l3_var"] = d.get("active_reactive_power_l3_var") d["power_factor"] = d.get("active_power_factor") d["power_factor_l1"] = d.get("active_power_factor_l1") d["power_factor_l2"] = d.get("active_power_factor_l2") d["power_factor_l3"] = d.get("active_power_factor_l3") d["frequency_hz"] = d.get("active_frequency_hz") d["average_power_15m_w"] = d.get("active_power_average_w") d["monthly_power_peak_w"] = d.get("montly_power_peak_w") d["monthly_power_peak_timestamp"] = d.get("montly_power_peak_timestamp") d["external_devices"] = d.get("external_devices") return d @classmethod def __post_deserialize__(cls, obj: Measurement) -> Measurement: """Post deserialize hook for Measurement object.""" _ = cls # Unused # Some smart meters report a tariff other than 1, 2, 3 or 4, which is invalid if obj.tariff not in (1, 2, 3, 4): obj.tariff = None return obj @dataclass(kw_only=True) class ExternalDevice(BaseModel): """Represents externally connected device.""" class DeviceType(StrEnum): """Device type allocations.""" GAS_METER = "gas_meter" HEAT_METER = "heat_meter" WARM_WATER_METER = "warm_water_meter" WATER_METER = "water_meter" INLET_HEAT_METER = "inlet_heat_meter" unique_id: datetime = field( metadata={"deserialize": lambda x: Measurement.hex_to_readable(x)} ) type: DeviceType | None = field( default=None, metadata={ "deserialize": lambda x: ExternalDevice.DeviceType.__members__.get( x.upper(), None ) }, ) value: float = field() unit: str = field() timestamp: datetime = field( metadata={"deserialize": lambda x: Measurement.to_datetime(x)} ) @dataclass(kw_only=True) class StateUpdate(UpdateBaseModel): """Represent State update config.""" power_on: bool | None = field(default=None) switch_lock: bool | None = field(default=None) brightness: int | None = field(default=None) @dataclass(kw_only=True) class State(BaseModel): """Represent current state.""" power_on: bool | None = field( default=None, ) switch_lock: bool | None = field( default=None, ) brightness: int | None = field( default=None, ) @dataclass class SystemUpdate(UpdateBaseModel): """Represent System update config.""" cloud_enabled: bool | None = field(default=None) status_led_brightness_pct: int | None = field(default=None) api_v1_enabled: bool | None = field(default=None) @dataclass(kw_only=True) class System(BaseModel): """Represent System config.""" wifi_strength_pct: int | None = None wifi_ssid: str | None = field(default=None) wifi_rssi_db: int | None = field(default=None) cloud_enabled: bool | None = field(default=None) uptime_s: int | None = field(default=None) status_led_brightness_pct: int | None = field(default=None) api_v1_enabled: bool | None = field(default=None) @classmethod def __post_deserialize__(cls, obj: System) -> System: _ = cls # Unused if obj.wifi_rssi_db is not None: obj.wifi_strength_pct = ( 0 if obj.wifi_rssi_db <= -100 or obj.wifi_rssi_db == 0 else 100 if obj.wifi_rssi_db >= -50 else 2 * (obj.wifi_rssi_db + 100) ) return obj @dataclass(kw_only=True) class Token(BaseModel): """Represent Token.""" token: str = field() python-homewizard-energy-8.3.2/homewizard_energy/py.typed000066400000000000000000000000001474712727000237250ustar00rootroot00000000000000python-homewizard-energy-8.3.2/homewizard_energy/utils.py000066400000000000000000000005331474712727000237530ustar00rootroot00000000000000"""Utilities for Python HomeWizard Energy.""" from functools import lru_cache from awesomeversion import AwesomeVersion @lru_cache def get_awesome_version(version: str) -> AwesomeVersion: """Return a cached AwesomeVersion object.""" if version.lower() == "v1": return AwesomeVersion("1.0.0") return AwesomeVersion(version) python-homewizard-energy-8.3.2/homewizard_energy/v1/000077500000000000000000000000001474712727000225665ustar00rootroot00000000000000python-homewizard-energy-8.3.2/homewizard_energy/v1/__init__.py000066400000000000000000000137051474712727000247050ustar00rootroot00000000000000"""Representation of a HomeWizard Energy device.""" from __future__ import annotations import asyncio from collections.abc import Callable, Coroutine from http import HTTPStatus from typing import Any, TypeVar import async_timeout import backoff from aiohttp.client import ClientError, ClientResponseError from aiohttp.hdrs import METH_GET, METH_PUT from ..const import LOGGER from ..errors import DisabledError, NotFoundError, RequestError, UnsupportedError from ..homewizard_energy import HomeWizardEnergy from ..models import Device, Measurement, State, StateUpdate, System, SystemUpdate T = TypeVar("T") def optional_method( func: Callable[..., Coroutine[Any, Any, T]], ) -> Callable[..., Coroutine[Any, Any, T]]: """Check if method is supported.""" async def wrapper(self, *args, **kwargs) -> T: try: return await func(self, *args, **kwargs) except NotFoundError as ex: raise UnsupportedError(f"{func.__name__} is not supported") from ex return wrapper # pylint: disable=abstract-method class HomeWizardEnergyV1(HomeWizardEnergy): """Communicate with a HomeWizard Energy device.""" async def device(self, reset_cache: bool = False) -> Device: """Return the device object.""" if self._device is not None and not reset_cache: return self._device _, response = await self._request("api") device = Device.from_json(response) # Cache device object self._device = device return device async def measurement(self) -> Measurement: """Return the data object.""" _, response = await self._request("api/v1/data") return Measurement.from_json(response) @optional_method async def system( self, cloud_enabled: bool | None = None, status_led_brightness_pct: int | None = None, api_v1_enabled: bool | None = None, ) -> System: """Return the system object.""" # Legacy: raise on unsupported field if api_v1_enabled is not None: raise UnsupportedError("Setting api_v1_enabled is not supported in v1") # Legacy: route 'status_led_brightness_pct' to state if status_led_brightness_pct is not None: state = await self.state(brightness=status_led_brightness_pct * 2.55) return System(status_led_brightness_pct=state.brightness / 2.55) if cloud_enabled is not None: # Executing the update data = SystemUpdate(cloud_enabled=cloud_enabled).to_dict() _, response = await self._request( "api/v1/system", method=METH_PUT, data=data ) else: _, response = await self._request("api/v1/system") system = System.from_json(response) return system @optional_method async def state( self, power_on: bool | None = None, switch_lock: bool | None = None, brightness: int | None = None, ) -> State: """Return or update the state object.""" if self._device is not None and self._device.supports_state() is False: raise UnsupportedError("State is not supported") if power_on is not None or switch_lock is not None or brightness is not None: data = StateUpdate( power_on=power_on, switch_lock=switch_lock, brightness=brightness ).to_dict() _, response = await self._request( "api/v1/state", method=METH_PUT, data=data ) else: _, response = await self._request("api/v1/state") state = State.from_json(response) return state @optional_method async def identify( self, ) -> bool: """Send identify request.""" if self._device is not None and self._device.supports_identify() is False: raise UnsupportedError("State is not supported") await self._request("api/v1/identify", method=METH_PUT) return True @backoff.on_exception(backoff.expo, RequestError, max_tries=3, logger=None) async def _request( self, path: str, method: str = METH_GET, data: object = None ) -> tuple[HTTPStatus, dict[str, Any] | None]: """Make a request to the API.""" if self._session is None: await self._create_clientsession() # Construct request url = f"http://{self.host}/{path}" headers = {"Content-Type": "application/json"} LOGGER.debug("%s, %s, %s", method, url, data) try: async with async_timeout.timeout(self._request_timeout): resp = await self._session.request( method, url, json=data, headers=headers, ) LOGGER.debug("%s, %s", resp.status, await resp.text("utf-8")) except asyncio.TimeoutError as exception: raise RequestError( f"Timeout occurred while connecting to the HomeWizard Energy device at {self.host}" ) from exception except (ClientError, ClientResponseError) as exception: raise RequestError( f"Error occurred while communicating with the HomeWizard Energy device at {self.host}" ) from exception match resp.status: case HTTPStatus.FORBIDDEN: raise DisabledError( "API disabled. API must be enabled in HomeWizard Energy app" ) case HTTPStatus.NOT_FOUND: raise NotFoundError("Resource not found") case HTTPStatus.OK: pass if resp.status != HTTPStatus.OK: # Something else went wrong raise RequestError(f"API request error ({resp.status})") return (resp.status, await resp.text()) async def __aenter__(self) -> HomeWizardEnergyV1: """Async enter. Returns: The HomeWizardEnergyV1 object. """ return self python-homewizard-energy-8.3.2/homewizard_energy/v1/const.py000066400000000000000000000000521474712727000242630ustar00rootroot00000000000000"""Constants for HomeWizard Energy v1.""" python-homewizard-energy-8.3.2/homewizard_energy/v2/000077500000000000000000000000001474712727000225675ustar00rootroot00000000000000python-homewizard-energy-8.3.2/homewizard_energy/v2/__init__.py000066400000000000000000000220771474712727000247100ustar00rootroot00000000000000"""Representation of a HomeWizard Energy device.""" from __future__ import annotations import asyncio import json import ssl from collections.abc import Callable, Coroutine from http import HTTPStatus from typing import Any, TypeVar import async_timeout import backoff from aiohttp.client import ClientError, ClientResponseError, ClientSession from aiohttp.hdrs import METH_DELETE, METH_GET, METH_POST, METH_PUT from mashumaro.exceptions import InvalidFieldValue, MissingField from ..const import LOGGER from ..errors import ( DisabledError, InvalidUserNameError, RequestError, ResponseError, UnauthorizedError, ) from ..homewizard_energy import HomeWizardEnergy from ..models import Device, Measurement, System, SystemUpdate, Token from .cacert import CACERT T = TypeVar("T") def authorized_method( func: Callable[..., Coroutine[Any, Any, T]], ) -> Callable[..., Coroutine[Any, Any, T]]: """Decorator method to check if token is set.""" async def wrapper(self, *args, **kwargs) -> T: # pylint: disable=protected-access if self._token is None: raise UnauthorizedError("Token missing") return await func(self, *args, **kwargs) return wrapper # pylint: disable=abstract-method class HomeWizardEnergyV2(HomeWizardEnergy): """Communicate with a HomeWizard Energy device.""" _ssl: ssl.SSLContext | bool = False _identifier: str | None = None # pylint: disable=too-many-arguments # pylint: disable=too-many-positional-arguments def __init__( self, host: str, identifier: str | None = None, token: str | None = None, clientsession: ClientSession = None, timeout: int = 10, ): """Create a HomeWizard Energy object. Args: host: IP or URL for device. id: ID for device. token: Token for device. timeout: Request timeout in seconds. """ super().__init__(host, clientsession, timeout) self._identifier = identifier self._token = token @authorized_method async def device(self, reset_cache: bool = False) -> Device: """Return the device object.""" if self._device is not None and not reset_cache: return self._device _, response = await self._request("/api") device = Device.from_json(response) # Cache device object self._device = device return device @authorized_method async def measurement(self) -> Measurement: """Return the measurement object.""" _, response = await self._request("/api/measurement") measurement = Measurement.from_json(response) return measurement @authorized_method async def system( self, cloud_enabled: bool | None = None, status_led_brightness_pct: int | None = None, api_v1_enabled: bool | None = None, ) -> System: """Return the system object.""" if ( cloud_enabled is not None or status_led_brightness_pct is not None or api_v1_enabled is not None ): data = SystemUpdate( cloud_enabled=cloud_enabled, status_led_brightness_pct=status_led_brightness_pct, api_v1_enabled=api_v1_enabled, ).to_dict() status, response = await self._request( "/api/system", method=METH_PUT, data=data ) else: status, response = await self._request("/api/system") if status != HTTPStatus.OK: error = json.loads(response).get("error", response) raise RequestError(f"Failed to get system: {error}") system = System.from_json(response) return system @authorized_method async def identify( self, ) -> None: """Send identify request.""" await self._request("/api/system/identify", method=METH_PUT) @authorized_method async def reboot( self, ) -> None: """Reboot the HomeWizard Energy device. This will cause the device to restart, resulting in temporary unavailability. The reboot process typically takes a few seconds to complete. Note: A reboot is usually not necessary. Make sure to inform the user that if the issue persists and frequent reboots are required, they need to contact our support team to help identify and resolve the root cause. """ await self._request("/api/system/reboot", method=METH_PUT) async def get_token( self, name: str, ) -> str: """Get authorization token from device.""" status, response = await self._request( "/api/user", method=METH_POST, data={"name": f"local/{name}"} ) if status == HTTPStatus.FORBIDDEN: raise DisabledError("User creation is not enabled on the device") if status != HTTPStatus.OK: error = json.loads(response).get("error", response) raise InvalidUserNameError( f"Error occurred while getting token: {error}", error ) try: token = Token.from_json(response).token except (InvalidFieldValue, MissingField) as ex: raise ResponseError("Failed to get token") from ex self._token = token return token @authorized_method async def delete_token( self, name: str | None = None, ) -> None: """Delete authorization token from device.""" status, response = await self._request( "/api/user", method=METH_DELETE, data={"name": name} if name is not None else None, ) if status != HTTPStatus.NO_CONTENT: error = json.loads(response).get("error", response) raise RequestError(f"Error occurred while getting token: {error}", error) # Our token was invalided, resetting it if name is None: self._token = None async def _get_ssl_context(self) -> ssl.SSLContext: """ Get a clientsession that is tuned for communication with the HomeWizard Energy Device """ def _build_ssl_context() -> ssl.SSLContext: context = ssl.create_default_context(cadata=CACERT) context.verify_flags = ssl.VERIFY_X509_PARTIAL_CHAIN # pylint: disable=no-member if self._identifier is not None: context.hostname_checks_common_name = True else: context.check_hostname = False # Skip hostname validation context.verify_mode = ssl.CERT_REQUIRED # Keep SSL verification active return context # Creating an SSL context has some blocking IO so need to run it in the executor loop = asyncio.get_running_loop() return await loop.run_in_executor(None, _build_ssl_context) @backoff.on_exception(backoff.expo, RequestError, max_tries=3, logger=None) async def _request( self, path: str, method: str = METH_GET, data: object = None ) -> tuple[HTTPStatus, dict[str, Any] | None]: """Make a request to the API.""" async with self._lock: if self._session is None: await self._create_clientsession() async with self._lock: if self._ssl is False: self._ssl = await self._get_ssl_context() # Construct request url = f"https://{self.host}{path}" headers = { "Content-Type": "application/json", } if self._token is not None: headers["Authorization"] = f"Bearer {self._token}" LOGGER.debug("%s, %s, %s", method, url, data) try: async with async_timeout.timeout(self._request_timeout): async with self._lock: resp = await self._session.request( method, url, json=data, headers=headers, ssl=self._ssl, server_hostname=self._identifier, ) LOGGER.debug("%s, %s", resp.status, await resp.text("utf-8")) except asyncio.TimeoutError as exception: raise RequestError( f"Timeout occurred while connecting to the HomeWizard Energy device at {self.host}" ) from exception except (ClientError, ClientResponseError) as exception: raise RequestError( f"Error occurred while communicating with the HomeWizard Energy device at {self.host}" ) from exception match resp.status: case HTTPStatus.UNAUTHORIZED: raise UnauthorizedError("Token rejected") case HTTPStatus.NO_CONTENT: # No content, just return return (HTTPStatus.NO_CONTENT, None) case HTTPStatus.OK: pass return (resp.status, await resp.text()) async def __aenter__(self) -> HomeWizardEnergyV2: """Async enter. Returns: The HomeWizardEnergyV2 object. """ return self python-homewizard-energy-8.3.2/homewizard_energy/v2/cacert.py000066400000000000000000000022731474712727000244060ustar00rootroot00000000000000"""Contents of homewizard-ca-cert.pem file""" CACERT = """ -----BEGIN CERTIFICATE----- MIIDITCCAgkCFDn7cwYLioTM3VxdAygLl/Px9ovFMA0GCSqGSIb3DQEBCwUAME0x CzAJBgNVBAYTAk5MMQswCQYDVQQIDAJaSDETMBEGA1UECgwKSG9tZVdpemFyZDEc MBoGA1UEAwwTQXBwbGlhbmNlIEFjY2VzcyBDQTAeFw0yMTEyMTgxOTEyMTJaFw0z MTEyMTYxOTEyMTJaME0xCzAJBgNVBAYTAk5MMQswCQYDVQQIDAJaSDETMBEGA1UE CgwKSG9tZVdpemFyZDEcMBoGA1UEAwwTQXBwbGlhbmNlIEFjY2VzcyBDQTCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPBIvW8NRffqdvzHZY0M32fQHiGm pJgNGhiaQmpJfRDhT9yihM0S/hYcN8IqnfrMqoCQb/56Ub0+dZizmtfcGsE+Lpm1 K1znkWqSDlpnuTNOb70TrsxBmbFuNOZQEi/xOjzT2j98wT0GSfxz1RVq6lZhDRRz xoe08+Xo4+ttUGanfOggJi0BXygeFEVBpbctVVJ9EgqeEE9itjcMlcxMe1QN14f8 hCcOnId+9PSsdmyUCLrTB0FVYrbNfbJPk/vMU57fu6swBjWhYBxPx9ZhFy+7WnPR 9BFg4seHNVQIqZNrf1YwBXlmZQIL32SRPaiH/+AVNMrYGXBvncY0Km6ZHIMCAwEA ATANBgkqhkiG9w0BAQsFAAOCAQEA6ybM8xm0PCXg8Rr/q0v1vPxQy44PmwXTDj0e r2vW4ZMiEwXZCp0Kk2K16KJYz4iJyfiQk8ikAIMiRSbyXzmyQ7XmL1O4l4d8E1Pg 8EImvcyoBxFhd0Lq7VKriLc8Bw8SXbahPMGT+Y8Yz0uIsLAYVwlkLfgppVPmBaLD QautcQnI8WxPvCIQf5anyzgAyJC5ac6/CkB+iyPcuWcG3RMYvXnC0QoTlRa5YMlE FweVDlT2C/MdDyOxiAD/H1EP/eaySnU0zsxyD0yNFRKsQfQ+UJEPd2GS1AGA1lTy CGdyYj/Gghrusw0hM4rYXQSERWGF0mpEnuJ+7bHDolHu0rzgTQ== -----END CERTIFICATE----- """ python-homewizard-energy-8.3.2/homewizard_energy/v2/const.py000066400000000000000000000000521474712727000242640ustar00rootroot00000000000000"""Constants for HomeWizard Energy v2.""" python-homewizard-energy-8.3.2/poetry.lock000066400000000000000000006364211474712727000207260ustar00rootroot00000000000000# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" version = "2.4.4" description = "Happy Eyeballs for asyncio" optional = false python-versions = ">=3.8" files = [ {file = "aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8"}, {file = "aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745"}, ] [[package]] name = "aiohttp" version = "3.11.11" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.9" files = [ {file = "aiohttp-3.11.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a60804bff28662cbcf340a4d61598891f12eea3a66af48ecfdc975ceec21e3c8"}, {file = "aiohttp-3.11.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b4fa1cb5f270fb3eab079536b764ad740bb749ce69a94d4ec30ceee1b5940d5"}, {file = "aiohttp-3.11.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:731468f555656767cda219ab42e033355fe48c85fbe3ba83a349631541715ba2"}, {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb23d8bb86282b342481cad4370ea0853a39e4a32a0042bb52ca6bdde132df43"}, {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f047569d655f81cb70ea5be942ee5d4421b6219c3f05d131f64088c73bb0917f"}, {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd7659baae9ccf94ae5fe8bfaa2c7bc2e94d24611528395ce88d009107e00c6d"}, {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af01e42ad87ae24932138f154105e88da13ce7d202a6de93fafdafb2883a00ef"}, {file = "aiohttp-3.11.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5854be2f3e5a729800bac57a8d76af464e160f19676ab6aea74bde18ad19d438"}, {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6526e5fb4e14f4bbf30411216780c9967c20c5a55f2f51d3abd6de68320cc2f3"}, {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:85992ee30a31835fc482468637b3e5bd085fa8fe9392ba0bdcbdc1ef5e9e3c55"}, {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:88a12ad8ccf325a8a5ed80e6d7c3bdc247d66175afedbe104ee2aaca72960d8e"}, {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0a6d3fbf2232e3a08c41eca81ae4f1dff3d8f1a30bae415ebe0af2d2458b8a33"}, {file = "aiohttp-3.11.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84a585799c58b795573c7fa9b84c455adf3e1d72f19a2bf498b54a95ae0d194c"}, {file = "aiohttp-3.11.11-cp310-cp310-win32.whl", hash = "sha256:bfde76a8f430cf5c5584553adf9926534352251d379dcb266ad2b93c54a29745"}, {file = "aiohttp-3.11.11-cp310-cp310-win_amd64.whl", hash = "sha256:0fd82b8e9c383af11d2b26f27a478640b6b83d669440c0a71481f7c865a51da9"}, {file = "aiohttp-3.11.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ba74ec819177af1ef7f59063c6d35a214a8fde6f987f7661f4f0eecc468a8f76"}, {file = "aiohttp-3.11.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4af57160800b7a815f3fe0eba9b46bf28aafc195555f1824555fa2cfab6c1538"}, {file = "aiohttp-3.11.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ffa336210cf9cd8ed117011085817d00abe4c08f99968deef0013ea283547204"}, {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81b8fe282183e4a3c7a1b72f5ade1094ed1c6345a8f153506d114af5bf8accd9"}, {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3af41686ccec6a0f2bdc66686dc0f403c41ac2089f80e2214a0f82d001052c03"}, {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70d1f9dde0e5dd9e292a6d4d00058737052b01f3532f69c0c65818dac26dc287"}, {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:249cc6912405917344192b9f9ea5cd5b139d49e0d2f5c7f70bdfaf6b4dbf3a2e"}, {file = "aiohttp-3.11.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0eb98d90b6690827dcc84c246811feeb4e1eea683c0eac6caed7549be9c84665"}, {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec82bf1fda6cecce7f7b915f9196601a1bd1a3079796b76d16ae4cce6d0ef89b"}, {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9fd46ce0845cfe28f108888b3ab17abff84ff695e01e73657eec3f96d72eef34"}, {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:bd176afcf8f5d2aed50c3647d4925d0db0579d96f75a31e77cbaf67d8a87742d"}, {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ec2aa89305006fba9ffb98970db6c8221541be7bee4c1d027421d6f6df7d1ce2"}, {file = "aiohttp-3.11.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:92cde43018a2e17d48bb09c79e4d4cb0e236de5063ce897a5e40ac7cb4878773"}, {file = "aiohttp-3.11.11-cp311-cp311-win32.whl", hash = "sha256:aba807f9569455cba566882c8938f1a549f205ee43c27b126e5450dc9f83cc62"}, {file = "aiohttp-3.11.11-cp311-cp311-win_amd64.whl", hash = "sha256:ae545f31489548c87b0cced5755cfe5a5308d00407000e72c4fa30b19c3220ac"}, {file = "aiohttp-3.11.11-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e595c591a48bbc295ebf47cb91aebf9bd32f3ff76749ecf282ea7f9f6bb73886"}, {file = "aiohttp-3.11.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3ea1b59dc06396b0b424740a10a0a63974c725b1c64736ff788a3689d36c02d2"}, {file = "aiohttp-3.11.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8811f3f098a78ffa16e0ea36dffd577eb031aea797cbdba81be039a4169e242c"}, {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7227b87a355ce1f4bf83bfae4399b1f5bb42e0259cb9405824bd03d2f4336a"}, {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d40f9da8cabbf295d3a9dae1295c69975b86d941bc20f0a087f0477fa0a66231"}, {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffb3dc385f6bb1568aa974fe65da84723210e5d9707e360e9ecb51f59406cd2e"}, {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8f5f7515f3552d899c61202d99dcb17d6e3b0de777900405611cd747cecd1b8"}, {file = "aiohttp-3.11.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3499c7ffbfd9c6a3d8d6a2b01c26639da7e43d47c7b4f788016226b1e711caa8"}, {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8e2bf8029dbf0810c7bfbc3e594b51c4cc9101fbffb583a3923aea184724203c"}, {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b6212a60e5c482ef90f2d788835387070a88d52cf6241d3916733c9176d39eab"}, {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d119fafe7b634dbfa25a8c597718e69a930e4847f0b88e172744be24515140da"}, {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:6fba278063559acc730abf49845d0e9a9e1ba74f85f0ee6efd5803f08b285853"}, {file = "aiohttp-3.11.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:92fc484e34b733704ad77210c7957679c5c3877bd1e6b6d74b185e9320cc716e"}, {file = "aiohttp-3.11.11-cp312-cp312-win32.whl", hash = "sha256:9f5b3c1ed63c8fa937a920b6c1bec78b74ee09593b3f5b979ab2ae5ef60d7600"}, {file = "aiohttp-3.11.11-cp312-cp312-win_amd64.whl", hash = "sha256:1e69966ea6ef0c14ee53ef7a3d68b564cc408121ea56c0caa2dc918c1b2f553d"}, {file = "aiohttp-3.11.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:541d823548ab69d13d23730a06f97460f4238ad2e5ed966aaf850d7c369782d9"}, {file = "aiohttp-3.11.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:929f3ed33743a49ab127c58c3e0a827de0664bfcda566108989a14068f820194"}, {file = "aiohttp-3.11.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0882c2820fd0132240edbb4a51eb8ceb6eef8181db9ad5291ab3332e0d71df5f"}, {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b63de12e44935d5aca7ed7ed98a255a11e5cb47f83a9fded7a5e41c40277d104"}, {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa54f8ef31d23c506910c21163f22b124facb573bff73930735cf9fe38bf7dff"}, {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a344d5dc18074e3872777b62f5f7d584ae4344cd6006c17ba12103759d407af3"}, {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7fb429ab1aafa1f48578eb315ca45bd46e9c37de11fe45c7f5f4138091e2f1"}, {file = "aiohttp-3.11.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c341c7d868750e31961d6d8e60ff040fb9d3d3a46d77fd85e1ab8e76c3e9a5c4"}, {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed9ee95614a71e87f1a70bc81603f6c6760128b140bc4030abe6abaa988f1c3d"}, {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:de8d38f1c2810fa2a4f1d995a2e9c70bb8737b18da04ac2afbf3971f65781d87"}, {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a9b7371665d4f00deb8f32208c7c5e652059b0fda41cf6dbcac6114a041f1cc2"}, {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:620598717fce1b3bd14dd09947ea53e1ad510317c85dda2c9c65b622edc96b12"}, {file = "aiohttp-3.11.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf8d9bfee991d8acc72d060d53860f356e07a50f0e0d09a8dfedea1c554dd0d5"}, {file = "aiohttp-3.11.11-cp313-cp313-win32.whl", hash = "sha256:9d73ee3725b7a737ad86c2eac5c57a4a97793d9f442599bea5ec67ac9f4bdc3d"}, {file = "aiohttp-3.11.11-cp313-cp313-win_amd64.whl", hash = "sha256:c7a06301c2fb096bdb0bd25fe2011531c1453b9f2c163c8031600ec73af1cc99"}, {file = "aiohttp-3.11.11-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3e23419d832d969f659c208557de4a123e30a10d26e1e14b73431d3c13444c2e"}, {file = "aiohttp-3.11.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:21fef42317cf02e05d3b09c028712e1d73a9606f02467fd803f7c1f39cc59add"}, {file = "aiohttp-3.11.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1f21bb8d0235fc10c09ce1d11ffbd40fc50d3f08a89e4cf3a0c503dc2562247a"}, {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1642eceeaa5ab6c9b6dfeaaa626ae314d808188ab23ae196a34c9d97efb68350"}, {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2170816e34e10f2fd120f603e951630f8a112e1be3b60963a1f159f5699059a6"}, {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8be8508d110d93061197fd2d6a74f7401f73b6d12f8822bbcd6d74f2b55d71b1"}, {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4eed954b161e6b9b65f6be446ed448ed3921763cc432053ceb606f89d793927e"}, {file = "aiohttp-3.11.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6c9af134da4bc9b3bd3e6a70072509f295d10ee60c697826225b60b9959acdd"}, {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:44167fc6a763d534a6908bdb2592269b4bf30a03239bcb1654781adf5e49caf1"}, {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:479b8c6ebd12aedfe64563b85920525d05d394b85f166b7873c8bde6da612f9c"}, {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:10b4ff0ad793d98605958089fabfa350e8e62bd5d40aa65cdc69d6785859f94e"}, {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:b540bd67cfb54e6f0865ceccd9979687210d7ed1a1cc8c01f8e67e2f1e883d28"}, {file = "aiohttp-3.11.11-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dac54e8ce2ed83b1f6b1a54005c87dfed139cf3f777fdc8afc76e7841101226"}, {file = "aiohttp-3.11.11-cp39-cp39-win32.whl", hash = "sha256:568c1236b2fde93b7720f95a890741854c1200fba4a3471ff48b2934d2d93fd3"}, {file = "aiohttp-3.11.11-cp39-cp39-win_amd64.whl", hash = "sha256:943a8b052e54dfd6439fd7989f67fc6a7f2138d0a2cf0a7de5f18aa4fe7eb3b1"}, {file = "aiohttp-3.11.11.tar.gz", hash = "sha256:bb49c7f1e6ebf3821a42d81d494f538107610c3a705987f53068546b0e90303e"}, ] [package.dependencies] aiohappyeyeballs = ">=2.3.0" aiosignal = ">=1.1.2" attrs = ">=17.3.0" frozenlist = ">=1.1.1" multidict = ">=4.5,<7.0" propcache = ">=0.2.0" yarl = ">=1.17.0,<2.0" [package.extras] speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"] [[package]] name = "aiosignal" version = "1.3.2" description = "aiosignal: a list of registered asynchronous callbacks" optional = false python-versions = ">=3.9" files = [ {file = "aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5"}, {file = "aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54"}, ] [package.dependencies] frozenlist = ">=1.1.0" [[package]] name = "annotated-types" version = "0.7.0" description = "Reusable constraint types to use with typing.Annotated" optional = false python-versions = ">=3.8" files = [ {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, ] [[package]] name = "aresponses" version = "3.0.0" description = "Asyncio response mocking. Similar to the responses library used for 'requests'" optional = false python-versions = ">=3.7" files = [ {file = "aresponses-3.0.0-py3-none-any.whl", hash = "sha256:8093ab4758eb4aba91c765a50295b269ecfc0a9e7c7158954760bc0c23503970"}, {file = "aresponses-3.0.0.tar.gz", hash = "sha256:8731d0609fe4c954e21f17753dc868dca9e2e002b020a33dc9212004599b11e7"}, ] [package.dependencies] aiohttp = {version = ">=3.7.0,<3.8.dev0 || >=3.9.dev0", markers = "python_version >= \"3.12\""} pytest-asyncio = {version = ">=0.17.0", markers = "python_version >= \"3.7\""} [[package]] name = "astor" version = "0.8.1" description = "Read/rewrite/write Python ASTs" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ {file = "astor-0.8.1-py2.py3-none-any.whl", hash = "sha256:070a54e890cefb5b3739d19f30f5a5ec840ffc9c50ffa7d23cc9fc1a38ebbfc5"}, {file = "astor-0.8.1.tar.gz", hash = "sha256:6a6effda93f4e1ce9f618779b2dd1d9d84f1e32812c23a29b3fff6fd7f63fa5e"}, ] [[package]] name = "astroid" version = "3.3.8" description = "An abstract syntax tree for Python with inference support." optional = false python-versions = ">=3.9.0" files = [ {file = "astroid-3.3.8-py3-none-any.whl", hash = "sha256:187ccc0c248bfbba564826c26f070494f7bc964fd286b6d9fff4420e55de828c"}, {file = "astroid-3.3.8.tar.gz", hash = "sha256:a88c7994f914a4ea8572fac479459f4955eeccc877be3f2d959a33273b0cf40b"}, ] [[package]] name = "async-timeout" version = "5.0.1" description = "Timeout context manager for asyncio programs" optional = false python-versions = ">=3.8" files = [ {file = "async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c"}, {file = "async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3"}, ] [[package]] name = "attrs" version = "24.3.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.8" files = [ {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] [[package]] name = "authlib" version = "1.4.0" description = "The ultimate Python library in building OAuth and OpenID Connect servers and clients." optional = false python-versions = ">=3.9" files = [ {file = "Authlib-1.4.0-py2.py3-none-any.whl", hash = "sha256:4bb20b978c8b636222b549317c1815e1fe62234fc1c5efe8855d84aebf3a74e3"}, {file = "authlib-1.4.0.tar.gz", hash = "sha256:1c1e6608b5ed3624aeeee136ca7f8c120d6f51f731aa152b153d54741840e1f2"}, ] [package.dependencies] cryptography = "*" [[package]] name = "awesomeversion" version = "24.6.0" description = "One version package to rule them all, One version package to find them, One version package to bring them all, and in the darkness bind them." optional = false python-versions = "<4.0,>=3.8" files = [ {file = "awesomeversion-24.6.0-py3-none-any.whl", hash = "sha256:6768415b8954b379a25cebf21ed4f682cab10aebf3f82a6640aaaa15ec6821f2"}, {file = "awesomeversion-24.6.0.tar.gz", hash = "sha256:aee7ccbaed6f8d84e0f0364080c7734a0166d77ea6ccfcc4900b38917f1efc71"}, ] [[package]] name = "backoff" version = "2.2.1" description = "Function decoration for backoff and retry" optional = false python-versions = ">=3.7,<4.0" files = [ {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, ] [[package]] name = "bandit" version = "1.8.0" description = "Security oriented static analyser for python code." optional = false python-versions = ">=3.9" files = [ {file = "bandit-1.8.0-py3-none-any.whl", hash = "sha256:b1a61d829c0968aed625381e426aa378904b996529d048f8d908fa28f6b13e38"}, {file = "bandit-1.8.0.tar.gz", hash = "sha256:b5bfe55a095abd9fe20099178a7c6c060f844bfd4fe4c76d28e35e4c52b9d31e"}, ] [package.dependencies] colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} PyYAML = ">=5.3.1" rich = "*" stevedore = ">=1.20.0" [package.extras] baseline = ["GitPython (>=3.1.30)"] sarif = ["jschema-to-python (>=1.2.3)", "sarif-om (>=1.0.4)"] test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)"] toml = ["tomli (>=1.1.0)"] yaml = ["PyYAML"] [[package]] name = "certifi" version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, ] [[package]] name = "cffi" version = "1.17.1" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" files = [ {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, ] [package.dependencies] pycparser = "*" [[package]] name = "cfgv" version = "3.4.0" description = "Validate configuration and produce human readable error messages." optional = false python-versions = ">=3.8" files = [ {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, ] [[package]] name = "charset-normalizer" version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" files = [ {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "codespell" version = "2.3.0" description = "Codespell" optional = false python-versions = ">=3.8" files = [ {file = "codespell-2.3.0-py3-none-any.whl", hash = "sha256:a9c7cef2501c9cfede2110fd6d4e5e62296920efe9abfb84648df866e47f58d1"}, {file = "codespell-2.3.0.tar.gz", hash = "sha256:360c7d10f75e65f67bad720af7007e1060a5d395670ec11a7ed1fed9dd17471f"}, ] [package.extras] dev = ["Pygments", "build", "chardet", "pre-commit", "pytest", "pytest-cov", "pytest-dependency", "ruff", "tomli", "twine"] hard-encoding-detection = ["chardet"] toml = ["tomli"] types = ["chardet (>=5.1.0)", "mypy", "pytest", "pytest-cov", "pytest-dependency"] [[package]] name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] [[package]] name = "coverage" version = "7.6.10" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" files = [ {file = "coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78"}, {file = "coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c"}, {file = "coverage-7.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a"}, {file = "coverage-7.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165"}, {file = "coverage-7.6.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988"}, {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5"}, {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3"}, {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5"}, {file = "coverage-7.6.10-cp310-cp310-win32.whl", hash = "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244"}, {file = "coverage-7.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e"}, {file = "coverage-7.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3"}, {file = "coverage-7.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43"}, {file = "coverage-7.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132"}, {file = "coverage-7.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f"}, {file = "coverage-7.6.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994"}, {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99"}, {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd"}, {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377"}, {file = "coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8"}, {file = "coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609"}, {file = "coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853"}, {file = "coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078"}, {file = "coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0"}, {file = "coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50"}, {file = "coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022"}, {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b"}, {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0"}, {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852"}, {file = "coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359"}, {file = "coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247"}, {file = "coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9"}, {file = "coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b"}, {file = "coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690"}, {file = "coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18"}, {file = "coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c"}, {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd"}, {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e"}, {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694"}, {file = "coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6"}, {file = "coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e"}, {file = "coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe"}, {file = "coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273"}, {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8"}, {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098"}, {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb"}, {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0"}, {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf"}, {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2"}, {file = "coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312"}, {file = "coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d"}, {file = "coverage-7.6.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:656c82b8a0ead8bba147de9a89bda95064874c91a3ed43a00e687f23cc19d53a"}, {file = "coverage-7.6.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccc2b70a7ed475c68ceb548bf69cec1e27305c1c2606a5eb7c3afff56a1b3b27"}, {file = "coverage-7.6.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5e37dc41d57ceba70956fa2fc5b63c26dba863c946ace9705f8eca99daecdc4"}, {file = "coverage-7.6.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0aa9692b4fdd83a4647eeb7db46410ea1322b5ed94cd1715ef09d1d5922ba87f"}, {file = "coverage-7.6.10-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa744da1820678b475e4ba3dfd994c321c5b13381d1041fe9c608620e6676e25"}, {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c0b1818063dc9e9d838c09e3a473c1422f517889436dd980f5d721899e66f315"}, {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:59af35558ba08b758aec4d56182b222976330ef8d2feacbb93964f576a7e7a90"}, {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7ed2f37cfce1ce101e6dffdfd1c99e729dd2ffc291d02d3e2d0af8b53d13840d"}, {file = "coverage-7.6.10-cp39-cp39-win32.whl", hash = "sha256:4bcc276261505d82f0ad426870c3b12cb177752834a633e737ec5ee79bbdff18"}, {file = "coverage-7.6.10-cp39-cp39-win_amd64.whl", hash = "sha256:457574f4599d2b00f7f637a0700a6422243b3565509457b2dbd3f50703e11f59"}, {file = "coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f"}, {file = "coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23"}, ] [package.extras] toml = ["tomli"] [[package]] name = "cryptography" version = "44.0.0" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = "!=3.9.0,!=3.9.1,>=3.7" files = [ {file = "cryptography-44.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123"}, {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092"}, {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f"}, {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb"}, {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b"}, {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543"}, {file = "cryptography-44.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e"}, {file = "cryptography-44.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e"}, {file = "cryptography-44.0.0-cp37-abi3-win32.whl", hash = "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053"}, {file = "cryptography-44.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd"}, {file = "cryptography-44.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591"}, {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7"}, {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc"}, {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289"}, {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7"}, {file = "cryptography-44.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c"}, {file = "cryptography-44.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64"}, {file = "cryptography-44.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285"}, {file = "cryptography-44.0.0-cp39-abi3-win32.whl", hash = "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417"}, {file = "cryptography-44.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede"}, {file = "cryptography-44.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:37d76e6863da3774cd9db5b409a9ecfd2c71c981c38788d3fcfaf177f447b731"}, {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:f677e1268c4e23420c3acade68fac427fffcb8d19d7df95ed7ad17cdef8404f4"}, {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f5e7cb1e5e56ca0933b4873c0220a78b773b24d40d186b6738080b73d3d0a756"}, {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:8b3e6eae66cf54701ee7d9c83c30ac0a1e3fa17be486033000f2a73a12ab507c"}, {file = "cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:be4ce505894d15d5c5037167ffb7f0ae90b7be6f2a98f9a5c3442395501c32fa"}, {file = "cryptography-44.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:62901fb618f74d7d81bf408c8719e9ec14d863086efe4185afd07c352aee1d2c"}, {file = "cryptography-44.0.0.tar.gz", hash = "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02"}, ] [package.dependencies] cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} [package.extras] docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0)"] docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2)"] pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] sdist = ["build (>=1.0.0)"] ssh = ["bcrypt (>=3.1.5)"] test = ["certifi (>=2024)", "cryptography-vectors (==44.0.0)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] test-randomorder = ["pytest-randomly"] [[package]] name = "darglint" version = "1.8.1" description = "A utility for ensuring Google-style docstrings stay up to date with the source code." optional = false python-versions = ">=3.6,<4.0" files = [ {file = "darglint-1.8.1-py3-none-any.whl", hash = "sha256:5ae11c259c17b0701618a20c3da343a3eb98b3bc4b5a83d31cdd94f5ebdced8d"}, {file = "darglint-1.8.1.tar.gz", hash = "sha256:080d5106df149b199822e7ee7deb9c012b49891538f14a11be681044f0bb20da"}, ] [[package]] name = "dill" version = "0.3.9" description = "serialize all of Python" optional = false python-versions = ">=3.8" files = [ {file = "dill-0.3.9-py3-none-any.whl", hash = "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a"}, {file = "dill-0.3.9.tar.gz", hash = "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c"}, ] [package.extras] graph = ["objgraph (>=1.7.2)"] profile = ["gprof2dot (>=2022.7.29)"] [[package]] name = "distlib" version = "0.3.9" description = "Distribution utilities" optional = false python-versions = "*" files = [ {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, ] [[package]] name = "dparse" version = "0.6.4" description = "A parser for Python dependency files" optional = false python-versions = ">=3.7" files = [ {file = "dparse-0.6.4-py3-none-any.whl", hash = "sha256:fbab4d50d54d0e739fbb4dedfc3d92771003a5b9aa8545ca7a7045e3b174af57"}, {file = "dparse-0.6.4.tar.gz", hash = "sha256:90b29c39e3edc36c6284c82c4132648eaf28a01863eb3c231c2512196132201a"}, ] [package.dependencies] packaging = "*" [package.extras] all = ["pipenv", "poetry", "pyyaml"] conda = ["pyyaml"] pipenv = ["pipenv"] poetry = ["poetry"] [[package]] name = "eradicate" version = "2.3.0" description = "Removes commented-out code." optional = false python-versions = "*" files = [ {file = "eradicate-2.3.0-py3-none-any.whl", hash = "sha256:2b29b3dd27171f209e4ddd8204b70c02f0682ae95eecb353f10e8d72b149c63e"}, {file = "eradicate-2.3.0.tar.gz", hash = "sha256:06df115be3b87d0fc1c483db22a2ebb12bcf40585722810d809cc770f5031c37"}, ] [[package]] name = "filelock" version = "3.16.1" description = "A platform independent file lock." optional = false python-versions = ">=3.8" files = [ {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, ] [package.extras] docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"] testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"] typing = ["typing-extensions (>=4.12.2)"] [[package]] name = "flake8" version = "4.0.1" description = "the modular source code checker: pep8 pyflakes and co" optional = false python-versions = ">=3.6" files = [ {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"}, {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"}, ] [package.dependencies] mccabe = ">=0.6.0,<0.7.0" pycodestyle = ">=2.8.0,<2.9.0" pyflakes = ">=2.4.0,<2.5.0" [[package]] name = "flake8-bandit" version = "3.0.0" description = "Automated security testing with bandit and flake8." optional = false python-versions = ">=3.6" files = [ {file = "flake8_bandit-3.0.0-py2.py3-none-any.whl", hash = "sha256:61b617f4f7cdaa0e2b1e6bf7b68afb2b619a227bb3e3ae00dd36c213bd17900a"}, {file = "flake8_bandit-3.0.0.tar.gz", hash = "sha256:54d19427e6a8d50322a7b02e1841c0a7c22d856975f3459803320e0e18e2d6a1"}, ] [package.dependencies] bandit = ">=1.7.3" flake8 = "*" flake8-polyfill = "*" pycodestyle = "*" [[package]] name = "flake8-bugbear" version = "23.3.12" description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle." optional = false python-versions = ">=3.7" files = [ {file = "flake8-bugbear-23.3.12.tar.gz", hash = "sha256:e3e7f74c8a49ad3794a7183353026dabd68c74030d5f46571f84c1fb0eb79363"}, {file = "flake8_bugbear-23.3.12-py3-none-any.whl", hash = "sha256:beb5c7efcd7ccc2039ef66a77bb8db925e7be3531ff1cb4d0b7030d0e2113d72"}, ] [package.dependencies] attrs = ">=19.2.0" flake8 = ">=3.0.0" [package.extras] dev = ["coverage", "hypothesis", "hypothesmith (>=0.2)", "pre-commit", "pytest", "tox"] [[package]] name = "flake8-builtins" version = "2.5.0" description = "Check for python builtins being used as variables or parameters" optional = false python-versions = ">=3.8" files = [ {file = "flake8_builtins-2.5.0-py3-none-any.whl", hash = "sha256:8cac7c52c6f0708c0902b46b385bc7e368a9068965083796f1431c0d2e6550cf"}, {file = "flake8_builtins-2.5.0.tar.gz", hash = "sha256:bdaa3dd823e4f5308c5e712d19fa5f69daa52781ea874f5ea9c3637bcf56faa6"}, ] [package.dependencies] flake8 = "*" [package.extras] test = ["pytest"] [[package]] name = "flake8-comprehensions" version = "3.16.0" description = "A flake8 plugin to help you write better list/set/dict comprehensions." optional = false python-versions = ">=3.9" files = [ {file = "flake8_comprehensions-3.16.0-py3-none-any.whl", hash = "sha256:7c1eadc9d22e765f39857798febe7766b4d9c519793c6c149e3e13bf99693f70"}, {file = "flake8_comprehensions-3.16.0.tar.gz", hash = "sha256:9cbf789905a8f03f9d350fb82b17b264d9a16c7ce3542b2a7b871ef568cafabe"}, ] [package.dependencies] flake8 = ">=3,<3.2 || >3.2" [[package]] name = "flake8-docstrings" version = "1.7.0" description = "Extension for flake8 which uses pydocstyle to check docstrings" optional = false python-versions = ">=3.7" files = [ {file = "flake8_docstrings-1.7.0-py2.py3-none-any.whl", hash = "sha256:51f2344026da083fc084166a9353f5082b01f72901df422f74b4d953ae88ac75"}, {file = "flake8_docstrings-1.7.0.tar.gz", hash = "sha256:4c8cc748dc16e6869728699e5d0d685da9a10b0ea718e090b1ba088e67a941af"}, ] [package.dependencies] flake8 = ">=3" pydocstyle = ">=2.1" [[package]] name = "flake8-eradicate" version = "1.4.0" description = "Flake8 plugin to find commented out code" optional = false python-versions = ">=3.7,<4.0" files = [ {file = "flake8-eradicate-1.4.0.tar.gz", hash = "sha256:3088cfd6717d1c9c6c3ac45ef2e5f5b6c7267f7504d5a74b781500e95cb9c7e1"}, {file = "flake8_eradicate-1.4.0-py3-none-any.whl", hash = "sha256:e3bbd0871be358e908053c1ab728903c114f062ba596b4d40c852fd18f473d56"}, ] [package.dependencies] attrs = "*" eradicate = ">=2.0,<3.0" flake8 = ">=3.5,<6" [[package]] name = "flake8-markdown" version = "0.3.0" description = "Lints Python code blocks in Markdown files using flake8" optional = false python-versions = ">=3.6,<4.0" files = [ {file = "flake8-markdown-0.3.0.tar.gz", hash = "sha256:5b54f143c9568da11a9d74ce5e580e96685fe758a14933f140c6d7006041fafd"}, {file = "flake8_markdown-0.3.0-py3-none-any.whl", hash = "sha256:122705b8b26b1523c5a225a728743393d254394e142680e4af17f930cdd87386"}, ] [package.dependencies] flake8 = ">=3.0,<5.0" [[package]] name = "flake8-polyfill" version = "1.0.2" description = "Polyfill package for Flake8 plugins" optional = false python-versions = "*" files = [ {file = "flake8-polyfill-1.0.2.tar.gz", hash = "sha256:e44b087597f6da52ec6393a709e7108b2905317d0c0b744cdca6208e670d8eda"}, {file = "flake8_polyfill-1.0.2-py2.py3-none-any.whl", hash = "sha256:12be6a34ee3ab795b19ca73505e7b55826d5f6ad7230d31b18e106400169b9e9"}, ] [package.dependencies] flake8 = "*" [[package]] name = "flake8-simplify" version = "0.21.0" description = "flake8 plugin which checks for code that can be simplified" optional = false python-versions = ">=3.6.1" files = [ {file = "flake8_simplify-0.21.0-py3-none-any.whl", hash = "sha256:439391e762a9370b371208add0b5c5c40c3d25a98e1f5421d263215d08194183"}, {file = "flake8_simplify-0.21.0.tar.gz", hash = "sha256:c95ff1dcc1de5949af47e0087cbf1164445881131b15bcd7a71252670f492f4d"}, ] [package.dependencies] astor = ">=0.1" flake8 = ">=3.7" [[package]] name = "frozenlist" version = "1.5.0" description = "A list-like structure which implements collections.abc.MutableSequence" optional = false python-versions = ">=3.8" files = [ {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a"}, {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb"}, {file = "frozenlist-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:15538c0cbf0e4fa11d1e3a71f823524b0c46299aed6e10ebb4c2089abd8c3bec"}, {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e79225373c317ff1e35f210dd5f1344ff31066ba8067c307ab60254cd3a78ad5"}, {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9272fa73ca71266702c4c3e2d4a28553ea03418e591e377a03b8e3659d94fa76"}, {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:498524025a5b8ba81695761d78c8dd7382ac0b052f34e66939c42df860b8ff17"}, {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92b5278ed9d50fe610185ecd23c55d8b307d75ca18e94c0e7de328089ac5dcba"}, {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f3c8c1dacd037df16e85227bac13cca58c30da836c6f936ba1df0c05d046d8d"}, {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f2ac49a9bedb996086057b75bf93538240538c6d9b38e57c82d51f75a73409d2"}, {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e66cc454f97053b79c2ab09c17fbe3c825ea6b4de20baf1be28919460dd7877f"}, {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:5a3ba5f9a0dfed20337d3e966dc359784c9f96503674c2faf015f7fe8e96798c"}, {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6321899477db90bdeb9299ac3627a6a53c7399c8cd58d25da094007402b039ab"}, {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76e4753701248476e6286f2ef492af900ea67d9706a0155335a40ea21bf3b2f5"}, {file = "frozenlist-1.5.0-cp310-cp310-win32.whl", hash = "sha256:977701c081c0241d0955c9586ffdd9ce44f7a7795df39b9151cd9a6fd0ce4cfb"}, {file = "frozenlist-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:189f03b53e64144f90990d29a27ec4f7997d91ed3d01b51fa39d2dbe77540fd4"}, {file = "frozenlist-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fd74520371c3c4175142d02a976aee0b4cb4a7cc912a60586ffd8d5929979b30"}, {file = "frozenlist-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2f3f7a0fbc219fb4455264cae4d9f01ad41ae6ee8524500f381de64ffaa077d5"}, {file = "frozenlist-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f47c9c9028f55a04ac254346e92977bf0f166c483c74b4232bee19a6697e4778"}, {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0996c66760924da6e88922756d99b47512a71cfd45215f3570bf1e0b694c206a"}, {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2fe128eb4edeabe11896cb6af88fca5346059f6c8d807e3b910069f39157869"}, {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a8ea951bbb6cacd492e3948b8da8c502a3f814f5d20935aae74b5df2b19cf3d"}, {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de537c11e4aa01d37db0d403b57bd6f0546e71a82347a97c6a9f0dcc532b3a45"}, {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c2623347b933fcb9095841f1cc5d4ff0b278addd743e0e966cb3d460278840d"}, {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cee6798eaf8b1416ef6909b06f7dc04b60755206bddc599f52232606e18179d3"}, {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f5f9da7f5dbc00a604fe74aa02ae7c98bcede8a3b8b9666f9f86fc13993bc71a"}, {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:90646abbc7a5d5c7c19461d2e3eeb76eb0b204919e6ece342feb6032c9325ae9"}, {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bdac3c7d9b705d253b2ce370fde941836a5f8b3c5c2b8fd70940a3ea3af7f4f2"}, {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03d33c2ddbc1816237a67f66336616416e2bbb6beb306e5f890f2eb22b959cdf"}, {file = "frozenlist-1.5.0-cp311-cp311-win32.whl", hash = "sha256:237f6b23ee0f44066219dae14c70ae38a63f0440ce6750f868ee08775073f942"}, {file = "frozenlist-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:0cc974cc93d32c42e7b0f6cf242a6bd941c57c61b618e78b6c0a96cb72788c1d"}, {file = "frozenlist-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21"}, {file = "frozenlist-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d"}, {file = "frozenlist-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e"}, {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a"}, {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a"}, {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee"}, {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6"}, {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e"}, {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9"}, {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039"}, {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784"}, {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631"}, {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f"}, {file = "frozenlist-1.5.0-cp312-cp312-win32.whl", hash = "sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8"}, {file = "frozenlist-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f"}, {file = "frozenlist-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7a1a048f9215c90973402e26c01d1cff8a209e1f1b53f72b95c13db61b00f953"}, {file = "frozenlist-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dd47a5181ce5fcb463b5d9e17ecfdb02b678cca31280639255ce9d0e5aa67af0"}, {file = "frozenlist-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1431d60b36d15cda188ea222033eec8e0eab488f39a272461f2e6d9e1a8e63c2"}, {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6482a5851f5d72767fbd0e507e80737f9c8646ae7fd303def99bfe813f76cf7f"}, {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44c49271a937625619e862baacbd037a7ef86dd1ee215afc298a417ff3270608"}, {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:12f78f98c2f1c2429d42e6a485f433722b0061d5c0b0139efa64f396efb5886b"}, {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce3aa154c452d2467487765e3adc730a8c153af77ad84096bc19ce19a2400840"}, {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b7dc0c4338e6b8b091e8faf0db3168a37101943e687f373dce00959583f7439"}, {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45e0896250900b5aa25180f9aec243e84e92ac84bd4a74d9ad4138ef3f5c97de"}, {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:561eb1c9579d495fddb6da8959fd2a1fca2c6d060d4113f5844b433fc02f2641"}, {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:df6e2f325bfee1f49f81aaac97d2aa757c7646534a06f8f577ce184afe2f0a9e"}, {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:140228863501b44b809fb39ec56b5d4071f4d0aa6d216c19cbb08b8c5a7eadb9"}, {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7707a25d6a77f5d27ea7dc7d1fc608aa0a478193823f88511ef5e6b8a48f9d03"}, {file = "frozenlist-1.5.0-cp313-cp313-win32.whl", hash = "sha256:31a9ac2b38ab9b5a8933b693db4939764ad3f299fcaa931a3e605bc3460e693c"}, {file = "frozenlist-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:11aabdd62b8b9c4b84081a3c246506d1cddd2dd93ff0ad53ede5defec7886b28"}, {file = "frozenlist-1.5.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:dd94994fc91a6177bfaafd7d9fd951bc8689b0a98168aa26b5f543868548d3ca"}, {file = "frozenlist-1.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0da8bbec082bf6bf18345b180958775363588678f64998c2b7609e34719b10"}, {file = "frozenlist-1.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:73f2e31ea8dd7df61a359b731716018c2be196e5bb3b74ddba107f694fbd7604"}, {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:828afae9f17e6de596825cf4228ff28fbdf6065974e5ac1410cecc22f699d2b3"}, {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1577515d35ed5649d52ab4319db757bb881ce3b2b796d7283e6634d99ace307"}, {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2150cc6305a2c2ab33299453e2968611dacb970d2283a14955923062c8d00b10"}, {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a72b7a6e3cd2725eff67cd64c8f13335ee18fc3c7befc05aed043d24c7b9ccb9"}, {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c16d2fa63e0800723139137d667e1056bee1a1cf7965153d2d104b62855e9b99"}, {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:17dcc32fc7bda7ce5875435003220a457bcfa34ab7924a49a1c19f55b6ee185c"}, {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:97160e245ea33d8609cd2b8fd997c850b56db147a304a262abc2b3be021a9171"}, {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f1e6540b7fa044eee0bb5111ada694cf3dc15f2b0347ca125ee9ca984d5e9e6e"}, {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:91d6c171862df0a6c61479d9724f22efb6109111017c87567cfeb7b5d1449fdf"}, {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c1fac3e2ace2eb1052e9f7c7db480818371134410e1f5c55d65e8f3ac6d1407e"}, {file = "frozenlist-1.5.0-cp38-cp38-win32.whl", hash = "sha256:b97f7b575ab4a8af9b7bc1d2ef7f29d3afee2226bd03ca3875c16451ad5a7723"}, {file = "frozenlist-1.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:374ca2dabdccad8e2a76d40b1d037f5bd16824933bf7bcea3e59c891fd4a0923"}, {file = "frozenlist-1.5.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9bbcdfaf4af7ce002694a4e10a0159d5a8d20056a12b05b45cea944a4953f972"}, {file = "frozenlist-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1893f948bf6681733aaccf36c5232c231e3b5166d607c5fa77773611df6dc336"}, {file = "frozenlist-1.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2b5e23253bb709ef57a8e95e6ae48daa9ac5f265637529e4ce6b003a37b2621f"}, {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f253985bb515ecd89629db13cb58d702035ecd8cfbca7d7a7e29a0e6d39af5f"}, {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04a5c6babd5e8fb7d3c871dc8b321166b80e41b637c31a995ed844a6139942b6"}, {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9fe0f1c29ba24ba6ff6abf688cb0b7cf1efab6b6aa6adc55441773c252f7411"}, {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:226d72559fa19babe2ccd920273e767c96a49b9d3d38badd7c91a0fdeda8ea08"}, {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15b731db116ab3aedec558573c1a5eec78822b32292fe4f2f0345b7f697745c2"}, {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:366d8f93e3edfe5a918c874702f78faac300209a4d5bf38352b2c1bdc07a766d"}, {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1b96af8c582b94d381a1c1f51ffaedeb77c821c690ea5f01da3d70a487dd0a9b"}, {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c03eff4a41bd4e38415cbed054bbaff4a075b093e2394b6915dca34a40d1e38b"}, {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:50cf5e7ee9b98f22bdecbabf3800ae78ddcc26e4a435515fc72d97903e8488e0"}, {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e76bfbc72353269c44e0bc2cfe171900fbf7f722ad74c9a7b638052afe6a00c"}, {file = "frozenlist-1.5.0-cp39-cp39-win32.whl", hash = "sha256:666534d15ba8f0fda3f53969117383d5dc021266b3c1a42c9ec4855e4b58b9d3"}, {file = "frozenlist-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:5c28f4b5dbef8a0d8aad0d4de24d1e9e981728628afaf4ea0792f5d0939372f0"}, {file = "frozenlist-1.5.0-py3-none-any.whl", hash = "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3"}, {file = "frozenlist-1.5.0.tar.gz", hash = "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817"}, ] [[package]] name = "identify" version = "2.6.5" description = "File identification library for Python" optional = false python-versions = ">=3.9" files = [ {file = "identify-2.6.5-py2.py3-none-any.whl", hash = "sha256:14181a47091eb75b337af4c23078c9d09225cd4c48929f521f3bf16b09d02566"}, {file = "identify-2.6.5.tar.gz", hash = "sha256:c10b33f250e5bba374fae86fb57f3adcebf1161bce7cdf92031915fd480c13bc"}, ] [package.extras] license = ["ukkonen"] [[package]] name = "idna" version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" files = [ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, ] [package.extras] all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] [[package]] name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.7" files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] [[package]] name = "isort" version = "5.13.2" description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.8.0" files = [ {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, ] [package.extras] colors = ["colorama (>=0.4.6)"] [[package]] name = "jinja2" version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] MarkupSafe = ">=2.0" [package.extras] i18n = ["Babel (>=2.7)"] [[package]] name = "markdown-it-py" version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" optional = false python-versions = ">=3.8" files = [ {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, ] [package.dependencies] mdurl = ">=0.1,<1.0" [package.extras] benchmarking = ["psutil", "pytest", "pytest-benchmark"] code-style = ["pre-commit (>=3.0,<4.0)"] compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] linkify = ["linkify-it-py (>=1,<3)"] plugins = ["mdit-py-plugins"] profiling = ["gprof2dot"] rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "markupsafe" version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" files = [ {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] name = "marshmallow" version = "3.23.3" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." optional = false python-versions = ">=3.9" files = [ {file = "marshmallow-3.23.3-py3-none-any.whl", hash = "sha256:20c0f8c613f68bcb45b2a0d3282e2f172575560170bf220d67aafb42717910e4"}, {file = "marshmallow-3.23.3.tar.gz", hash = "sha256:d586c8685ebdb80bf754e1f96e3f305aaf30951f1fc69175b977453633467e76"}, ] [package.dependencies] packaging = ">=17.0" [package.extras] dev = ["marshmallow[tests]", "pre-commit (>=3.5,<5.0)", "tox"] docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.14)", "sphinx (==8.1.3)", "sphinx-issues (==5.0.0)"] tests = ["pytest", "simplejson"] [[package]] name = "mashumaro" version = "3.15" description = "Fast and well tested serialization library" optional = false python-versions = ">=3.9" files = [ {file = "mashumaro-3.15-py3-none-any.whl", hash = "sha256:cdd45ef5a4d09860846a3ee37a4c2f5f4bc70eb158caa55648c4c99451ca6c4c"}, {file = "mashumaro-3.15.tar.gz", hash = "sha256:32a2a38a1e942a07f2cbf9c3061cb2a247714ee53e36a5958548b66bd116d0a9"}, ] [package.dependencies] typing-extensions = ">=4.1.0" [package.extras] msgpack = ["msgpack (>=0.5.6)"] orjson = ["orjson"] toml = ["tomli (>=1.1.0)", "tomli-w (>=1.0)"] yaml = ["pyyaml (>=3.13)"] [[package]] name = "mccabe" version = "0.6.1" description = "McCabe checker, plugin for flake8" optional = false python-versions = "*" files = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] [[package]] name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" optional = false python-versions = ">=3.7" files = [ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] [[package]] name = "multidict" version = "6.1.0" description = "multidict implementation" optional = false python-versions = ">=3.8" files = [ {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3380252550e372e8511d49481bd836264c009adb826b23fefcc5dd3c69692f60"}, {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99f826cbf970077383d7de805c0681799491cb939c25450b9b5b3ced03ca99f1"}, {file = "multidict-6.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a114d03b938376557927ab23f1e950827c3b893ccb94b62fd95d430fd0e5cf53"}, {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1c416351ee6271b2f49b56ad7f308072f6f44b37118d69c2cad94f3fa8a40d5"}, {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b5d83030255983181005e6cfbac1617ce9746b219bc2aad52201ad121226581"}, {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3e97b5e938051226dc025ec80980c285b053ffb1e25a3db2a3aa3bc046bf7f56"}, {file = "multidict-6.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d618649d4e70ac6efcbba75be98b26ef5078faad23592f9b51ca492953012429"}, {file = "multidict-6.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10524ebd769727ac77ef2278390fb0068d83f3acb7773792a5080f2b0abf7748"}, {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ff3827aef427c89a25cc96ded1759271a93603aba9fb977a6d264648ebf989db"}, {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:06809f4f0f7ab7ea2cabf9caca7d79c22c0758b58a71f9d32943ae13c7ace056"}, {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f179dee3b863ab1c59580ff60f9d99f632f34ccb38bf67a33ec6b3ecadd0fd76"}, {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:aaed8b0562be4a0876ee3b6946f6869b7bcdb571a5d1496683505944e268b160"}, {file = "multidict-6.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3c8b88a2ccf5493b6c8da9076fb151ba106960a2df90c2633f342f120751a9e7"}, {file = "multidict-6.1.0-cp310-cp310-win32.whl", hash = "sha256:4a9cb68166a34117d6646c0023c7b759bf197bee5ad4272f420a0141d7eb03a0"}, {file = "multidict-6.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:20b9b5fbe0b88d0bdef2012ef7dee867f874b72528cf1d08f1d59b0e3850129d"}, {file = "multidict-6.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3efe2c2cb5763f2f1b275ad2bf7a287d3f7ebbef35648a9726e3b69284a4f3d6"}, {file = "multidict-6.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7053d3b0353a8b9de430a4f4b4268ac9a4fb3481af37dfe49825bf45ca24156"}, {file = "multidict-6.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27e5fc84ccef8dfaabb09d82b7d179c7cf1a3fbc8a966f8274fcb4ab2eb4cadb"}, {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2b90b43e696f25c62656389d32236e049568b39320e2735d51f08fd362761b"}, {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d83a047959d38a7ff552ff94be767b7fd79b831ad1cd9920662db05fec24fe72"}, {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1a9dd711d0877a1ece3d2e4fea11a8e75741ca21954c919406b44e7cf971304"}, {file = "multidict-6.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec2abea24d98246b94913b76a125e855eb5c434f7c46546046372fe60f666351"}, {file = "multidict-6.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4867cafcbc6585e4b678876c489b9273b13e9fff9f6d6d66add5e15d11d926cb"}, {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5b48204e8d955c47c55b72779802b219a39acc3ee3d0116d5080c388970b76e3"}, {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d8fff389528cad1618fb4b26b95550327495462cd745d879a8c7c2115248e399"}, {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a7a9541cd308eed5e30318430a9c74d2132e9a8cb46b901326272d780bf2d423"}, {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:da1758c76f50c39a2efd5e9859ce7d776317eb1dd34317c8152ac9251fc574a3"}, {file = "multidict-6.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c943a53e9186688b45b323602298ab727d8865d8c9ee0b17f8d62d14b56f0753"}, {file = "multidict-6.1.0-cp311-cp311-win32.whl", hash = "sha256:90f8717cb649eea3504091e640a1b8568faad18bd4b9fcd692853a04475a4b80"}, {file = "multidict-6.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:82176036e65644a6cc5bd619f65f6f19781e8ec2e5330f51aa9ada7504cc1926"}, {file = "multidict-6.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b04772ed465fa3cc947db808fa306d79b43e896beb677a56fb2347ca1a49c1fa"}, {file = "multidict-6.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6180c0ae073bddeb5a97a38c03f30c233e0a4d39cd86166251617d1bbd0af436"}, {file = "multidict-6.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:071120490b47aa997cca00666923a83f02c7fbb44f71cf7f136df753f7fa8761"}, {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50b3a2710631848991d0bf7de077502e8994c804bb805aeb2925a981de58ec2e"}, {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b58c621844d55e71c1b7f7c498ce5aa6985d743a1a59034c57a905b3f153c1ef"}, {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55b6d90641869892caa9ca42ff913f7ff1c5ece06474fbd32fb2cf6834726c95"}, {file = "multidict-6.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b820514bfc0b98a30e3d85462084779900347e4d49267f747ff54060cc33925"}, {file = "multidict-6.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10a9b09aba0c5b48c53761b7c720aaaf7cf236d5fe394cd399c7ba662d5f9966"}, {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e16bf3e5fc9f44632affb159d30a437bfe286ce9e02754759be5536b169b305"}, {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76f364861c3bfc98cbbcbd402d83454ed9e01a5224bb3a28bf70002a230f73e2"}, {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:820c661588bd01a0aa62a1283f20d2be4281b086f80dad9e955e690c75fb54a2"}, {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0e5f362e895bc5b9e67fe6e4ded2492d8124bdf817827f33c5b46c2fe3ffaca6"}, {file = "multidict-6.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ec660d19bbc671e3a6443325f07263be452c453ac9e512f5eb935e7d4ac28b3"}, {file = "multidict-6.1.0-cp312-cp312-win32.whl", hash = "sha256:58130ecf8f7b8112cdb841486404f1282b9c86ccb30d3519faf301b2e5659133"}, {file = "multidict-6.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:188215fc0aafb8e03341995e7c4797860181562380f81ed0a87ff455b70bf1f1"}, {file = "multidict-6.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d569388c381b24671589335a3be6e1d45546c2988c2ebe30fdcada8457a31008"}, {file = "multidict-6.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:052e10d2d37810b99cc170b785945421141bf7bb7d2f8799d431e7db229c385f"}, {file = "multidict-6.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f90c822a402cb865e396a504f9fc8173ef34212a342d92e362ca498cad308e28"}, {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b225d95519a5bf73860323e633a664b0d85ad3d5bede6d30d95b35d4dfe8805b"}, {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:23bfd518810af7de1116313ebd9092cb9aa629beb12f6ed631ad53356ed6b86c"}, {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c09fcfdccdd0b57867577b719c69e347a436b86cd83747f179dbf0cc0d4c1f3"}, {file = "multidict-6.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf6bea52ec97e95560af5ae576bdac3aa3aae0b6758c6efa115236d9e07dae44"}, {file = "multidict-6.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57feec87371dbb3520da6192213c7d6fc892d5589a93db548331954de8248fd2"}, {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0c3f390dc53279cbc8ba976e5f8035eab997829066756d811616b652b00a23a3"}, {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:59bfeae4b25ec05b34f1956eaa1cb38032282cd4dfabc5056d0a1ec4d696d3aa"}, {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b2f59caeaf7632cc633b5cf6fc449372b83bbdf0da4ae04d5be36118e46cc0aa"}, {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:37bb93b2178e02b7b618893990941900fd25b6b9ac0fa49931a40aecdf083fe4"}, {file = "multidict-6.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4e9f48f58c2c523d5a06faea47866cd35b32655c46b443f163d08c6d0ddb17d6"}, {file = "multidict-6.1.0-cp313-cp313-win32.whl", hash = "sha256:3a37ffb35399029b45c6cc33640a92bef403c9fd388acce75cdc88f58bd19a81"}, {file = "multidict-6.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:e9aa71e15d9d9beaad2c6b9319edcdc0a49a43ef5c0a4c8265ca9ee7d6c67774"}, {file = "multidict-6.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:db7457bac39421addd0c8449933ac32d8042aae84a14911a757ae6ca3eef1392"}, {file = "multidict-6.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d094ddec350a2fb899fec68d8353c78233debde9b7d8b4beeafa70825f1c281a"}, {file = "multidict-6.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5845c1fd4866bb5dd3125d89b90e57ed3138241540897de748cdf19de8a2fca2"}, {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9079dfc6a70abe341f521f78405b8949f96db48da98aeb43f9907f342f627cdc"}, {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3914f5aaa0f36d5d60e8ece6a308ee1c9784cd75ec8151062614657a114c4478"}, {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c08be4f460903e5a9d0f76818db3250f12e9c344e79314d1d570fc69d7f4eae4"}, {file = "multidict-6.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d093be959277cb7dee84b801eb1af388b6ad3ca6a6b6bf1ed7585895789d027d"}, {file = "multidict-6.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3702ea6872c5a2a4eeefa6ffd36b042e9773f05b1f37ae3ef7264b1163c2dcf6"}, {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2090f6a85cafc5b2db085124d752757c9d251548cedabe9bd31afe6363e0aff2"}, {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:f67f217af4b1ff66c68a87318012de788dd95fcfeb24cc889011f4e1c7454dfd"}, {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:189f652a87e876098bbc67b4da1049afb5f5dfbaa310dd67c594b01c10388db6"}, {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:6bb5992037f7a9eff7991ebe4273ea7f51f1c1c511e6a2ce511d0e7bdb754492"}, {file = "multidict-6.1.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f4c2b9e770c4e393876e35a7046879d195cd123b4f116d299d442b335bcd"}, {file = "multidict-6.1.0-cp38-cp38-win32.whl", hash = "sha256:e27bbb6d14416713a8bd7aaa1313c0fc8d44ee48d74497a0ff4c3a1b6ccb5167"}, {file = "multidict-6.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:22f3105d4fb15c8f57ff3959a58fcab6ce36814486500cd7485651230ad4d4ef"}, {file = "multidict-6.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4e18b656c5e844539d506a0a06432274d7bd52a7487e6828c63a63d69185626c"}, {file = "multidict-6.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a185f876e69897a6f3325c3f19f26a297fa058c5e456bfcff8015e9a27e83ae1"}, {file = "multidict-6.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab7c4ceb38d91570a650dba194e1ca87c2b543488fe9309b4212694174fd539c"}, {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e617fb6b0b6953fffd762669610c1c4ffd05632c138d61ac7e14ad187870669c"}, {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16e5f4bf4e603eb1fdd5d8180f1a25f30056f22e55ce51fb3d6ad4ab29f7d96f"}, {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c035da3f544b1882bac24115f3e2e8760f10a0107614fc9839fd232200b875"}, {file = "multidict-6.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:957cf8e4b6e123a9eea554fa7ebc85674674b713551de587eb318a2df3e00255"}, {file = "multidict-6.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:483a6aea59cb89904e1ceabd2b47368b5600fb7de78a6e4a2c2987b2d256cf30"}, {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:87701f25a2352e5bf7454caa64757642734da9f6b11384c1f9d1a8e699758057"}, {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:682b987361e5fd7a139ed565e30d81fd81e9629acc7d925a205366877d8c8657"}, {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce2186a7df133a9c895dea3331ddc5ddad42cdd0d1ea2f0a51e5d161e4762f28"}, {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9f636b730f7e8cb19feb87094949ba54ee5357440b9658b2a32a5ce4bce53972"}, {file = "multidict-6.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:73eae06aa53af2ea5270cc066dcaf02cc60d2994bbb2c4ef5764949257d10f43"}, {file = "multidict-6.1.0-cp39-cp39-win32.whl", hash = "sha256:1ca0083e80e791cffc6efce7660ad24af66c8d4079d2a750b29001b53ff59ada"}, {file = "multidict-6.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:aa466da5b15ccea564bdab9c89175c762bc12825f4659c11227f515cee76fa4a"}, {file = "multidict-6.1.0-py3-none-any.whl", hash = "sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506"}, {file = "multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a"}, ] [[package]] name = "nodeenv" version = "1.9.1" description = "Node.js virtual environment builder" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, ] [[package]] name = "orjson" version = "3.10.13" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ {file = "orjson-3.10.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1232c5e873a4d1638ef957c5564b4b0d6f2a6ab9e207a9b3de9de05a09d1d920"}, {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26a0eca3035619fa366cbaf49af704c7cb1d4a0e6c79eced9f6a3f2437964b6"}, {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d4b6acd7c9c829895e50d385a357d4b8c3fafc19c5989da2bae11783b0fd4977"}, {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1884e53c6818686891cc6fc5a3a2540f2f35e8c76eac8dc3b40480fb59660b00"}, {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a428afb5720f12892f64920acd2eeb4d996595bf168a26dd9190115dbf1130d"}, {file = "orjson-3.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5b13b8739ce5b630c65cb1c85aedbd257bcc2b9c256b06ab2605209af75a2e"}, {file = "orjson-3.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cab83e67f6aabda1b45882254b2598b48b80ecc112968fc6483fa6dae609e9f0"}, {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:62c3cc00c7e776c71c6b7b9c48c5d2701d4c04e7d1d7cdee3572998ee6dc57cc"}, {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:dc03db4922e75bbc870b03fc49734cefbd50fe975e0878327d200022210b82d8"}, {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:22f1c9a30b43d14a041a6ea190d9eca8a6b80c4beb0e8b67602c82d30d6eec3e"}, {file = "orjson-3.10.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b42f56821c29e697c68d7d421410d7c1d8f064ae288b525af6a50cf99a4b1200"}, {file = "orjson-3.10.13-cp310-cp310-win32.whl", hash = "sha256:0dbf3b97e52e093d7c3e93eb5eb5b31dc7535b33c2ad56872c83f0160f943487"}, {file = "orjson-3.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:46c249b4e934453be4ff2e518cd1adcd90467da7391c7a79eaf2fbb79c51e8c7"}, {file = "orjson-3.10.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a36c0d48d2f084c800763473020a12976996f1109e2fcb66cfea442fdf88047f"}, {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0065896f85d9497990731dfd4a9991a45b0a524baec42ef0a63c34630ee26fd6"}, {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92b4ec30d6025a9dcdfe0df77063cbce238c08d0404471ed7a79f309364a3d19"}, {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a94542d12271c30044dadad1125ee060e7a2048b6c7034e432e116077e1d13d2"}, {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3723e137772639af8adb68230f2aa4bcb27c48b3335b1b1e2d49328fed5e244c"}, {file = "orjson-3.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f00c7fb18843bad2ac42dc1ce6dd214a083c53f1e324a0fd1c8137c6436269b"}, {file = "orjson-3.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0e2759d3172300b2f892dee85500b22fca5ac49e0c42cfff101aaf9c12ac9617"}, {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee948c6c01f6b337589c88f8e0bb11e78d32a15848b8b53d3f3b6fea48842c12"}, {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa6fe68f0981fba0d4bf9cdc666d297a7cdba0f1b380dcd075a9a3dd5649a69e"}, {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbcd7aad6bcff258f6896abfbc177d54d9b18149c4c561114f47ebfe74ae6bfd"}, {file = "orjson-3.10.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2149e2fcd084c3fd584881c7f9d7f9e5ad1e2e006609d8b80649655e0d52cd02"}, {file = "orjson-3.10.13-cp311-cp311-win32.whl", hash = "sha256:89367767ed27b33c25c026696507c76e3d01958406f51d3a2239fe9e91959df2"}, {file = "orjson-3.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:dca1d20f1af0daff511f6e26a27354a424f0b5cf00e04280279316df0f604a6f"}, {file = "orjson-3.10.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a3614b00621c77f3f6487792238f9ed1dd8a42f2ec0e6540ee34c2d4e6db813a"}, {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c976bad3996aa027cd3aef78aa57873f3c959b6c38719de9724b71bdc7bd14b"}, {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f74d878d1efb97a930b8a9f9898890067707d683eb5c7e20730030ecb3fb930"}, {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:33ef84f7e9513fb13b3999c2a64b9ca9c8143f3da9722fbf9c9ce51ce0d8076e"}, {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd2bcde107221bb9c2fa0c4aaba735a537225104173d7e19cf73f70b3126c993"}, {file = "orjson-3.10.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:064b9dbb0217fd64a8d016a8929f2fae6f3312d55ab3036b00b1d17399ab2f3e"}, {file = "orjson-3.10.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0044b0b8c85a565e7c3ce0a72acc5d35cda60793edf871ed94711e712cb637d"}, {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7184f608ad563032e398f311910bc536e62b9fbdca2041be889afcbc39500de8"}, {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d36f689e7e1b9b6fb39dbdebc16a6f07cbe994d3644fb1c22953020fc575935f"}, {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:54433e421618cd5873e51c0e9d0b9fb35f7bf76eb31c8eab20b3595bb713cd3d"}, {file = "orjson-3.10.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e1ba0c5857dd743438acecc1cd0e1adf83f0a81fee558e32b2b36f89e40cee8b"}, {file = "orjson-3.10.13-cp312-cp312-win32.whl", hash = "sha256:a42b9fe4b0114b51eb5cdf9887d8c94447bc59df6dbb9c5884434eab947888d8"}, {file = "orjson-3.10.13-cp312-cp312-win_amd64.whl", hash = "sha256:3a7df63076435f39ec024bdfeb4c9767ebe7b49abc4949068d61cf4857fa6d6c"}, {file = "orjson-3.10.13-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2cdaf8b028a976ebab837a2c27b82810f7fc76ed9fb243755ba650cc83d07730"}, {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a946796e390cbb803e069472de37f192b7a80f4ac82e16d6eb9909d9e39d56"}, {file = "orjson-3.10.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d64f1db5ecbc21eb83097e5236d6ab7e86092c1cd4c216c02533332951afc"}, {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:711878da48f89df194edd2ba603ad42e7afed74abcd2bac164685e7ec15f96de"}, {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:cf16f06cb77ce8baf844bc222dbcb03838f61d0abda2c3341400c2b7604e436e"}, {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8257c3fb8dd7b0b446b5e87bf85a28e4071ac50f8c04b6ce2d38cb4abd7dff57"}, {file = "orjson-3.10.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9c3a87abe6f849a4a7ac8a8a1dede6320a4303d5304006b90da7a3cd2b70d2c"}, {file = "orjson-3.10.13-cp313-cp313-win32.whl", hash = "sha256:527afb6ddb0fa3fe02f5d9fba4920d9d95da58917826a9be93e0242da8abe94a"}, {file = "orjson-3.10.13-cp313-cp313-win_amd64.whl", hash = "sha256:b5f7c298d4b935b222f52d6c7f2ba5eafb59d690d9a3840b7b5c5cda97f6ec5c"}, {file = "orjson-3.10.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e49333d1038bc03a25fdfe11c86360df9b890354bfe04215f1f54d030f33c342"}, {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:003721c72930dbb973f25c5d8e68d0f023d6ed138b14830cc94e57c6805a2eab"}, {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:63664bf12addb318dc8f032160e0f5dc17eb8471c93601e8f5e0d07f95003784"}, {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6066729cf9552d70de297b56556d14b4f49c8f638803ee3c90fd212fa43cc6af"}, {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a1152e2761025c5d13b5e1908d4b1c57f3797ba662e485ae6f26e4e0c466388"}, {file = "orjson-3.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b21d91c5c5ef8a201036d207b1adf3aa596b930b6ca3c71484dd11386cf6c3"}, {file = "orjson-3.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b12a63f48bb53dba8453d36ca2661f2330126d54e26c1661e550b32864b28ce3"}, {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:a5a7624ab4d121c7e035708c8dd1f99c15ff155b69a1c0affc4d9d8b551281ba"}, {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:0fee076134398d4e6cb827002468679ad402b22269510cf228301b787fdff5ae"}, {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ae537fcf330b3947e82c6ae4271e092e6cf16b9bc2cef68b14ffd0df1fa8832a"}, {file = "orjson-3.10.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f81b26c03f5fb5f0d0ee48d83cea4d7bc5e67e420d209cc1a990f5d1c62f9be0"}, {file = "orjson-3.10.13-cp38-cp38-win32.whl", hash = "sha256:0bc858086088b39dc622bc8219e73d3f246fb2bce70a6104abd04b3a080a66a8"}, {file = "orjson-3.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:3ca6f17467ebbd763f8862f1d89384a5051b461bb0e41074f583a0ebd7120e8e"}, {file = "orjson-3.10.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a11532cbfc2f5752c37e84863ef8435b68b0e6d459b329933294f65fa4bda1a"}, {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c96d2fb80467d1d0dfc4d037b4e1c0f84f1fe6229aa7fea3f070083acef7f3d7"}, {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dda4ba4d3e6f6c53b6b9c35266788053b61656a716a7fef5c884629c2a52e7aa"}, {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f998bbf300690be881772ee9c5281eb9c0044e295bcd4722504f5b5c6092ff"}, {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1cc42ed75b585c0c4dc5eb53a90a34ccb493c09a10750d1a1f9b9eff2bd12"}, {file = "orjson-3.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03b0f29d485411e3c13d79604b740b14e4e5fb58811743f6f4f9693ee6480a8f"}, {file = "orjson-3.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:233aae4474078d82f425134bb6a10fb2b3fc5a1a1b3420c6463ddd1b6a97eda8"}, {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e384e330a67cf52b3597ee2646de63407da6f8fc9e9beec3eaaaef5514c7a1c9"}, {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4222881d0aab76224d7b003a8e5fdae4082e32c86768e0e8652de8afd6c4e2c1"}, {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e400436950ba42110a20c50c80dff4946c8e3ec09abc1c9cf5473467e83fd1c5"}, {file = "orjson-3.10.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f47c9e7d224b86ffb086059cdcf634f4b3f32480f9838864aa09022fe2617ce2"}, {file = "orjson-3.10.13-cp39-cp39-win32.whl", hash = "sha256:a9ecea472f3eb653e1c0a3d68085f031f18fc501ea392b98dcca3e87c24f9ebe"}, {file = "orjson-3.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:5385935a73adce85cc7faac9d396683fd813566d3857fa95a0b521ef84a5b588"}, {file = "orjson-3.10.13.tar.gz", hash = "sha256:eb9bfb14ab8f68d9d9492d4817ae497788a15fd7da72e14dfabc289c3bb088ec"}, ] [[package]] name = "packaging" version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] name = "pathspec" version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." optional = false python-versions = ">=3.8" files = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] [[package]] name = "pbr" version = "6.1.0" description = "Python Build Reasonableness" optional = false python-versions = ">=2.6" files = [ {file = "pbr-6.1.0-py2.py3-none-any.whl", hash = "sha256:a776ae228892d8013649c0aeccbb3d5f99ee15e005a4cbb7e61d55a067b28a2a"}, {file = "pbr-6.1.0.tar.gz", hash = "sha256:788183e382e3d1d7707db08978239965e8b9e4e5ed42669bf4758186734d5f24"}, ] [[package]] name = "platformdirs" version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, ] [package.extras] docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] type = ["mypy (>=1.11.2)"] [[package]] name = "pluggy" version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" files = [ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" version = "4.0.1" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false python-versions = ">=3.9" files = [ {file = "pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878"}, {file = "pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2"}, ] [package.dependencies] cfgv = ">=2.0.0" identify = ">=1.0.0" nodeenv = ">=0.11.1" pyyaml = ">=5.1" virtualenv = ">=20.10.0" [[package]] name = "pre-commit-hooks" version = "5.0.0" description = "Some out-of-the-box hooks for pre-commit." optional = false python-versions = ">=3.8" files = [ {file = "pre_commit_hooks-5.0.0-py2.py3-none-any.whl", hash = "sha256:8d71cfb582c5c314a5498d94e0104b6567a8b93fb35903ea845c491f4e290a7a"}, {file = "pre_commit_hooks-5.0.0.tar.gz", hash = "sha256:10626959a9eaf602fbfc22bc61b6e75801436f82326bfcee82bb1f2fc4bc646e"}, ] [package.dependencies] "ruamel.yaml" = ">=0.15" [[package]] name = "propcache" version = "0.2.1" description = "Accelerated property cache" optional = false python-versions = ">=3.9" files = [ {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6"}, {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2"}, {file = "propcache-0.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6445804cf4ec763dc70de65a3b0d9954e868609e83850a47ca4f0cb64bd79fea"}, {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9479aa06a793c5aeba49ce5c5692ffb51fcd9a7016e017d555d5e2b0045d212"}, {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9631c5e8b5b3a0fda99cb0d29c18133bca1e18aea9effe55adb3da1adef80d3"}, {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3156628250f46a0895f1f36e1d4fbe062a1af8718ec3ebeb746f1d23f0c5dc4d"}, {file = "propcache-0.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b6fb63ae352e13748289f04f37868099e69dba4c2b3e271c46061e82c745634"}, {file = "propcache-0.2.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:887d9b0a65404929641a9fabb6452b07fe4572b269d901d622d8a34a4e9043b2"}, {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a96dc1fa45bd8c407a0af03b2d5218392729e1822b0c32e62c5bf7eeb5fb3958"}, {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a7e65eb5c003a303b94aa2c3852ef130230ec79e349632d030e9571b87c4698c"}, {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:999779addc413181912e984b942fbcc951be1f5b3663cd80b2687758f434c583"}, {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:19a0f89a7bb9d8048d9c4370c9c543c396e894c76be5525f5e1ad287f1750ddf"}, {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1ac2f5fe02fa75f56e1ad473f1175e11f475606ec9bd0be2e78e4734ad575034"}, {file = "propcache-0.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:574faa3b79e8ebac7cb1d7930f51184ba1ccf69adfdec53a12f319a06030a68b"}, {file = "propcache-0.2.1-cp310-cp310-win32.whl", hash = "sha256:03ff9d3f665769b2a85e6157ac8b439644f2d7fd17615a82fa55739bc97863f4"}, {file = "propcache-0.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:2d3af2e79991102678f53e0dbf4c35de99b6b8b58f29a27ca0325816364caaba"}, {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16"}, {file = "propcache-0.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717"}, {file = "propcache-0.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3"}, {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9"}, {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787"}, {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465"}, {file = "propcache-0.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af"}, {file = "propcache-0.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7"}, {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f"}, {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54"}, {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505"}, {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82"}, {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca"}, {file = "propcache-0.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e"}, {file = "propcache-0.2.1-cp311-cp311-win32.whl", hash = "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034"}, {file = "propcache-0.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3"}, {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a"}, {file = "propcache-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0"}, {file = "propcache-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d"}, {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4"}, {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d"}, {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5"}, {file = "propcache-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24"}, {file = "propcache-0.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff"}, {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f"}, {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec"}, {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348"}, {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6"}, {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6"}, {file = "propcache-0.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518"}, {file = "propcache-0.2.1-cp312-cp312-win32.whl", hash = "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246"}, {file = "propcache-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1"}, {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc"}, {file = "propcache-0.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9"}, {file = "propcache-0.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439"}, {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536"}, {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629"}, {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b"}, {file = "propcache-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052"}, {file = "propcache-0.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce"}, {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d"}, {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce"}, {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95"}, {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf"}, {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f"}, {file = "propcache-0.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30"}, {file = "propcache-0.2.1-cp313-cp313-win32.whl", hash = "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6"}, {file = "propcache-0.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1"}, {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6a9a8c34fb7bb609419a211e59da8887eeca40d300b5ea8e56af98f6fbbb1541"}, {file = "propcache-0.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae1aa1cd222c6d205853b3013c69cd04515f9d6ab6de4b0603e2e1c33221303e"}, {file = "propcache-0.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:accb6150ce61c9c4b7738d45550806aa2b71c7668c6942f17b0ac182b6142fd4"}, {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5eee736daafa7af6d0a2dc15cc75e05c64f37fc37bafef2e00d77c14171c2097"}, {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7a31fc1e1bd362874863fdeed71aed92d348f5336fd84f2197ba40c59f061bd"}, {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba4cfa1052819d16699e1d55d18c92b6e094d4517c41dd231a8b9f87b6fa681"}, {file = "propcache-0.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f089118d584e859c62b3da0892b88a83d611c2033ac410e929cb6754eec0ed16"}, {file = "propcache-0.2.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:781e65134efaf88feb447e8c97a51772aa75e48b794352f94cb7ea717dedda0d"}, {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31f5af773530fd3c658b32b6bdc2d0838543de70eb9a2156c03e410f7b0d3aae"}, {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:a7a078f5d37bee6690959c813977da5291b24286e7b962e62a94cec31aa5188b"}, {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:cea7daf9fc7ae6687cf1e2c049752f19f146fdc37c2cc376e7d0032cf4f25347"}, {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:8b3489ff1ed1e8315674d0775dc7d2195fb13ca17b3808721b54dbe9fd020faf"}, {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9403db39be1393618dd80c746cb22ccda168efce239c73af13c3763ef56ffc04"}, {file = "propcache-0.2.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5d97151bc92d2b2578ff7ce779cdb9174337390a535953cbb9452fb65164c587"}, {file = "propcache-0.2.1-cp39-cp39-win32.whl", hash = "sha256:9caac6b54914bdf41bcc91e7eb9147d331d29235a7c967c150ef5df6464fd1bb"}, {file = "propcache-0.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:92fc4500fcb33899b05ba73276dfb684a20d31caa567b7cb5252d48f896a91b1"}, {file = "propcache-0.2.1-py3-none-any.whl", hash = "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54"}, {file = "propcache-0.2.1.tar.gz", hash = "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64"}, ] [[package]] name = "psutil" version = "6.1.1" description = "Cross-platform lib for process and system monitoring in Python." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ {file = "psutil-6.1.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9ccc4316f24409159897799b83004cb1e24f9819b0dcf9c0b68bdcb6cefee6a8"}, {file = "psutil-6.1.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ca9609c77ea3b8481ab005da74ed894035936223422dc591d6772b147421f777"}, {file = "psutil-6.1.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:8df0178ba8a9e5bc84fed9cfa61d54601b371fbec5c8eebad27575f1e105c0d4"}, {file = "psutil-6.1.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:1924e659d6c19c647e763e78670a05dbb7feaf44a0e9c94bf9e14dfc6ba50468"}, {file = "psutil-6.1.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:018aeae2af92d943fdf1da6b58665124897cfc94faa2ca92098838f83e1b1bca"}, {file = "psutil-6.1.1-cp27-none-win32.whl", hash = "sha256:6d4281f5bbca041e2292be3380ec56a9413b790579b8e593b1784499d0005dac"}, {file = "psutil-6.1.1-cp27-none-win_amd64.whl", hash = "sha256:c777eb75bb33c47377c9af68f30e9f11bc78e0f07fbf907be4a5d70b2fe5f030"}, {file = "psutil-6.1.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed7fe2231a444fc219b9c42d0376e0a9a1a72f16c5cfa0f68d19f1a0663e8"}, {file = "psutil-6.1.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0bdd4eab935276290ad3cb718e9809412895ca6b5b334f5a9111ee6d9aff9377"}, {file = "psutil-6.1.1-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6e06c20c05fe95a3d7302d74e7097756d4ba1247975ad6905441ae1b5b66003"}, {file = "psutil-6.1.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97f7cb9921fbec4904f522d972f0c0e1f4fabbdd4e0287813b21215074a0f160"}, {file = "psutil-6.1.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33431e84fee02bc84ea36d9e2c4a6d395d479c9dd9bba2376c1f6ee8f3a4e0b3"}, {file = "psutil-6.1.1-cp36-cp36m-win32.whl", hash = "sha256:384636b1a64b47814437d1173be1427a7c83681b17a450bfc309a1953e329603"}, {file = "psutil-6.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8be07491f6ebe1a693f17d4f11e69d0dc1811fa082736500f649f79df7735303"}, {file = "psutil-6.1.1-cp37-abi3-win32.whl", hash = "sha256:eaa912e0b11848c4d9279a93d7e2783df352b082f40111e078388701fd479e53"}, {file = "psutil-6.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:f35cfccb065fff93529d2afb4a2e89e363fe63ca1e4a5da22b603a85833c2649"}, {file = "psutil-6.1.1.tar.gz", hash = "sha256:cf8496728c18f2d0b45198f06895be52f36611711746b7f30c464b422b50e2f5"}, ] [package.extras] dev = ["abi3audit", "black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "vulture", "wheel"] test = ["pytest", "pytest-xdist", "setuptools"] [[package]] name = "pycodestyle" version = "2.8.0" description = "Python style guide checker" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ {file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"}, {file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"}, ] [[package]] name = "pycparser" version = "2.22" description = "C parser in Python" optional = false python-versions = ">=3.8" files = [ {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, ] [[package]] name = "pydantic" version = "2.9.2" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, ] [package.dependencies] annotated-types = ">=0.6.0" pydantic-core = "2.23.4" typing-extensions = [ {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, {version = ">=4.6.1", markers = "python_version < \"3.13\""}, ] [package.extras] email = ["email-validator (>=2.0.0)"] timezone = ["tzdata"] [[package]] name = "pydantic-core" version = "2.23.4" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" files = [ {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"}, {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"}, {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"}, {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"}, {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"}, {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"}, {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"}, {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"}, {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"}, {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"}, {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"}, {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"}, {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"}, {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"}, {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"}, {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"}, {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"}, {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"}, {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"}, {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"}, {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"}, {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"}, {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"}, {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"}, {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"}, {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"}, {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"}, {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"}, {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"}, {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"}, {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"}, {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"}, {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, ] [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydocstyle" version = "6.3.0" description = "Python docstring style checker" optional = false python-versions = ">=3.6" files = [ {file = "pydocstyle-6.3.0-py3-none-any.whl", hash = "sha256:118762d452a49d6b05e194ef344a55822987a462831ade91ec5c06fd2169d019"}, {file = "pydocstyle-6.3.0.tar.gz", hash = "sha256:7ce43f0c0ac87b07494eb9c0b462c0b73e6ff276807f204d6b53edc72b7e44e1"}, ] [package.dependencies] snowballstemmer = ">=2.2.0" [package.extras] toml = ["tomli (>=1.2.3)"] [[package]] name = "pyflakes" version = "2.4.0" description = "passive checker of Python programs" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"}, {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"}, ] [[package]] name = "pygments" version = "2.19.0" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" files = [ {file = "pygments-2.19.0-py3-none-any.whl", hash = "sha256:4755e6e64d22161d5b61432c0600c923c5927214e7c956e31c23923c89251a9b"}, {file = "pygments-2.19.0.tar.gz", hash = "sha256:afc4146269910d4bdfabcd27c24923137a74d562a23a320a41a55ad303e19783"}, ] [package.extras] windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pylint" version = "3.3.3" description = "python code static checker" optional = false python-versions = ">=3.9.0" files = [ {file = "pylint-3.3.3-py3-none-any.whl", hash = "sha256:26e271a2bc8bce0fc23833805a9076dd9b4d5194e2a02164942cb3cdc37b4183"}, {file = "pylint-3.3.3.tar.gz", hash = "sha256:07c607523b17e6d16e2ae0d7ef59602e332caa762af64203c24b41c27139f36a"}, ] [package.dependencies] astroid = ">=3.3.8,<=3.4.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = {version = ">=0.3.7", markers = "python_version >= \"3.12\""} isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" mccabe = ">=0.6,<0.8" platformdirs = ">=2.2.0" tomlkit = ">=0.10.1" [package.extras] spelling = ["pyenchant (>=3.2,<4.0)"] testutils = ["gitpython (>3)"] [[package]] name = "pytest" version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} iniconfig = "*" packaging = "*" pluggy = ">=1.5,<2" [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-asyncio" version = "0.25.1" description = "Pytest support for asyncio" optional = false python-versions = ">=3.9" files = [ {file = "pytest_asyncio-0.25.1-py3-none-any.whl", hash = "sha256:c84878849ec63ff2ca509423616e071ef9cd8cc93c053aa33b5b8fb70a990671"}, {file = "pytest_asyncio-0.25.1.tar.gz", hash = "sha256:79be8a72384b0c917677e00daa711e07db15259f4d23203c59012bcd989d4aee"}, ] [package.dependencies] pytest = ">=8.2,<9" [package.extras] docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1)"] testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] [[package]] name = "pytest-cov" version = "6.0.0" description = "Pytest plugin for measuring coverage." optional = false python-versions = ">=3.9" files = [ {file = "pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0"}, {file = "pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35"}, ] [package.dependencies] coverage = {version = ">=7.5", extras = ["toml"]} pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] [[package]] name = "pyupgrade" version = "3.19.1" description = "A tool to automatically upgrade syntax for newer versions." optional = false python-versions = ">=3.9" files = [ {file = "pyupgrade-3.19.1-py2.py3-none-any.whl", hash = "sha256:8c5b0bfacae5ff30fa136a53eb7f22c34ba007450d4099e9da8089dabb9e67c9"}, {file = "pyupgrade-3.19.1.tar.gz", hash = "sha256:d10e8c5f54b8327211828769e98d95d95e4715de632a3414f1eef3f51357b9e2"}, ] [package.dependencies] tokenize-rt = ">=6.1.0" [[package]] name = "pyyaml" version = "6.0.2" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" files = [ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] [[package]] name = "requests" version = "2.32.3" description = "Python HTTP for Humans." optional = false python-versions = ">=3.8" files = [ {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, ] [package.dependencies] certifi = ">=2017.4.17" charset-normalizer = ">=2,<4" idna = ">=2.5,<4" urllib3 = ">=1.21.1,<3" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" version = "13.9.4" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.8.0" files = [ {file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"}, {file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"}, ] [package.dependencies] markdown-it-py = ">=2.2.0" pygments = ">=2.13.0,<3.0.0" [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruamel-yaml" version = "0.18.9" description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" optional = false python-versions = ">=3.7" files = [ {file = "ruamel.yaml-0.18.9-py3-none-any.whl", hash = "sha256:c17d2a7ccf7fd2dd4b6d699111c37e94f12277a1db71e847ad7f3d19b8e3e9f4"}, {file = "ruamel.yaml-0.18.9.tar.gz", hash = "sha256:59d0f8b10c658bd55ecd107e334d4117d766a2b9cc8f5176afcdadcff6f84a5e"}, ] [package.dependencies] "ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\""} [package.extras] docs = ["mercurial (>5.7)", "ryd"] jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] [[package]] name = "ruamel-yaml-clib" version = "0.2.12" description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" optional = false python-versions = ">=3.9" files = [ {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:11f891336688faf5156a36293a9c362bdc7c88f03a8a027c2c1d8e0bcde998e5"}, {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:a606ef75a60ecf3d924613892cc603b154178ee25abb3055db5062da811fd969"}, {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd5415dded15c3822597455bc02bcd66e81ef8b7a48cb71a33628fc9fdde39df"}, {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f66efbc1caa63c088dead1c4170d148eabc9b80d95fb75b6c92ac0aad2437d76"}, {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22353049ba4181685023b25b5b51a574bce33e7f51c759371a7422dcae5402a6"}, {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:932205970b9f9991b34f55136be327501903f7c66830e9760a8ffb15b07f05cd"}, {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl", hash = "sha256:3eac5a91891ceb88138c113f9db04f3cebdae277f5d44eaa3651a4f573e6a5da"}, {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl", hash = "sha256:ab007f2f5a87bd08ab1499bdf96f3d5c6ad4dcfa364884cb4549aa0154b13a28"}, {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6"}, {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:d84318609196d6bd6da0edfa25cedfbabd8dbde5140a0a23af29ad4b8f91fb1e"}, {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb43a269eb827806502c7c8efb7ae7e9e9d0573257a46e8e952f4d4caba4f31e"}, {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52"}, {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642"}, {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2"}, {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl", hash = "sha256:bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4"}, {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl", hash = "sha256:a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb"}, {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632"}, {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:943f32bc9dedb3abff9879edc134901df92cfce2c3d5c9348f172f62eb2d771d"}, {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c3829bb364fdb8e0332c9931ecf57d9be3519241323c5274bd82f709cebc0c"}, {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd"}, {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31"}, {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680"}, {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl", hash = "sha256:e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5"}, {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4"}, {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4c8c5d82f50bb53986a5e02d1b3092b03622c02c2eb78e29bec33fd9593bae1a"}, {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:e7e3736715fbf53e9be2a79eb4db68e4ed857017344d697e8b9749444ae57475"}, {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7e75b4965e1d4690e93021adfcecccbca7d61c7bddd8e22406ef2ff20d74ef"}, {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96777d473c05ee3e5e3c3e999f5d23c6f4ec5b0c38c098b3a5229085f74236c6"}, {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:3bc2a80e6420ca8b7d3590791e2dfc709c88ab9152c00eeb511c9875ce5778bf"}, {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e188d2699864c11c36cdfdada94d781fd5d6b0071cd9c427bceb08ad3d7c70e1"}, {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl", hash = "sha256:6442cb36270b3afb1b4951f060eccca1ce49f3d087ca1ca4563a6eb479cb3de6"}, {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:e5b8daf27af0b90da7bb903a876477a9e6d7270be6146906b276605997c7e9a3"}, {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:fc4b630cd3fa2cf7fce38afa91d7cfe844a9f75d7f0f36393fa98815e911d987"}, {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bc5f1e1c28e966d61d2519f2a3d451ba989f9ea0f2307de7bc45baa526de9e45"}, {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a0e060aace4c24dcaf71023bbd7d42674e3b230f7e7b97317baf1e953e5b519"}, {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2f1c3765db32be59d18ab3953f43ab62a761327aafc1594a2a1fbe038b8b8a7"}, {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d85252669dc32f98ebcd5d36768f5d4faeaeaa2d655ac0473be490ecdae3c285"}, {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e143ada795c341b56de9418c58d028989093ee611aa27ffb9b7f609c00d813ed"}, {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-win32.whl", hash = "sha256:beffaed67936fbbeffd10966a4eb53c402fafd3d6833770516bf7314bc6ffa12"}, {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-win_amd64.whl", hash = "sha256:040ae85536960525ea62868b642bdb0c2cc6021c9f9d507810c0c604e66f5a7b"}, {file = "ruamel.yaml.clib-0.2.12.tar.gz", hash = "sha256:6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f"}, ] [[package]] name = "ruff" version = "0.8.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ {file = "ruff-0.8.4-py3-none-linux_armv6l.whl", hash = "sha256:58072f0c06080276804c6a4e21a9045a706584a958e644353603d36ca1eb8a60"}, {file = "ruff-0.8.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ffb60904651c00a1e0b8df594591770018a0f04587f7deeb3838344fe3adabac"}, {file = "ruff-0.8.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6ddf5d654ac0d44389f6bf05cee4caeefc3132a64b58ea46738111d687352296"}, {file = "ruff-0.8.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e248b1f0fa2749edd3350a2a342b67b43a2627434c059a063418e3d375cfe643"}, {file = "ruff-0.8.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf197b98ed86e417412ee3b6c893f44c8864f816451441483253d5ff22c0e81e"}, {file = "ruff-0.8.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c41319b85faa3aadd4d30cb1cffdd9ac6b89704ff79f7664b853785b48eccdf3"}, {file = "ruff-0.8.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9f8402b7c4f96463f135e936d9ab77b65711fcd5d72e5d67597b543bbb43cf3f"}, {file = "ruff-0.8.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4e56b3baa9c23d324ead112a4fdf20db9a3f8f29eeabff1355114dd96014604"}, {file = "ruff-0.8.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:736272574e97157f7edbbb43b1d046125fce9e7d8d583d5d65d0c9bf2c15addf"}, {file = "ruff-0.8.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5fe710ab6061592521f902fca7ebcb9fabd27bc7c57c764298b1c1f15fff720"}, {file = "ruff-0.8.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:13e9ec6d6b55f6da412d59953d65d66e760d583dd3c1c72bf1f26435b5bfdbae"}, {file = "ruff-0.8.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:97d9aefef725348ad77d6db98b726cfdb075a40b936c7984088804dfd38268a7"}, {file = "ruff-0.8.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ab78e33325a6f5374e04c2ab924a3367d69a0da36f8c9cb6b894a62017506111"}, {file = "ruff-0.8.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:8ef06f66f4a05c3ddbc9121a8b0cecccd92c5bf3dd43b5472ffe40b8ca10f0f8"}, {file = "ruff-0.8.4-py3-none-win32.whl", hash = "sha256:552fb6d861320958ca5e15f28b20a3d071aa83b93caee33a87b471f99a6c0835"}, {file = "ruff-0.8.4-py3-none-win_amd64.whl", hash = "sha256:f21a1143776f8656d7f364bd264a9d60f01b7f52243fbe90e7670c0dfe0cf65d"}, {file = "ruff-0.8.4-py3-none-win_arm64.whl", hash = "sha256:9183dd615d8df50defa8b1d9a074053891ba39025cf5ae88e8bcb52edcc4bf08"}, {file = "ruff-0.8.4.tar.gz", hash = "sha256:0d5f89f254836799af1615798caa5f80b7f935d7a670fad66c5007928e57ace8"}, ] [[package]] name = "safety" version = "3.2.14" description = "Checks installed dependencies for known vulnerabilities and licenses." optional = false python-versions = ">=3.8" files = [ {file = "safety-3.2.14-py3-none-any.whl", hash = "sha256:23ceeb06038ff65607c7f1311bffa3e92b029148b367b360ad8287d9f3395194"}, {file = "safety-3.2.14.tar.gz", hash = "sha256:7a45d88b1903c5b7c370eaeb6ca131a52f147e0b8a0b302265f82824ef92adc7"}, ] [package.dependencies] Authlib = ">=1.2.0" Click = ">=8.0.2" dparse = ">=0.6.4" filelock = ">=3.16.1,<3.17.0" jinja2 = ">=3.1.0" marshmallow = ">=3.15.0" packaging = ">=21.0" psutil = ">=6.1.0,<6.2.0" pydantic = ">=2.6.0,<2.10.0" requests = "*" rich = "*" "ruamel.yaml" = ">=0.17.21" safety_schemas = "0.0.10" setuptools = ">=65.5.1" typer = ">=0.12.1" typing-extensions = ">=4.7.1" urllib3 = ">=1.26.5" [package.extras] github = ["pygithub (>=1.43.3)"] gitlab = ["python-gitlab (>=1.3.0)"] spdx = ["spdx-tools (>=0.8.2)"] [[package]] name = "safety-schemas" version = "0.0.10" description = "Schemas for Safety tools" optional = false python-versions = ">=3.7" files = [ {file = "safety_schemas-0.0.10-py3-none-any.whl", hash = "sha256:83978c14fcf598f00a6d98e70450e635d3deb33b3abbb5a886004ade7ca84b7f"}, {file = "safety_schemas-0.0.10.tar.gz", hash = "sha256:5ec83bb19e17003748d2a4b11e43e1f2b4471c9434329e9a0d80d1069966b96c"}, ] [package.dependencies] dparse = ">=0.6.4" packaging = ">=21.0" pydantic = ">=2.6.0,<2.10.0" ruamel-yaml = ">=0.17.21" typing-extensions = ">=4.7.1" [[package]] name = "setuptools" version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.9" files = [ {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "shellingham" version = "1.5.4" description = "Tool to Detect Surrounding Shell" optional = false python-versions = ">=3.7" files = [ {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, ] [[package]] name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." optional = false python-versions = "*" files = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] [[package]] name = "stevedore" version = "5.4.0" description = "Manage dynamic plugins for Python applications" optional = false python-versions = ">=3.9" files = [ {file = "stevedore-5.4.0-py3-none-any.whl", hash = "sha256:b0be3c4748b3ea7b854b265dcb4caa891015e442416422be16f8b31756107857"}, {file = "stevedore-5.4.0.tar.gz", hash = "sha256:79e92235ecb828fe952b6b8b0c6c87863248631922c8e8e0fa5b17b232c4514d"}, ] [package.dependencies] pbr = ">=2.0.0" [[package]] name = "syrupy" version = "4.8.0" description = "Pytest Snapshot Test Utility" optional = false python-versions = ">=3.8.1" files = [ {file = "syrupy-4.8.0-py3-none-any.whl", hash = "sha256:544f4ec6306f4b1c460fdab48fd60b2c7fe54a6c0a8243aeea15f9ad9c638c3f"}, {file = "syrupy-4.8.0.tar.gz", hash = "sha256:648f0e9303aaa8387c8365d7314784c09a6bab0a407455c6a01d6a4f5c6a8ede"}, ] [package.dependencies] pytest = ">=7.0.0,<9.0.0" [[package]] name = "tokenize-rt" version = "6.1.0" description = "A wrapper around the stdlib `tokenize` which roundtrips." optional = false python-versions = ">=3.9" files = [ {file = "tokenize_rt-6.1.0-py2.py3-none-any.whl", hash = "sha256:d706141cdec4aa5f358945abe36b911b8cbdc844545da99e811250c0cee9b6fc"}, {file = "tokenize_rt-6.1.0.tar.gz", hash = "sha256:e8ee836616c0877ab7c7b54776d2fefcc3bde714449a206762425ae114b53c86"}, ] [[package]] name = "tomlkit" version = "0.13.2" description = "Style preserving TOML library" optional = false python-versions = ">=3.8" files = [ {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, ] [[package]] name = "typer" version = "0.15.1" description = "Typer, build great CLIs. Easy to code. Based on Python type hints." optional = false python-versions = ">=3.7" files = [ {file = "typer-0.15.1-py3-none-any.whl", hash = "sha256:7994fb7b8155b64d3402518560648446072864beefd44aa2dc36972a5972e847"}, {file = "typer-0.15.1.tar.gz", hash = "sha256:a0588c0a7fa68a1978a069818657778f86abe6ff5ea6abf472f940a08bfe4f0a"}, ] [package.dependencies] click = ">=8.0.0" rich = ">=10.11.0" shellingham = ">=1.3.0" typing-extensions = ">=3.7.4.3" [[package]] name = "typing-extensions" version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] name = "urllib3" version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" files = [ {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" version = "20.28.1" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" files = [ {file = "virtualenv-20.28.1-py3-none-any.whl", hash = "sha256:412773c85d4dab0409b83ec36f7a6499e72eaf08c80e81e9576bca61831c71cb"}, {file = "virtualenv-20.28.1.tar.gz", hash = "sha256:5d34ab240fdb5d21549b76f9e8ff3af28252f5499fb6d6f031adac4e5a8c5329"}, ] [package.dependencies] distlib = ">=0.3.7,<1" filelock = ">=3.12.2,<4" platformdirs = ">=3.9.1,<5" [package.extras] docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] [[package]] name = "vulture" version = "2.14" description = "Find dead code" optional = false python-versions = ">=3.8" files = [ {file = "vulture-2.14-py2.py3-none-any.whl", hash = "sha256:d9a90dba89607489548a49d557f8bac8112bd25d3cbc8aeef23e860811bd5ed9"}, {file = "vulture-2.14.tar.gz", hash = "sha256:cb8277902a1138deeab796ec5bef7076a6e0248ca3607a3f3dee0b6d9e9b8415"}, ] [[package]] name = "yamllint" version = "1.35.1" description = "A linter for YAML files." optional = false python-versions = ">=3.8" files = [ {file = "yamllint-1.35.1-py3-none-any.whl", hash = "sha256:2e16e504bb129ff515b37823b472750b36b6de07963bd74b307341ef5ad8bdc3"}, {file = "yamllint-1.35.1.tar.gz", hash = "sha256:7a003809f88324fd2c877734f2d575ee7881dd9043360657cc8049c809eba6cd"}, ] [package.dependencies] pathspec = ">=0.5.3" pyyaml = "*" [package.extras] dev = ["doc8", "flake8", "flake8-import-order", "rstcheck[sphinx]", "sphinx"] [[package]] name = "yarl" version = "1.18.3" description = "Yet another URL library" optional = false python-versions = ">=3.9" files = [ {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34"}, {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7"}, {file = "yarl-1.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:602d98f2c2d929f8e697ed274fbadc09902c4025c5a9963bf4e9edfc3ab6f7ed"}, {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c654d5207c78e0bd6d749f6dae1dcbbfde3403ad3a4b11f3c5544d9906969dde"}, {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5094d9206c64181d0f6e76ebd8fb2f8fe274950a63890ee9e0ebfd58bf9d787b"}, {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35098b24e0327fc4ebdc8ffe336cee0a87a700c24ffed13161af80124b7dc8e5"}, {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3236da9272872443f81fedc389bace88408f64f89f75d1bdb2256069a8730ccc"}, {file = "yarl-1.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c08cc9b16f4f4bc522771d96734c7901e7ebef70c6c5c35dd0f10845270bcd"}, {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80316a8bd5109320d38eef8833ccf5f89608c9107d02d2a7f985f98ed6876990"}, {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1e1cc06da1491e6734f0ea1e6294ce00792193c463350626571c287c9a704db"}, {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fea09ca13323376a2fdfb353a5fa2e59f90cd18d7ca4eaa1fd31f0a8b4f91e62"}, {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e3b9fd71836999aad54084906f8663dffcd2a7fb5cdafd6c37713b2e72be1760"}, {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:757e81cae69244257d125ff31663249b3013b5dc0a8520d73694aed497fb195b"}, {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b1771de9944d875f1b98a745bc547e684b863abf8f8287da8466cf470ef52690"}, {file = "yarl-1.18.3-cp310-cp310-win32.whl", hash = "sha256:8874027a53e3aea659a6d62751800cf6e63314c160fd607489ba5c2edd753cf6"}, {file = "yarl-1.18.3-cp310-cp310-win_amd64.whl", hash = "sha256:93b2e109287f93db79210f86deb6b9bbb81ac32fc97236b16f7433db7fc437d8"}, {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8503ad47387b8ebd39cbbbdf0bf113e17330ffd339ba1144074da24c545f0069"}, {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02ddb6756f8f4517a2d5e99d8b2f272488e18dd0bfbc802f31c16c6c20f22193"}, {file = "yarl-1.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67a283dd2882ac98cc6318384f565bffc751ab564605959df4752d42483ad889"}, {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d980e0325b6eddc81331d3f4551e2a333999fb176fd153e075c6d1c2530aa8a8"}, {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b643562c12680b01e17239be267bc306bbc6aac1f34f6444d1bded0c5ce438ca"}, {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c017a3b6df3a1bd45b9fa49a0f54005e53fbcad16633870104b66fa1a30a29d8"}, {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75674776d96d7b851b6498f17824ba17849d790a44d282929c42dbb77d4f17ae"}, {file = "yarl-1.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccaa3a4b521b780a7e771cc336a2dba389a0861592bbce09a476190bb0c8b4b3"}, {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d06d3005e668744e11ed80812e61efd77d70bb7f03e33c1598c301eea20efbb"}, {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:9d41beda9dc97ca9ab0b9888cb71f7539124bc05df02c0cff6e5acc5a19dcc6e"}, {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ba23302c0c61a9999784e73809427c9dbedd79f66a13d84ad1b1943802eaaf59"}, {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6748dbf9bfa5ba1afcc7556b71cda0d7ce5f24768043a02a58846e4a443d808d"}, {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0b0cad37311123211dc91eadcb322ef4d4a66008d3e1bdc404808992260e1a0e"}, {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0fb2171a4486bb075316ee754c6d8382ea6eb8b399d4ec62fde2b591f879778a"}, {file = "yarl-1.18.3-cp311-cp311-win32.whl", hash = "sha256:61b1a825a13bef4a5f10b1885245377d3cd0bf87cba068e1d9a88c2ae36880e1"}, {file = "yarl-1.18.3-cp311-cp311-win_amd64.whl", hash = "sha256:b9d60031cf568c627d028239693fd718025719c02c9f55df0a53e587aab951b5"}, {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50"}, {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576"}, {file = "yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640"}, {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2"}, {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75"}, {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512"}, {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba"}, {file = "yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb"}, {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272"}, {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6"}, {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e"}, {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb"}, {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393"}, {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285"}, {file = "yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2"}, {file = "yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477"}, {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:90adb47ad432332d4f0bc28f83a5963f426ce9a1a8809f5e584e704b82685dcb"}, {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:913829534200eb0f789d45349e55203a091f45c37a2674678744ae52fae23efa"}, {file = "yarl-1.18.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ef9f7768395923c3039055c14334ba4d926f3baf7b776c923c93d80195624782"}, {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a19f62ff30117e706ebc9090b8ecc79aeb77d0b1f5ec10d2d27a12bc9f66d0"}, {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e17c9361d46a4d5addf777c6dd5eab0715a7684c2f11b88c67ac37edfba6c482"}, {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a74a13a4c857a84a845505fd2d68e54826a2cd01935a96efb1e9d86c728e186"}, {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41f7ce59d6ee7741af71d82020346af364949314ed3d87553763a2df1829cc58"}, {file = "yarl-1.18.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f52a265001d830bc425f82ca9eabda94a64a4d753b07d623a9f2863fde532b53"}, {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:82123d0c954dc58db301f5021a01854a85bf1f3bb7d12ae0c01afc414a882ca2"}, {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2ec9bbba33b2d00999af4631a3397d1fd78290c48e2a3e52d8dd72db3a067ac8"}, {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbd6748e8ab9b41171bb95c6142faf068f5ef1511935a0aa07025438dd9a9bc1"}, {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:877d209b6aebeb5b16c42cbb377f5f94d9e556626b1bfff66d7b0d115be88d0a"}, {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b464c4ab4bfcb41e3bfd3f1c26600d038376c2de3297760dfe064d2cb7ea8e10"}, {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8d39d351e7faf01483cc7ff7c0213c412e38e5a340238826be7e0e4da450fdc8"}, {file = "yarl-1.18.3-cp313-cp313-win32.whl", hash = "sha256:61ee62ead9b68b9123ec24bc866cbef297dd266175d53296e2db5e7f797f902d"}, {file = "yarl-1.18.3-cp313-cp313-win_amd64.whl", hash = "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c"}, {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:61e5e68cb65ac8f547f6b5ef933f510134a6bf31bb178be428994b0cb46c2a04"}, {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe57328fbc1bfd0bd0514470ac692630f3901c0ee39052ae47acd1d90a436719"}, {file = "yarl-1.18.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a440a2a624683108a1b454705ecd7afc1c3438a08e890a1513d468671d90a04e"}, {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09c7907c8548bcd6ab860e5f513e727c53b4a714f459b084f6580b49fa1b9cee"}, {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4f6450109834af88cb4cc5ecddfc5380ebb9c228695afc11915a0bf82116789"}, {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9ca04806f3be0ac6d558fffc2fdf8fcef767e0489d2684a21912cc4ed0cd1b8"}, {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77a6e85b90a7641d2e07184df5557132a337f136250caafc9ccaa4a2a998ca2c"}, {file = "yarl-1.18.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6333c5a377c8e2f5fae35e7b8f145c617b02c939d04110c76f29ee3676b5f9a5"}, {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0b3c92fa08759dbf12b3a59579a4096ba9af8dd344d9a813fc7f5070d86bbab1"}, {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4ac515b860c36becb81bb84b667466885096b5fc85596948548b667da3bf9f24"}, {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:045b8482ce9483ada4f3f23b3774f4e1bf4f23a2d5c912ed5170f68efb053318"}, {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:a4bb030cf46a434ec0225bddbebd4b89e6471814ca851abb8696170adb163985"}, {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:54d6921f07555713b9300bee9c50fb46e57e2e639027089b1d795ecd9f7fa910"}, {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1d407181cfa6e70077df3377938c08012d18893f9f20e92f7d2f314a437c30b1"}, {file = "yarl-1.18.3-cp39-cp39-win32.whl", hash = "sha256:ac36703a585e0929b032fbaab0707b75dc12703766d0b53486eabd5139ebadd5"}, {file = "yarl-1.18.3-cp39-cp39-win_amd64.whl", hash = "sha256:ba87babd629f8af77f557b61e49e7c7cac36f22f871156b91e10a6e9d4f829e9"}, {file = "yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b"}, {file = "yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1"}, ] [package.dependencies] idna = ">=2.0" multidict = ">=4.0" propcache = ">=0.2.0" [metadata] lock-version = "2.0" python-versions = "^3.12" content-hash = "f85519fdc1c81c7c3cffc4aac8a69e682095ea7dd8a0af0a64eb3edfba4cac88" python-homewizard-energy-8.3.2/pyproject.toml000066400000000000000000000047641474712727000214450ustar00rootroot00000000000000[tool.poetry] name = "python-homewizard-energy" version = "0.0.0" description = "Asynchronous Python client for the HomeWizard Energy" authors = ["DCSBL"] maintainers = ["DCSBL"] license = "Apache License 2.0" readme = "README.md" homepage = "https://github.com/homewizard/python-homewizard-energy" repository = "https://github.com/homewizard/python-homewizard-energy" documentation = "https://github.com/homewizard/python-homewizard-energy" classifiers = [ ] packages = [ { include = "homewizard_energy" }, ] [tool.poetry.dependencies] python = "^3.12" aiohttp = ">=3.0.0" async-timeout = ">=4.0.3,<6.0.0" multidict = "^6.0.5" ## To fix aiohttp dependency at python 3.12 backoff = "^2.2.1" orjson = "^3.10" mashumaro = "^3.15" awesomeversion = "^24.6.0" [tool.poetry.dev-dependencies] aresponses = "^3.0.0" flake8 = "^4.0.1" flake8-docstrings = "^1.7.0" isort = "^5.13.2" pre-commit = "^4.0.1" pre-commit-hooks = "^5.0.0" pylint = "^3.3.3" pytest = "^8.3.3" pytest-asyncio = "^0.25.0" pytest-cov = "^6.0.0" yamllint = "^1.35.1" pyupgrade = "^3.19.0" flake8-simplify = "^0.21.0" vulture = "^2.13" flake8-bandit = "^3.0.0" flake8-bugbear = "^23.3.12" flake8-builtins = "^2.5.0" flake8-comprehensions = "^3.15.0" flake8-eradicate = "^1.2.1" flake8-markdown = "^0.3.0" ruff = "0.8.4" darglint = "^1.8.1" safety = "^3.2.10" codespell = "^2.3.0" bandit = "^1.7.9" syrupy = "^4.7.2" [tool.poetry.urls] "Bug Tracker" = "https://github.com/homewizard/python-homewizard-energy/issues" Changelog = "https://github.com/homewizard/python-homewizard-energy/releases" [tool.coverage.paths] source = ["homewizard_energy"] [tool.coverage.report] show_missing = true exclude_lines = ["pragma: no cover", "if TYPE_CHECKING:"] [tool.coverage.run] branch = true source = ["homewizard_energy"] [tool.isort] profile = "black" multi_line_output = 3 [tool.pylint.BASIC] good-names = [ "_", "ex", "fp", "i", "id", "j", "k", "on", "Run", "T", ] [tool.pylint."MESSAGES CONTROL"] disable= [ "too-few-public-methods", "duplicate-code", "format", "unsubscriptable-object", "too-many-instance-attributes", "unnecessary-lambda", ] [tool.pylint.SIMILARITIES] ignore-imports = true [tool.pylint.FORMAT] max-line-length=120 [tool.pylint.DESIGN] max-attributes=20 [tool.pytest.ini_options] addopts = "--cov" asyncio_mode = "auto" [tool.vulture] min_confidence = 80 paths = ["homewizard_energy"] verbose = true [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" python-homewizard-energy-8.3.2/tests/000077500000000000000000000000001474712727000176605ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/__snapshots__/000077500000000000000000000000001474712727000224765ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/__snapshots__/test_models.ambr000066400000000000000000000052461474712727000256720ustar00rootroot00000000000000# serializer version: 1 # name: test_known_product_strings[HWE-BAT] 'HomeWizard Plug-In Battery - HWE-BAT' # --- # name: test_known_product_strings[HWE-KWH1] 'HomeWizard Wi-Fi kWh Meter 1-phase - HWE-KWH1' # --- # name: test_known_product_strings[HWE-KWH3] 'HomeWizard Wi-Fi kWh Meter 3-phase - HWE-KWH3' # --- # name: test_known_product_strings[HWE-P1] 'HomeWizard Wi-Fi P1 Meter - HWE-P1' # --- # name: test_known_product_strings[HWE-SKT] 'HomeWizard Wi-Fi Energy Socket - HWE-SKT' # --- # name: test_known_product_strings[HWE-WTR] 'HomeWizard Wi-Fi Watermeter - HWE-WTR' # --- # name: test_known_product_strings[SDM230-wifi] 'HomeWizard Wi-Fi kWh Meter 1-phase - SDM230-wifi' # --- # name: test_known_product_strings[SDM630-wifi] 'HomeWizard Wi-Fi kWh Meter 3-phase - SDM630-wifi' # --- # name: test_known_products[HWE-BAT] Product(model='HWE-BAT', name='Plug-In Battery', url='https://www.homewizard.com/plug-in-battery/', description='Solar energy, day and night.') # --- # name: test_known_products[HWE-KWH1] Product(model='HWE-KWH1', name='Wi-Fi kWh Meter 1-phase', url='https://www.homewizard.com/kwh-meter/', description='Measure solar panels, car chargers and more.') # --- # name: test_known_products[HWE-KWH3] Product(model='HWE-KWH3', name='Wi-Fi kWh Meter 3-phase', url='https://www.homewizard.com/kwh-meter/', description='Measure solar panels, car chargers and more.') # --- # name: test_known_products[HWE-P1] Product(model='HWE-P1', name='Wi-Fi P1 Meter', url='https://www.homewizard.com/p1-meter/', description='The HomeWizard P1 Meter gives you detailed insight in your electricity-, gas consumption and solar surplus.') # --- # name: test_known_products[HWE-SKT] Product(model='HWE-SKT', name='Wi-Fi Energy Socket', url='https://www.homewizard.com/energy-socket/', description='Measure and switch every device.') # --- # name: test_known_products[HWE-WTR] Product(model='HWE-WTR', name='Wi-Fi Watermeter', url='https://www.homewizard.com/watermeter/', description='Real-time water consumption insights') # --- # name: test_known_products[SDM230-wifi] Product(model='SDM230-wifi', name='Wi-Fi kWh Meter 1-phase', url='https://www.homewizard.com/kwh-meter/', description='Measure solar panels, car chargers and more.') # --- # name: test_known_products[SDM630-wifi] Product(model='SDM630-wifi', name='Wi-Fi kWh Meter 3-phase', url='https://www.homewizard.com/kwh-meter/', description='Measure solar panels, car chargers and more.') # --- # name: test_unknown_or_invalid_products[HWE-P2] None # --- # name: test_unknown_or_invalid_products[None] None # --- # name: test_unknown_or_invalid_products[WTR] None # --- # name: test_unknown_or_invalid_products[] None # --- python-homewizard-energy-8.3.2/tests/test_helpers.py000066400000000000000000000030721474712727000227350ustar00rootroot00000000000000"""Test the helper functions.""" import asyncio from unittest.mock import AsyncMock import pytest from aiohttp import ClientSession from homewizard_energy import has_v2_api pytestmark = [pytest.mark.asyncio] async def test_has_v2_api_true(aresponses): """Test if has_v2_api returns True for a v2 device.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( status=401, ), ) async with ClientSession() as session: result = await has_v2_api("example.com", session) assert result is True async def test_has_v2_api_false(aresponses): """Test if has_v2_api returns False for a non-v2 device.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( status=404, ), ) async with ClientSession() as session: result = await has_v2_api("example.com", session) assert result is False async def test_has_v2_api_exception(): """Test if has_v2_api returns False when an exception occurs.""" session = AsyncMock() session.get = AsyncMock(side_effect=asyncio.TimeoutError) result = await has_v2_api("example.com", session) assert result is False async def test_has_v2_api_own_session(aresponses): """Test if has_v2_api opens and closes its own session.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( status=401, ), ) result = await has_v2_api("example.com") assert result is True python-homewizard-energy-8.3.2/tests/test_homewizard_energy.py000066400000000000000000000014431474712727000250150ustar00rootroot00000000000000"""Test the base class.""" import pytest from homewizard_energy.errors import UnsupportedError from homewizard_energy.homewizard_energy import HomeWizardEnergy pytestmark = [pytest.mark.asyncio] @pytest.mark.parametrize( ("function", "exception"), [ ("device", NotImplementedError), ("measurement", NotImplementedError), ("system", NotImplementedError), ("state", UnsupportedError), ("identify", NotImplementedError), ("reboot", UnsupportedError), ], ) async def test_base_class_raises_notimplementederror( function: str, exception: Exception ): """Test the base class raises NotImplementedError.""" with pytest.raises(exception): async with HomeWizardEnergy("host") as api: await getattr(api, function)() python-homewizard-energy-8.3.2/tests/test_models.py000066400000000000000000000023451474712727000225600ustar00rootroot00000000000000"""Test the helper functions.""" import pytest from homewizard_energy.models import get_verification_hostname pytestmark = [pytest.mark.asyncio] @pytest.mark.parametrize( ("model", "expected"), [ ("HWE-P1", "appliance/p1dongle/1234567890"), ("HWE-SKT", "appliance/energysocket/1234567890"), ("HWE-WTR", "appliance/watermeter/1234567890"), ("HWE-DSP", "appliance/display/1234567890"), ("HWE-KWH1", "appliance/energymeter/1234567890"), ("SDM230-wifi", "appliance/energymeter/1234567890"), ("HWE-KWH3", "appliance/energymeter/1234567890"), ("SDM630-wifi", "appliance/energymeter/1234567890"), ("HWE-BAT", "appliance/battery/1234567890"), ], ) async def test_get_verification_hostname_returns_expected_identifier( model: str, expected: str ): """Test if get_verification_hostname returns the expected identifier.""" result = get_verification_hostname(model, "1234567890") assert result == expected async def test_get_verification_hostname_raises_value_error(): """Test if get_verification_hostname raises a ValueError for an unsupported model.""" with pytest.raises(ValueError): get_verification_hostname("unsupported", "1234567890") python-homewizard-energy-8.3.2/tests/v1/000077500000000000000000000000001474712727000202065ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v1/__init__.py000066400000000000000000000004011474712727000223120ustar00rootroot00000000000000"""Tests for python-homewizard-energy.""" import os def load_fixtures(filename): """Load a fixture.""" path = os.path.join(os.path.dirname(__file__), "fixtures", filename) with open(path, encoding="utf-8") as fptr: return fptr.read() python-homewizard-energy-8.3.2/tests/v1/__snapshots__/000077500000000000000000000000001474712727000230245ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v1/__snapshots__/test_v1_homewizard_energy.ambr000066400000000000000000001747471474712727000311020ustar00rootroot00000000000000# serializer version: 1 # name: test_combined_models_with_valid_authentication[HWE-KWH1-device-data-None-system] CombinedModels(device=Device(model_name='Wi-Fi kWh Meter 1-phase', id='appliance/energymeter/3c39e7aabbcc', product_name='kWh Meter', product_type='HWE-KWH1', serial='3c39e7aabbcc', api_version=, firmware_version='2.11'), measurement=Measurement(wifi_ssid='My Wi-Fi', wifi_strength=74, energy_import_kwh=122.376, energy_import_t1_kwh=122.376, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=579.813, energy_export_t1_kwh=579.813, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-45.252, power_l1_w=-45.252, power_l2_w=None, power_l3_w=None, voltage_v=228.472, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=0.273, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=74.052, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=-58.612, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=0.611, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.0, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None), state=None, system=System(wifi_strength_pct=74, wifi_ssid='My Wi-Fi', wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None)) # --- # name: test_combined_models_with_valid_authentication[HWE-KWH3-device-data-None-system] CombinedModels(device=Device(model_name='Wi-Fi kWh Meter 3-phase', id='appliance/energymeter/3c39e7aabbcc', product_name='kWh Meter 3-phase', product_type='HWE-KWH3', serial='3c39e7aabbcc', api_version=, firmware_version='2.11'), measurement=Measurement(wifi_ssid='HW WiFi', wifi_strength=84, energy_import_kwh=2940.101, energy_import_t1_kwh=2940.101, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=7100.278, power_l1_w=0.0, power_l2_w=3547.015, power_l3_w=3553.263, voltage_v=None, voltage_l1_v=230.751, voltage_l2_v=228.391, voltage_l3_v=229.612, current_a=30.999, current_l1_a=0.0, current_l2_a=15.521, current_l3_a=15.477, apparent_power_va=7112.293, apparent_power_l1_va=0.0, apparent_power_l2_va=3548.879, apparent_power_l3_va=3563.414, reactive_power_var=-429.025, reactive_power_l1_var=0.0, reactive_power_l2_var=-166.675, reactive_power_l3_var=-262.35, power_factor=None, power_factor_l1=1.0, power_factor_l2=0.999, power_factor_l3=0.997, frequency_hz=49.926, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None), state=None, system=System(wifi_strength_pct=84, wifi_ssid='HW WiFi', wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None)) # --- # name: test_combined_models_with_valid_authentication[HWE-P1-device-data_all_data-None-system] CombinedModels(device=Device(model_name='Wi-Fi P1 Meter', id='appliance/p1dongle/3c39e7aabbcc', product_name='P1 Meter', product_type='HWE-P1', serial='3c39e7aabbcc', api_version=, firmware_version='2.11'), measurement=Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=13779.338, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=0.0, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-543.0, power_l1_w=-676.0, power_l2_w=133.0, power_l3_w=0.0, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=-4.0, current_l2_a=2.0, current_l3_a=0.0, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.0, timestamp=None, protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id='NGGYU', tariff=2, voltage_sag_l1_count=1, voltage_sag_l2_count=1, voltage_sag_l3_count=0, voltage_swell_l1_count=0, voltage_swell_l2_count=0, voltage_swell_l3_count=0, any_power_fail_count=4, long_power_fail_count=5, average_power_15m_w=123.0, monthly_power_peak_w=1111.0, monthly_power_peak_timestamp=datetime.datetime(2023, 1, 1, 8, 0, 10), external_devices={'gas_meter_NGLYD': ExternalDevice(unique_id='NGLYD', type=, value=111.111, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'heat_meter_NGRAADY': ExternalDevice(unique_id='NGRAADY', type=, value=222.222, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'warm_water_meter_NGMYC': ExternalDevice(unique_id='NGMYC', type=, value=333.333, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'water_meter_NGSG': ExternalDevice(unique_id='NGSG', type=, value=444.444, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'inlet_heat_meter_NGTALAHY': ExternalDevice(unique_id='NGTALAHY', type=, value=555.555, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10))}, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None), state=None, system=System(wifi_strength_pct=100, wifi_ssid='My Wi-Fi', wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None)) # --- # name: test_combined_models_with_valid_authentication[HWE-SKT-device-data-state_all-system] CombinedModels(device=Device(model_name='Wi-Fi Energy Socket', id='appliance/energysocket/3c39e7aabbcc', product_name='Energy Socket', product_type='HWE-SKT', serial='3c39e7aabbcc', api_version=, firmware_version='2.11'), measurement=Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=10830.511, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=2948.827, energy_export_t1_kwh=2948.827, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=123.0, power_l1_w=123.0, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None), state=State(power_on=False, switch_lock=False, brightness=255), system=System(wifi_strength_pct=100, wifi_ssid='My Wi-Fi', wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=100.0, api_v1_enabled=None)) # --- # name: test_combined_models_with_valid_authentication[HWE-WTR-device-data-None-system] CombinedModels(device=Device(model_name='Wi-Fi Watermeter', id='appliance/watermeter/3c39e7aabbcc', product_name='Water Meter', product_type='HWE-WTR', serial='3c39e7aabbcc', api_version=, firmware_version='2.11'), measurement=Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=None, energy_import_t1_kwh=None, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=None, energy_export_t1_kwh=None, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=None, power_l1_w=None, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=13.12, total_liter_m3=8129.123, cycles=None, state_of_charge_pct=None), state=None, system=System(wifi_strength_pct=100, wifi_ssid='My Wi-Fi', wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None)) # --- # name: test_combined_models_with_valid_authentication[SDM230-wifi-device-data-None-system] CombinedModels(device=Device(model_name='Wi-Fi kWh Meter 1-phase', id='appliance/energymeter/3c39e7aabbcc', product_name='kWh Meter', product_type='SDM230-wifi', serial='3c39e7aabbcc', api_version=, firmware_version='2.11'), measurement=Measurement(wifi_ssid='My Wi-Fi', wifi_strength=74, energy_import_kwh=122.376, energy_import_t1_kwh=122.376, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=579.813, energy_export_t1_kwh=579.813, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-45.252, power_l1_w=-45.252, power_l2_w=None, power_l3_w=None, voltage_v=228.472, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=0.273, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=74.052, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=-58.612, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=0.611, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.0, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None), state=None, system=System(wifi_strength_pct=74, wifi_ssid='My Wi-Fi', wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None)) # --- # name: test_combined_models_with_valid_authentication[SDM630-wifi-device-data-None-system] CombinedModels(device=Device(model_name='Wi-Fi kWh Meter 3-phase', id='appliance/energymeter/3c39e7aabbcc', product_name='kWh Meter 3-phase', product_type='SDM630-wifi', serial='3c39e7aabbcc', api_version=, firmware_version='2.11'), measurement=Measurement(wifi_ssid='HW WiFi', wifi_strength=84, energy_import_kwh=2940.101, energy_import_t1_kwh=2940.101, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=7100.278, power_l1_w=0.0, power_l2_w=3547.015, power_l3_w=3553.263, voltage_v=None, voltage_l1_v=230.751, voltage_l2_v=228.391, voltage_l3_v=229.612, current_a=30.999, current_l1_a=0.0, current_l2_a=15.521, current_l3_a=15.477, apparent_power_va=7112.293, apparent_power_l1_va=0.0, apparent_power_l2_va=3548.879, apparent_power_l3_va=3563.414, reactive_power_var=-429.025, reactive_power_l1_var=0.0, reactive_power_l2_var=-166.675, reactive_power_l3_var=-262.35, power_factor=None, power_factor_l1=1.0, power_factor_l2=0.999, power_factor_l3=0.997, frequency_hz=49.926, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None), state=None, system=System(wifi_strength_pct=84, wifi_ssid='HW WiFi', wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None)) # --- # name: test_combined_models_with_valid_authentication_caches_device[HWE-KWH1-device-data-None-system] CombinedModels(device=Device(model_name='Wi-Fi kWh Meter 1-phase', id='appliance/energymeter/3c39e7aabbcc', product_name='kWh Meter', product_type='HWE-KWH1', serial='3c39e7aabbcc', api_version=, firmware_version='2.11'), measurement=Measurement(wifi_ssid='My Wi-Fi', wifi_strength=74, energy_import_kwh=122.376, energy_import_t1_kwh=122.376, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=579.813, energy_export_t1_kwh=579.813, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-45.252, power_l1_w=-45.252, power_l2_w=None, power_l3_w=None, voltage_v=228.472, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=0.273, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=74.052, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=-58.612, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=0.611, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.0, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None), state=None, system=System(wifi_strength_pct=74, wifi_ssid='My Wi-Fi', wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None)) # --- # name: test_combined_models_with_valid_authentication_caches_device[HWE-KWH3-device-data-None-system] CombinedModels(device=Device(model_name='Wi-Fi kWh Meter 3-phase', id='appliance/energymeter/3c39e7aabbcc', product_name='kWh Meter 3-phase', product_type='HWE-KWH3', serial='3c39e7aabbcc', api_version=, firmware_version='2.11'), measurement=Measurement(wifi_ssid='HW WiFi', wifi_strength=84, energy_import_kwh=2940.101, energy_import_t1_kwh=2940.101, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=7100.278, power_l1_w=0.0, power_l2_w=3547.015, power_l3_w=3553.263, voltage_v=None, voltage_l1_v=230.751, voltage_l2_v=228.391, voltage_l3_v=229.612, current_a=30.999, current_l1_a=0.0, current_l2_a=15.521, current_l3_a=15.477, apparent_power_va=7112.293, apparent_power_l1_va=0.0, apparent_power_l2_va=3548.879, apparent_power_l3_va=3563.414, reactive_power_var=-429.025, reactive_power_l1_var=0.0, reactive_power_l2_var=-166.675, reactive_power_l3_var=-262.35, power_factor=None, power_factor_l1=1.0, power_factor_l2=0.999, power_factor_l3=0.997, frequency_hz=49.926, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None), state=None, system=System(wifi_strength_pct=84, wifi_ssid='HW WiFi', wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None)) # --- # name: test_combined_models_with_valid_authentication_caches_device[HWE-P1-device-data_all_data-None-system] CombinedModels(device=Device(model_name='Wi-Fi P1 Meter', id='appliance/p1dongle/3c39e7aabbcc', product_name='P1 Meter', product_type='HWE-P1', serial='3c39e7aabbcc', api_version=, firmware_version='2.11'), measurement=Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=13779.338, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=0.0, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-543.0, power_l1_w=-676.0, power_l2_w=133.0, power_l3_w=0.0, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=-4.0, current_l2_a=2.0, current_l3_a=0.0, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.0, timestamp=None, protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id='NGGYU', tariff=2, voltage_sag_l1_count=1, voltage_sag_l2_count=1, voltage_sag_l3_count=0, voltage_swell_l1_count=0, voltage_swell_l2_count=0, voltage_swell_l3_count=0, any_power_fail_count=4, long_power_fail_count=5, average_power_15m_w=123.0, monthly_power_peak_w=1111.0, monthly_power_peak_timestamp=datetime.datetime(2023, 1, 1, 8, 0, 10), external_devices={'gas_meter_NGLYD': ExternalDevice(unique_id='NGLYD', type=, value=111.111, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'heat_meter_NGRAADY': ExternalDevice(unique_id='NGRAADY', type=, value=222.222, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'warm_water_meter_NGMYC': ExternalDevice(unique_id='NGMYC', type=, value=333.333, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'water_meter_NGSG': ExternalDevice(unique_id='NGSG', type=, value=444.444, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'inlet_heat_meter_NGTALAHY': ExternalDevice(unique_id='NGTALAHY', type=, value=555.555, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10))}, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None), state=None, system=System(wifi_strength_pct=100, wifi_ssid='My Wi-Fi', wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None)) # --- # name: test_combined_models_with_valid_authentication_caches_device[HWE-SKT-device-data-state_all-system] CombinedModels(device=Device(model_name='Wi-Fi Energy Socket', id='appliance/energysocket/3c39e7aabbcc', product_name='Energy Socket', product_type='HWE-SKT', serial='3c39e7aabbcc', api_version=, firmware_version='2.11'), measurement=Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=10830.511, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=2948.827, energy_export_t1_kwh=2948.827, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=123.0, power_l1_w=123.0, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None), state=State(power_on=False, switch_lock=False, brightness=255), system=System(wifi_strength_pct=100, wifi_ssid='My Wi-Fi', wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=100.0, api_v1_enabled=None)) # --- # name: test_combined_models_with_valid_authentication_caches_device[HWE-WTR-device-data-None-system] CombinedModels(device=Device(model_name='Wi-Fi Watermeter', id='appliance/watermeter/3c39e7aabbcc', product_name='Water Meter', product_type='HWE-WTR', serial='3c39e7aabbcc', api_version=, firmware_version='2.11'), measurement=Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=None, energy_import_t1_kwh=None, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=None, energy_export_t1_kwh=None, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=None, power_l1_w=None, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=13.12, total_liter_m3=8129.123, cycles=None, state_of_charge_pct=None), state=None, system=System(wifi_strength_pct=100, wifi_ssid='My Wi-Fi', wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None)) # --- # name: test_combined_models_with_valid_authentication_caches_device[SDM230-wifi-device-data-None-system] CombinedModels(device=Device(model_name='Wi-Fi kWh Meter 1-phase', id='appliance/energymeter/3c39e7aabbcc', product_name='kWh Meter', product_type='SDM230-wifi', serial='3c39e7aabbcc', api_version=, firmware_version='2.11'), measurement=Measurement(wifi_ssid='My Wi-Fi', wifi_strength=74, energy_import_kwh=122.376, energy_import_t1_kwh=122.376, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=579.813, energy_export_t1_kwh=579.813, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-45.252, power_l1_w=-45.252, power_l2_w=None, power_l3_w=None, voltage_v=228.472, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=0.273, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=74.052, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=-58.612, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=0.611, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.0, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None), state=None, system=System(wifi_strength_pct=74, wifi_ssid='My Wi-Fi', wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None)) # --- # name: test_combined_models_with_valid_authentication_caches_device[SDM630-wifi-device-data-None-system] CombinedModels(device=Device(model_name='Wi-Fi kWh Meter 3-phase', id='appliance/energymeter/3c39e7aabbcc', product_name='kWh Meter 3-phase', product_type='SDM630-wifi', serial='3c39e7aabbcc', api_version=, firmware_version='2.11'), measurement=Measurement(wifi_ssid='HW WiFi', wifi_strength=84, energy_import_kwh=2940.101, energy_import_t1_kwh=2940.101, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=7100.278, power_l1_w=0.0, power_l2_w=3547.015, power_l3_w=3553.263, voltage_v=None, voltage_l1_v=230.751, voltage_l2_v=228.391, voltage_l3_v=229.612, current_a=30.999, current_l1_a=0.0, current_l2_a=15.521, current_l3_a=15.477, apparent_power_va=7112.293, apparent_power_l1_va=0.0, apparent_power_l2_va=3548.879, apparent_power_l3_va=3563.414, reactive_power_var=-429.025, reactive_power_l1_var=0.0, reactive_power_l2_var=-166.675, reactive_power_l3_var=-262.35, power_factor=None, power_factor_l1=1.0, power_factor_l2=0.999, power_factor_l3=0.997, frequency_hz=49.926, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None), state=None, system=System(wifi_strength_pct=84, wifi_ssid='HW WiFi', wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None)) # --- # name: test_get_data_object[HWE-KWH1-fixtures3] Measurement(wifi_ssid='My Wi-Fi', wifi_strength=74, energy_import_kwh=122.376, energy_import_t1_kwh=122.376, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=579.813, energy_export_t1_kwh=579.813, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-45.252, power_l1_w=-45.252, power_l2_w=None, power_l3_w=None, voltage_v=228.472, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=0.273, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=74.052, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=-58.612, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=0.611, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.0, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object[HWE-KWH3-fixtures4] Measurement(wifi_ssid='HW WiFi', wifi_strength=84, energy_import_kwh=2940.101, energy_import_t1_kwh=2940.101, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=7100.278, power_l1_w=0.0, power_l2_w=3547.015, power_l3_w=3553.263, voltage_v=None, voltage_l1_v=230.751, voltage_l2_v=228.391, voltage_l3_v=229.612, current_a=30.999, current_l1_a=0.0, current_l2_a=15.521, current_l3_a=15.477, apparent_power_va=7112.293, apparent_power_l1_va=0.0, apparent_power_l2_va=3548.879, apparent_power_l3_va=3563.414, reactive_power_var=-429.025, reactive_power_l1_var=0.0, reactive_power_l2_var=-166.675, reactive_power_l3_var=-262.35, power_factor=None, power_factor_l1=1.0, power_factor_l2=0.999, power_factor_l3=0.997, frequency_hz=49.926, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object[HWE-P1-fixtures0] Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=13779.338, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=0.0, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-543.0, power_l1_w=-676.0, power_l2_w=133.0, power_l3_w=0.0, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=-4.0, current_l2_a=2.0, current_l3_a=0.0, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.0, timestamp=None, protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id='NGGYU', tariff=2, voltage_sag_l1_count=1, voltage_sag_l2_count=1, voltage_sag_l3_count=0, voltage_swell_l1_count=0, voltage_swell_l2_count=0, voltage_swell_l3_count=0, any_power_fail_count=4, long_power_fail_count=5, average_power_15m_w=123.0, monthly_power_peak_w=1111.0, monthly_power_peak_timestamp=datetime.datetime(2023, 1, 1, 8, 0, 10), external_devices={'gas_meter_NGLYD': ExternalDevice(unique_id='NGLYD', type=, value=111.111, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'heat_meter_NGRAADY': ExternalDevice(unique_id='NGRAADY', type=, value=222.222, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'warm_water_meter_NGMYC': ExternalDevice(unique_id='NGMYC', type=, value=333.333, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'water_meter_NGSG': ExternalDevice(unique_id='NGSG', type=, value=444.444, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'inlet_heat_meter_NGTALAHY': ExternalDevice(unique_id='NGTALAHY', type=, value=555.555, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10))}, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object[HWE-P1-fixtures0].1 Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=10830.511, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=1285.951, energy_export_t1_kwh=1285.951, energy_export_t2_kwh=2876.51, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-543.0, power_l1_w=-676.0, power_l2_w=133.0, power_l3_w=0.0, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object[HWE-P1-fixtures0].2 Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=10830.511, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=1285.951, energy_export_t1_kwh=1285.951, energy_export_t2_kwh=2876.51, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-543.0, power_l1_w=-676.0, power_l2_w=133.0, power_l3_w=0.0, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object[HWE-P1-fixtures0].3 Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=10830.511, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=1285.951, energy_export_t1_kwh=1285.951, energy_export_t2_kwh=2876.51, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-543.0, power_l1_w=-676.0, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object[HWE-SKT-fixtures1] Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=10830.511, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=2948.827, energy_export_t1_kwh=2948.827, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=123.0, power_l1_w=123.0, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object[HWE-WTR-fixtures2] Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=None, energy_import_t1_kwh=None, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=None, energy_export_t1_kwh=None, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=None, power_l1_w=None, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=13.12, total_liter_m3=8129.123, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object[SDM230-wifi-fixtures5] Measurement(wifi_ssid='My Wi-Fi', wifi_strength=74, energy_import_kwh=122.376, energy_import_t1_kwh=122.376, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=579.813, energy_export_t1_kwh=579.813, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-45.252, power_l1_w=-45.252, power_l2_w=None, power_l3_w=None, voltage_v=228.472, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=0.273, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=74.052, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=-58.612, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=0.611, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.0, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object[SDM630-wifi-fixtures6] Measurement(wifi_ssid='HW WiFi', wifi_strength=84, energy_import_kwh=2940.101, energy_import_t1_kwh=2940.101, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=7100.278, power_l1_w=0.0, power_l2_w=3547.015, power_l3_w=3553.263, voltage_v=None, voltage_l1_v=230.751, voltage_l2_v=228.391, voltage_l3_v=229.612, current_a=30.999, current_l1_a=0.0, current_l2_a=15.521, current_l3_a=15.477, apparent_power_va=7112.293, apparent_power_l1_va=0.0, apparent_power_l2_va=3548.879, apparent_power_l3_va=3563.414, reactive_power_var=-429.025, reactive_power_l1_var=0.0, reactive_power_l2_var=-166.675, reactive_power_l3_var=-262.35, power_factor=None, power_factor_l1=1.0, power_factor_l2=0.999, power_factor_l3=0.997, frequency_hz=49.926, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object_with_known_device[HWE-KWH1-fixtures3] Measurement(wifi_ssid='My Wi-Fi', wifi_strength=74, energy_import_kwh=122.376, energy_import_t1_kwh=122.376, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=579.813, energy_export_t1_kwh=579.813, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-45.252, power_l1_w=-45.252, power_l2_w=None, power_l3_w=None, voltage_v=228.472, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=0.273, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=74.052, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=-58.612, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=0.611, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.0, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object_with_known_device[HWE-KWH3-fixtures4] Measurement(wifi_ssid='HW WiFi', wifi_strength=84, energy_import_kwh=2940.101, energy_import_t1_kwh=2940.101, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=7100.278, power_l1_w=0.0, power_l2_w=3547.015, power_l3_w=3553.263, voltage_v=None, voltage_l1_v=230.751, voltage_l2_v=228.391, voltage_l3_v=229.612, current_a=30.999, current_l1_a=0.0, current_l2_a=15.521, current_l3_a=15.477, apparent_power_va=7112.293, apparent_power_l1_va=0.0, apparent_power_l2_va=3548.879, apparent_power_l3_va=3563.414, reactive_power_var=-429.025, reactive_power_l1_var=0.0, reactive_power_l2_var=-166.675, reactive_power_l3_var=-262.35, power_factor=None, power_factor_l1=1.0, power_factor_l2=0.999, power_factor_l3=0.997, frequency_hz=49.926, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object_with_known_device[HWE-P1-fixtures0] Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=13779.338, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=0.0, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-543.0, power_l1_w=-676.0, power_l2_w=133.0, power_l3_w=0.0, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=-4.0, current_l2_a=2.0, current_l3_a=0.0, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.0, timestamp=None, protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id='NGGYU', tariff=2, voltage_sag_l1_count=1, voltage_sag_l2_count=1, voltage_sag_l3_count=0, voltage_swell_l1_count=0, voltage_swell_l2_count=0, voltage_swell_l3_count=0, any_power_fail_count=4, long_power_fail_count=5, average_power_15m_w=123.0, monthly_power_peak_w=1111.0, monthly_power_peak_timestamp=datetime.datetime(2023, 1, 1, 8, 0, 10), external_devices={'gas_meter_NGLYD': ExternalDevice(unique_id='NGLYD', type=, value=111.111, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'heat_meter_NGRAADY': ExternalDevice(unique_id='NGRAADY', type=, value=222.222, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'warm_water_meter_NGMYC': ExternalDevice(unique_id='NGMYC', type=, value=333.333, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'water_meter_NGSG': ExternalDevice(unique_id='NGSG', type=, value=444.444, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'inlet_heat_meter_NGTALAHY': ExternalDevice(unique_id='NGTALAHY', type=, value=555.555, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10))}, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object_with_known_device[HWE-P1-fixtures0].1 Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=10830.511, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=1285.951, energy_export_t1_kwh=1285.951, energy_export_t2_kwh=2876.51, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-543.0, power_l1_w=-676.0, power_l2_w=133.0, power_l3_w=0.0, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object_with_known_device[HWE-P1-fixtures0].2 Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=10830.511, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=1285.951, energy_export_t1_kwh=1285.951, energy_export_t2_kwh=2876.51, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-543.0, power_l1_w=-676.0, power_l2_w=133.0, power_l3_w=0.0, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object_with_known_device[HWE-P1-fixtures0].3 Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=10830.511, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=1285.951, energy_export_t1_kwh=1285.951, energy_export_t2_kwh=2876.51, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-543.0, power_l1_w=-676.0, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object_with_known_device[HWE-SKT-fixtures1] Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=10830.511, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=2948.827, energy_export_t1_kwh=2948.827, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=123.0, power_l1_w=123.0, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object_with_known_device[HWE-WTR-fixtures2] Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=None, energy_import_t1_kwh=None, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=None, energy_export_t1_kwh=None, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=None, power_l1_w=None, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=13.12, total_liter_m3=8129.123, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object_with_known_device[SDM230-wifi-fixtures5] Measurement(wifi_ssid='My Wi-Fi', wifi_strength=74, energy_import_kwh=122.376, energy_import_t1_kwh=122.376, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=579.813, energy_export_t1_kwh=579.813, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-45.252, power_l1_w=-45.252, power_l2_w=None, power_l3_w=None, voltage_v=228.472, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=0.273, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=74.052, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=-58.612, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=0.611, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.0, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_data_object_with_known_device[SDM630-wifi-fixtures6] Measurement(wifi_ssid='HW WiFi', wifi_strength=84, energy_import_kwh=2940.101, energy_import_t1_kwh=2940.101, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=7100.278, power_l1_w=0.0, power_l2_w=3547.015, power_l3_w=3553.263, voltage_v=None, voltage_l1_v=230.751, voltage_l2_v=228.391, voltage_l3_v=229.612, current_a=30.999, current_l1_a=0.0, current_l2_a=15.521, current_l3_a=15.477, apparent_power_va=7112.293, apparent_power_l1_va=0.0, apparent_power_l2_va=3548.879, apparent_power_l3_va=3563.414, reactive_power_var=-429.025, reactive_power_l1_var=0.0, reactive_power_l2_var=-166.675, reactive_power_l3_var=-262.35, power_factor=None, power_factor_l1=1.0, power_factor_l2=0.999, power_factor_l3=0.997, frequency_hz=49.926, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_get_device_object[HWE-KWH1-fixtures3] Device(model_name='Wi-Fi kWh Meter 1-phase', id='appliance/energymeter/3c39e7aabbcc', product_name='kWh Meter', product_type='HWE-KWH1', serial='3c39e7aabbcc', api_version=, firmware_version='2.11') # --- # name: test_get_device_object[HWE-KWH3-fixtures4] Device(model_name='Wi-Fi kWh Meter 3-phase', id='appliance/energymeter/3c39e7aabbcc', product_name='kWh Meter 3-phase', product_type='HWE-KWH3', serial='3c39e7aabbcc', api_version=, firmware_version='2.11') # --- # name: test_get_device_object[HWE-P1-fixtures0] Device(model_name='Wi-Fi P1 Meter', id='appliance/p1dongle/3c39e7aabbcc', product_name='P1 Meter', product_type='HWE-P1', serial='3c39e7aabbcc', api_version=, firmware_version='2.11') # --- # name: test_get_device_object[HWE-SKT-fixtures1] Device(model_name='Wi-Fi Energy Socket', id='appliance/energysocket/3c39e7aabbcc', product_name='Energy Socket', product_type='HWE-SKT', serial='3c39e7aabbcc', api_version=, firmware_version='2.11') # --- # name: test_get_device_object[HWE-WTR-fixtures2] Device(model_name='Wi-Fi Watermeter', id='appliance/watermeter/3c39e7aabbcc', product_name='Water Meter', product_type='HWE-WTR', serial='3c39e7aabbcc', api_version=, firmware_version='2.11') # --- # name: test_get_device_object[SDM230-wifi-fixtures5] Device(model_name='Wi-Fi kWh Meter 1-phase', id='appliance/energymeter/3c39e7aabbcc', product_name='kWh Meter', product_type='SDM230-wifi', serial='3c39e7aabbcc', api_version=, firmware_version='2.11') # --- # name: test_get_device_object[SDM630-wifi-fixtures6] Device(model_name='Wi-Fi kWh Meter 3-phase', id='appliance/energymeter/3c39e7aabbcc', product_name='kWh Meter 3-phase', product_type='SDM630-wifi', serial='3c39e7aabbcc', api_version=, firmware_version='2.11') # --- # name: test_get_state_object[HWE-SKT-fixtures0] State(power_on=False, switch_lock=False, brightness=255) # --- # name: test_get_state_object[HWE-SKT-fixtures0].1 State(power_on=False, switch_lock=None, brightness=None) # --- # name: test_get_state_object[HWE-SKT-fixtures0].2 State(power_on=None, switch_lock=False, brightness=None) # --- # name: test_get_state_object[HWE-SKT-fixtures0].3 State(power_on=None, switch_lock=None, brightness=255) # --- # name: test_identify[HWE-P1] True # --- # name: test_identify[HWE-SKT] True # --- # name: test_identify[HWE-WTR] True # --- # name: test_state_set[HWE-SKT-fixtures0] State(power_on=False, switch_lock=False, brightness=255) # --- # name: test_system_set[HWE-KWH1] System(wifi_strength_pct=None, wifi_ssid=None, wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None) # --- # name: test_system_set[HWE-KWH3] System(wifi_strength_pct=None, wifi_ssid=None, wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None) # --- # name: test_system_set[HWE-P1] System(wifi_strength_pct=None, wifi_ssid=None, wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None) # --- # name: test_system_set[HWE-SKT] System(wifi_strength_pct=None, wifi_ssid=None, wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None) # --- # name: test_system_set[HWE-WTR] System(wifi_strength_pct=None, wifi_ssid=None, wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None) # --- # name: test_system_set[SDM230-wifi] System(wifi_strength_pct=None, wifi_ssid=None, wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None) # --- # name: test_system_set[SDM630-wifi] System(wifi_strength_pct=None, wifi_ssid=None, wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None) # --- python-homewizard-energy-8.3.2/tests/v1/__snapshots__/test_v1_models.ambr000066400000000000000000000631241474712727000266250ustar00rootroot00000000000000# serializer version: 1 # name: test_combined_remaps_legacy_brightness_to_system CombinedModels(device=Device(model_name='Wi-Fi Energy Socket', id='appliance/energysocket/3c39e7aabbcc', product_name='Energy Socket', product_type='HWE-SKT', serial='3c39e7aabbcc', api_version=, firmware_version='2.11'), measurement=None, state=State(power_on=False, switch_lock=False, brightness=255), system=System(wifi_strength_pct=None, wifi_ssid=None, wifi_rssi_db=None, cloud_enabled=None, uptime_s=None, status_led_brightness_pct=100.0, api_v1_enabled=None)) # --- # name: test_combined_remaps_legacy_wifi_ssid_to_system CombinedModels(device=Device(model_name='Wi-Fi Energy Socket', id='appliance/energysocket/3c39e7aabbcc', product_name='Energy Socket', product_type='HWE-SKT', serial='3c39e7aabbcc', api_version=, firmware_version='2.11'), measurement=Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=10830.511, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=2948.827, energy_export_t1_kwh=2948.827, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=123.0, power_l1_w=123.0, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None), state=None, system=System(wifi_strength_pct=100, wifi_ssid='My Wi-Fi', wifi_rssi_db=None, cloud_enabled=None, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None)) # --- # name: test_data[HWE-KWH1-fixtures3] Measurement(wifi_ssid='My Wi-Fi', wifi_strength=74, energy_import_kwh=122.376, energy_import_t1_kwh=122.376, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=579.813, energy_export_t1_kwh=579.813, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-45.252, power_l1_w=-45.252, power_l2_w=None, power_l3_w=None, voltage_v=228.472, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=0.273, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=74.052, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=-58.612, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=0.611, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.0, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_data[HWE-KWH3-fixtures4] Measurement(wifi_ssid='HW WiFi', wifi_strength=84, energy_import_kwh=2940.101, energy_import_t1_kwh=2940.101, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=7100.278, power_l1_w=0.0, power_l2_w=3547.015, power_l3_w=3553.263, voltage_v=None, voltage_l1_v=230.751, voltage_l2_v=228.391, voltage_l3_v=229.612, current_a=30.999, current_l1_a=0.0, current_l2_a=15.521, current_l3_a=15.477, apparent_power_va=7112.293, apparent_power_l1_va=0.0, apparent_power_l2_va=3548.879, apparent_power_l3_va=3563.414, reactive_power_var=-429.025, reactive_power_l1_var=0.0, reactive_power_l2_var=-166.675, reactive_power_l3_var=-262.35, power_factor=None, power_factor_l1=1.0, power_factor_l2=0.999, power_factor_l3=0.997, frequency_hz=49.926, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_data[HWE-P1-fixtures0] Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=10830.511, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=1285.951, energy_export_t1_kwh=1285.951, energy_export_t2_kwh=2876.51, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-543.0, power_l1_w=-676.0, power_l2_w=133.0, power_l3_w=0.0, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_data[HWE-P1-fixtures0].1 Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=13779.338, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=0.0, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-543.0, power_l1_w=-676.0, power_l2_w=133.0, power_l3_w=0.0, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=-4.0, current_l2_a=2.0, current_l3_a=0.0, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.0, timestamp=None, protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id='NGGYU', tariff=2, voltage_sag_l1_count=1, voltage_sag_l2_count=1, voltage_sag_l3_count=0, voltage_swell_l1_count=0, voltage_swell_l2_count=0, voltage_swell_l3_count=0, any_power_fail_count=4, long_power_fail_count=5, average_power_15m_w=123.0, monthly_power_peak_w=1111.0, monthly_power_peak_timestamp=datetime.datetime(2023, 1, 1, 8, 0, 10), external_devices={'gas_meter_NGLYD': ExternalDevice(unique_id='NGLYD', type=, value=111.111, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'heat_meter_NGRAADY': ExternalDevice(unique_id='NGRAADY', type=, value=222.222, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'warm_water_meter_NGMYC': ExternalDevice(unique_id='NGMYC', type=, value=333.333, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'water_meter_NGSG': ExternalDevice(unique_id='NGSG', type=, value=444.444, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'inlet_heat_meter_NGTALAHY': ExternalDevice(unique_id='NGTALAHY', type=, value=555.555, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10))}, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_data[HWE-P1-fixtures0].2 Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=10830.511, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=1285.951, energy_export_t1_kwh=1285.951, energy_export_t2_kwh=2876.51, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-543.0, power_l1_w=-676.0, power_l2_w=133.0, power_l3_w=0.0, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_data[HWE-P1-fixtures0].3 Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=10830.511, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=1285.951, energy_export_t1_kwh=1285.951, energy_export_t2_kwh=2876.51, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-543.0, power_l1_w=-676.0, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_data[HWE-SKT-fixtures1] Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=10830.511, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=2948.827, energy_export_t1_kwh=2948.827, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=123.0, power_l1_w=123.0, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_data[HWE-WTR-fixtures2] Measurement(wifi_ssid='My Wi-Fi', wifi_strength=100, energy_import_kwh=None, energy_import_t1_kwh=None, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=None, energy_export_t1_kwh=None, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=None, power_l1_w=None, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=13.12, total_liter_m3=8129.123, cycles=None, state_of_charge_pct=None) # --- # name: test_data[SDM230-wifi-fixtures5] Measurement(wifi_ssid='My Wi-Fi', wifi_strength=74, energy_import_kwh=122.376, energy_import_t1_kwh=122.376, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=579.813, energy_export_t1_kwh=579.813, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-45.252, power_l1_w=-45.252, power_l2_w=None, power_l3_w=None, voltage_v=228.472, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=0.273, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=74.052, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=-58.612, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=0.611, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.0, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_data[SDM630-wifi-fixtures6] Measurement(wifi_ssid='HW WiFi', wifi_strength=84, energy_import_kwh=2940.101, energy_import_t1_kwh=2940.101, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=7100.278, power_l1_w=0.0, power_l2_w=3547.015, power_l3_w=3553.263, voltage_v=None, voltage_l1_v=230.751, voltage_l2_v=228.391, voltage_l3_v=229.612, current_a=30.999, current_l1_a=0.0, current_l2_a=15.521, current_l3_a=15.477, apparent_power_va=7112.293, apparent_power_l1_va=0.0, apparent_power_l2_va=3548.879, apparent_power_l3_va=3563.414, reactive_power_var=-429.025, reactive_power_l1_var=0.0, reactive_power_l2_var=-166.675, reactive_power_l3_var=-262.35, power_factor=None, power_factor_l1=1.0, power_factor_l2=0.999, power_factor_l3=0.997, frequency_hz=49.926, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_data[exceptions-fixtures7] Measurement(wifi_ssid=None, wifi_strength=None, energy_import_kwh=None, energy_import_t1_kwh=None, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=None, energy_export_t1_kwh=None, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=None, power_l1_w=None, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=None, meter_model=None, unique_id='SomeInvalidEANWhichIsNotAHexadecimalString', tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices={'gas_meter_\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': ExternalDevice(unique_id='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', type=, value=111.111, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'heat_meter_\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': ExternalDevice(unique_id='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', type=, value=222.222, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'warm_water_meter_\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': ExternalDevice(unique_id='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', type=, value=333.333, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'water_meter_\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': ExternalDevice(unique_id='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', type=, value=444.444, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'inlet_heat_meter_\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': ExternalDevice(unique_id='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', type=, value=555.555, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10)), 'None_\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': ExternalDevice(unique_id='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', type=None, value=555.555, unit=',3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10))}, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_data[exceptions-fixtures7].1 Measurement(wifi_ssid=None, wifi_strength=None, energy_import_kwh=None, energy_import_t1_kwh=None, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=None, energy_export_t1_kwh=None, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=None, power_l1_w=None, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices={'None_NGLYD': ExternalDevice(unique_id='NGLYD', type=None, value=111.111, unit='m3', timestamp=datetime.datetime(2021, 6, 6, 14, 0, 10))}, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_device[HWE-KWH1-fixtures3] Device(model_name='Wi-Fi kWh Meter 1-phase', id='appliance/energymeter/3c39e7aabbcc', product_name='kWh Meter', product_type='HWE-KWH1', serial='3c39e7aabbcc', api_version=, firmware_version='2.11') # --- # name: test_device[HWE-KWH3-fixtures4] Device(model_name='Wi-Fi kWh Meter 3-phase', id='appliance/energymeter/3c39e7aabbcc', product_name='kWh Meter 3-phase', product_type='HWE-KWH3', serial='3c39e7aabbcc', api_version=, firmware_version='2.11') # --- # name: test_device[HWE-P1-fixtures0] Device(model_name='Wi-Fi P1 Meter', id='appliance/p1dongle/3c39e7aabbcc', product_name='P1 Meter', product_type='HWE-P1', serial='3c39e7aabbcc', api_version=, firmware_version='2.11') # --- # name: test_device[HWE-SKT-fixtures1] Device(model_name='Wi-Fi Energy Socket', id='appliance/energysocket/3c39e7aabbcc', product_name='Energy Socket', product_type='HWE-SKT', serial='3c39e7aabbcc', api_version=, firmware_version='2.11') # --- # name: test_device[HWE-WTR-fixtures2] Device(model_name='Wi-Fi Watermeter', id='appliance/watermeter/3c39e7aabbcc', product_name='Water Meter', product_type='HWE-WTR', serial='3c39e7aabbcc', api_version=, firmware_version='2.11') # --- # name: test_device[SDM230-wifi-fixtures5] Device(model_name='Wi-Fi kWh Meter 1-phase', id='appliance/energymeter/3c39e7aabbcc', product_name='kWh Meter', product_type='SDM230-wifi', serial='3c39e7aabbcc', api_version=, firmware_version='2.11') # --- # name: test_device[SDM630-wifi-fixtures6] Device(model_name='Wi-Fi kWh Meter 3-phase', id='appliance/energymeter/3c39e7aabbcc', product_name='kWh Meter 3-phase', product_type='SDM630-wifi', serial='3c39e7aabbcc', api_version=, firmware_version='2.11') # --- # name: test_state[HWE-SKT-fixtures0] State(power_on=False, switch_lock=False, brightness=255) # --- # name: test_state[HWE-SKT-fixtures0].1 State(power_on=False, switch_lock=None, brightness=None) # --- # name: test_state[HWE-SKT-fixtures0].2 State(power_on=None, switch_lock=False, brightness=None) # --- # name: test_state[HWE-SKT-fixtures0].3 State(power_on=None, switch_lock=None, brightness=255) # --- # name: test_system[HWE-KWH1-fixtures3] System(wifi_strength_pct=None, wifi_ssid=None, wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None) # --- # name: test_system[HWE-KWH3-fixtures4] System(wifi_strength_pct=None, wifi_ssid=None, wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None) # --- # name: test_system[HWE-P1-fixtures0] System(wifi_strength_pct=None, wifi_ssid=None, wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None) # --- # name: test_system[HWE-SKT-fixtures1] System(wifi_strength_pct=None, wifi_ssid=None, wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None) # --- # name: test_system[HWE-WTR-fixtures2] System(wifi_strength_pct=None, wifi_ssid=None, wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None) # --- # name: test_system[SDM230-wifi-fixtures5] System(wifi_strength_pct=None, wifi_ssid=None, wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None) # --- # name: test_system[SDM630-wifi-fixtures6] System(wifi_strength_pct=None, wifi_ssid=None, wifi_rssi_db=None, cloud_enabled=True, uptime_s=None, status_led_brightness_pct=None, api_v1_enabled=None) # --- python-homewizard-energy-8.3.2/tests/v1/fixtures/000077500000000000000000000000001474712727000220575ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-KWH1/000077500000000000000000000000001474712727000232125ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-KWH1/data.json000066400000000000000000000010771474712727000250230ustar00rootroot00000000000000{ "wifi_ssid": "My Wi-Fi", "wifi_strength": 74, "total_power_import_kwh": 122.376, "total_power_import_t1_kwh": 122.376, "total_power_export_kwh": 579.813, "total_power_export_t1_kwh": 579.813, "active_power_w": -45.252, "active_power_l1_w": -45.252, "active_voltage_v": 228.472, "active_current_a": 0.273, "active_apparent_current_a": 0.447, "active_reactive_current_a": 0.354, "active_apparent_power_va": 74.052, "active_reactive_power_var": -58.612, "active_power_factor": 0.611, "active_frequency_hz": 50 } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-KWH1/device.json000066400000000000000000000002331474712727000253420ustar00rootroot00000000000000{ "product_type": "HWE-KWH1", "product_name": "kWh Meter", "serial": "3c39e7aabbcc", "firmware_version": "2.11", "api_version": "v1" } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-KWH1/system.json000066400000000000000000000000371474712727000254310ustar00rootroot00000000000000{ "cloud_enabled": true } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-KWH3/000077500000000000000000000000001474712727000232145ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-KWH3/data.json000066400000000000000000000025631474712727000250260ustar00rootroot00000000000000{ "wifi_ssid": "HW WiFi", "wifi_strength": 84, "total_power_import_kwh": 2940.101, "total_power_import_t1_kwh": 2940.101, "total_power_export_kwh": 0, "total_power_export_t1_kwh": 0, "active_power_w": 7100.278, "active_power_l1_w": 0, "active_power_l2_w": 3547.015, "active_power_l3_w": 3553.263, "active_voltage_l1_v": 230.751, "active_voltage_l2_v": 228.391, "active_voltage_l3_v": 229.612, "active_current_a": 30.999, "active_current_l1_a": 0, "active_current_l2_a": 15.521, "active_current_l3_a": 15.477, "active_apparent_current_a": 31.058, "active_apparent_current_l1_a": 0, "active_apparent_current_l2_a": 15.539, "active_apparent_current_l3_a": 15.519, "active_reactive_current_a": 1.872, "active_reactive_current_l1_a": 0, "active_reactive_current_l2_a": 0.73, "active_reactive_current_l3_a": 1.143, "active_apparent_power_va": 7112.293, "active_apparent_power_l1_va": 0, "active_apparent_power_l2_va": 3548.879, "active_apparent_power_l3_va": 3563.414, "active_reactive_power_var": -429.025, "active_reactive_power_l1_var": 0, "active_reactive_power_l2_var": -166.675, "active_reactive_power_l3_var": -262.35, "active_power_factor_l1": 1, "active_power_factor_l2": 0.999, "active_power_factor_l3": 0.997, "active_frequency_hz": 49.926 } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-KWH3/device.json000066400000000000000000000002431474712727000253450ustar00rootroot00000000000000{ "product_type": "HWE-KWH3", "product_name": "kWh Meter 3-phase", "serial": "3c39e7aabbcc", "firmware_version": "2.11", "api_version": "v1" } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-KWH3/system.json000066400000000000000000000000371474712727000254330ustar00rootroot00000000000000{ "cloud_enabled": true } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-P1/000077500000000000000000000000001474712727000227605ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-P1/data_all_data.json000066400000000000000000000041001474712727000264000ustar00rootroot00000000000000{ "wifi_ssid": "My Wi-Fi", "wifi_strength": 100, "smr_version": 50, "meter_model": "ISKRA 2M550T-101", "unique_id": "4E47475955", "active_tariff": 2, "total_power_import_kwh": 13779.338, "total_power_import_t1_kwh": 10830.511, "total_power_import_t2_kwh": 2948.827, "total_power_export_kwh": 0, "total_power_export_t1_kwh": 0, "total_power_export_t2_kwh": 0, "active_power_w": -543, "active_power_l1_w": -676, "active_power_l2_w": 133, "active_power_l3_w": 0, "active_current_l1_a": -4, "active_current_l2_a": 2, "active_current_l3_a": 0, "active_frequency_hz": 50, "voltage_sag_l1_count": 1, "voltage_sag_l2_count": 1, "voltage_sag_l3_count": 0, "voltage_swell_l1_count": 0, "voltage_swell_l2_count": 0, "voltage_swell_l3_count": 0, "any_power_fail_count": 4, "long_power_fail_count": 5, "total_gas_m3": 2569.646, "gas_timestamp": 210606140010, "gas_unique_id": "4E474C5944", "active_power_average_w": 123.000, "montly_power_peak_w": 1111.000, "montly_power_peak_timestamp": 230101080010, "external": [ { "unique_id": "4E474C5944", "type": "gas_meter", "timestamp": 210606140010, "value": 111.111, "unit": "m3" }, { "unique_id": "4E475241414459", "type": "heat_meter", "timestamp": 210606140010, "value": 222.222, "unit": "m3" }, { "unique_id": "4E474D5943", "type": "warm_water_meter", "timestamp": 210606140010, "value": 333.333, "unit": "m3" }, { "unique_id": "4E475347", "type": "water_meter", "timestamp": 210606140010, "value": 444.444, "unit": "m3" }, { "unique_id": "4E4754414C414859", "type": "inlet_heat_meter", "timestamp": 210606140010, "value": 555.555, "unit": "m3" } ] } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-P1/data_minimal.json000066400000000000000000000007341474712727000262760ustar00rootroot00000000000000{ "smr_version": 50, "meter_model": "ISKRA 2M550T-101", "wifi_ssid": "My Wi-Fi", "wifi_strength": 100, "total_power_import_t1_kwh": 10830.511, "total_power_import_t2_kwh": 2948.827, "total_power_export_t1_kwh": 1285.951, "total_power_export_t2_kwh": 2876.51, "active_power_w": -543, "active_power_l1_w": -676, "active_power_l2_w": 133, "active_power_l3_w": 0, "total_gas_m3": 2569.646, "gas_timestamp": 210606140010 } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-P1/data_no_gas.json000066400000000000000000000007201474712727000261110ustar00rootroot00000000000000{ "smr_version": 50, "meter_model": "ISKRA 2M550T-101", "wifi_ssid": "My Wi-Fi", "wifi_strength": 100, "total_power_import_t1_kwh": 10830.511, "total_power_import_t2_kwh": 2948.827, "total_power_export_t1_kwh": 1285.951, "total_power_export_t2_kwh": 2876.51, "active_power_w": -543, "active_power_l1_w": -676, "active_power_l2_w": 133, "active_power_l3_w": 0, "total_gas_m3": null, "gas_timestamp": null } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-P1/data_single_phase.json000066400000000000000000000007401474712727000273060ustar00rootroot00000000000000{ "smr_version": 50, "meter_model": "ISKRA 2M550T-101", "wifi_ssid": "My Wi-Fi", "wifi_strength": 100, "total_power_import_t1_kwh": 10830.511, "total_power_import_t2_kwh": 2948.827, "total_power_export_t1_kwh": 1285.951, "total_power_export_t2_kwh": 2876.51, "active_power_w": -543, "active_power_l1_w": -676, "active_power_l2_w": null, "active_power_l3_w": null, "total_gas_m3": 2569.646, "gas_timestamp": 210606140010 } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-P1/decryption.json000066400000000000000000000000461474712727000260330ustar00rootroot00000000000000{ "key": true, "aad": true } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-P1/device.json000066400000000000000000000002301474712727000251050ustar00rootroot00000000000000{ "product_type": "HWE-P1", "product_name": "P1 Meter", "serial": "3c39e7aabbcc", "firmware_version": "2.11", "api_version": "v1" } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-P1/identify.json000066400000000000000000000000231474712727000254610ustar00rootroot00000000000000{"identify": "ok"} python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-P1/system.json000066400000000000000000000000371474712727000251770ustar00rootroot00000000000000{ "cloud_enabled": true } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-SKT/000077500000000000000000000000001474712727000231415ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-SKT/data.json000066400000000000000000000003131474712727000247420ustar00rootroot00000000000000{ "wifi_ssid": "My Wi-Fi", "wifi_strength": 100, "total_power_import_t1_kwh": 10830.511, "total_power_export_t1_kwh": 2948.827, "active_power_w": 123, "active_power_l1_w": 123 } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-SKT/device.json000066400000000000000000000002361474712727000252740ustar00rootroot00000000000000{ "product_type": "HWE-SKT", "product_name": "Energy Socket", "serial": "3c39e7aabbcc", "firmware_version": "2.11", "api_version": "v1" } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-SKT/identify.json000066400000000000000000000000231474712727000256420ustar00rootroot00000000000000{"identify": "ok"} python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-SKT/state_all.json000066400000000000000000000001131474712727000257770ustar00rootroot00000000000000{ "power_on": false, "switch_lock": false, "brightness": 255 } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-SKT/state_brightness.json000066400000000000000000000000321474712727000273770ustar00rootroot00000000000000{ "brightness": 255 } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-SKT/state_power_on.json000066400000000000000000000000321474712727000270570ustar00rootroot00000000000000{ "power_on": false } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-SKT/state_switch_lock.json000066400000000000000000000000351474712727000275430ustar00rootroot00000000000000{ "switch_lock": false } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-SKT/system.json000066400000000000000000000000371474712727000253600ustar00rootroot00000000000000{ "cloud_enabled": true } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-WTR/000077500000000000000000000000001474712727000231545ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-WTR/data.json000066400000000000000000000001721474712727000247600ustar00rootroot00000000000000{ "wifi_ssid": "My Wi-Fi", "wifi_strength": 100, "active_liter_lpm": 13.12, "total_liter_m3": 8129.123 } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-WTR/device.json000066400000000000000000000002341474712727000253050ustar00rootroot00000000000000{ "product_type": "HWE-WTR", "product_name": "Water Meter", "serial": "3c39e7aabbcc", "firmware_version": "2.11", "api_version": "v1" } python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-WTR/identify.json000066400000000000000000000000231474712727000256550ustar00rootroot00000000000000{"identify": "ok"} python-homewizard-energy-8.3.2/tests/v1/fixtures/HWE-WTR/system.json000066400000000000000000000000371474712727000253730ustar00rootroot00000000000000{ "cloud_enabled": true } python-homewizard-energy-8.3.2/tests/v1/fixtures/SDM230-wifi/000077500000000000000000000000001474712727000236635ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v1/fixtures/SDM230-wifi/data.json000066400000000000000000000010771474712727000254740ustar00rootroot00000000000000{ "wifi_ssid": "My Wi-Fi", "wifi_strength": 74, "total_power_import_kwh": 122.376, "total_power_import_t1_kwh": 122.376, "total_power_export_kwh": 579.813, "total_power_export_t1_kwh": 579.813, "active_power_w": -45.252, "active_power_l1_w": -45.252, "active_voltage_v": 228.472, "active_current_a": 0.273, "active_apparent_current_a": 0.447, "active_reactive_current_a": 0.354, "active_apparent_power_va": 74.052, "active_reactive_power_var": -58.612, "active_power_factor": 0.611, "active_frequency_hz": 50 } python-homewizard-energy-8.3.2/tests/v1/fixtures/SDM230-wifi/device.json000066400000000000000000000002361474712727000260160ustar00rootroot00000000000000{ "product_type": "SDM230-wifi", "product_name": "kWh Meter", "serial": "3c39e7aabbcc", "firmware_version": "2.11", "api_version": "v1" } python-homewizard-energy-8.3.2/tests/v1/fixtures/SDM230-wifi/system.json000066400000000000000000000000371474712727000261020ustar00rootroot00000000000000{ "cloud_enabled": true } python-homewizard-energy-8.3.2/tests/v1/fixtures/SDM630-wifi/000077500000000000000000000000001474712727000236675ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v1/fixtures/SDM630-wifi/data.json000066400000000000000000000025631474712727000255010ustar00rootroot00000000000000{ "wifi_ssid": "HW WiFi", "wifi_strength": 84, "total_power_import_kwh": 2940.101, "total_power_import_t1_kwh": 2940.101, "total_power_export_kwh": 0, "total_power_export_t1_kwh": 0, "active_power_w": 7100.278, "active_power_l1_w": 0, "active_power_l2_w": 3547.015, "active_power_l3_w": 3553.263, "active_voltage_l1_v": 230.751, "active_voltage_l2_v": 228.391, "active_voltage_l3_v": 229.612, "active_current_a": 30.999, "active_current_l1_a": 0, "active_current_l2_a": 15.521, "active_current_l3_a": 15.477, "active_apparent_current_a": 31.058, "active_apparent_current_l1_a": 0, "active_apparent_current_l2_a": 15.539, "active_apparent_current_l3_a": 15.519, "active_reactive_current_a": 1.872, "active_reactive_current_l1_a": 0, "active_reactive_current_l2_a": 0.73, "active_reactive_current_l3_a": 1.143, "active_apparent_power_va": 7112.293, "active_apparent_power_l1_va": 0, "active_apparent_power_l2_va": 3548.879, "active_apparent_power_l3_va": 3563.414, "active_reactive_power_var": -429.025, "active_reactive_power_l1_var": 0, "active_reactive_power_l2_var": -166.675, "active_reactive_power_l3_var": -262.35, "active_power_factor_l1": 1, "active_power_factor_l2": 0.999, "active_power_factor_l3": 0.997, "active_frequency_hz": 49.926 } python-homewizard-energy-8.3.2/tests/v1/fixtures/SDM630-wifi/device.json000066400000000000000000000002461474712727000260230ustar00rootroot00000000000000{ "product_type": "SDM630-wifi", "product_name": "kWh Meter 3-phase", "serial": "3c39e7aabbcc", "firmware_version": "2.11", "api_version": "v1" } python-homewizard-energy-8.3.2/tests/v1/fixtures/SDM630-wifi/system.json000066400000000000000000000000371474712727000261060ustar00rootroot00000000000000{ "cloud_enabled": true } python-homewizard-energy-8.3.2/tests/v1/fixtures/exceptions/000077500000000000000000000000001474712727000242405ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v1/fixtures/exceptions/data_invalid_external_data.json000066400000000000000000000015771474712727000324570ustar00rootroot00000000000000{ "total_gas_m3": 2569.646, "gas_timestamp": 210606140010, "gas_unique_id": "4E474C5944", "external": [ { "type": "gas_meter", "timestamp": 210606140010, "value": 111.111, "unit": "m3" }, { "unique_id": "4E474C5944", "timestamp": 210606140010, "value": 111.111, "unit": "m3" }, { "unique_id": "4E474C5944", "type": "gas_meter", "value": 111.111, "unit": "m3" }, { "unique_id": "4E474C5944", "type": "gas_meter", "timestamp": 210606140010, "unit": "m3" }, { "unique_id": "4E474C5944", "type": "gas_meter", "timestamp": 210606140010, "value": 111.111 } ] } python-homewizard-energy-8.3.2/tests/v1/fixtures/exceptions/data_invalid_external_ean.json000066400000000000000000000035161474712727000323040ustar00rootroot00000000000000{ "total_gas_m3": 2569.646, "gas_timestamp": 210606140010, "gas_unique_id": "00000000000000000000000000000000", "unique_id": "SomeInvalidEANWhichIsNotAHexadecimalString", "external": [ { "unique_id": "00000000000000000000000000000000", "type": "gas_meter", "timestamp": 210606140010, "value": 111.111, "unit": "m3" }, { "unique_id": "00000000000000000000000000000000", "type": "heat_meter", "timestamp": 210606140010, "value": 222.222, "unit": "m3" }, { "unique_id": "00000000000000000000000000000000", "type": "warm_water_meter", "timestamp": 210606140010, "value": 333.333, "unit": "m3" }, { "unique_id": "00000000000000000000000000000000", "type": "water_meter", "timestamp": 210606140010, "value": 444.444, "unit": "m3" }, { "unique_id": "00000000000000000000000000000000", "type": "inlet_heat_meter", "timestamp": 210606140010, "value": 555.555, "unit": "m3" }, { "type": "00000000000000000000000000000000", "timestamp": 210606140010, "value": 555.555, "unit": "should_not_be_included_because_of_missing_id" }, { "unique_id": "00000000000000000000000000000000", "type": "catfish", "timestamp": 210606140010, "value": 555.555, "unit": ",3" }, { "unique_id": "00000000000000000000000000000000", "timestamp": 210606140010, "value": 555.555, "unit": ",3" } ] } python-homewizard-energy-8.3.2/tests/v1/fixtures/exceptions/device_extra_parameters.json000066400000000000000000000003011474712727000320120ustar00rootroot00000000000000{ "product_type": "HWE-P1", "product_name": "P1 Meter", "serial": "3c39e7aabbcc", "firmware_version": "2.11", "api_version": "v1", "new_undocumented_parameter": false } python-homewizard-energy-8.3.2/tests/v1/fixtures/exceptions/device_invalid_api.json000066400000000000000000000002301474712727000307240ustar00rootroot00000000000000{ "product_type": "HWE-P1", "product_name": "P1 Meter", "serial": "3c39e7aabbcc", "firmware_version": "2.11", "api_version": "v2" } python-homewizard-energy-8.3.2/tests/v1/pytest.ini000066400000000000000000000000351474712727000222350ustar00rootroot00000000000000[pytest] asyncio_mode=strict python-homewizard-energy-8.3.2/tests/v1/test_v1_homewizard_energy.py000066400000000000000000000566301474712727000257610ustar00rootroot00000000000000"""Test for HomeWizard Energy.""" import asyncio import json from unittest.mock import AsyncMock, patch import aiohttp import pytest from syrupy.assertion import SnapshotAssertion from homewizard_energy import HomeWizardEnergyV1 from homewizard_energy.errors import DisabledError, RequestError, UnsupportedError from . import load_fixtures pytestmark = [pytest.mark.asyncio] async def test_request_returns_str(aresponses): """Test JSON response is handled correctly.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"status": "ok"}', ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) # pylint: disable=protected-access _, return_value = await api._request("api") assert isinstance(return_value, str) return_value = json.loads(return_value) assert return_value["status"] == "ok" await api.close() async def test_request_internal_session(aresponses): """Test session is closed when created internally.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"status": "ok"}', ), ) api = HomeWizardEnergyV1("example.com") # pylint: disable=protected-access assert await api._request("api") await api.close() async def test_request_detects_403(aresponses): """Test request detects disabled API.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( status=403, headers={"Content-Type": "application/json"}, text='{"status": "ok"}', ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) with pytest.raises(DisabledError): # pylint: disable=protected-access await api._request("api") await api.close() async def test_request_detects_non_200(aresponses): """Test detects non-ok response.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( status=500, headers={"Content-Type": "application/json"}, text='{"status": "ok"}', ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) with pytest.raises(RequestError): # pylint: disable=protected-access await api._request("api") await api.close() async def test_request_detects_clienterror(): """Test other clienterror.""" async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) with ( patch.object(session, "request", side_effect=aiohttp.ClientError), pytest.raises(RequestError), ): # pylint: disable=protected-access await api._request("api") await api.close() ### CombinedModels tests ### # pylint: disable=too-many-arguments # pylint: disable=too-many-positional-arguments @pytest.mark.parametrize( ("model", "device", "data", "state", "system"), [ ("HWE-KWH1", "device", "data", None, "system"), ("HWE-KWH3", "device", "data", None, "system"), ("HWE-P1", "device", "data_all_data", None, "system"), ("HWE-SKT", "device", "data", "state_all", "system"), ("HWE-WTR", "device", "data", None, "system"), ("SDM230-wifi", "device", "data", None, "system"), ("SDM630-wifi", "device", "data", None, "system"), ], ) async def test_combined_models_with_valid_authentication( model: str, device: str, data: str, state: str | None, system: str, snapshot: SnapshotAssertion, aresponses, ): """Test combined models request is successful when valid authentication is provided.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( text=load_fixtures(f"{model}/{device}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "example.com", "/api/v1/data", "GET", aresponses.Response( text=load_fixtures(f"{model}/{data}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "example.com", "/api/v1/state", "GET", aresponses.Response( text=load_fixtures(f"{model}/{state}.json") if state else "404 Not Found", status=200 if state else 404, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "example.com", "/api/v1/system", "GET", aresponses.Response( text=load_fixtures(f"{model}/{system}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) async with HomeWizardEnergyV1("example.com") as api: data = await api.combined() assert data is not None assert data == snapshot # pylint: disable=too-many-arguments # pylint: disable=too-many-positional-arguments @pytest.mark.parametrize( ("model", "device", "data", "state", "system"), [ ("HWE-KWH1", "device", "data", None, "system"), ("HWE-KWH3", "device", "data", None, "system"), ("HWE-P1", "device", "data_all_data", None, "system"), ("HWE-SKT", "device", "data", "state_all", "system"), ("HWE-WTR", "device", "data", None, "system"), ("SDM230-wifi", "device", "data", None, "system"), ("SDM630-wifi", "device", "data", None, "system"), ], ) async def test_combined_models_with_valid_authentication_caches_device( model: str, device: str, data: str, state: str | None, system: str, snapshot: SnapshotAssertion, aresponses, ): """Test combined models request is successful when valid authentication is provided.""" # Request 1 aresponses.add( "example.com", "/api", "GET", aresponses.Response( text=load_fixtures(f"{model}/{device}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "example.com", "/api/v1/data", "GET", aresponses.Response( text=load_fixtures(f"{model}/{data}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "example.com", "/api/v1/state", "GET", aresponses.Response( text=load_fixtures(f"{model}/{state}.json") if state else "404 Not Found", status=200 if state else 404, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "example.com", "/api/v1/system", "GET", aresponses.Response( text=load_fixtures(f"{model}/{system}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) # Request 2, should use cache of `/api` aresponses.add( "example.com", "/api/v1/data", "GET", aresponses.Response( text=load_fixtures(f"{model}/{data}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "example.com", "/api/v1/state", "GET", aresponses.Response( text=load_fixtures(f"{model}/{state}.json") if state else "404 Not Found", status=200 if state else 404, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "example.com", "/api/v1/system", "GET", aresponses.Response( text=load_fixtures(f"{model}/{system}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) async with HomeWizardEnergyV1("example.com") as api: data = await api.combined() assert data is not None assert data == snapshot data_2 = await api.combined() assert data_2 == data @pytest.mark.parametrize( ("model", "fixtures"), [ ("HWE-P1", ["device"]), ("HWE-SKT", ["device"]), ("HWE-WTR", ["device"]), ("HWE-KWH1", ["device"]), ("HWE-KWH3", ["device"]), ("SDM230-wifi", ["device"]), ("SDM630-wifi", ["device"]), ], ) async def test_get_device_object( model: str, fixtures: str, snapshot: SnapshotAssertion, aresponses ): """Test device object is fetched and sets detected values.""" for fixture in fixtures: aresponses.add( "example.com", "/api", "GET", aresponses.Response( text=load_fixtures(f"{model}/{fixture}.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) device = await api.device() assert device assert device.product_type == model assert device == snapshot await api.close() async def test_get_device_used_cached_device_object(aresponses): """Test device object is fetched and sets detected values.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( text=load_fixtures("HWE-P1/device.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) device = await api.device() assert device assert device.product_type == "HWE-P1" device_2 = await api.device() assert device_2 == device await api.close() async def test_get_device_with_clear_cache_flag(aresponses): """Test device object is fetched and sets detected values.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( text=load_fixtures("HWE-P1/device.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) aresponses.add( "example.com", "/api", "GET", aresponses.Response( text=load_fixtures("HWE-SKT/device.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) device = await api.device() assert device assert device.product_type == "HWE-P1" device_2 = await api.device(reset_cache=True) assert device_2 != device assert device_2.product_type == "HWE-SKT" await api.close() @pytest.mark.parametrize( ("model", "fixtures"), [ ( "HWE-P1", ["data_all_data", "data_minimal", "data_no_gas", "data_single_phase"], ), ("HWE-SKT", ["data"]), ("HWE-WTR", ["data"]), ("HWE-KWH1", ["data"]), ("HWE-KWH3", ["data"]), ("SDM230-wifi", ["data"]), ("SDM630-wifi", ["data"]), ], ) async def test_get_data_object( model: str, fixtures: str, snapshot: SnapshotAssertion, aresponses ): """Test fetches data object and device object when unknown.""" for fixture in fixtures: aresponses.add( "example.com", "/api", "GET", aresponses.Response( text=load_fixtures(f"{model}/device.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) aresponses.add( "example.com", "/api/v1/data", "GET", aresponses.Response( text=load_fixtures(f"{model}/{fixture}.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) measurement = await api.measurement() assert measurement is not None assert measurement == snapshot await api.close() @pytest.mark.parametrize( ("model", "fixtures"), [ ( "HWE-P1", ["data_all_data", "data_minimal", "data_no_gas", "data_single_phase"], ), ("HWE-SKT", ["data"]), ("HWE-WTR", ["data"]), ("HWE-KWH1", ["data"]), ("HWE-KWH3", ["data"]), ("SDM230-wifi", ["data"]), ("SDM630-wifi", ["data"]), ], ) async def test_get_data_object_with_known_device( model: str, fixtures: str, snapshot: SnapshotAssertion, aresponses ): """Test fetches data object.""" for fixture in fixtures: aresponses.add( "example.com", "/api/v1/data", "GET", aresponses.Response( text=load_fixtures(f"{model}/{fixture}.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) # pylint: disable=protected-access api._detected_api_version = "v1" measurement = await api.measurement() assert measurement is not None assert measurement == snapshot await api.close() @pytest.mark.parametrize( ("model", "fixtures"), [ ( "HWE-SKT", ["state_all", "state_power_on", "state_switch_lock", "state_brightness"], ), ], ) async def test_get_state_object( model: str, fixtures: str, snapshot: SnapshotAssertion, aresponses ): """Test fetches state object and device object when unknown.""" for fixture in fixtures: aresponses.add( "example.com", "/api", "GET", aresponses.Response( text=load_fixtures(f"{model}/device.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) aresponses.add( "example.com", "/api/v1/state", "GET", aresponses.Response( text=load_fixtures(f"{model}/{fixture}.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) state = await api.state() assert state is not None assert state == snapshot await api.close() @pytest.mark.parametrize( ("model", "fixtures"), [ ("HWE-SKT", ["state_all"]), ], ) async def test_state_set( model: str, fixtures: str, snapshot: SnapshotAssertion, aresponses ): """Test state set.""" for fixture in fixtures: aresponses.add( "example.com", "/api/v1/state", "PUT", aresponses.Response( text=load_fixtures(f"{model}/{fixture}.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) state = await api.state(power_on=False, switch_lock=False, brightness=255) assert state assert state == snapshot await api.close() @pytest.mark.parametrize( "model", [ "HWE-P1", "HWE-WTR", "HWE-KWH1", "HWE-KWH3", "SDM230-wifi", "SDM630-wifi", ], ) async def test_state_not_supported_with_cached_device(aresponses, model: str): """Test state set uses cached device to check is unsupported.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( text=load_fixtures(f"{model}/device.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) await api.device() with pytest.raises(UnsupportedError): await api.state() await api.close() @pytest.mark.parametrize( "model", [ "HWE-P1", "HWE-SKT", "HWE-WTR", ], ) async def test_identify(model: str, snapshot: SnapshotAssertion, aresponses): """Test identify call.""" aresponses.add( "example.com", "/api/v1/identify", "PUT", aresponses.Response( text=load_fixtures(f"{model}/identify.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) state = await api.identify() assert state assert state == snapshot await api.close() @pytest.mark.parametrize( "model", [ "HWE-KWH1", "HWE-KWH3", "SDM230-wifi", "SDM630-wifi", ], ) async def test_identify_not_supported(model: str, aresponses): """Test identify call when not supported.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( text=load_fixtures(f"{model}/device.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) aresponses.add( "example.com", "/api/v1/identify", "PUT", aresponses.Response( text="404 Not Found", status=404, headers={"Content-Type": "application/txt; charset=utf-8"}, ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) with pytest.raises(UnsupportedError): await api.identify() await api.close() @pytest.mark.parametrize( "model", [ "HWE-KWH1", "HWE-KWH3", "SDM230-wifi", "SDM630-wifi", ], ) async def test_identify_not_supported_with_cached_device(aresponses, model: str): """Test identify set uses cached device to check is unsupported.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( text=load_fixtures(f"{model}/device.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) await api.device() with pytest.raises(UnsupportedError): await api.identify() await api.close() async def test_get_system_object(aresponses): """Test fetches system object and device object when unknown.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( text=load_fixtures("HWE-SKT/device.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) aresponses.add( "example.com", "/api/v1/system", "GET", aresponses.Response( text=json.dumps({"cloud_enabled": True}), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) aresponses.add( "example.com", "/api/v1/system", "GET", aresponses.Response( text=json.dumps({"cloud_enabled": False}), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) system = await api.system() assert system assert system.cloud_enabled system = await api.system() assert system assert not system.cloud_enabled await api.close() @pytest.mark.parametrize( "model", [ "HWE-P1", "HWE-SKT", "HWE-WTR", "HWE-KWH1", "HWE-KWH3", "SDM230-wifi", "SDM630-wifi", ], ) async def test_system_set(model: str, snapshot: SnapshotAssertion, aresponses): """Test system set.""" aresponses.add( "example.com", "/api/v1/system", "PUT", aresponses.Response( text=load_fixtures(f"{model}/system.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) system = await api.system(cloud_enabled=True) assert system assert system == snapshot await api.close() async def test_system_set_unsupported_arguments(): """Test system set when no arguments are given.""" async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) with pytest.raises(UnsupportedError): await api.system(api_v1_enabled=True) async def test_system_routes_brightness_to_state(aresponses): """Test system sets brightness to state.""" aresponses.add( "example.com", "/api/v1/state", "PUT", aresponses.Response( text=load_fixtures("HWE-SKT/state_brightness.json"), status=200, headers={"Content-Type": "application/json; charset=utf-8"}, ), ) async with aiohttp.ClientSession() as session: api = HomeWizardEnergyV1("example.com", clientsession=session) system = await api.system(status_led_brightness_pct=100) assert system.status_led_brightness_pct == 100 await api.close() # pylint: disable=protected-access async def test_request_handles_timeout(): """Test request raises timeout when request takes too long.""" api = HomeWizardEnergyV1("example.com") api._session = AsyncMock() api._session.request = AsyncMock(side_effect=asyncio.TimeoutError()) with pytest.raises(RequestError): # pylint: disable=protected-access await api._request("api/v1/data") assert api._session.request.call_count == 3 async def test_close_when_out_of_scope(): """Test close called when object goes out of scope.""" api = HomeWizardEnergyV1("example.com") api.close = AsyncMock() async with api as hwe: assert hwe == api assert api.close.call_count == 1 python-homewizard-energy-8.3.2/tests/v1/test_v1_models.py000066400000000000000000000117361474712727000235200ustar00rootroot00000000000000"""Test for HomeWizard Energy Models.""" import json import pytest from syrupy.assertion import SnapshotAssertion from homewizard_energy.models import CombinedModels, Device, Measurement, State, System from . import load_fixtures pytestmark = [pytest.mark.asyncio] @pytest.mark.parametrize( ("model", "fixtures"), [ ("HWE-P1", ["device"]), ("HWE-SKT", ["device"]), ("HWE-WTR", ["device"]), ("HWE-KWH1", ["device"]), ("HWE-KWH3", ["device"]), ("SDM230-wifi", ["device"]), ("SDM630-wifi", ["device"]), ], ) async def test_device(model: str, fixtures: str, snapshot: SnapshotAssertion): """Test Device model.""" for fixture in fixtures: data = Device.from_dict(json.loads(load_fixtures(f"{model}/{fixture}.json"))) assert data assert snapshot == data async def test_combined_remaps_legacy_wifi_ssid_to_system(snapshot: SnapshotAssertion): """Test CombinedModels model remaps wifi_ssid to system.""" device = Device.from_dict(json.loads(load_fixtures("HWE-SKT/device.json"))) measurement = Measurement.from_dict(json.loads(load_fixtures("HWE-SKT/data.json"))) combined = CombinedModels( device=device, measurement=measurement, state=None, system=None ) assert combined.system.wifi_ssid == measurement.wifi_ssid assert snapshot == combined async def test_combined_remaps_legacy_brightness_to_system(snapshot: SnapshotAssertion): """Test CombinedModels model remaps wifi_ssid to system.""" device = Device.from_dict(json.loads(load_fixtures("HWE-SKT/device.json"))) state = State.from_dict(json.loads(load_fixtures("HWE-SKT/state_all.json"))) combined = CombinedModels(device=device, measurement=None, state=state, system=None) assert combined.system.status_led_brightness_pct == state.brightness / 2.55 assert snapshot == combined @pytest.mark.parametrize( ("model", "supports_state", "supports_identify", "supports_cloud_enable"), [ ("HWE-P1", False, True, True), ("HWE-SKT", True, True, True), ("HWE-WTR", False, True, True), ("HWE-KWH1", False, False, True), ("HWE-KWH3", False, False, True), ("SDM230-wifi", False, False, True), ("SDM630-wifi", False, False, True), ], ) async def test_device_support_functions( model: str, supports_state: bool, supports_identify: bool, supports_cloud_enable: bool, ): """Test Device model support functions.""" device = Device.from_dict(json.loads(load_fixtures(f"{model}/device.json"))) assert device assert device.supports_state() == supports_state assert device.supports_identify() == supports_identify assert device.supports_cloud_enable() == supports_cloud_enable assert device.supports_reboot() is False # Always False for v1 @pytest.mark.parametrize( ("model", "fixtures"), [ ( "HWE-P1", [ "data_minimal", "data_all_data", "data_no_gas", "data_single_phase", ], ), ("HWE-SKT", ["data"]), ("HWE-WTR", ["data"]), ("HWE-KWH1", ["data"]), ("HWE-KWH3", ["data"]), ("SDM230-wifi", ["data"]), ("SDM630-wifi", ["data"]), ( "exceptions", [ "data_invalid_external_ean", "data_invalid_external_data", ], ), ], ) async def test_data(model: str, fixtures: str, snapshot: SnapshotAssertion): """Test Measurement model.""" for fixture in fixtures: data = Measurement.from_dict( json.loads(load_fixtures(f"{model}/{fixture}.json")) ) assert data assert snapshot == data async def test_data_ignores_invalid_tariff(): """Test Data model ignores invalid tariff.""" measurement = Measurement.from_dict({"active_tariff": 5432}) assert measurement assert measurement.tariff is None @pytest.mark.parametrize( ("model", "fixtures"), [ ( "HWE-SKT", ["state_all", "state_power_on", "state_switch_lock", "state_brightness"], ), ], ) async def test_state(model: str, fixtures: str, snapshot: SnapshotAssertion): """Test State model.""" for fixture in fixtures: data = State.from_dict(json.loads(load_fixtures(f"{model}/{fixture}.json"))) assert data assert snapshot == data @pytest.mark.parametrize( ("model", "fixtures"), [ ("HWE-P1", ["system"]), ("HWE-SKT", ["system"]), ("HWE-WTR", ["system"]), ("HWE-KWH1", ["system"]), ("HWE-KWH3", ["system"]), ("SDM230-wifi", ["system"]), ("SDM630-wifi", ["system"]), ], ) async def test_system(model: str, fixtures: str, snapshot: SnapshotAssertion): """Test System model.""" for fixture in fixtures: data = System.from_dict(json.loads(load_fixtures(f"{model}/{fixture}.json"))) assert data assert snapshot == data python-homewizard-energy-8.3.2/tests/v2/000077500000000000000000000000001474712727000202075ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v2/__init__.py000066400000000000000000000004011474712727000223130ustar00rootroot00000000000000"""Tests for python-homewizard-energy.""" import os def load_fixtures(filename): """Load a fixture.""" path = os.path.join(os.path.dirname(__file__), "fixtures", filename) with open(path, encoding="utf-8") as fptr: return fptr.read() python-homewizard-energy-8.3.2/tests/v2/__snapshots__/000077500000000000000000000000001474712727000230255ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v2/__snapshots__/test_v2_homewizard_energy.ambr000066400000000000000000000267501474712727000310720ustar00rootroot00000000000000# serializer version: 1 # name: test_combined_models_with_valid_authentication[HWE-BAT-device-measurement-None-system] CombinedModels(device=Device(model_name='Plug-In Battery', id='appliance/battery/5c2fafaabbcc', product_name='Plug-in Battery', product_type='HWE-BAT', serial='5c2fafaabbcc', api_version=, firmware_version='6.00'), measurement=Measurement(wifi_ssid=None, wifi_strength=None, energy_import_kwh=123.456, energy_import_t1_kwh=None, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=321.654, energy_export_t1_kwh=None, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=1234.0, power_l1_w=None, power_l2_w=None, power_l3_w=None, voltage_v=230.123, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=5.678, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.123, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=123, state_of_charge_pct=50.123), state=None, system=System(wifi_strength_pct=46, wifi_ssid='My Wi-Fi', wifi_rssi_db=-77, cloud_enabled=False, uptime_s=356, status_led_brightness_pct=100, api_v1_enabled=None)) # --- # name: test_combined_models_with_valid_authentication[HWE-P1-device-measurement_1_phase_no_gas-None-system] CombinedModels(device=Device(model_name='Wi-Fi P1 Meter', id='appliance/p1dongle/5c2fafaabbcc', product_name='P1 Meter', product_type='HWE-P1', serial='5c2fafaabbcc', api_version=, firmware_version='6.00'), measurement=Measurement(wifi_ssid=None, wifi_strength=None, energy_import_kwh=None, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=None, energy_export_t1_kwh=1285.951, energy_export_t2_kwh=2876.51, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-678.0, power_l1_w=-676.0, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=datetime.datetime(2024, 6, 28, 14, 12, 34), protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id='Never Gonna Give You Up', tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None), state=None, system=System(wifi_strength_pct=46, wifi_ssid='My Wi-Fi', wifi_rssi_db=-77, cloud_enabled=False, uptime_s=356, status_led_brightness_pct=100, api_v1_enabled=True)) # --- # name: test_combined_models_with_valid_authentication_caches_device[HWE-BAT-device-measurement-None-system] CombinedModels(device=Device(model_name='Plug-In Battery', id='appliance/battery/5c2fafaabbcc', product_name='Plug-in Battery', product_type='HWE-BAT', serial='5c2fafaabbcc', api_version=, firmware_version='6.00'), measurement=Measurement(wifi_ssid=None, wifi_strength=None, energy_import_kwh=123.456, energy_import_t1_kwh=None, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=321.654, energy_export_t1_kwh=None, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=1234.0, power_l1_w=None, power_l2_w=None, power_l3_w=None, voltage_v=230.123, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=5.678, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.123, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=123, state_of_charge_pct=50.123), state=None, system=System(wifi_strength_pct=46, wifi_ssid='My Wi-Fi', wifi_rssi_db=-77, cloud_enabled=False, uptime_s=356, status_led_brightness_pct=100, api_v1_enabled=None)) # --- # name: test_combined_models_with_valid_authentication_caches_device[HWE-P1-device-measurement_1_phase_no_gas-None-system] CombinedModels(device=Device(model_name='Wi-Fi P1 Meter', id='appliance/p1dongle/5c2fafaabbcc', product_name='P1 Meter', product_type='HWE-P1', serial='5c2fafaabbcc', api_version=, firmware_version='6.00'), measurement=Measurement(wifi_ssid=None, wifi_strength=None, energy_import_kwh=None, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=None, energy_export_t1_kwh=1285.951, energy_export_t2_kwh=2876.51, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-678.0, power_l1_w=-676.0, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=datetime.datetime(2024, 6, 28, 14, 12, 34), protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id='Never Gonna Give You Up', tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None), state=None, system=System(wifi_strength_pct=46, wifi_ssid='My Wi-Fi', wifi_rssi_db=-77, cloud_enabled=False, uptime_s=356, status_led_brightness_pct=100, api_v1_enabled=True)) # --- # name: test_device_with_valid_authentication[HWE-P1-fixtures0] Device(model_name='Wi-Fi P1 Meter', id='appliance/p1dongle/5c2fafaabbcc', product_name='P1 Meter', product_type='HWE-P1', serial='5c2fafaabbcc', api_version=, firmware_version='6.00') # --- # name: test_measurement_with_valid_authentication[HWE-P1-fixtures0] Measurement(wifi_ssid=None, wifi_strength=None, energy_import_kwh=None, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=None, energy_export_t1_kwh=1285.951, energy_export_t2_kwh=2876.51, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-678.0, power_l1_w=-676.0, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=datetime.datetime(2024, 6, 28, 14, 12, 34), protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id='Never Gonna Give You Up', tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_measurement_with_valid_authentication[HWE-P1-fixtures0].1 Measurement(wifi_ssid=None, wifi_strength=None, energy_import_kwh=13779.338, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=0.0, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-543.0, power_l1_w=-676.0, power_l2_w=133.0, power_l3_w=0.0, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=6.0, current_l1_a=-4.0, current_l2_a=2.0, current_l3_a=0.0, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=datetime.datetime(2024, 6, 28, 14, 12, 34), protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id='Never Gonna Let You Down', tariff=2, voltage_sag_l1_count=1, voltage_sag_l2_count=1, voltage_sag_l3_count=0, voltage_swell_l1_count=0, voltage_swell_l2_count=0, voltage_swell_l3_count=0, any_power_fail_count=4, long_power_fail_count=5, average_power_15m_w=123.0, monthly_power_peak_w=1111.0, monthly_power_peak_timestamp=datetime.datetime(2024, 6, 4, 10, 11, 22), external_devices={'gas_meter_Never gonna run around': ExternalDevice(unique_id='Never gonna run around', type=, value=2569.646, unit='m3', timestamp=datetime.datetime(2024, 6, 28, 14, 0)), 'water_meter_and desert you': ExternalDevice(unique_id='and desert you', type=, value=123.456, unit='m3', timestamp=datetime.datetime(2024, 6, 28, 14, 5))}, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_system_with_valid_authentication[HWE-P1-fixtures0] System(wifi_strength_pct=46, wifi_ssid='My Wi-Fi', wifi_rssi_db=-77, cloud_enabled=False, uptime_s=356, status_led_brightness_pct=100, api_v1_enabled=True) # --- python-homewizard-energy-8.3.2/tests/v2/__snapshots__/test_v2_models.ambr000066400000000000000000000260751474712727000266330ustar00rootroot00000000000000# serializer version: 1 # name: test_device[HWE-BAT-fixtures1] Device(model_name='Plug-In Battery', id='appliance/battery/5c2fafaabbcc', product_name='Plug-in Battery', product_type='HWE-BAT', serial='5c2fafaabbcc', api_version=, firmware_version='6.00') # --- # name: test_device[HWE-P1-fixtures0] Device(model_name='Wi-Fi P1 Meter', id='appliance/p1dongle/5c2fafaabbcc', product_name='P1 Meter', product_type='HWE-P1', serial='5c2fafaabbcc', api_version=, firmware_version='6.00') # --- # name: test_measurement[HWE-BAT-fixtures1] Measurement(wifi_ssid=None, wifi_strength=None, energy_import_kwh=123.456, energy_import_t1_kwh=None, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=321.654, energy_export_t1_kwh=None, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=1234.0, power_l1_w=None, power_l2_w=None, power_l3_w=None, voltage_v=230.123, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=5.678, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=50.123, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=123, state_of_charge_pct=50.123) # --- # name: test_measurement[HWE-P1-fixtures0] Measurement(wifi_ssid=None, wifi_strength=None, energy_import_kwh=None, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=None, energy_export_t1_kwh=1285.951, energy_export_t2_kwh=2876.51, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-678.0, power_l1_w=-676.0, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=datetime.datetime(2024, 6, 28, 14, 12, 34), protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id='Never Gonna Give You Up', tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices=None, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_measurement[HWE-P1-fixtures0].1 Measurement(wifi_ssid=None, wifi_strength=None, energy_import_kwh=13779.338, energy_import_t1_kwh=10830.511, energy_import_t2_kwh=2948.827, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=0.0, energy_export_t1_kwh=0.0, energy_export_t2_kwh=0.0, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=-543.0, power_l1_w=-676.0, power_l2_w=133.0, power_l3_w=0.0, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=6.0, current_l1_a=-4.0, current_l2_a=2.0, current_l3_a=0.0, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=datetime.datetime(2024, 6, 28, 14, 12, 34), protocol_version=50, meter_model='ISKRA 2M550T-101', unique_id='Never Gonna Let You Down', tariff=2, voltage_sag_l1_count=1, voltage_sag_l2_count=1, voltage_sag_l3_count=0, voltage_swell_l1_count=0, voltage_swell_l2_count=0, voltage_swell_l3_count=0, any_power_fail_count=4, long_power_fail_count=5, average_power_15m_w=123.0, monthly_power_peak_w=1111.0, monthly_power_peak_timestamp=datetime.datetime(2024, 6, 4, 10, 11, 22), external_devices={'gas_meter_Never gonna run around': ExternalDevice(unique_id='Never gonna run around', type=, value=2569.646, unit='m3', timestamp=datetime.datetime(2024, 6, 28, 14, 0)), 'water_meter_and desert you': ExternalDevice(unique_id='and desert you', type=, value=123.456, unit='m3', timestamp=datetime.datetime(2024, 6, 28, 14, 5))}, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_measurement[HWE-P1-fixtures0].2 Measurement(wifi_ssid=None, wifi_strength=None, energy_import_kwh=None, energy_import_t1_kwh=None, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=None, energy_export_t1_kwh=None, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=None, power_l1_w=None, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=None, meter_model=None, unique_id='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices={'gas_meter_\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': ExternalDevice(unique_id='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', type=, value=111.111, unit='m3', timestamp=datetime.datetime(2024, 6, 28, 14, 0)), 'heat_meter_\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': ExternalDevice(unique_id='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', type=, value=222.222, unit='m3', timestamp=datetime.datetime(2024, 6, 28, 14, 0)), 'warm_water_meter_\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': ExternalDevice(unique_id='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', type=, value=333.333, unit='m3', timestamp=datetime.datetime(2024, 6, 28, 14, 0)), 'water_meter_\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': ExternalDevice(unique_id='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', type=, value=444.444, unit='m3', timestamp=datetime.datetime(2024, 6, 28, 14, 0)), 'inlet_heat_meter_\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': ExternalDevice(unique_id='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', type=, value=555.555, unit='m3', timestamp=datetime.datetime(2024, 6, 28, 14, 0)), 'None_\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00': ExternalDevice(unique_id='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', type=None, value=555.555, unit=',3', timestamp=datetime.datetime(2024, 6, 28, 14, 0))}, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_measurement[HWE-P1-fixtures0].3 Measurement(wifi_ssid=None, wifi_strength=None, energy_import_kwh=None, energy_import_t1_kwh=None, energy_import_t2_kwh=None, energy_import_t3_kwh=None, energy_import_t4_kwh=None, energy_export_kwh=None, energy_export_t1_kwh=None, energy_export_t2_kwh=None, energy_export_t3_kwh=None, energy_export_t4_kwh=None, power_w=None, power_l1_w=None, power_l2_w=None, power_l3_w=None, voltage_v=None, voltage_l1_v=None, voltage_l2_v=None, voltage_l3_v=None, current_a=None, current_l1_a=None, current_l2_a=None, current_l3_a=None, apparent_power_va=None, apparent_power_l1_va=None, apparent_power_l2_va=None, apparent_power_l3_va=None, reactive_power_var=None, reactive_power_l1_var=None, reactive_power_l2_var=None, reactive_power_l3_var=None, power_factor=None, power_factor_l1=None, power_factor_l2=None, power_factor_l3=None, frequency_hz=None, timestamp=None, protocol_version=None, meter_model=None, unique_id=None, tariff=None, voltage_sag_l1_count=None, voltage_sag_l2_count=None, voltage_sag_l3_count=None, voltage_swell_l1_count=None, voltage_swell_l2_count=None, voltage_swell_l3_count=None, any_power_fail_count=None, long_power_fail_count=None, average_power_15m_w=None, monthly_power_peak_w=None, monthly_power_peak_timestamp=None, external_devices={'None_Never gonna run around': ExternalDevice(unique_id='Never gonna run around', type=None, value=555.555, unit=',3', timestamp=datetime.datetime(2024, 6, 28, 14, 0))}, active_liter_lpm=None, total_liter_m3=None, cycles=None, state_of_charge_pct=None) # --- # name: test_system[HWE-BAT-fixtures1] System(wifi_strength_pct=46, wifi_ssid='My Wi-Fi', wifi_rssi_db=-77, cloud_enabled=False, uptime_s=356, status_led_brightness_pct=100, api_v1_enabled=None) # --- # name: test_system[HWE-P1-fixtures0] System(wifi_strength_pct=46, wifi_ssid='My Wi-Fi', wifi_rssi_db=-77, cloud_enabled=False, uptime_s=356, status_led_brightness_pct=100, api_v1_enabled=True) # --- # name: test_system_update[None-100-None] dict({ 'status_led_brightness_pct': 100, }) # --- # name: test_system_update[None-100-True] dict({ 'api_v1_enabled': True, 'status_led_brightness_pct': 100, }) # --- # name: test_system_update[None-None-True] dict({ 'api_v1_enabled': True, }) # --- # name: test_system_update[True-100-None] dict({ 'cloud_enabled': True, 'status_led_brightness_pct': 100, }) # --- # name: test_system_update[True-100-True] dict({ 'api_v1_enabled': True, 'cloud_enabled': True, 'status_led_brightness_pct': 100, }) # --- # name: test_system_update[True-None-None] dict({ 'cloud_enabled': True, }) # --- # name: test_system_update[True-None-True] dict({ 'api_v1_enabled': True, 'cloud_enabled': True, }) # --- python-homewizard-energy-8.3.2/tests/v2/fixtures/000077500000000000000000000000001474712727000220605ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v2/fixtures/HWE-BAT/000077500000000000000000000000001474712727000231075ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v2/fixtures/HWE-BAT/device.json000066400000000000000000000002431474712727000252400ustar00rootroot00000000000000{ "product_name": "Plug-in Battery", "product_type": "HWE-BAT", "serial": "5c2fafaabbcc", "firmware_version": "6.00", "api_version": "2.0.0" } python-homewizard-energy-8.3.2/tests/v2/fixtures/HWE-BAT/measurement.json000066400000000000000000000003411474712727000263250ustar00rootroot00000000000000{ "energy_import_kwh": 123.456, "energy_export_kwh": 321.654, "power_w": 1234, "voltage_v": 230.123, "current_a": 5.678, "frequency_hz": 50.123, "cycles": 123, "state_of_charge_pct": 50.123 } python-homewizard-energy-8.3.2/tests/v2/fixtures/HWE-BAT/system.json000066400000000000000000000002201474712727000253200ustar00rootroot00000000000000{ "wifi_ssid": "My Wi-Fi", "wifi_rssi_db": -77, "cloud_enabled": false, "uptime_s": 356, "status_led_brightness_pct": 100 } python-homewizard-energy-8.3.2/tests/v2/fixtures/HWE-P1/000077500000000000000000000000001474712727000227615ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v2/fixtures/HWE-P1/device.json000066400000000000000000000002331474712727000251110ustar00rootroot00000000000000{ "product_name": "P1 Meter", "product_type": "HWE-P1", "serial": "5c2fafaabbcc", "firmware_version": "6.00", "api_version": "2.0.0" } python-homewizard-energy-8.3.2/tests/v2/fixtures/HWE-P1/measurement_1_phase_no_gas.json000066400000000000000000000005701474712727000311310ustar00rootroot00000000000000{ "protocol_version": 50, "meter_model": "ISKRA 2M550T-101", "unique_id": "4E6576657220476F6E6E61204769766520596F75205570", "timestamp": "2024-06-28T14:12:34", "energy_import_t1_kwh": 10830.511, "energy_import_t2_kwh": 2948.827, "energy_export_t1_kwh": 1285.951, "energy_export_t2_kwh": 2876.51, "power_w": -678, "power_l1_w": -676 } measurement_3_phase_with_gas_with_watermeter.json000066400000000000000000000026071474712727000347100ustar00rootroot00000000000000python-homewizard-energy-8.3.2/tests/v2/fixtures/HWE-P1{ "protocol_version": 50, "meter_model": "ISKRA 2M550T-101", "unique_id": "4E6576657220476F6E6E61204C657420596F7520446F776E", "timestamp": "2024-06-28T14:12:34", "tariff": 2, "energy_import_kwh": 13779.338, "energy_import_t1_kwh": 10830.511, "energy_import_t2_kwh": 2948.827, "energy_export_kwh": 0, "energy_export_t1_kwh": 0, "energy_export_t2_kwh": 0, "power_w": -543, "power_l1_w": -676, "power_l2_w": 133, "power_l3_w": 0, "current_a": 6, "current_l1_a": -4, "current_l2_a": 2, "current_l3_a": 0, "voltage_sag_l1_count": 1, "voltage_sag_l2_count": 1, "voltage_sag_l3_count": 0, "voltage_swell_l1_count": 0, "voltage_swell_l2_count": 0, "voltage_swell_l3_count": 0, "any_power_fail_count": 4, "long_power_fail_count": 5, "average_power_15m_w": 123.000, "monthly_power_peak_w": 1111.000, "monthly_power_peak_timestamp": "2024-06-04T10:11:22", "external": [ { "unique_id": "4E6576657220676F6E6E612072756E2061726F756E64", "type": "gas_meter", "timestamp": "2024-06-28T14:00:00", "value": 2569.646, "unit": "m3" }, { "unique_id": "616E642064657365727420796F75", "type": "water_meter", "timestamp": "2024-06-28T14:05:00", "value": 123.456, "unit": "m3" } ] } python-homewizard-energy-8.3.2/tests/v2/fixtures/HWE-P1/measurement_invalid_ean.json000066400000000000000000000034221474712727000305330ustar00rootroot00000000000000{ "unique_id": "00000000000000000000000000000000", "external": [ { "unique_id": "00000000000000000000000000000000", "type": "gas_meter", "timestamp": "2024-06-28T14:00:00", "value": 111.111, "unit": "m3" }, { "unique_id": "00000000000000000000000000000000", "type": "heat_meter", "timestamp": "2024-06-28T14:00:00", "value": 222.222, "unit": "m3" }, { "unique_id": "00000000000000000000000000000000", "type": "warm_water_meter", "timestamp": "2024-06-28T14:00:00", "value": 333.333, "unit": "m3" }, { "unique_id": "00000000000000000000000000000000", "type": "water_meter", "timestamp": "2024-06-28T14:00:00", "value": 444.444, "unit": "m3" }, { "unique_id": "00000000000000000000000000000000", "type": "inlet_heat_meter", "timestamp": "2024-06-28T14:00:00", "value": 555.555, "unit": "m3" }, { "type": "00000000000000000000000000000000", "timestamp": "2024-06-28T14:00:00", "value": 555.555, "unit": "should_not_be_included_because_of_missing_id" }, { "unique_id": "00000000000000000000000000000000", "type": "catfish", "timestamp": "2024-06-28T14:00:00", "value": 555.555, "unit": ",3" }, { "unique_id": "00000000000000000000000000000000", "timestamp": "2024-06-28T14:00:00", "value": 555.555, "unit": ",3" } ] } python-homewizard-energy-8.3.2/tests/v2/fixtures/HWE-P1/measurement_invalid_external.json000066400000000000000000000012131474712727000316060ustar00rootroot00000000000000{ "external": [ { "type": "gas_meter", "timestamp": "2024-06-28T14:00:00", "value": 555.555, "unit": "should_not_be_included_because_of_missing_id" }, { "unique_id": "4E6576657220676F6E6E612072756E2061726F756E64", "type": "catfish", "timestamp": "2024-06-28T14:00:00", "value": 555.555, "unit": ",3" }, { "unique_id": "4E6576657220676F6E6E612072756E2061726F756E64", "timestamp": "2024-06-28T14:00:00", "value": 555.555, "unit": ",3" } ] } python-homewizard-energy-8.3.2/tests/v2/fixtures/HWE-P1/system.json000066400000000000000000000002541474712727000252010ustar00rootroot00000000000000{ "wifi_ssid": "My Wi-Fi", "wifi_rssi_db": -77, "cloud_enabled": false, "uptime_s": 356, "status_led_brightness_pct": 100, "api_v1_enabled": true } python-homewizard-energy-8.3.2/tests/v2/test_v2_homewizard_energy.py000066400000000000000000000540461474712727000257620ustar00rootroot00000000000000"""Test for HomeWizard Energy.""" import asyncio from unittest.mock import AsyncMock import aiohttp import pytest from syrupy.assertion import SnapshotAssertion from homewizard_energy import HomeWizardEnergyV2 from homewizard_energy.errors import ( DisabledError, InvalidUserNameError, RequestError, ResponseError, UnauthorizedError, ) from . import load_fixtures pytestmark = [pytest.mark.asyncio] ### CombinedModels tests ### async def test_combined_models_without_authentication(): """Test combined models request is rejected when no authentication is provided.""" async with HomeWizardEnergyV2("example.com") as api: with pytest.raises(UnauthorizedError): await api.combined() async def test_combined_models_with_invalid_authentication(aresponses): """Test combined models request is unsuccessful when invalid authentication is provided.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( status=401, headers={"Content-Type": "application/json"}, text='{"error": "user:unauthorized"}', ), ) aresponses.add( "example.com", "/api/measurement", "GET", aresponses.Response( status=401, headers={"Content-Type": "application/json"}, text='{"error": "user:unauthorized"}', ), ) aresponses.add( "example.com", "/api/system", "GET", aresponses.Response( status=401, headers={"Content-Type": "application/json"}, text='{"error": "user:unauthorized"}', ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: with pytest.raises(UnauthorizedError): await api.combined() # pylint: disable=too-many-arguments # pylint: disable=too-many-positional-arguments @pytest.mark.parametrize( ("model", "device", "measurement", "state", "system"), [ ("HWE-P1", "device", "measurement_1_phase_no_gas", None, "system"), ("HWE-BAT", "device", "measurement", None, "system"), ], ) async def test_combined_models_with_valid_authentication( model: str, device: str, measurement: str, state: str | None, system: str, snapshot: SnapshotAssertion, aresponses, ): """Test combined models request is successful when valid authentication is provided.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( text=load_fixtures(f"{model}/{device}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "example.com", "/api/measurement", "GET", aresponses.Response( text=load_fixtures(f"{model}/{measurement}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "example.com", "/api/state", "GET", aresponses.Response( text=load_fixtures(f"{model}/{state}.json") if state else "404 Not Found", status=200 if state else 404, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "example.com", "/api/system", "GET", aresponses.Response( text=load_fixtures(f"{model}/{system}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: data = await api.combined() assert data is not None assert data == snapshot # pylint: disable=too-many-arguments # pylint: disable=too-many-positional-arguments @pytest.mark.parametrize( ("model", "device", "measurement", "state", "system"), [ ("HWE-P1", "device", "measurement_1_phase_no_gas", None, "system"), ("HWE-BAT", "device", "measurement", None, "system"), ], ) async def test_combined_models_with_valid_authentication_caches_device( model: str, device: str, measurement: str, state: str | None, system: str, snapshot: SnapshotAssertion, aresponses, ): """Test combined models request is successful when valid authentication is provided.""" # Request 1 aresponses.add( "example.com", "/api", "GET", aresponses.Response( text=load_fixtures(f"{model}/{device}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "example.com", "/api/measurement", "GET", aresponses.Response( text=load_fixtures(f"{model}/{measurement}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "example.com", "/api/state", "GET", aresponses.Response( text=load_fixtures(f"{model}/{state}.json") if state else "404 Not Found", status=200 if state else 404, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "example.com", "/api/system", "GET", aresponses.Response( text=load_fixtures(f"{model}/{system}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) # Request 2, should use cache of `/api` aresponses.add( "example.com", "/api/measurement", "GET", aresponses.Response( text=load_fixtures(f"{model}/{measurement}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "example.com", "/api/state", "GET", aresponses.Response( text=load_fixtures(f"{model}/{state}.json") if state else "404 Not Found", status=200 if state else 404, headers={"Content-Type": "application/json"}, ), ) aresponses.add( "example.com", "/api/system", "GET", aresponses.Response( text=load_fixtures(f"{model}/{system}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: data = await api.combined() assert data is not None assert data == snapshot data_2 = await api.combined() assert data_2 == data ### Device tests ### async def test_class_returns_host(): """Test class returns host.""" async with HomeWizardEnergyV2("example.com") as api: assert api.host == "example.com" async def test_device_without_authentication(): """Test device request is rejected when no authentication is provided.""" async with HomeWizardEnergyV2("example.com") as api: with pytest.raises(UnauthorizedError): await api.device() async def test_device_with_invalid_authentication(aresponses): """Test device request is unsuccessful when invalid authentication is provided.""" aresponses.add( "example.com", "/api", "GET", aresponses.Response( status=401, headers={"Content-Type": "application/json"}, text='{"error": "user:unauthorized"}', ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: with pytest.raises(UnauthorizedError): await api.device() @pytest.mark.parametrize( ("model", "fixtures"), [ ("HWE-P1", ["device"]), ], ) async def test_device_with_valid_authentication( model: str, fixtures: list[str], snapshot: SnapshotAssertion, aresponses ): """Test device request is successful when valid authentication is provided.""" for fixture in fixtures: aresponses.add( "example.com", "/api", "GET", aresponses.Response( text=load_fixtures(f"{model}/{fixture}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: device = await api.device() assert device assert device.product_type == model assert device == snapshot ### Measurement tests ### async def test_measurement_without_authentication(): """Test measurement request is rejected when no authentication is provided.""" async with HomeWizardEnergyV2("example.com") as api: with pytest.raises(UnauthorizedError): await api.measurement() async def test_measurement_with_invalid_authentication(aresponses): """Test measurement request is unsuccessful when invalid authentication is provided.""" aresponses.add( "example.com", "/api/measurement", "GET", aresponses.Response( status=401, headers={"Content-Type": "application/json"}, text='{"error": "user:unauthorized"}', ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: with pytest.raises(UnauthorizedError): await api.measurement() @pytest.mark.parametrize( ("model", "fixtures"), [ ( "HWE-P1", [ "measurement_1_phase_no_gas", "measurement_3_phase_with_gas_with_watermeter", ], ), ], ) async def test_measurement_with_valid_authentication( model: str, fixtures: list[str], snapshot: SnapshotAssertion, aresponses ): """Test measurement request is successful when valid authentication is provided.""" for fixture in fixtures: aresponses.add( "example.com", "/api/measurement", "GET", aresponses.Response( text=load_fixtures(f"{model}/{fixture}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: measurement = await api.measurement() assert measurement is not None assert measurement == snapshot ### System tests ### async def test_system_without_authentication(): """Test system request is rejected when no authentication is provided.""" async with HomeWizardEnergyV2("example.com") as api: with pytest.raises(UnauthorizedError): await api.system() async def test_system_with_invalid_authentication(aresponses): """Test system request is unsuccessful when invalid authentication is provided.""" aresponses.add( "example.com", "/api/system", "GET", aresponses.Response( status=401, headers={"Content-Type": "application/json"}, text='{"error": "user:unauthorized"}', ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: with pytest.raises(UnauthorizedError): await api.system() @pytest.mark.parametrize( ("model", "fixtures"), [ ("HWE-P1", ["system"]), ], ) async def test_system_with_valid_authentication( model: str, fixtures: list[str], snapshot: SnapshotAssertion, aresponses ): """Test system request is successful when valid authentication is provided.""" for fixture in fixtures: aresponses.add( "example.com", "/api/system", "GET", aresponses.Response( text=load_fixtures(f"{model}/{fixture}.json"), status=200, headers={"Content-Type": "application/json"}, ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: system = await api.system() assert system is not None assert system == snapshot async def test_system_set_with_valid_authentication(aresponses): """Test system set request is successful when valid authentication is provided.""" aresponses.add( "example.com", "/api/system", "PUT", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"cloud_enabled": true}', ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: data = await api.system(cloud_enabled=True) assert data is not None assert data.cloud_enabled is True async def test_system_returns_unexpected_response(aresponses): """Test system set request is successful when valid authentication is provided.""" aresponses.add( "example.com", "/api/system", "GET", aresponses.Response( status=500, headers={"Content-Type": "application/json"}, text='{"error": "server:error"}', ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: with pytest.raises(RequestError) as e: await api.system() assert str(e.value) == "server:error" ### Identify tests ### async def test_identify_without_authentication(): """Test identify request is rejected when no authentication is provided.""" async with HomeWizardEnergyV2("example.com") as api: with pytest.raises(UnauthorizedError): await api.identify() async def test_identify_with_invalid_authentication(aresponses): """Test identify request is unsuccessful when invalid authentication is provided.""" aresponses.add( "example.com", "/api/system/identify", "PUT", aresponses.Response( status=401, headers={"Content-Type": "application/json"}, text='{"error": "user:unauthorized"}', ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: with pytest.raises(UnauthorizedError): await api.identify() async def test_identify_with_authentication(aresponses): """Test identify request is successful when authentication is provided.""" aresponses.add( "example.com", "/api/system/identify", "PUT", aresponses.Response( status=204, headers={"Content-Type": "application/json"}, ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: data = await api.identify() assert data is None ### Reboot tests ### async def test_reboot_without_authentication(): """Test reboot request is rejected when no authentication is provided.""" async with HomeWizardEnergyV2("example.com") as api: with pytest.raises(UnauthorizedError): await api.reboot() async def test_reboot_with_invalid_authentication(aresponses): """Test reboot request is unsuccessful when invalid authentication is provided.""" aresponses.add( "example.com", "/api/system/reboot", "PUT", aresponses.Response( status=401, headers={"Content-Type": "application/json"}, text='{"error": "user:unauthorized"}', ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: with pytest.raises(UnauthorizedError): await api.reboot() async def test_reboot_with_authentication(aresponses): """Test reboot request is successful when authentication is provided.""" aresponses.add( "example.com", "/api/system/reboot", "PUT", aresponses.Response( status=204, headers={"Content-Type": "application/json"}, ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: data = await api.reboot() assert data is None ### Get token tests ### async def test_get_token_without_permission(aresponses): """Test get token request is rejected when no permission, user must authorize.""" aresponses.add( "example.com", "/api/user", "POST", aresponses.Response( status=403, headers={"Content-Type": "application/json"}, text='{"error": "user:creation-not-enabled"}', ), ) async with HomeWizardEnergyV2("example.com") as api: with pytest.raises(DisabledError): await api.get_token("name") async def test_get_token_with_permission(aresponses): """Test get token request accepted.""" aresponses.add( "example.com", "/api/user", "POST", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"token": "new_token", "name": "local/name"}', ), ) async with HomeWizardEnergyV2("example.com") as api: token = await api.get_token("name") assert token == "new_token" async def test_get_token_returns_unexpected_response_code(aresponses): """Test get token request is successful when valid authentication is provided.""" aresponses.add( "example.com", "/api/user", "POST", aresponses.Response( status=500, headers={"Content-Type": "application/json"}, text='{"error": "server:error"}', ), ) async with HomeWizardEnergyV2("example.com") as api: with pytest.raises(InvalidUserNameError) as e: await api.get_token("name") assert str(e.value) == "server:error" async def test_get_token_returns_unexpected_response_data(aresponses): """Test get token request is successful when valid authentication is provided.""" aresponses.add( "example.com", "/api/user", "POST", aresponses.Response( status=200, headers={"Content-Type": "application/json"}, text='{"error": "user:error"}', ), ) async with HomeWizardEnergyV2("example.com") as api: with pytest.raises(ResponseError) as e: await api.get_token("name") assert str(e.value) == "user:error" async def test_delete_token_without_authentication(): """Test delete token request is rejected when no authentication is provided.""" async with HomeWizardEnergyV2("example.com") as api: with pytest.raises(UnauthorizedError): await api.delete_token() async def test_delete_token_with_invalid_authentication(aresponses): """Test delete token request is unsuccessful when invalid authentication is provided.""" aresponses.add( "example.com", "/api/user", "DELETE", aresponses.Response( status=401, headers={"Content-Type": "application/json"}, text='{"error": "user:unauthorized"}', ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: with pytest.raises(UnauthorizedError): await api.delete_token() async def test_delete_token_with_authentication(aresponses): """Test delete_token request is successful when authentication is provided.""" aresponses.add( "example.com", "/api/user", "DELETE", aresponses.Response( status=204, headers={"Content-Type": "application/json"}, ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: await api.delete_token() assert api._token is None # pylint: disable=protected-access async def test_delete_token_from_other_user_with_authentication(aresponses): """Test delete_token request is successful when authentication is provided.""" aresponses.add( "example.com", "/api/user", "DELETE", aresponses.Response( status=204, headers={"Content-Type": "application/json"}, ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: await api.delete_token(name="local/other") assert api._token == "token" # pylint: disable=protected-access async def test_delete_token_returns_unexpected_response_code(aresponses): """Test delete token request is successful when valid authentication is provided.""" aresponses.add( "example.com", "/api/user", "DELETE", aresponses.Response( status=500, headers={"Content-Type": "application/json"}, text='{"error": "server:error"}', ), ) async with HomeWizardEnergyV2("example.com", token="token") as api: with pytest.raises(RequestError) as e: await api.delete_token() assert str(e.value) == "server:error" ### Generic request tests ### # pylint: disable=protected-access async def test_request_handles_timeout(): """Test request times out when request takes too long.""" async with HomeWizardEnergyV2("example.com", token="token") as api: api._session = AsyncMock() api._session.request = AsyncMock(side_effect=asyncio.TimeoutError) with pytest.raises(RequestError): await api.device() assert api._session.request.call_count == 3 # pylint: disable=protected-access async def test_request_handles_clienterror(): """Test request times out when request takes too long.""" async with HomeWizardEnergyV2("example.com", token="token") as api: api._session = AsyncMock() api._session.request = AsyncMock(side_effect=aiohttp.ClientError) with pytest.raises(RequestError): await api.device() assert api._session.request.call_count == 3 async def test_request_with_identifier_sets_common_name(aresponses): """Test request with identifier sets common name.""" device = load_fixtures("HWE-P1/device.json") device.replace("HWE-P1", "NEW-DEVICE") aresponses.add( "example.com", "/api", "GET", aresponses.Response( text=device, status=200, headers={"Content-Type": "application/json"}, ), ) async with HomeWizardEnergyV2("example.com", token="token", identifier="id") as api: data = await api.device() assert data is not None python-homewizard-energy-8.3.2/tests/v2/test_v2_models.py000066400000000000000000000073321474712727000235170ustar00rootroot00000000000000"""Test for HomeWizard Energy Models.""" import json import pytest from syrupy.assertion import SnapshotAssertion from homewizard_energy.models import Device, Measurement, System, SystemUpdate from . import load_fixtures pytestmark = [pytest.mark.asyncio] @pytest.mark.parametrize( ("model", "fixtures"), [ ("HWE-P1", ["device"]), ("HWE-BAT", ["device"]), ], ) async def test_device(model: str, fixtures: str, snapshot: SnapshotAssertion): """Test Device model.""" for fixture in fixtures: data = Device.from_dict(json.loads(load_fixtures(f"{model}/{fixture}.json"))) assert data assert snapshot == data @pytest.mark.parametrize( ("model", "fixtures"), [ ( "HWE-P1", [ "measurement_1_phase_no_gas", "measurement_3_phase_with_gas_with_watermeter", "measurement_invalid_ean", "measurement_invalid_external", ], ), ( "HWE-BAT", [ "measurement", ], ), ], ) async def test_measurement(model: str, fixtures: str, snapshot: SnapshotAssertion): """Test Measurement model.""" for fixture in fixtures: data = Measurement.from_dict( json.loads(load_fixtures(f"{model}/{fixture}.json")) ) assert data assert snapshot == data async def test_measurement_ignores_invalid_tariff(): """Test Measurement model ignores invalid tariff.""" measurement = Measurement.from_dict({"tariff": 5432}) assert measurement assert measurement.tariff is None @pytest.mark.parametrize( ("model", "fixtures"), [ ("HWE-P1", ["system"]), ("HWE-BAT", ["system"]), ], ) async def test_system(model: str, fixtures: str, snapshot: SnapshotAssertion): """Test System model.""" for fixture in fixtures: data = System.from_dict(json.loads(load_fixtures(f"{model}/{fixture}.json"))) assert data assert snapshot == data @pytest.mark.parametrize( ("cloud_enabled", "status_led_brightness_pct", "api_v1_enabled"), [ (True, None, None), (None, 100, None), (None, None, True), (True, 100, None), (True, None, True), (None, 100, True), (True, 100, True), ], ) async def test_system_update( cloud_enabled: bool, status_led_brightness_pct: int, api_v1_enabled: bool, snapshot: SnapshotAssertion, ): """Test System update.""" data = SystemUpdate( cloud_enabled=cloud_enabled, status_led_brightness_pct=status_led_brightness_pct, api_v1_enabled=api_v1_enabled, ) assert snapshot == data.to_dict() async def test_system_update_raises_when_none_set(): """Test systemUpdate raises when all values are None.""" update = SystemUpdate( cloud_enabled=None, status_led_brightness_pct=None, api_v1_enabled=None ) with pytest.raises(ValueError): update.to_dict() @pytest.mark.parametrize( ("model", "supports_state", "supports_identify", "supports_cloud_enable"), [ ("HWE-P1", False, True, True), ("HWE-BAT", False, True, False), ], ) async def test_device_support_functions( model: str, supports_state: bool, supports_identify: bool, supports_cloud_enable: bool, ): """Test Device model support functions.""" device = Device.from_dict(json.loads(load_fixtures(f"{model}/device.json"))) assert device assert device.supports_state() == supports_state assert device.supports_identify() == supports_identify assert device.supports_cloud_enable() == supports_cloud_enable assert device.supports_reboot() is True # Always True for v2