pax_global_header00006660000000000000000000000064150353475500014521gustar00rootroot0000000000000052 comment=c7622a5e57ebb023a41fc8175d2781aa51578b4c pytouchlinesl-0.4.0/000077500000000000000000000000001503534755000144245ustar00rootroot00000000000000pytouchlinesl-0.4.0/.github/000077500000000000000000000000001503534755000157645ustar00rootroot00000000000000pytouchlinesl-0.4.0/.github/dependabot.yml000066400000000000000000000006131503534755000206140ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "github-actions" directory: "/" schedule: interval: "monthly" groups: actions-deps: patterns: - "*" - package-ecosystem: "uv" directory: "/" schedule: interval: "monthly" groups: uv-deps: patterns: - "*" update-types: - "patch" - "minor" pytouchlinesl-0.4.0/.github/tag-release.sh000077500000000000000000000007621503534755000205210ustar00rootroot00000000000000#!/usr/bin/env bash set -euo pipefail export VERSION="${1:-}" echo "$VERSION" | grep -qEo '[0-9]+\.[0-9]+\.[0-9]+' if [ $? -ne 0 ]; then echo "Invalid version number. Please use the format '0.2.0'" exit 1 fi # Bump version in pyproject.toml and sync the uv.lock file sed -i 's/^\(version = \).*$/\1'\"$VERSION\"'/' pyproject.toml uv sync git add pyproject.toml uv.lock git commit -m "chore: bump version to $VERSION" git tag -a "$VERSION" -m "$VERSION" git push origin main "$VERSION" pytouchlinesl-0.4.0/.github/workflows/000077500000000000000000000000001503534755000200215ustar00rootroot00000000000000pytouchlinesl-0.4.0/.github/workflows/_test.yaml000066400000000000000000000020601503534755000220210ustar00rootroot00000000000000name: Test & Lint on: workflow_call: jobs: lint: name: Lint runs-on: ubuntu-latest steps: - name: Checkout the code uses: actions/checkout@v4 - name: Install `uv` run: | curl -LsSf https://astral.sh/uv/install.sh | sh - name: Lint with `ruff` run: | uv run ruff check - name: Format with `ruff` run: | uv run ruff format --check test: name: Test (Python ${{ matrix.python-version }}) strategy: matrix: python-version: - "3.10" - "3.11" - "3.12" fail-fast: false runs-on: ubuntu-latest steps: - name: Checkout the code uses: actions/checkout@v4 - name: Install `uv` run: | curl -LsSf https://astral.sh/uv/install.sh | sh - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Run tests run: | uv run pytest -v pytouchlinesl-0.4.0/.github/workflows/publish.yaml000066400000000000000000000014151503534755000223540ustar00rootroot00000000000000name: Publish on: push: tags: - "*" concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: tests: uses: ./.github/workflows/_test.yaml publish: name: Build and Publish to PyPI runs-on: ubuntu-latest needs: - tests environment: name: pypi url: https://pypi.org/p/pytouchlinesl permissions: id-token: write steps: - name: Checkout the code uses: actions/checkout@v4 - name: Install `uv` run: | curl -LsSf https://astral.sh/uv/install.sh | sh - name: Build the package run: | uvx --from build pyproject-build --installer uv - name: Publish to PyPi uses: pypa/gh-action-pypi-publish@v1.12.4 pytouchlinesl-0.4.0/.github/workflows/test.yaml000066400000000000000000000003231503534755000216620ustar00rootroot00000000000000name: Push on: pull_request: push: branches: ["main"] concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: tests: uses: ./.github/workflows/_test.yaml pytouchlinesl-0.4.0/.gitignore000066400000000000000000000004151503534755000164140ustar00rootroot00000000000000# Files used in development *.env test.py dump.json # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ dist/ parts/ sdist/ wheels/ *.egg-info/ *.egg MANIFEST .coverage* .tox/ .venvpytouchlinesl-0.4.0/LICENSE000066400000000000000000000261071503534755000154370ustar00rootroot00000000000000 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 jnsgruk 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.pytouchlinesl-0.4.0/README.md000066400000000000000000000105531503534755000157070ustar00rootroot00000000000000# A Python Library for Roth's TouchlineSL System Roth TouchlineSL is a control system for underfloor heating, cooling and radiator control. They have a public API which is documented on [their website](https://api-documentation.roth-touchlinesl.com/). This project provides a Python client for interacting with the API, and controlling heating systems. It does not have complete coverage of the API, and currently provides the facility to: - Authenticate with a https://roth-touchlinesl.com account - List modules associated with an account - Get details of individual zones - Get details of global heating schedules - Set a constant target temperature for a zone - Assign a zone to a specific global schedule The library was designed primarily to support the development of a [Home Assistant](https://home-assistant.io/) integration. ## Design Roth's API design makes operations on individual zones or schedules quite difficult. Only one endpoint is provided for fetching the configuration of zones, and it's the same endpoint that returns data for _all_ zones attached to a module. As a result, this client implements some basic caching. Each time the modules endpoint is queried, the result is cached for 30 seconds. Any POST requests made (setting temperatures, assigning zones to schedules) will invalidate the cache, and all GET methods have a `refresh` argument that can be used to force a refresh of the underlying data. ## Installation The package can be installed from PyPi as usual: ```bash pip install pytouchlinesl ``` ## Example Usage ```python import asyncio import os from pytouchlinesl import TouchlineSL async def touchlinesl_example(): tsl = TouchlineSL( username=os.getenv("TOUCHLINESL_LOGIN"), password=os.getenv("TOUCHLINESL_PASSWORD"), ) # Fetch a list of modules associated with the account modules = await tsl.modules() module = await tsl.module(module_id=modules[0].id) # Fetch a zone by name, set a constant target temperature of 17.0 utility = await module.zone_by_name("Utility Room") await utility.set_temperature(17.0) # Fetch a zone by ID, assign it to a global schedule named "Living Spaces" kitchen = await module.zone(2411) living_spaces = await module.schedule_by_name("Living Spaces") await kitchen.set_schedule(living_spaces.id) if __name__ == "__main__": asyncio.set_event_loop(asyncio.new_event_loop()) asyncio.run(touchlinesl_example()) ``` ## Contributing / Hacking Contributions in either code or documentation are welcome. The set of features is limited at the moment, but I'm happy to expand as the need arises. Commit messages and PR titles should be formatted using [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). The project does not have many dependencies; just `asyncio` and `pytest`/`pytest-asyncio` for testing. Dependencies are managed using [`uv`](https://github.com/astral-sh/uv). You can get started like so: ```bash # Clone the repository git clone https://github.com/jnsgruk/pytouchlinesl cd pytouchlinesl # Run the tests uv run pytest # Lint the code uv run ruff check --fix # Format the code uv run ruff format ``` If you'd rather use standard Python tooling, you can do so: ```python # Clone the repository git clone https://github.com/jnsgruk/pytouchlinesl cd pytouchlinesl # Create a virtual environment python3 -m venv .venv source .venv/bin/activate # Install dev/project dependencies pip install -e '.[dev]' # Run the tests pytest -s # Lint the code ruff check --fix # Format the code ruff format ``` ## Releasing Once all the changes have been merged into `main` for a release, use the [`.github/tag-release`](./.github/tag-release.sh) script to create a version bump commit in the right format, create, **and push** the tag ready for release. This could be automated with Github Actions - but commit signing gets a little complicated, so for now it's just a script that can be run by maintainers. pytouchlinesl-0.4.0/pyproject.toml000066400000000000000000000025671503534755000173520ustar00rootroot00000000000000[project] name = "pytouchlinesl" version = "0.4.0" authors = [{ name = "Jon Seager", email = "jon@sgrs.uk" }] description = "An API client for Roth's TouchlineSL control system." readme = "README.md" requires-python = ">=3.10" classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", ] dependencies = ["aiohttp", "pydantic>=2"] [project.optional-dependencies] dev = ["pytest", "pytest-asyncio", "ruff"] [project.urls] Homepage = "https://github.com/jnsgruk/pytouchlinesl" Issues = "https://github.com/jnsgruk/pytouchlinesl/issues" [build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [tool.uv] dev-dependencies = ["pytest>=8.3.2", "pytest-asyncio>=0.24.0", "ruff>=0.6.2"] [tool.pytest.ini_options] asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "module" # Linting tools configuration [tool.ruff] line-length = 99 extend-exclude = ["__pycache__", "*.egg_info"] [tool.ruff.lint] per-file-ignores = { "tests/**" = [ "D", ], "__init__.py" = [ "F401", ], "pytouchlinesl/client/models/models.py" = [ "D101", ] } select = ["E", "W", "F", "C", "N", "D", "I001"] ignore = ["E501", "D107"] extend-ignore = [ "D203", "D204", "D213", "D215", "D400", "D404", "D406", "D407", "D408", "D409", "D413", ] pytouchlinesl-0.4.0/pytouchlinesl/000077500000000000000000000000001503534755000173265ustar00rootroot00000000000000pytouchlinesl-0.4.0/pytouchlinesl/__init__.py000066400000000000000000000003001503534755000214300ustar00rootroot00000000000000"""A Python client for controlling Roth TouchlineSL underfloor heating modules.""" from . import client from .module import Module from .touchlinesl import TouchlineSL from .zone import Zone pytouchlinesl-0.4.0/pytouchlinesl/client/000077500000000000000000000000001503534755000206045ustar00rootroot00000000000000pytouchlinesl-0.4.0/pytouchlinesl/client/__init__.py000066400000000000000000000002071503534755000227140ustar00rootroot00000000000000"""A Python API implementation of the Roth TouchlineSL API.""" from .base import BaseClient from .client import RothAPI, RothAPIError pytouchlinesl-0.4.0/pytouchlinesl/client/base.py000066400000000000000000000026541503534755000220770ustar00rootroot00000000000000"""Provides an abstract API client implementation for clients working with the Roth API.""" from abc import ABC, abstractmethod from pytouchlinesl.client.models.models import AccountModuleModel from .models import ModuleModel class BaseClient(ABC): """Base API client implementation for Roth API clients.""" @abstractmethod async def user_id(self) -> int: """Return the unique user id for the authenticated account.""" pass @abstractmethod async def authenticated(self) -> bool: """Report whether or not the client is authenticated with the API.""" pass @abstractmethod async def modules(self) -> list[AccountModuleModel]: """Return a list of TouchlineSL modules associated with the authenticated account.""" pass @abstractmethod async def module(self, module_id: str) -> ModuleModel: """Return a specific module, by ID, that's associated with the authenticated account.""" pass @abstractmethod async def set_zone_temperature( self, module_id: str, mode_id: int, zone_id: int, temperature: float ): """Set a constant target temperature for a specific zone, in a specific module.""" pass @abstractmethod async def set_zone_schedule(self, module_id: str, zone_id: int, schedule_id: int): """Assign a specific zone to a specific global schedule in the module's configuration.""" pass pytouchlinesl-0.4.0/pytouchlinesl/client/client.py000066400000000000000000000166011503534755000224400ustar00rootroot00000000000000"""An API client for the public Roth TouchlineSL API. API Documentation: https://api-documentation.roth-touchlinesl.com/ """ import json import logging from typing import Any import aiohttp from pytouchlinesl.client.models import GlobalScheduleModel from .base import BaseClient from .models import AccountModuleModel, ModuleModel API_URL = "https://roth-touchlinesl.com/api/v1" logger = logging.getLogger(__name__) class RothAPIError(Exception): """An exception raised when an unsuccessful request is made to the Roth API.""" def __init__(self, status: int, data: Any = None): """Construct an instance of the exception.""" super().__init__() self._status = status self._data = data @property def status(self) -> int: """Return the HTTP status code of the failed request.""" return self._status @property def data(self) -> Any: """Return any data included in the response of the failed request.""" return self._data def __repr__(self) -> str: # noqa: D105 return f"{self.__class__.__name__}({self.__str__()})" def __str__(self) -> str: # noqa: D105 msg = f"{self.status}" if self.data is not None: msg += " " + json.dumps(self.data) return msg class RothAPI(BaseClient): """An implementation of the BaseClient which interacts with Roth's public API.""" def __init__(self, username, password): """Construct an instance of the client. Args: username: Roth TouchlineSL account email. password: Roth TouchlineSL account password. """ self._username = username self._password = password self._user_id = None self._token = None async def _login(self): """Login to the Roth API, and store the received bearer token and user id.""" data = {"username": self._username, "password": self._password} resp = await self._post("/authentication", json=data) self._user_id = resp.get("user_id") self._token = resp.get("token") async def user_id(self) -> int: """Return the unique user id for the authenticated account.""" if self._token is None: await self._login() assert isinstance(self._user_id, int) return self._user_id async def authenticated(self) -> bool: """Report whether or not the client is authenticated with the API.""" if self._token is None: return False resp = await self._authed_get("/authentication") return resp.get("authenticated", False) async def modules(self) -> list[AccountModuleModel]: """Return a list of TouchlineSL modules associated with the authenticated account.""" if self._token is None: await self._login() resp = await self._authed_get(f"/users/{self._user_id}/modules") return [AccountModuleModel(**m) for m in resp] async def module(self, module_id: str) -> ModuleModel: """Return a specific module, by ID, that's associated with the authenticated account.""" if self._token is None: await self._login() resp = await self._authed_get(f"/users/{self._user_id}/modules/{module_id}") return ModuleModel(**resp) async def set_zone_temperature( self, module_id: str, mode_id: int, zone_id: int, temperature: float ): """Set a constant target temperature for a specific zone, in a specific module.""" data = { "mode": { "id": mode_id, "parentId": zone_id, "mode": "constantTemp", "constTempTime": 0, "setTemperature": int(temperature * 10), "scheduleIndex": 0, } } await self._authd_post(url=f"/users/{self._user_id}/modules/{module_id}/zones", data=data) async def set_zone_schedule(self, module_id: str, zone_id: int, schedule_id: int): """Assign a specific zone to a specific global schedule in the module's configuration.""" module: ModuleModel = await self.module(module_id=module_id) schedules = module.zones.global_schedules.elements schedule = next((s for s in schedules if s.id == schedule_id), None) assert isinstance(schedule, GlobalScheduleModel) # Get a list of zones which are already assigned to the schedule. # The Roth API is relatively limited, and adding a zone to a schedule means # completely re-specifying the schedule, including intervals and assigned zones. zones_on_schedule = [ z for z in module.zones.elements if (z.mode.mode == "globalSchedule" and z.mode.schedule_index == schedule.index) or z.zone.id == zone_id ] p0_intervals = [ i.model_dump(by_alias=True) for i in schedule.p0_intervals if i.start != 6100 ] p1_intervals = [ i.model_dump(by_alias=True) for i in schedule.p1_intervals if i.start != 6100 ] # TODO: This be simplified with Pydantic models data = { "scheduleName": schedule.name, "setInZones": [{"zoneId": z.zone.id, "modeId": z.mode.id} for z in zones_on_schedule], "schedule": { "id": schedule.id, "index": schedule.index, "p0Days": schedule.p0_days, "p0SetbackTemp": schedule.p0_setback_temp, # Empty intervals start/end with a value of 6100, which is invalid # if sent in this request. "p0Intervals": p0_intervals, "p1Days": schedule.p1_days, "p1SetbackTemp": schedule.p1_setback_temp, "p1Intervals": p1_intervals, }, } await self._authd_post( url=f"/users/{self._user_id}/modules/{module_id}/zones/{zone_id}/global_schedule", data=data, ) async def _authed_get(self, url: str, headers: dict[str, str] = {}) -> dict: """Perform an authenticated GET request to the Roth TouchlineSL API.""" headers.update({"authorization": f"Bearer {self._token}"}) return await self._get(url, headers) async def _get(self, url: str, headers: dict[str, str] = {}) -> dict: """Perform a GET request to the Roth TouchlineSL API.""" logger.debug("GET %s%s", API_URL, url) async with aiohttp.ClientSession() as session: req = await session.get(f"{API_URL}{url}", headers=headers) resp = await req.json() if not req.ok: raise RothAPIError(status=req.status, data=resp) return resp async def _authd_post(self, url: str, headers: dict[str, str] = {}, data: dict = {}) -> dict: """Perform an authenticated POST request to the Roth TouchlineSL API.""" headers.update({"authorization": f"Bearer {self._token}"}) return await self._post(url, headers, data) async def _post(self, url: str, headers: dict[str, str] = {}, json: dict = {}) -> dict: """Perform a POST request to the Roth TouchlineSL API.""" logger.debug("POST %s%s", API_URL, url) async with aiohttp.ClientSession() as session: req = await session.post(f"{API_URL}{url}", headers=headers, json=json) resp = await req.json() if not req.ok: raise RothAPIError(status=req.status, data=resp) return resp pytouchlinesl-0.4.0/pytouchlinesl/client/models/000077500000000000000000000000001503534755000220675ustar00rootroot00000000000000pytouchlinesl-0.4.0/pytouchlinesl/client/models/__init__.py000066400000000000000000000007161503534755000242040ustar00rootroot00000000000000"""Provides Pydantic models representing responses from the Roth TouchlineSL API.""" from .models import ( AccountModuleModel, ControllerModeModel, ControllerParametersModel, GlobalScheduleModel, GlobalSchedulesModel, LocalScheduleModel, ModuleModel, ParamsModel, ScheduleIntervalModel, TileModel, ZoneAttributesModel, ZoneDescriptionModel, ZoneFlagsModel, ZoneModel, ZoneModeModel, ZonesModel, ) pytouchlinesl-0.4.0/pytouchlinesl/client/models/models.py000066400000000000000000000141201503534755000237220ustar00rootroot00000000000000"""Provides models that represent the data structures returned by the Roth API. These are mostly auto-generated using responses received from the API, with some tweaks to types and names. """ from typing import Any, Dict, List, Literal, Optional from pydantic import BaseModel, Field class ZoneFlagsModel(BaseModel): relay_state: str = Field(..., alias="relayState") min_one_window_open: bool = Field(..., alias="minOneWindowOpen") algorithm: Literal["heating", "cooling"] floor_sensor: int = Field(..., alias="floorSensor") humidity_algorytm: int = Field(..., alias="humidityAlgorytm") zone_excluded: int = Field(..., alias="zoneExcluded") class ZoneAttributesModel(BaseModel): id: int parent_id: int = Field(..., alias="parentId") time: str during_change: bool = Field(..., alias="duringChange") index: int current_temperature: Optional[int] = Field(..., alias="currentTemperature") set_temperature: int = Field(..., alias="setTemperature") flags: ZoneFlagsModel zone_state: Literal[ "zoneOff", "noAlarm", "zoneUnregistered", "sensorDamaged", "noCommunication" ] = Field(..., alias="zoneState") signal_strength: Optional[int] = Field(..., alias="signalStrength") battery_level: Optional[int] = Field(..., alias="batteryLevel") actuators_open: int = Field(..., alias="actuatorsOpen") humidity: int visibility: bool class ZoneDescriptionModel(BaseModel): id: int parent_id: int = Field(..., alias="parentId") name: str style_id: int = Field(..., alias="styleId") style_icon: str = Field(..., alias="styleIcon") during_change: bool = Field(..., alias="duringChange") class ZoneModeModel(BaseModel): id: int parent_id: int = Field(..., alias="parentId") mode: Literal["constantTemp", "globalSchedule", "localSchedule", "timeLimit"] const_temp_time: int = Field(..., alias="constTempTime") set_temperature: int = Field(..., alias="setTemperature") schedule_index: int = Field(..., alias="scheduleIndex") class ScheduleIntervalModel(BaseModel): start: int stop: int temp: int class LocalScheduleModel(BaseModel): id: int parent_id: int = Field(..., alias="parentId") index: int p0_days: List[str] = Field(..., alias="p0Days") p0_intervals: List[ScheduleIntervalModel] = Field(..., alias="p0Intervals") p0_setback_temp: int = Field(..., alias="p0SetbackTemp") p1_days: List[str] = Field(..., alias="p1Days") p1_intervals: List[ScheduleIntervalModel] = Field(..., alias="p1Intervals") p1_setback_temp: int = Field(..., alias="p1SetbackTemp") class ZoneModel(BaseModel): zone: ZoneAttributesModel description: ZoneDescriptionModel mode: ZoneModeModel schedule: LocalScheduleModel actuators: List underfloor: Dict[str, Any] windows_sensors: List = Field(..., alias="windowsSensors") additional_contacts: List = Field(..., alias="additionalContacts") class GlobalScheduleModel(BaseModel): id: int parent_id: int = Field(..., alias="parentId") index: int name: str p0_days: List[str] = Field(..., alias="p0Days") p0_setback_temp: int = Field(..., alias="p0SetbackTemp") p0_intervals: List[ScheduleIntervalModel] = Field(..., alias="p0Intervals") p1_days: List[str] = Field(..., alias="p1Days") p1_setback_temp: int = Field(..., alias="p1SetbackTemp") p1_intervals: List[ScheduleIntervalModel] = Field(..., alias="p1Intervals") class GlobalSchedulesModel(BaseModel): time: str during_change: bool = Field(..., alias="duringChange") elements: List[GlobalScheduleModel] class ControllerModeModel(BaseModel): id: int parent_id: int = Field(..., alias="parentId") type: int txt_id: int = Field(..., alias="txtId") icon_id: int = Field(..., alias="iconId") value: int menu_id: int = Field(..., alias="menuId") class ControllerParametersModel(BaseModel): controller_mode: ControllerModeModel = Field(..., alias="controllerMode") global_schedules_number: Dict[str, Any] = Field(..., alias="globalSchedulesNumber") class ZonesModel(BaseModel): transaction_time: str elements: List[ZoneModel] global_schedules: GlobalSchedulesModel = Field(..., alias="globalSchedules") controller_parameters: ControllerParametersModel = Field(..., alias="controllerParameters") class ParamsModel(BaseModel): description: Optional[str] working_status: Optional[bool] = Field(None, alias="workingStatus") txt_id: Optional[int] = Field(None, alias="txtId") icon_id: Optional[int] = Field(None, alias="iconId") version: Optional[str] = None company_id: Optional[int] = Field(None, alias="companyId") controller_name: Optional[str] = Field(None, alias="controllerName") main_controller_id: Optional[int] = Field(None, alias="mainControllerId") class TileModel(BaseModel): id: int parent_id: int = Field(..., alias="parentId") type: int menu_id: int = Field(..., alias="menuId") order_id: Any = Field(..., alias="orderId") visibility: bool params: ParamsModel class ModuleModel(BaseModel): zones: ZonesModel tiles: Optional[List[TileModel]] = [] tiles_order: Optional[Any] = Field(None, alias="tilesOrder") tiles_last_update: Optional[str] = Field(None, alias="tilesLastUpdate") class AccountModuleModel(BaseModel): id: int default: bool name: str email: str type: str controller_status: Optional[str] = Field(None, alias="controllerStatus") module_status: Optional[str] = Field(None, alias="moduleStatus") additional_information: Optional[str] = Field(None, alias="additionalInformation") phone_number: Optional[Any] = Field(None, alias="phoneNumber") zip_code: Optional[str] = Field(None, alias="zipCode") tag: Optional[str] = None country: Optional[str] = None gmt_id: Optional[int] = Field(None, alias="gmtId") gmt_time: Optional[str] = Field(None, alias="gmtTime") postcode_policy_accepted: Optional[bool] = Field(None, alias="postcodePolicyAccepted") style: Optional[str] = None version: Optional[str] = None company: Optional[str] = None udid: str pytouchlinesl-0.4.0/pytouchlinesl/module.py000066400000000000000000000151561503534755000211750ustar00rootroot00000000000000"""Provides a representation of a single Roth TouchlineSL module. In reality, this usually represents the underfloor heating for a specific building. It masks the upstream Roth API, which provides relatively few methods for fetching details about particular zones and schedules by providing methods to query them directly. Because of the upstream API design, there is an inbuilt caching mechanism that's used to prevent making too many calls to the modules endpoint. The cache can be invalidated to ensure that new data is fetched using the `invalidate_cache` method. Typical usage: import os from pytouchlinesl import TouchlineSL tsl = TouchlineSL(username"foo@bar.com", password="deadbeef") modules = await tsl.modules() if modules: module = modules[0] zone = await module.zone_by_name("Kitchen") """ import time from pytouchlinesl.client import BaseClient from pytouchlinesl.client.models import GlobalScheduleModel, ModuleModel from pytouchlinesl.client.models.models import AccountModuleModel from pytouchlinesl.zone import Zone class Module: """A representation of a single Roth TouchlineSL module.""" def __init__( self, *, client: BaseClient, module_data: AccountModuleModel, cache_validity: int = 30, ): """Construct an instance of a module. Args: client: The underlying API client to use for fetching data. module_data: A raw representation of the Module returned from a client instance. cache_validity: (Optional) The number of seconds for which module data should be cached. """ self._client: BaseClient = client # Information about the module itself self.id = module_data.udid self.name = module_data.name self.email = module_data.email self.type = module_data.type self.version = module_data.version # Raw data about the zones, schedules, tiles in the module self._raw_data: ModuleModel # Unix timestamp representing the last time the _raw_data was fetched self._last_fetched = 0 self._cache_validity = cache_validity * 1000 self._zones: list[Zone] = [] self._schedules: list[GlobalScheduleModel] = [] async def _data(self, *, refresh: bool = False) -> ModuleModel: """Get the raw representation of the module from the upstream API. If the data has never been fetched from upstream, or the data is older than the cache validity period, then the data is refreshed using the upstream API. Args: refresh: (Optional): Force the data to be refreshed using the API. """ if refresh or (round(time.time() * 1000) - self._last_fetched) > self._cache_validity: self._raw_data = await self._client.module(self.id) self._last_fetched = round(time.time() * 1000) return self._raw_data def invalidate_cache(self): """Reset the cache, ensuring new data is fetched the next time its accessed.""" self._last_fetched = 0 self._zones = [] self._schedules = [] async def zones(self, *, include_off: bool = False, refresh: bool = False) -> list[Zone]: """Return a list of zones, optionally including those which are disabled. Args: include_off: (Optional) Include zones which are switched off in the results. refresh: (Optional) Force the data to be refreshed using the API. """ data = await self._data(refresh=refresh) self._zones = [] for z in data.zones.elements: schedule = await self.schedule_by_idx(z.mode.schedule_index) zone = Zone(module=self, client=self._client, zone_data=z, schedule=schedule) self._zones.append(zone) if include_off: return self._zones return [z for z in self._zones if z.enabled] async def zone(self, zone_id: int, *, refresh: bool = False) -> Zone | None: """Return a specific zone, by ID. Args: zone_id: The ID of the desired zone. refresh: (Optional) Force the data to be refreshed using the API. """ zones = await self.zones(include_off=True, refresh=refresh) return next((z for z in zones if z.id == zone_id), None) async def zone_by_name(self, zone_name: str, *, refresh: bool = False) -> Zone | None: """Return a specific zone, by name. Args: zone_name: The name of the desired zone. include_off: (Optional) Include zones which are switched off in the results. refresh: (Optional) Force the data to be refreshed using the API. """ zones = await self.zones(include_off=True, refresh=refresh) return next((z for z in zones if z.name == zone_name), None) async def schedules(self, *, refresh: bool = False) -> list[GlobalScheduleModel]: """Return a list of the module's global schedules. Args: refresh: (Optional) Force the data to be refreshed using the API. """ data = await self._data(refresh=refresh) self._schedules = data.zones.global_schedules.elements return self._schedules async def schedule( self, schedule_id: int, *, refresh: bool = False ) -> GlobalScheduleModel | None: """Return a specific global schedule, by ID. Args: schedule_id: The ID of the desired schedule. refresh: (Optional) Force the data to be refreshed using the API. """ schedules = await self.schedules(refresh=refresh) return next((s for s in schedules if s.id == schedule_id), None) async def schedule_by_idx( self, schedule_idx: int, *, refresh: bool = False ) -> GlobalScheduleModel | None: """Return a specific global schedule, by index. Args: schedule_idx: The index of the desired schedule. refresh: (Optional) Force the data to be refreshed using the API. """ schedules = await self.schedules(refresh=refresh) return next((s for s in schedules if s.index == schedule_idx), None) async def schedule_by_name( self, schedule_name: str, *, refresh: bool = False ) -> GlobalScheduleModel | None: """Return a specific global schedule, by name. Args: schedule_name: The name of the desired schedule. refresh: (Optional) Force the data to be refreshed using the API. """ schedules = await self.schedules(refresh=refresh) return next((s for s in schedules if s.name == schedule_name), None) pytouchlinesl-0.4.0/pytouchlinesl/touchlinesl.py000066400000000000000000000060641503534755000222370ustar00rootroot00000000000000"""Provides an API client for a specific Roth TouchlineSL account. This is the top-level construct expected to be used for interacting with the TouchlineSL API. It provides a way to list the heating modules associated with a given account, the authentication details for which are provided by a RothAPI instance. Typical usage example: import os from pytouchlinesl import TouchlineSL tsl = TouchlineSL(username"foo@bar.com", password="deadbeef") modules = await tsl.modules() """ import logging from pytouchlinesl.client import BaseClient, RothAPI from pytouchlinesl.module import Module logger = logging.getLogger(__name__) class TouchlineSL: """An API client for a specific Roth TouchlineSL account.""" def __init__( self, *, username: str | None = None, password: str | None = None, client: BaseClient | None = None, cache_validity: int = 30, ): """Construct the instance with either credentials or an authenticated client. Args: username: (Optional) Username for TouchlineSL account. Ignored if client is passed. password: (Optional) Password for TouchlineSL account. Ignored if client is passed. client: (Optional) An instance of a RothAPI class. cache_validity: (Optional) The number of seconds for which module data should be cached. """ self._modules: list[Module] = [] if client: if username or password: logger.warning( "username and password arguments will be ignored because a client was passed" ) self._client = client else: if username is None or password is None: raise TypeError("username and password must be strings if no client is provided") self._client = RothAPI(username=username, password=password) self._cache_validity = cache_validity async def user_id(self) -> int: """Return the unique user ID of the authenticated account.""" return await self._client.user_id() async def modules(self, *, refresh: bool = False) -> list[Module]: """Report a list of Roth TouchlineSL modules associated with the account. Args: refresh: Force the API client to refresh cached module data """ if not self._modules or refresh: data = await self._client.modules() self._modules = [ Module(client=self._client, module_data=m, cache_validity=self._cache_validity) for m in data ] return self._modules async def module(self, *, module_id: str, refresh: bool = False) -> Module | None: """Fetch a specific module, by module ID. Args: module_id: The unique identifier of the TouchlineSL module to fetch refresh: Force the API client to refresh cached module data """ modules = await self.modules(refresh=refresh) return next((m for m in modules if m.id == module_id), None) pytouchlinesl-0.4.0/pytouchlinesl/zone.py000066400000000000000000000120061503534755000206520ustar00rootroot00000000000000"""A representation of a single Roth TouchlineSL zone. In most cases, a Zone represents a specific room in a building. Zones can report on both temperature and humidity. Each zone can either be set with a constant target temperature, set to a specific global schedule, or set onto a local schedule. Typical Usage: import os from pytouchlinesl import TouchlineSL tsl = TouchlineSL(username"foo@bar.com", password="deadbeef") # Get the module from the account module = await tsl.modules() module = modules[0] # Get a specific zone from the module zone = await module.zone_by_name("Kitchen") temp = zone.temperature # Set the zone to a constant target temp of 22.5 await zone.set_temperature(22.5) # Set the zone onto a specific global schedule schedule = module.schedule_by_name("Living Spaces") await zone.set_schedule(schedule.id) """ from typing import TYPE_CHECKING, Literal from .client import BaseClient from .client.models import GlobalScheduleModel, LocalScheduleModel, ZoneModel if TYPE_CHECKING: from .module import Module class Zone: """A representation of a single Roth TouchlineSL zone.""" def __init__( self, module: "Module", client: BaseClient, zone_data: ZoneModel, schedule: GlobalScheduleModel | LocalScheduleModel | None, ): """Construct an instance of a zone. Args: module: The Module this Zone belongs to. client: The underlying API client to use for fetching data. zone_data: A raw representation of the Zone returned from a client instance. schedule: None if Zone is set to constant temp, otherwise instance of the global schedule assigned to the zone """ self._module = module self._client = client self._raw_data = zone_data self._schedule = schedule @property def name(self) -> str: """Return the configured name of the zone.""" return self._raw_data.description.name @property def id(self) -> int: """Return the ID of the zone.""" return self._raw_data.zone.id @property def battery_level(self) -> int | None: """Return the battery level of the zone.""" return self._raw_data.zone.battery_level @property def temperature(self) -> float | None: """Return the current temperature of the zone, if it's enabled, otherwise None.""" if self._raw_data.zone.current_temperature: return float(int(self._raw_data.zone.current_temperature) / 10) return None @property def target_temperature(self) -> float: """Return the target temperature of the zone.""" return float(int(self._raw_data.zone.set_temperature) / 10) @property def humidity(self) -> float: """Return the humidity of the zone.""" return float(int(self._raw_data.zone.humidity)) @property def mode(self) -> Literal["constantTemp", "globalSchedule", "localSchedule", "timeLimit"]: """Return the mode of the zone.""" return self._raw_data.mode.mode @property def enabled(self) -> bool: """Return whether or not the zone is enabled.""" return self._raw_data.zone.zone_state != "zoneOff" @property def schedule(self) -> GlobalScheduleModel | LocalScheduleModel | None: """Return the zone's current schedule. If a constant temp is set, returns None.""" if self.mode == "constantTemp": return None return self._schedule @property def relay_on(self) -> bool: """Return whether or not the zone's relay is on.""" return self._raw_data.zone.flags.relay_state == "on" @property def algorithm(self) -> Literal["heating", "cooling"]: """Return the zone's current algorithm, either `heating` or `cooling`.""" return self._raw_data.zone.flags.algorithm @property def signal_strength(self) -> int | None: """Return the signal strength of the zone.""" return self._raw_data.zone.signal_strength @property def alarm(self) -> Literal["sensor_damaged", "no_communication"] | None: """Return the alarm state of the zone.""" state = self._raw_data.zone.zone_state if state == "sensorDamaged": return "sensor_damaged" elif state == "noCommunication": return "no_communication" return None async def set_temperature(self, temperature: float): """Set a constant target temperature for the zone.""" await self._client.set_zone_temperature( module_id=self._module.id, zone_id=self.id, mode_id=self._raw_data.mode.id, temperature=temperature, ) self._module.invalidate_cache() async def set_schedule(self, schedule_id: int): """Assign the zone to a specific global schedule.""" await self._client.set_zone_schedule(self._module.id, self.id, schedule_id) self._module.invalidate_cache() pytouchlinesl-0.4.0/tests/000077500000000000000000000000001503534755000155665ustar00rootroot00000000000000pytouchlinesl-0.4.0/tests/.gitkeep000066400000000000000000000000001503534755000172050ustar00rootroot00000000000000pytouchlinesl-0.4.0/tests/__init__.py000066400000000000000000000000451503534755000176760ustar00rootroot00000000000000from .fake_client import FakeRothAPI pytouchlinesl-0.4.0/tests/conftest.py000066400000000000000000000017531503534755000177730ustar00rootroot00000000000000import pytest from pytouchlinesl import Module, TouchlineSL, Zone from .fake_client import FakeRothAPI @pytest.fixture def test_touchlinesl() -> TouchlineSL: client = FakeRothAPI() return TouchlineSL(client=client) @pytest.fixture def test_touchlinesl_short_cache() -> TouchlineSL: client = FakeRothAPI() return TouchlineSL(client=client, cache_validity=0.1) @pytest.fixture async def test_module(test_touchlinesl: TouchlineSL) -> Module: m = await test_touchlinesl.module(module_id="1234a5678a9123a456a7891234a56789") assert isinstance(m, Module) return m @pytest.fixture async def test_module_short_cache(test_touchlinesl_short_cache: TouchlineSL) -> Module: m = await test_touchlinesl_short_cache.module(module_id="1234a5678a9123a456a7891234a56789") assert isinstance(m, Module) return m @pytest.fixture async def test_zone(test_module: Module) -> Zone: z = await test_module.zone_by_name("Kitchen") assert isinstance(z, Zone) return z pytouchlinesl-0.4.0/tests/fake_client.py000066400000000000000000000022261503534755000204060ustar00rootroot00000000000000import json import os from pathlib import Path from pytouchlinesl.client import BaseClient from pytouchlinesl.client.models import AccountModuleModel, ModuleModel data_dir = Path(os.path.realpath(__file__)).parent / "sample-data" class FakeRothAPI(BaseClient): def __init__(self): self._user_id = 123456789 self._token = "deadbeef" async def user_id(self) -> int: return self._user_id async def authenticated(self) -> bool: return True if self._token else False async def modules(self) -> list[AccountModuleModel]: with open(data_dir / "modules.json", "r") as f: data = json.load(f) return [AccountModuleModel(**m) for m in data] async def module(self, module_id: str) -> ModuleModel: with open(data_dir / "module.json", "r") as f: data = json.load(f) return ModuleModel(**data) async def set_zone_temperature( self, module_id: str, mode_id: int, zone_id: int, temperature: float ): raise NotImplementedError async def set_zone_schedule(self, module_id: str, zone_id: int, schedule_id: int): raise NotImplementedError pytouchlinesl-0.4.0/tests/sample-data/000077500000000000000000000000001503534755000177565ustar00rootroot00000000000000pytouchlinesl-0.4.0/tests/sample-data/module.json000066400000000000000000002400471503534755000221450ustar00rootroot00000000000000{ "zones": { "transaction_time": "2024-08-22T15:46:33.843796+02:00", "elements": [ { "zone": { "id": 2335, "parentId": 2333, "time": "2024-08-22T15:44:00.936163", "duringChange": false, "index": 0, "currentTemperature": 229, "setTemperature": 170, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "noAlarm", "signalStrength": 23, "batteryLevel": 100, "actuatorsOpen": 0, "humidity": 58, "visibility": true }, "description": { "id": 2336, "parentId": 2335, "name": "Playroom", "styleId": 3, "styleIcon": "children", "duringChange": false }, "mode": { "id": 2337, "parentId": 2335, "mode": "globalSchedule", "constTempTime": 60, "setTemperature": 170, "scheduleIndex": 3 }, "schedule": { "id": 2339, "parentId": 2335, "index": -1, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2354, "parentId": 2333, "time": "2024-08-12T21:40:43.451932", "duringChange": false, "index": 1, "currentTemperature": null, "setTemperature": 169, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2355, "parentId": 2354, "name": "Zone 2", "styleId": 1, "styleIcon": "bathroom", "duringChange": false }, "mode": { "id": 2356, "parentId": 2354, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2358, "parentId": 2354, "index": -2, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2373, "parentId": 2333, "time": "2024-08-22T15:42:46.320969", "duringChange": false, "index": 2, "currentTemperature": 222, "setTemperature": 180, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "noAlarm", "signalStrength": 30, "batteryLevel": 100, "actuatorsOpen": 0, "humidity": 59, "visibility": true }, "description": { "id": 2374, "parentId": 2373, "name": "Lounge", "styleId": 2, "styleIcon": "kitchen", "duringChange": false }, "mode": { "id": 2375, "parentId": 2373, "mode": "globalSchedule", "constTempTime": 60, "setTemperature": 180, "scheduleIndex": 0 }, "schedule": { "id": 2377, "parentId": 2373, "index": -3, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2392, "parentId": 2333, "time": "2024-08-12T21:41:17.584356", "duringChange": false, "index": 3, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2393, "parentId": 2392, "name": "Zone 4", "styleId": 3, "styleIcon": "children", "duringChange": false }, "mode": { "id": 2394, "parentId": 2392, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2396, "parentId": 2392, "index": -4, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2411, "parentId": 2333, "time": "2024-08-22T15:18:44.608665", "duringChange": false, "index": 4, "currentTemperature": 221, "setTemperature": 180, "flags": { "relayState": "on", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "noAlarm", "signalStrength": 53, "batteryLevel": 100, "actuatorsOpen": 0, "humidity": 61, "visibility": true }, "description": { "id": 2412, "parentId": 2411, "name": "Kitchen", "styleId": 0, "styleIcon": "living_room", "duringChange": false }, "mode": { "id": 2413, "parentId": 2411, "mode": "globalSchedule", "constTempTime": 60, "setTemperature": 180, "scheduleIndex": 0 }, "schedule": { "id": 2415, "parentId": 2411, "index": -5, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2430, "parentId": 2333, "time": "2024-08-22T15:32:21.208915", "duringChange": false, "index": 5, "currentTemperature": 231, "setTemperature": 170, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "noAlarm", "signalStrength": 100, "batteryLevel": 100, "actuatorsOpen": 0, "humidity": 58, "visibility": true }, "description": { "id": 2431, "parentId": 2430, "name": "Utility Room", "styleId": 5, "styleIcon": "wardrobe", "duringChange": false }, "mode": { "id": 2432, "parentId": 2430, "mode": "constantTemp", "constTempTime": 60, "setTemperature": 170, "scheduleIndex": 0 }, "schedule": { "id": 2434, "parentId": 2430, "index": -6, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2448, "parentId": 2333, "time": "2024-08-22T15:45:26.259793", "duringChange": false, "index": 6, "currentTemperature": 225, "setTemperature": 170, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "noAlarm", "signalStrength": 24, "batteryLevel": 100, "actuatorsOpen": 0, "humidity": 58, "visibility": true }, "description": { "id": 2449, "parentId": 2448, "name": "Laura Office", "styleId": 0, "styleIcon": "living_room", "duringChange": false }, "mode": { "id": 2450, "parentId": 2448, "mode": "constantTemp", "constTempTime": 60, "setTemperature": 170, "scheduleIndex": 0 }, "schedule": { "id": 2452, "parentId": 2448, "index": -7, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2466, "parentId": 2333, "time": "2024-08-22T15:44:26.475553", "duringChange": false, "index": 7, "currentTemperature": 246, "setTemperature": 170, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "cooling", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "sensorDamaged", "signalStrength": 31, "batteryLevel": 100, "actuatorsOpen": 0, "humidity": 52, "visibility": true }, "description": { "id": 2467, "parentId": 2466, "name": "Jon Office", "styleId": 0, "styleIcon": "living_room", "duringChange": false }, "mode": { "id": 2468, "parentId": 2466, "mode": "constantTemp", "constTempTime": 60, "setTemperature": 170, "scheduleIndex": 0 }, "schedule": { "id": 2470, "parentId": 2466, "index": -8, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2484, "parentId": 2333, "time": "2024-08-22T15:36:08.168114", "duringChange": false, "index": 8, "currentTemperature": 221, "setTemperature": 170, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "noAlarm", "signalStrength": 87, "batteryLevel": 100, "actuatorsOpen": 0, "humidity": 59, "visibility": true }, "description": { "id": 2485, "parentId": 2484, "name": "Guest Bed", "styleId": 4, "styleIcon": "bedroom", "duringChange": false }, "mode": { "id": 2486, "parentId": 2484, "mode": "globalSchedule", "constTempTime": 60, "setTemperature": 170, "scheduleIndex": 2 }, "schedule": { "id": 2488, "parentId": 2484, "index": -9, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2503, "parentId": 2333, "time": "2024-08-22T15:44:30.953926", "duringChange": false, "index": 9, "currentTemperature": 228, "setTemperature": 170, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "noAlarm", "signalStrength": 42, "batteryLevel": 100, "actuatorsOpen": 0, "humidity": 58, "visibility": true }, "description": { "id": 2504, "parentId": 2503, "name": "Snug", "styleId": 0, "styleIcon": "living_room", "duringChange": false }, "mode": { "id": 2505, "parentId": 2503, "mode": "globalSchedule", "constTempTime": 60, "setTemperature": 170, "scheduleIndex": 4 }, "schedule": { "id": 2507, "parentId": 2503, "index": -10, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2522, "parentId": 2333, "time": "2024-08-22T15:41:17.679043", "duringChange": false, "index": 10, "currentTemperature": 224, "setTemperature": 170, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "noCommunication", "signalStrength": 13, "batteryLevel": 100, "actuatorsOpen": 0, "humidity": 61, "visibility": true }, "description": { "id": 2523, "parentId": 2522, "name": "Master Bed", "styleId": 4, "styleIcon": "bedroom", "duringChange": false }, "mode": { "id": 2524, "parentId": 2522, "mode": "globalSchedule", "constTempTime": 60, "setTemperature": 170, "scheduleIndex": 2 }, "schedule": { "id": 2526, "parentId": 2522, "index": -11, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2541, "parentId": 2333, "time": "2024-08-22T15:46:11.13502", "duringChange": false, "index": 11, "currentTemperature": 215, "setTemperature": 170, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "noAlarm", "signalStrength": 97, "batteryLevel": 100, "actuatorsOpen": 0, "humidity": 61, "visibility": true }, "description": { "id": 2542, "parentId": 2541, "name": "Attic Bed", "styleId": 4, "styleIcon": "bedroom", "duringChange": false }, "mode": { "id": 2543, "parentId": 2541, "mode": "globalSchedule", "constTempTime": 60, "setTemperature": 170, "scheduleIndex": 3 }, "schedule": { "id": 2545, "parentId": 2541, "index": -12, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2560, "parentId": 2333, "time": "2024-08-12T21:43:23.776791", "duringChange": false, "index": 12, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2561, "parentId": 2560, "name": "Zone 13", "styleId": 4, "styleIcon": "bedroom", "duringChange": false }, "mode": { "id": 2562, "parentId": 2560, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2564, "parentId": 2560, "index": -13, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2579, "parentId": 2333, "time": "2024-08-12T21:43:41.601669", "duringChange": false, "index": 13, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2580, "parentId": 2579, "name": "Zone 14", "styleId": 5, "styleIcon": "wardrobe", "duringChange": false }, "mode": { "id": 2581, "parentId": 2579, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2583, "parentId": 2579, "index": -14, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2597, "parentId": 2333, "time": "2024-08-12T21:43:50.660486", "duringChange": false, "index": 14, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2598, "parentId": 2597, "name": "Zone 15", "styleId": 6, "styleIcon": "corridor", "duringChange": false }, "mode": { "id": 2599, "parentId": 2597, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2601, "parentId": 2597, "index": -15, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2615, "parentId": 2333, "time": "2024-08-12T21:44:08.621444", "duringChange": false, "index": 15, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2616, "parentId": 2615, "name": "Zone 16", "styleId": 7, "styleIcon": "garage", "duringChange": false }, "mode": { "id": 2617, "parentId": 2615, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2619, "parentId": 2615, "index": -16, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2633, "parentId": 2333, "time": "2024-08-12T21:44:17.644989", "duringChange": false, "index": 16, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2634, "parentId": 2633, "name": "Zone 17", "styleId": 0, "styleIcon": "living_room", "duringChange": false }, "mode": { "id": 2635, "parentId": 2633, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2637, "parentId": 2633, "index": -17, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2652, "parentId": 2333, "time": "2024-08-12T21:44:35.685728", "duringChange": false, "index": 17, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2653, "parentId": 2652, "name": "Zone 18", "styleId": 1, "styleIcon": "bathroom", "duringChange": false }, "mode": { "id": 2654, "parentId": 2652, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2656, "parentId": 2652, "index": -18, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2671, "parentId": 2333, "time": "2024-08-12T21:44:44.671977", "duringChange": false, "index": 18, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2672, "parentId": 2671, "name": "Zone 19", "styleId": 2, "styleIcon": "kitchen", "duringChange": false }, "mode": { "id": 2673, "parentId": 2671, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2675, "parentId": 2671, "index": -19, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2690, "parentId": 2333, "time": "2024-08-12T21:45:02.78159", "duringChange": false, "index": 19, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2691, "parentId": 2690, "name": "Zone 20", "styleId": 3, "styleIcon": "children", "duringChange": false }, "mode": { "id": 2692, "parentId": 2690, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2694, "parentId": 2690, "index": -20, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2709, "parentId": 2333, "time": "2024-08-12T21:45:11.667288", "duringChange": false, "index": 20, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2710, "parentId": 2709, "name": "Zone 21", "styleId": 4, "styleIcon": "bedroom", "duringChange": false }, "mode": { "id": 2711, "parentId": 2709, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2713, "parentId": 2709, "index": -21, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2728, "parentId": 2333, "time": "2024-08-12T21:45:29.630532", "duringChange": false, "index": 21, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2729, "parentId": 2728, "name": "Zone 22", "styleId": 5, "styleIcon": "wardrobe", "duringChange": false }, "mode": { "id": 2730, "parentId": 2728, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2732, "parentId": 2728, "index": -22, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2746, "parentId": 2333, "time": "2024-08-12T21:45:38.660197", "duringChange": false, "index": 22, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2747, "parentId": 2746, "name": "Zone 23", "styleId": 6, "styleIcon": "corridor", "duringChange": false }, "mode": { "id": 2748, "parentId": 2746, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2750, "parentId": 2746, "index": -23, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2764, "parentId": 2333, "time": "2024-08-12T21:45:57.446097", "duringChange": false, "index": 23, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2765, "parentId": 2764, "name": "Zone 24", "styleId": 7, "styleIcon": "garage", "duringChange": false }, "mode": { "id": 2766, "parentId": 2764, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2768, "parentId": 2764, "index": -24, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2782, "parentId": 2333, "time": "2024-08-12T21:46:05.679477", "duringChange": false, "index": 24, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2783, "parentId": 2782, "name": "Zone 25", "styleId": 0, "styleIcon": "living_room", "duringChange": false }, "mode": { "id": 2784, "parentId": 2782, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2786, "parentId": 2782, "index": -25, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2801, "parentId": 2333, "time": "2024-08-12T21:46:23.808992", "duringChange": false, "index": 25, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2802, "parentId": 2801, "name": "Zone 26", "styleId": 1, "styleIcon": "bathroom", "duringChange": false }, "mode": { "id": 2803, "parentId": 2801, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2805, "parentId": 2801, "index": -26, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2820, "parentId": 2333, "time": "2024-08-12T21:46:32.95147", "duringChange": false, "index": 26, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2821, "parentId": 2820, "name": "Zone 27", "styleId": 2, "styleIcon": "kitchen", "duringChange": false }, "mode": { "id": 2822, "parentId": 2820, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2824, "parentId": 2820, "index": -27, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2839, "parentId": 2333, "time": "2024-08-12T21:46:50.726384", "duringChange": false, "index": 27, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2840, "parentId": 2839, "name": "Zone 28", "styleId": 3, "styleIcon": "children", "duringChange": false }, "mode": { "id": 2841, "parentId": 2839, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2843, "parentId": 2839, "index": -28, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2858, "parentId": 2333, "time": "2024-08-12T21:46:59.781723", "duringChange": false, "index": 28, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2859, "parentId": 2858, "name": "Zone 29", "styleId": 4, "styleIcon": "bedroom", "duringChange": false }, "mode": { "id": 2860, "parentId": 2858, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2862, "parentId": 2858, "index": -29, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2877, "parentId": 2333, "time": "2024-08-12T21:47:17.701659", "duringChange": false, "index": 29, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2878, "parentId": 2877, "name": "Zone 30", "styleId": 5, "styleIcon": "wardrobe", "duringChange": false }, "mode": { "id": 2879, "parentId": 2877, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2881, "parentId": 2877, "index": -30, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2895, "parentId": 2333, "time": "2024-08-12T21:47:26.773943", "duringChange": false, "index": 30, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2896, "parentId": 2895, "name": "Zone 31", "styleId": 6, "styleIcon": "corridor", "duringChange": false }, "mode": { "id": 2897, "parentId": 2895, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2899, "parentId": 2895, "index": -31, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2913, "parentId": 2333, "time": "2024-08-12T21:47:44.682668", "duringChange": false, "index": 31, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2914, "parentId": 2913, "name": "Zone 32", "styleId": 7, "styleIcon": "garage", "duringChange": false }, "mode": { "id": 2915, "parentId": 2913, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2917, "parentId": 2913, "index": -32, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2931, "parentId": 2333, "time": "2024-08-12T21:47:53.747407", "duringChange": false, "index": 32, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2932, "parentId": 2931, "name": "Zone 33", "styleId": 0, "styleIcon": "living_room", "duringChange": false }, "mode": { "id": 2933, "parentId": 2931, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2935, "parentId": 2931, "index": -33, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2950, "parentId": 2333, "time": "2024-08-12T21:48:11.683631", "duringChange": false, "index": 33, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2951, "parentId": 2950, "name": "Zone 34", "styleId": 1, "styleIcon": "bathroom", "duringChange": false }, "mode": { "id": 2952, "parentId": 2950, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2954, "parentId": 2950, "index": -34, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2969, "parentId": 2333, "time": "2024-08-12T21:48:20.737711", "duringChange": false, "index": 34, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2970, "parentId": 2969, "name": "Zone 35", "styleId": 2, "styleIcon": "kitchen", "duringChange": false }, "mode": { "id": 2971, "parentId": 2969, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2973, "parentId": 2969, "index": -35, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 2988, "parentId": 2333, "time": "2024-08-12T21:48:38.693448", "duringChange": false, "index": 35, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 2989, "parentId": 2988, "name": "Zone 36", "styleId": 3, "styleIcon": "children", "duringChange": false }, "mode": { "id": 2990, "parentId": 2988, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 2992, "parentId": 2988, "index": -36, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 3007, "parentId": 2333, "time": "2024-08-12T21:48:43.218415", "duringChange": false, "index": 36, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 3008, "parentId": 3007, "name": "Zone 37", "styleId": 4, "styleIcon": "bedroom", "duringChange": false }, "mode": { "id": 3009, "parentId": 3007, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 3011, "parentId": 3007, "index": -37, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 3026, "parentId": 2333, "time": "2024-08-12T21:48:52.184392", "duringChange": false, "index": 37, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 3027, "parentId": 3026, "name": "Zone 38", "styleId": 5, "styleIcon": "wardrobe", "duringChange": false }, "mode": { "id": 3028, "parentId": 3026, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 3030, "parentId": 3026, "index": -38, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 3044, "parentId": 2333, "time": "2024-08-12T21:48:56.733603", "duringChange": false, "index": 38, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 3045, "parentId": 3044, "name": "Zone 39", "styleId": 6, "styleIcon": "corridor", "duringChange": false }, "mode": { "id": 3046, "parentId": 3044, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 3048, "parentId": 3044, "index": -39, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] }, { "zone": { "id": 3062, "parentId": 2333, "time": "2024-08-12T21:49:05.772826", "duringChange": false, "index": 39, "currentTemperature": null, "setTemperature": 190, "flags": { "relayState": "off", "minOneWindowOpen": false, "algorithm": "heating", "floorSensor": 0, "humidityAlgorytm": 0, "zoneExcluded": 0 }, "zoneState": "zoneOff", "signalStrength": null, "batteryLevel": null, "actuatorsOpen": 0, "humidity": 0, "visibility": true }, "description": { "id": 3063, "parentId": 3062, "name": "Zone 40", "styleId": 7, "styleIcon": "garage", "duringChange": false }, "mode": { "id": 3064, "parentId": 3062, "mode": "timeLimit", "constTempTime": 60, "setTemperature": 200, "scheduleIndex": 0 }, "schedule": { "id": 3066, "parentId": 3062, "index": -40, "p0Days": ["1", "1", "1", "1", "1", "0", "0"], "p0Intervals": [ { "start": 300, "stop": 600, "temp": 240 }, { "start": 660, "stop": 1380, "temp": 240 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p0SetbackTemp": 260, "p1Days": ["0", "0", "0", "0", "0", "1", "1"], "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1SetbackTemp": 150 }, "actuators": [], "underfloor": {}, "windowsSensors": [], "additionalContacts": [] } ], "globalSchedules": { "time": "2024-08-20T18:39:19.845888", "duringChange": false, "elements": [ { "id": 2948, "parentId": 2333, "index": 0, "name": "Living Spaces", "p0Days": ["1", "1", "1", "1", "1", "1", "1"], "p0SetbackTemp": 180, "p0Intervals": [ { "start": 300, "stop": 540, "temp": 200 }, { "start": 1020, "stop": 1200, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1Days": ["0", "0", "0", "0", "0", "0", "0"], "p1SetbackTemp": 175, "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ] }, { "id": 2967, "parentId": 2333, "index": 1, "name": "Holiday", "p0Days": ["1", "1", "1", "1", "1", "1", "1"], "p0SetbackTemp": 150, "p0Intervals": [ { "start": 300, "stop": 600, "temp": 170 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1Days": ["0", "0", "0", "0", "0", "0", "0"], "p1SetbackTemp": 260, "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ] }, { "id": 2986, "parentId": 2333, "index": 2, "name": "Bedrooms", "p0Days": ["1", "1", "1", "1", "1", "1", "1"], "p0SetbackTemp": 170, "p0Intervals": [ { "start": 300, "stop": 540, "temp": 190 }, { "start": 1200, "stop": 1320, "temp": 190 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1Days": ["0", "0", "0", "0", "0", "0", "0"], "p1SetbackTemp": 190, "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ] }, { "id": 3005, "parentId": 2333, "index": 3, "name": "Public Rooms", "p0Days": ["1", "1", "1", "1", "1", "1", "1"], "p0SetbackTemp": 170, "p0Intervals": [ { "start": 300, "stop": 540, "temp": 190 }, { "start": 1020, "stop": 1200, "temp": 190 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1Days": ["0", "0", "0", "0", "0", "0", "0"], "p1SetbackTemp": 150, "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ] }, { "id": 3024, "parentId": 2333, "index": 4, "name": "Snug", "p0Days": ["1", "1", "1", "1", "1", "1", "1"], "p0SetbackTemp": 170, "p0Intervals": [ { "start": 1020, "stop": 1260, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ], "p1Days": ["0", "0", "0", "0", "0", "0", "0"], "p1SetbackTemp": 190, "p1Intervals": [ { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 }, { "start": 6100, "stop": 6100, "temp": 200 } ] } ] }, "controllerParameters": { "controllerMode": { "id": 2334, "parentId": 0, "type": 108, "txtId": 0, "iconId": 0, "value": 0, "menuId": 1000 }, "globalSchedulesNumber": {} } }, "tiles": [ { "id": 2326, "parentId": 0, "type": 11, "menuId": 0, "orderId": null, "visibility": true, "params": { "description": "Relay", "workingStatus": false, "txtId": 1736, "iconId": 5 } }, { "id": 2328, "parentId": 0, "type": 11, "menuId": 0, "orderId": null, "visibility": true, "params": { "description": "Relay", "workingStatus": false, "txtId": 3089, "iconId": 17 } }, { "id": 3080, "parentId": 0, "type": 50, "menuId": 0, "orderId": null, "visibility": true, "params": { "description": "Controller software version", "version": "1.0.6", "txtId": 873, "iconId": 29, "companyId": 97, "controllerName": "L-11", "mainControllerId": 87 } } ], "tilesOrder": null, "tilesLastUpdate": "2024-08-22 15:46:33.921131+02" } pytouchlinesl-0.4.0/tests/sample-data/modules.json000066400000000000000000000010421503534755000223160ustar00rootroot00000000000000[ { "id": 0, "default": false, "name": "Test Module", "email": "foo@bar.com", "type": "zones_controller", "controllerStatus": "active", "moduleStatus": "active", "additionalInformation": "foo@bar.com", "phoneNumber": null, "zipCode": "12345", "tag": "ROTH", "country": "United Kingdom", "gmtId": 30, "gmtTime": "1", "postcodePolicyAccepted": true, "style": "roth", "version": "ROTH: L-11 (v.1.0.6)", "company": "roth", "udid": "1234a5678a9123a456a7891234a56789" } ] pytouchlinesl-0.4.0/tests/test_module.py000066400000000000000000000146631503534755000204760ustar00rootroot00000000000000import asyncio import pytest from pytouchlinesl.client.models import GlobalScheduleModel from pytouchlinesl.zone import Zone @pytest.mark.asyncio async def test_zones(test_module): zones = await test_module.zones() # There should be 10 enabled zones assert len(zones) == 10 # Ensure that each of the zones has been correctly constructed by the # modules method. for z in zones: assert isinstance(z, Zone) if z.mode == "constantTemp": assert z.schedule is None else: assert isinstance(z.schedule, GlobalScheduleModel) @pytest.mark.asyncio async def test_zones_include_off(test_module): zones = await test_module.zones(include_off=True) # There should be 40 total zones, 10 enabled, 30 disabled assert len(zones) == 40 @pytest.mark.asyncio async def test_zones_include_off_and_refresh(test_module): zones = await test_module.zones(include_off=True, refresh=True) # There should be 40 total zones, 10 enabled, 30 disabled assert len(zones) == 40 @pytest.mark.asyncio async def test_zones_cache(test_module): await test_module.zones() initial_fetch_time = test_module._last_fetched await asyncio.sleep(0.5) await test_module.zones() assert initial_fetch_time == test_module._last_fetched @pytest.mark.asyncio async def test_zones_cache_expired(test_module_short_cache): await test_module_short_cache.zones() initial_fetch_time = test_module_short_cache._last_fetched await asyncio.sleep(0.25) await test_module_short_cache.zones() assert initial_fetch_time != test_module_short_cache._last_fetched @pytest.mark.asyncio async def test_zones_force_refresh(test_module): await test_module.zones() initial_fetch_time = test_module._last_fetched await asyncio.sleep(0.5) await test_module.zones(refresh=True) assert initial_fetch_time != test_module._last_fetched @pytest.mark.asyncio @pytest.mark.parametrize("id", [2335, 2354]) # test both enabled and disabled zones async def test_zone(id, test_module): z = await test_module.zone(zone_id=id) assert z.id == id @pytest.mark.asyncio async def test_zone_non_existent(test_module): z = await test_module.zone(zone_id=1234) assert z is None @pytest.mark.asyncio async def test_zone_refresh(test_module): await test_module.zones() last_fetched = test_module._last_fetched await asyncio.sleep(0.5) await test_module.zone(zone_id=2335, refresh=True) assert last_fetched != test_module._last_fetched @pytest.mark.asyncio @pytest.mark.parametrize("name", ["Kitchen", "Zone 2"]) # test both enabled and disabled zones async def test_zone_by_name(name, test_module): z = await test_module.zone_by_name(zone_name=name) assert z.name == name @pytest.mark.asyncio async def test_zone_by_name_non_existent(test_module): z = await test_module.zone_by_name(zone_name="Foobar") assert z is None @pytest.mark.asyncio async def test_zone_by_name_refresh(test_module): await test_module.zones() last_fetched = test_module._last_fetched await asyncio.sleep(0.5) await test_module.zone_by_name(zone_name="Kitchen", refresh=True) assert last_fetched != test_module._last_fetched @pytest.mark.asyncio async def test_schedules(test_module): schedules = await test_module.schedules() # There should be 10 enabled schedules assert len(schedules) == 5 # Ensure that each of the schedules has been correctly constructed by the # modules method. for z in schedules: assert isinstance(z, GlobalScheduleModel) @pytest.mark.asyncio async def test_schedules_cache(test_module): await test_module.schedules() initial_fetch_time = test_module._last_fetched await asyncio.sleep(0.5) await test_module.schedules() assert initial_fetch_time == test_module._last_fetched @pytest.mark.asyncio async def test_schedules_cache_expired(test_module_short_cache): await test_module_short_cache.schedules() initial_fetch_time = test_module_short_cache._last_fetched await asyncio.sleep(0.5) await test_module_short_cache.schedules() assert initial_fetch_time != test_module_short_cache._last_fetched @pytest.mark.asyncio async def test_schedules_force_refresh(test_module): await test_module.schedules() initial_fetch_time = test_module._last_fetched await asyncio.sleep(0.5) await test_module.schedules(refresh=True) assert initial_fetch_time != test_module._last_fetched @pytest.mark.asyncio @pytest.mark.parametrize("id", [2948, 2967]) # test both enabled and disabled zones async def test_schedule(id, test_module): z = await test_module.schedule(schedule_id=id) assert z.id == id @pytest.mark.asyncio async def test_schedule_non_existent(test_module): z = await test_module.schedule(schedule_id=1234) assert z is None @pytest.mark.asyncio async def test_schedule_refresh(test_module): await test_module.schedules() last_fetched = test_module._last_fetched await asyncio.sleep(0.5) await test_module.schedule(schedule_id=2948, refresh=True) assert last_fetched != test_module._last_fetched @pytest.mark.asyncio @pytest.mark.parametrize("name", ["Living Spaces", "Bedrooms"]) async def test_schedule_by_name(name, test_module): z = await test_module.schedule_by_name(schedule_name=name) assert z.name == name @pytest.mark.asyncio async def test_schedule_by_name_non_existent(test_module): z = await test_module.schedule_by_name(schedule_name="Foobar") assert z is None @pytest.mark.asyncio async def test_schedule_by_name_refresh(test_module): await test_module.schedules() last_fetched = test_module._last_fetched await asyncio.sleep(0.5) await test_module.schedule_by_name(schedule_name="Holiday", refresh=True) assert last_fetched != test_module._last_fetched @pytest.mark.asyncio @pytest.mark.parametrize("idx", [0, 1]) async def test_schedule_by_idx(idx, test_module): z = await test_module.schedule_by_idx(schedule_idx=idx) assert z.index == idx @pytest.mark.asyncio async def test_schedule_by_idx_non_existent(test_module): z = await test_module.schedule_by_idx(schedule_idx=10) assert z is None @pytest.mark.asyncio async def test_schedule_by_idx_refresh(test_module): await test_module.schedules() last_fetched = test_module._last_fetched await asyncio.sleep(0.5) await test_module.schedule_by_idx(schedule_idx="Holiday", refresh=True) assert last_fetched != test_module._last_fetched pytouchlinesl-0.4.0/tests/test_touchlinesl.py000066400000000000000000000036351503534755000215370ustar00rootroot00000000000000import pytest from pytouchlinesl import Module, TouchlineSL from pytouchlinesl.client import RothAPI from . import FakeRothAPI def test_construct_touchlinesl_credentials(): TouchlineSL(username="foo", password="bar") def test_construct_touchlinesl_client(): fake_client = FakeRothAPI() TouchlineSL(client=fake_client) real_client = RothAPI(username="foo", password="bar") TouchlineSL(client=real_client) def test_construct_touchlinesl_client_and_creds(caplog): TouchlineSL(username="foo", password="bar", client=FakeRothAPI()) assert ( "username and password arguments will be ignored because a client was passed" in caplog.text ) @pytest.mark.parametrize("username,password", [(None, None), ("Foo", None), (None, "Foo")]) def test_construct_touchlinesl_bad_args(username, password): try: TouchlineSL(username=username, password=password) except Exception as e: assert isinstance(e, TypeError) assert str(e) == "username and password must be strings if no client is provided" @pytest.mark.asyncio async def test_modules(test_touchlinesl: TouchlineSL): modules = await test_touchlinesl.modules() for m in modules: assert isinstance(m, Module) assert m._cache_validity == 30000 @pytest.mark.asyncio async def test_modules_short_cache(test_touchlinesl_short_cache: TouchlineSL): modules = await test_touchlinesl_short_cache.modules() for m in modules: assert isinstance(m, Module) assert m._cache_validity == 100 @pytest.mark.asyncio async def test_module_bad_module_id(test_touchlinesl: TouchlineSL): module = await test_touchlinesl.module(module_id="123") assert module is None @pytest.mark.asyncio async def test_module_good_module_id(test_touchlinesl: TouchlineSL): module = await test_touchlinesl.module(module_id="1234a5678a9123a456a7891234a56789") assert isinstance(module, Module) pytouchlinesl-0.4.0/tests/test_zone.py000066400000000000000000000006751503534755000201620ustar00rootroot00000000000000import pytest test_attrs = [ ("temperature", 22.1), ("target_temperature", 18.0), ("humidity", 61.0), ("mode", "globalSchedule"), ("enabled", True), ("relay_on", True), ("algorithm", "heating"), ("signal_strength", 53), ("alarm", None), ] @pytest.mark.asyncio @pytest.mark.parametrize("attr,val", test_attrs) async def test_zone_attributes(attr, val, test_zone): assert getattr(test_zone, attr) == val pytouchlinesl-0.4.0/uv.lock000066400000000000000000003114511503534755000157350ustar00rootroot00000000000000version = 1 revision = 2 requires-python = ">=3.10" resolution-markers = [ "python_full_version < '3.13'", "python_full_version >= '3.13'", ] [[package]] name = "aiohappyeyeballs" version = "2.4.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/2d/f7/22bba300a16fd1cad99da1a23793fe43963ee326d012fdf852d0b4035955/aiohappyeyeballs-2.4.0.tar.gz", hash = "sha256:55a1714f084e63d49639800f95716da97a1f173d46a16dfcfda0016abb93b6b2", size = 16786, upload-time = "2024-08-19T17:16:06.861Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/18/b6/58ea188899950d759a837f9a58b2aee1d1a380ea4d6211ce9b1823748851/aiohappyeyeballs-2.4.0-py3-none-any.whl", hash = "sha256:7ce92076e249169a13c2f49320d1967425eaf1f407522d707d59cac7628d62bd", size = 12155, upload-time = "2024-08-19T17:16:05.464Z" }, ] [[package]] name = "aiohttp" version = "3.10.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, { name = "aiosignal" }, { name = "async-timeout", marker = "python_full_version < '3.11'" }, { name = "attrs" }, { name = "frozenlist" }, { name = "multidict" }, { name = "yarl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ca/28/ca549838018140b92a19001a8628578b0f2a3b38c16826212cc6f706e6d4/aiohttp-3.10.5.tar.gz", hash = "sha256:f071854b47d39591ce9a17981c46790acb30518e2f83dfca8db2dfa091178691", size = 7524360, upload-time = "2024-08-19T20:10:48.406Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c0/4a/b27dd9b88fe22dde88742b341fd10251746a6ffcfe1c0b8b15b4a8cbd7c1/aiohttp-3.10.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:18a01eba2574fb9edd5f6e5fb25f66e6ce061da5dab5db75e13fe1558142e0a3", size = 587010, upload-time = "2024-08-19T20:08:05.444Z" }, { url = "https://files.pythonhosted.org/packages/de/a9/0f7e2b71549c9d641086c423526ae7a10de3b88d03ba104a3df153574d0d/aiohttp-3.10.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:94fac7c6e77ccb1ca91e9eb4cb0ac0270b9fb9b289738654120ba8cebb1189c6", size = 397698, upload-time = "2024-08-19T20:08:07.525Z" }, { url = "https://files.pythonhosted.org/packages/3b/52/26baa486e811c25b0cd16a494038260795459055568713f841e78f016481/aiohttp-3.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f1f1c75c395991ce9c94d3e4aa96e5c59c8356a15b1c9231e783865e2772699", size = 389052, upload-time = "2024-08-19T20:08:08.931Z" }, { url = "https://files.pythonhosted.org/packages/33/df/71ba374a3e925539cb2f6e6d4f5326e7b6b200fabbe1b3cc5e6368f07ce7/aiohttp-3.10.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f7acae3cf1a2a2361ec4c8e787eaaa86a94171d2417aae53c0cca6ca3118ff6", size = 1248615, upload-time = "2024-08-19T20:08:10.625Z" }, { url = "https://files.pythonhosted.org/packages/67/02/bb89c1eba08a27fc844933bee505d63d480caf8e2816c06961d2941cd128/aiohttp-3.10.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:94c4381ffba9cc508b37d2e536b418d5ea9cfdc2848b9a7fea6aebad4ec6aac1", size = 1282930, upload-time = "2024-08-19T20:08:12.483Z" }, { url = "https://files.pythonhosted.org/packages/db/36/07d8cfcc37f39c039f93a4210cc71dadacca003609946c63af23659ba656/aiohttp-3.10.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c31ad0c0c507894e3eaa843415841995bf8de4d6b2d24c6e33099f4bc9fc0d4f", size = 1317250, upload-time = "2024-08-19T20:08:14.383Z" }, { url = "https://files.pythonhosted.org/packages/9a/44/cabeac994bef8ba521b552ae996928afc6ee1975a411385a07409811b01f/aiohttp-3.10.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0912b8a8fadeb32ff67a3ed44249448c20148397c1ed905d5dac185b4ca547bb", size = 1243212, upload-time = "2024-08-19T20:08:16.161Z" }, { url = "https://files.pythonhosted.org/packages/5a/11/23f1e31f5885ac72be52fd205981951dd2e4c87c5b1487cf82fde5bbd46c/aiohttp-3.10.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d93400c18596b7dc4794d48a63fb361b01a0d8eb39f28800dc900c8fbdaca91", size = 1213401, upload-time = "2024-08-19T20:08:17.977Z" }, { url = "https://files.pythonhosted.org/packages/3f/e7/6e69a0b0d896fbaf1192d492db4c21688e6c0d327486da610b0e8195bcc9/aiohttp-3.10.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d00f3c5e0d764a5c9aa5a62d99728c56d455310bcc288a79cab10157b3af426f", size = 1212450, upload-time = "2024-08-19T20:08:19.519Z" }, { url = "https://files.pythonhosted.org/packages/a9/7f/a42f51074c723ea848254946aec118f1e59914a639dc8ba20b0c9247c195/aiohttp-3.10.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d742c36ed44f2798c8d3f4bc511f479b9ceef2b93f348671184139e7d708042c", size = 1211324, upload-time = "2024-08-19T20:08:21.465Z" }, { url = "https://files.pythonhosted.org/packages/d5/43/c2f9d2f588ccef8f028f0a0c999b5ceafecbda50b943313faee7e91f3e03/aiohttp-3.10.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:814375093edae5f1cb31e3407997cf3eacefb9010f96df10d64829362ae2df69", size = 1266838, upload-time = "2024-08-19T20:08:23.513Z" }, { url = "https://files.pythonhosted.org/packages/c1/a7/ff9f067ecb06896d859e4f2661667aee4bd9c616689599ff034b63cbd9d7/aiohttp-3.10.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8224f98be68a84b19f48e0bdc14224b5a71339aff3a27df69989fa47d01296f3", size = 1285301, upload-time = "2024-08-19T20:08:25.074Z" }, { url = "https://files.pythonhosted.org/packages/9a/e3/dd56bb4c67d216046ce61d98dec0f3023043f1de48f561df1bf93dd47aea/aiohttp-3.10.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d9a487ef090aea982d748b1b0d74fe7c3950b109df967630a20584f9a99c0683", size = 1235806, upload-time = "2024-08-19T20:08:26.712Z" }, { url = "https://files.pythonhosted.org/packages/a7/64/90dcd42ac21927a49ba4140b2e4d50e1847379427ef6c43eb338ef9960e3/aiohttp-3.10.5-cp310-cp310-win32.whl", hash = "sha256:d9ef084e3dc690ad50137cc05831c52b6ca428096e6deb3c43e95827f531d5ef", size = 360162, upload-time = "2024-08-19T20:08:28.372Z" }, { url = "https://files.pythonhosted.org/packages/f3/45/145d8b4853fc92c0c8509277642767e7726a085e390ce04353dc68b0f5b5/aiohttp-3.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:66bf9234e08fe561dccd62083bf67400bdbf1c67ba9efdc3dac03650e97c6088", size = 379173, upload-time = "2024-08-19T20:08:29.883Z" }, { url = "https://files.pythonhosted.org/packages/f1/90/54ccb1e4eadfb6c95deff695582453f6208584431d69bf572782e9ae542b/aiohttp-3.10.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8c6a4e5e40156d72a40241a25cc226051c0a8d816610097a8e8f517aeacd59a2", size = 586455, upload-time = "2024-08-19T20:08:31.409Z" }, { url = "https://files.pythonhosted.org/packages/c3/7a/95e88c02756e7e718f054e1bb3ec6ad5d0ee4a2ca2bb1768c5844b3de30a/aiohttp-3.10.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c634a3207a5445be65536d38c13791904fda0748b9eabf908d3fe86a52941cf", size = 397255, upload-time = "2024-08-19T20:08:32.659Z" }, { url = "https://files.pythonhosted.org/packages/07/4f/767387b39990e1ee9aba8ce642abcc286d84d06e068dc167dab983898f18/aiohttp-3.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4aff049b5e629ef9b3e9e617fa6e2dfeda1bf87e01bcfecaf3949af9e210105e", size = 388973, upload-time = "2024-08-19T20:08:33.9Z" }, { url = "https://files.pythonhosted.org/packages/61/46/0df41170a4d228c07b661b1ba9d87101d99a79339dc93b8b1183d8b20545/aiohttp-3.10.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1942244f00baaacaa8155eca94dbd9e8cc7017deb69b75ef67c78e89fdad3c77", size = 1326126, upload-time = "2024-08-19T20:08:35.606Z" }, { url = "https://files.pythonhosted.org/packages/af/20/da0d65e07ce49d79173fed41598f487a0a722e87cfbaa8bb7e078a7c1d39/aiohttp-3.10.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e04a1f2a65ad2f93aa20f9ff9f1b672bf912413e5547f60749fa2ef8a644e061", size = 1364538, upload-time = "2024-08-19T20:08:37.754Z" }, { url = "https://files.pythonhosted.org/packages/aa/20/b59728405114e57541ba9d5b96033e69d004e811ded299537f74237629ca/aiohttp-3.10.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f2bfc0032a00405d4af2ba27f3c429e851d04fad1e5ceee4080a1c570476697", size = 1399896, upload-time = "2024-08-19T20:08:39.635Z" }, { url = "https://files.pythonhosted.org/packages/2a/92/006690c31b830acbae09d2618e41308fe4c81c0679b3b33a3af859e0b7bf/aiohttp-3.10.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:424ae21498790e12eb759040bbb504e5e280cab64693d14775c54269fd1d2bb7", size = 1312914, upload-time = "2024-08-19T20:08:41.417Z" }, { url = "https://files.pythonhosted.org/packages/d4/71/1a253ca215b6c867adbd503f1e142117527ea8775e65962bc09b2fad1d2c/aiohttp-3.10.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:975218eee0e6d24eb336d0328c768ebc5d617609affaca5dbbd6dd1984f16ed0", size = 1271301, upload-time = "2024-08-19T20:08:43.39Z" }, { url = "https://files.pythonhosted.org/packages/0a/ab/5d1d9ff9ce6cce8fa54774d0364e64a0f3cd50e512ff09082ced8e5217a1/aiohttp-3.10.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4120d7fefa1e2d8fb6f650b11489710091788de554e2b6f8347c7a20ceb003f5", size = 1291652, upload-time = "2024-08-19T20:08:45.335Z" }, { url = "https://files.pythonhosted.org/packages/75/5f/f90510ea954b9ae6e7a53d2995b97a3e5c181110fdcf469bc9238445871d/aiohttp-3.10.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b90078989ef3fc45cf9221d3859acd1108af7560c52397ff4ace8ad7052a132e", size = 1286289, upload-time = "2024-08-19T20:08:47.546Z" }, { url = "https://files.pythonhosted.org/packages/be/9e/1f523414237798660921817c82b9225a363af436458caf584d2fa6a2eb4a/aiohttp-3.10.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ba5a8b74c2a8af7d862399cdedce1533642fa727def0b8c3e3e02fcb52dca1b1", size = 1341848, upload-time = "2024-08-19T20:08:49.698Z" }, { url = "https://files.pythonhosted.org/packages/f6/36/443472ddaa85d7d80321fda541d9535b23ecefe0bf5792cc3955ea635190/aiohttp-3.10.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:02594361128f780eecc2a29939d9dfc870e17b45178a867bf61a11b2a4367277", size = 1361619, upload-time = "2024-08-19T20:08:51.942Z" }, { url = "https://files.pythonhosted.org/packages/19/f6/3ecbac0bc4359c7d7ba9e85c6b10f57e20edaf1f97751ad2f892db231ad0/aiohttp-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8fb4fc029e135859f533025bc82047334e24b0d489e75513144f25408ecaf058", size = 1320869, upload-time = "2024-08-19T20:08:53.708Z" }, { url = "https://files.pythonhosted.org/packages/34/7e/ed74ffb36e3a0cdec1b05d8fbaa29cb532371d5a20058b3a8052fc90fe7c/aiohttp-3.10.5-cp311-cp311-win32.whl", hash = "sha256:e1ca1ef5ba129718a8fc827b0867f6aa4e893c56eb00003b7367f8a733a9b072", size = 359271, upload-time = "2024-08-19T20:08:55.186Z" }, { url = "https://files.pythonhosted.org/packages/98/1b/718901f04bc8c886a742be9e83babb7b93facabf7c475cc95e2b3ab80b4d/aiohttp-3.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:349ef8a73a7c5665cca65c88ab24abe75447e28aa3bc4c93ea5093474dfdf0ff", size = 379143, upload-time = "2024-08-19T20:08:56.604Z" }, { url = "https://files.pythonhosted.org/packages/d9/1c/74f9dad4a2fc4107e73456896283d915937f48177b99867b63381fadac6e/aiohttp-3.10.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:305be5ff2081fa1d283a76113b8df7a14c10d75602a38d9f012935df20731487", size = 583468, upload-time = "2024-08-19T20:08:58.17Z" }, { url = "https://files.pythonhosted.org/packages/12/29/68d090551f2b58ce76c2b436ced8dd2dfd32115d41299bf0b0c308a5483c/aiohttp-3.10.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3a1c32a19ee6bbde02f1cb189e13a71b321256cc1d431196a9f824050b160d5a", size = 394066, upload-time = "2024-08-19T20:08:59.569Z" }, { url = "https://files.pythonhosted.org/packages/8f/f7/971f88b4cdcaaa4622925ba7d86de47b48ec02a9040a143514b382f78da4/aiohttp-3.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:61645818edd40cc6f455b851277a21bf420ce347baa0b86eaa41d51ef58ba23d", size = 389098, upload-time = "2024-08-19T20:09:00.965Z" }, { url = "https://files.pythonhosted.org/packages/f1/5a/fe3742efdce551667b2ddf1158b27c5b8eb1edc13d5e14e996e52e301025/aiohttp-3.10.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c225286f2b13bab5987425558baa5cbdb2bc925b2998038fa028245ef421e75", size = 1332742, upload-time = "2024-08-19T20:09:02.29Z" }, { url = "https://files.pythonhosted.org/packages/1a/52/a25c0334a1845eb4967dff279151b67ca32a948145a5812ed660ed900868/aiohttp-3.10.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ba01ebc6175e1e6b7275c907a3a36be48a2d487549b656aa90c8a910d9f3178", size = 1372134, upload-time = "2024-08-19T20:09:03.829Z" }, { url = "https://files.pythonhosted.org/packages/96/3d/33c1d8efc2d8ec36bff9a8eca2df9fdf8a45269c6e24a88e74f2aa4f16bd/aiohttp-3.10.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8eaf44ccbc4e35762683078b72bf293f476561d8b68ec8a64f98cf32811c323e", size = 1414413, upload-time = "2024-08-19T20:09:05.74Z" }, { url = "https://files.pythonhosted.org/packages/64/74/0f1ddaa5f0caba1d946f0dd0c31f5744116e4a029beec454ec3726d3311f/aiohttp-3.10.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1c43eb1ab7cbf411b8e387dc169acb31f0ca0d8c09ba63f9eac67829585b44f", size = 1328107, upload-time = "2024-08-19T20:09:07.476Z" }, { url = "https://files.pythonhosted.org/packages/0a/32/c10118f0ad50e4093227234f71fd0abec6982c29367f65f32ee74ed652c4/aiohttp-3.10.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de7a5299827253023c55ea549444e058c0eb496931fa05d693b95140a947cb73", size = 1280126, upload-time = "2024-08-19T20:09:09.061Z" }, { url = "https://files.pythonhosted.org/packages/c6/c9/77e3d648d97c03a42acfe843d03e97be3c5ef1b4d9de52e5bd2d28eed8e7/aiohttp-3.10.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4790f0e15f00058f7599dab2b206d3049d7ac464dc2e5eae0e93fa18aee9e7bf", size = 1292660, upload-time = "2024-08-19T20:09:10.853Z" }, { url = "https://files.pythonhosted.org/packages/7e/5d/99c71f8e5c8b64295be421b4c42d472766b263a1fe32e91b64bf77005bf2/aiohttp-3.10.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:44b324a6b8376a23e6ba25d368726ee3bc281e6ab306db80b5819999c737d820", size = 1300988, upload-time = "2024-08-19T20:09:12.341Z" }, { url = "https://files.pythonhosted.org/packages/8f/2c/76d2377dd947f52fbe8afb19b18a3b816d66c7966755c04030f93b1f7b2d/aiohttp-3.10.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0d277cfb304118079e7044aad0b76685d30ecb86f83a0711fc5fb257ffe832ca", size = 1339268, upload-time = "2024-08-19T20:09:14.198Z" }, { url = "https://files.pythonhosted.org/packages/fd/e6/3d9d935cc705d57ed524d82ec5d6b678a53ac1552720ae41282caa273584/aiohttp-3.10.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:54d9ddea424cd19d3ff6128601a4a4d23d54a421f9b4c0fff740505813739a91", size = 1366993, upload-time = "2024-08-19T20:09:15.725Z" }, { url = "https://files.pythonhosted.org/packages/fe/c2/f7eed4d602f3f224600d03ab2e1a7734999b0901b1c49b94dc5891340433/aiohttp-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4f1c9866ccf48a6df2b06823e6ae80573529f2af3a0992ec4fe75b1a510df8a6", size = 1329459, upload-time = "2024-08-19T20:09:17.556Z" }, { url = "https://files.pythonhosted.org/packages/ce/8f/27f205b76531fc592abe29e1ad265a16bf934a9f609509c02d765e6a8055/aiohttp-3.10.5-cp312-cp312-win32.whl", hash = "sha256:dc4826823121783dccc0871e3f405417ac116055bf184ac04c36f98b75aacd12", size = 356968, upload-time = "2024-08-19T20:09:19.14Z" }, { url = "https://files.pythonhosted.org/packages/39/8c/4f6c0b2b3629f6be6c81ab84d9d577590f74f01d4412bfc4067958eaa1e1/aiohttp-3.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:22c0a23a3b3138a6bf76fc553789cb1a703836da86b0f306b6f0dc1617398abc", size = 377650, upload-time = "2024-08-19T20:09:20.502Z" }, { url = "https://files.pythonhosted.org/packages/7b/b9/03b4327897a5b5d29338fa9b514f1c2f66a3e4fc88a4e40fad478739314d/aiohttp-3.10.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7f6b639c36734eaa80a6c152a238242bedcee9b953f23bb887e9102976343092", size = 576994, upload-time = "2024-08-19T20:09:22.439Z" }, { url = "https://files.pythonhosted.org/packages/67/1b/20c2e159cd07b8ed6dde71c2258233902fdf415b2fe6174bd2364ba63107/aiohttp-3.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f29930bc2921cef955ba39a3ff87d2c4398a0394ae217f41cb02d5c26c8b1b77", size = 390684, upload-time = "2024-08-19T20:09:23.844Z" }, { url = "https://files.pythonhosted.org/packages/4d/6b/ff83b34f157e370431d8081c5d1741963f4fb12f9aaddb2cacbf50305225/aiohttp-3.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f489a2c9e6455d87eabf907ac0b7d230a9786be43fbe884ad184ddf9e9c1e385", size = 386176, upload-time = "2024-08-19T20:09:25.259Z" }, { url = "https://files.pythonhosted.org/packages/4d/a1/6e92817eb657de287560962df4959b7ddd22859c4b23a0309e2d3de12538/aiohttp-3.10.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:123dd5b16b75b2962d0fff566effb7a065e33cd4538c1692fb31c3bda2bfb972", size = 1303310, upload-time = "2024-08-19T20:09:27.098Z" }, { url = "https://files.pythonhosted.org/packages/04/29/200518dc7a39c30ae6d5bc232d7207446536e93d3d9299b8e95db6e79c54/aiohttp-3.10.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b98e698dc34966e5976e10bbca6d26d6724e6bdea853c7c10162a3235aba6e16", size = 1340445, upload-time = "2024-08-19T20:09:29.228Z" }, { url = "https://files.pythonhosted.org/packages/8e/20/53f7bba841ba7b5bb5dea580fea01c65524879ba39cb917d08c845524717/aiohttp-3.10.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3b9162bab7e42f21243effc822652dc5bb5e8ff42a4eb62fe7782bcbcdfacf6", size = 1385121, upload-time = "2024-08-19T20:09:30.85Z" }, { url = "https://files.pythonhosted.org/packages/f1/b4/d99354ad614c48dd38fb1ee880a1a54bd9ab2c3bcad3013048d4a1797d3a/aiohttp-3.10.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1923a5c44061bffd5eebeef58cecf68096e35003907d8201a4d0d6f6e387ccaa", size = 1299669, upload-time = "2024-08-19T20:09:32.383Z" }, { url = "https://files.pythonhosted.org/packages/51/39/ca1de675f2a5729c71c327e52ac6344e63f036bd37281686ae5c3fb13bfb/aiohttp-3.10.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d55f011da0a843c3d3df2c2cf4e537b8070a419f891c930245f05d329c4b0689", size = 1252638, upload-time = "2024-08-19T20:09:34.287Z" }, { url = "https://files.pythonhosted.org/packages/54/cf/a3ae7ff43138422d477348e309ef8275779701bf305ff6054831ef98b782/aiohttp-3.10.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:afe16a84498441d05e9189a15900640a2d2b5e76cf4efe8cbb088ab4f112ee57", size = 1266889, upload-time = "2024-08-19T20:09:36.427Z" }, { url = "https://files.pythonhosted.org/packages/6e/7a/c6027ad70d9fb23cf254a26144de2723821dade1a624446aa22cd0b6d012/aiohttp-3.10.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8112fb501b1e0567a1251a2fd0747baae60a4ab325a871e975b7bb67e59221f", size = 1266249, upload-time = "2024-08-19T20:09:38.545Z" }, { url = "https://files.pythonhosted.org/packages/64/fd/ed136d46bc2c7e3342fed24662b4827771d55ceb5a7687847aae977bfc17/aiohttp-3.10.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1e72589da4c90337837fdfe2026ae1952c0f4a6e793adbbfbdd40efed7c63599", size = 1311036, upload-time = "2024-08-19T20:09:40.501Z" }, { url = "https://files.pythonhosted.org/packages/76/9a/43eeb0166f1119256d6f43468f900db1aed7fbe32069d2a71c82f987db4d/aiohttp-3.10.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4d46c7b4173415d8e583045fbc4daa48b40e31b19ce595b8d92cf639396c15d5", size = 1338756, upload-time = "2024-08-19T20:09:42.57Z" }, { url = "https://files.pythonhosted.org/packages/d5/bc/d01ff0810b3f5e26896f76d44225ed78b088ddd33079b85cd1a23514318b/aiohttp-3.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:33e6bc4bab477c772a541f76cd91e11ccb6d2efa2b8d7d7883591dfb523e5987", size = 1299976, upload-time = "2024-08-19T20:09:44.422Z" }, { url = "https://files.pythonhosted.org/packages/3e/c9/50a297c4f7ab57a949f4add2d3eafe5f3e68bb42f739e933f8b32a092bda/aiohttp-3.10.5-cp313-cp313-win32.whl", hash = "sha256:c58c6837a2c2a7cf3133983e64173aec11f9c2cd8e87ec2fdc16ce727bcf1a04", size = 355609, upload-time = "2024-08-19T20:09:45.95Z" }, { url = "https://files.pythonhosted.org/packages/65/28/aee9d04fb0b3b1f90622c338a08e54af5198e704a910e20947c473298fd0/aiohttp-3.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:38172a70005252b6893088c0f5e8a47d173df7cc2b2bd88650957eb84fcf5022", size = 375697, upload-time = "2024-08-19T20:09:47.63Z" }, ] [[package]] name = "aiosignal" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "frozenlist" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ae/67/0952ed97a9793b4958e5736f6d2b346b414a2cd63e82d05940032f45b32f/aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", size = 19422, upload-time = "2022-11-08T16:03:58.806Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/76/ac/a7305707cb852b7e16ff80eaf5692309bde30e2b1100a1fcacdc8f731d97/aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17", size = 7617, upload-time = "2022-11-08T16:03:57.483Z" }, ] [[package]] name = "annotated-types" version = "0.7.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, ] [[package]] name = "async-timeout" version = "4.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/87/d6/21b30a550dafea84b1b8eee21b5e23fa16d010ae006011221f33dcd8d7f8/async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", size = 8345, upload-time = "2023-08-10T16:35:56.907Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a7/fa/e01228c2938de91d47b307831c62ab9e4001e747789d0b05baf779a6488c/async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028", size = 5721, upload-time = "2023-08-10T16:35:55.203Z" }, ] [[package]] name = "attrs" version = "24.2.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/fc/0f/aafca9af9315aee06a89ffde799a10a582fe8de76c563ee80bbcdc08b3fb/attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", size = 792678, upload-time = "2024-08-06T14:37:38.364Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/6a/21/5b6702a7f963e95456c0de2d495f67bf5fd62840ac655dc451586d23d39a/attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2", size = 63001, upload-time = "2024-08-06T14:37:36.958Z" }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] name = "exceptiongroup" version = "1.2.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883, upload-time = "2024-07-12T22:26:00.161Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453, upload-time = "2024-07-12T22:25:58.476Z" }, ] [[package]] name = "frozenlist" version = "1.4.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/cf/3d/2102257e7acad73efc4a0c306ad3953f68c504c16982bbdfee3ad75d8085/frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b", size = 37820, upload-time = "2023-12-15T08:42:23.355Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7a/35/1328c7b0f780d34f8afc1d87ebdc2bb065a123b24766a0b475f0d67da637/frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac", size = 94315, upload-time = "2023-12-15T08:40:29.057Z" }, { url = "https://files.pythonhosted.org/packages/f4/d6/ca016b0adcf8327714ccef969740688808c86e0287bf3a639ff582f24e82/frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868", size = 53805, upload-time = "2023-12-15T08:40:30.96Z" }, { url = "https://files.pythonhosted.org/packages/ae/83/bcdaa437a9bd693ba658a0310f8cdccff26bd78e45fccf8e49897904a5cd/frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776", size = 52163, upload-time = "2023-12-15T08:40:32.089Z" }, { url = "https://files.pythonhosted.org/packages/d4/e9/759043ab7d169b74fe05ebfbfa9ee5c881c303ebc838e308346204309cd0/frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a", size = 238595, upload-time = "2023-12-15T08:40:33.625Z" }, { url = "https://files.pythonhosted.org/packages/f8/ce/b9de7dc61e753dc318cf0de862181b484178210c5361eae6eaf06792264d/frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad", size = 262428, upload-time = "2023-12-15T08:40:34.922Z" }, { url = "https://files.pythonhosted.org/packages/36/ce/dc6f29e0352fa34ebe45421960c8e7352ca63b31630a576e8ffb381e9c08/frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c", size = 258867, upload-time = "2023-12-15T08:40:36.784Z" }, { url = "https://files.pythonhosted.org/packages/51/47/159ac53faf8a11ae5ee8bb9db10327575557504e549cfd76f447b969aa91/frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe", size = 229412, upload-time = "2023-12-15T08:40:38.051Z" }, { url = "https://files.pythonhosted.org/packages/ec/25/0c87df2e53c0c5d90f7517ca0ff7aca78d050a8ec4d32c4278e8c0e52e51/frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a", size = 239539, upload-time = "2023-12-15T08:40:39.896Z" }, { url = "https://files.pythonhosted.org/packages/97/94/a1305fa4716726ae0abf3b1069c2d922fcfd442538cb850f1be543f58766/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98", size = 253379, upload-time = "2023-12-15T08:40:41.78Z" }, { url = "https://files.pythonhosted.org/packages/53/82/274e19f122e124aee6d113188615f63b0736b4242a875f482a81f91e07e2/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75", size = 245901, upload-time = "2023-12-15T08:40:43.72Z" }, { url = "https://files.pythonhosted.org/packages/b8/28/899931015b8cffbe155392fe9ca663f981a17e1adc69589ee0e1e7cdc9a2/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5", size = 263797, upload-time = "2023-12-15T08:40:45.355Z" }, { url = "https://files.pythonhosted.org/packages/6e/4f/b8a5a2f10c4a58c52a52a40cf6cf1ffcdbf3a3b64f276f41dab989bf3ab5/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950", size = 264415, upload-time = "2023-12-15T08:40:47.29Z" }, { url = "https://files.pythonhosted.org/packages/b0/2c/7be3bdc59dbae444864dbd9cde82790314390ec54636baf6b9ce212627ad/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc", size = 253964, upload-time = "2023-12-15T08:40:49.113Z" }, { url = "https://files.pythonhosted.org/packages/2e/ec/4fb5a88f6b9a352aed45ab824dd7ce4801b7bcd379adcb927c17a8f0a1a8/frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1", size = 44559, upload-time = "2023-12-15T08:40:50.319Z" }, { url = "https://files.pythonhosted.org/packages/61/15/2b5d644d81282f00b61e54f7b00a96f9c40224107282efe4cd9d2bf1433a/frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439", size = 50434, upload-time = "2023-12-15T08:40:51.411Z" }, { url = "https://files.pythonhosted.org/packages/01/bc/8d33f2d84b9368da83e69e42720cff01c5e199b5a868ba4486189a4d8fa9/frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0", size = 97060, upload-time = "2023-12-15T08:40:52.481Z" }, { url = "https://files.pythonhosted.org/packages/af/b2/904500d6a162b98a70e510e743e7ea992241b4f9add2c8063bf666ca21df/frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49", size = 55347, upload-time = "2023-12-15T08:40:54.163Z" }, { url = "https://files.pythonhosted.org/packages/5b/9c/f12b69997d3891ddc0d7895999a00b0c6a67f66f79498c0e30f27876435d/frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced", size = 53374, upload-time = "2023-12-15T08:40:55.966Z" }, { url = "https://files.pythonhosted.org/packages/ac/6e/e0322317b7c600ba21dec224498c0c5959b2bce3865277a7c0badae340a9/frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0", size = 273288, upload-time = "2023-12-15T08:40:57.59Z" }, { url = "https://files.pythonhosted.org/packages/a7/76/180ee1b021568dad5b35b7678616c24519af130ed3fa1e0f1ed4014e0f93/frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106", size = 284737, upload-time = "2023-12-15T08:40:59.022Z" }, { url = "https://files.pythonhosted.org/packages/05/08/40159d706a6ed983c8aca51922a93fc69f3c27909e82c537dd4054032674/frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068", size = 280267, upload-time = "2023-12-15T08:41:00.73Z" }, { url = "https://files.pythonhosted.org/packages/e0/18/9f09f84934c2b2aa37d539a322267939770362d5495f37783440ca9c1b74/frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2", size = 258778, upload-time = "2023-12-15T08:41:01.994Z" }, { url = "https://files.pythonhosted.org/packages/b3/c9/0bc5ee7e1f5cc7358ab67da0b7dfe60fbd05c254cea5c6108e7d1ae28c63/frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19", size = 272276, upload-time = "2023-12-15T08:41:03.329Z" }, { url = "https://files.pythonhosted.org/packages/12/5d/147556b73a53ad4df6da8bbb50715a66ac75c491fdedac3eca8b0b915345/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82", size = 272424, upload-time = "2023-12-15T08:41:05.188Z" }, { url = "https://files.pythonhosted.org/packages/83/61/2087bbf24070b66090c0af922685f1d0596c24bb3f3b5223625bdeaf03ca/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec", size = 260881, upload-time = "2023-12-15T08:41:07.056Z" }, { url = "https://files.pythonhosted.org/packages/a8/be/a235bc937dd803258a370fe21b5aa2dd3e7bfe0287a186a4bec30c6cccd6/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a", size = 282327, upload-time = "2023-12-15T08:41:08.316Z" }, { url = "https://files.pythonhosted.org/packages/5d/e7/b2469e71f082948066b9382c7b908c22552cc705b960363c390d2e23f587/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74", size = 281502, upload-time = "2023-12-15T08:41:09.686Z" }, { url = "https://files.pythonhosted.org/packages/db/1b/6a5b970e55dffc1a7d0bb54f57b184b2a2a2ad0b7bca16a97ca26d73c5b5/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2", size = 272292, upload-time = "2023-12-15T08:41:11.867Z" }, { url = "https://files.pythonhosted.org/packages/1a/05/ebad68130e6b6eb9b287dacad08ea357c33849c74550c015b355b75cc714/frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17", size = 44446, upload-time = "2023-12-15T08:41:13.148Z" }, { url = "https://files.pythonhosted.org/packages/b3/21/c5aaffac47fd305d69df46cfbf118768cdf049a92ee6b0b5cb029d449dcf/frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825", size = 50459, upload-time = "2023-12-15T08:41:14.288Z" }, { url = "https://files.pythonhosted.org/packages/b4/db/4cf37556a735bcdb2582f2c3fa286aefde2322f92d3141e087b8aeb27177/frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae", size = 93937, upload-time = "2023-12-15T08:41:16.085Z" }, { url = "https://files.pythonhosted.org/packages/46/03/69eb64642ca8c05f30aa5931d6c55e50b43d0cd13256fdd01510a1f85221/frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb", size = 53656, upload-time = "2023-12-15T08:41:17.442Z" }, { url = "https://files.pythonhosted.org/packages/3f/ab/c543c13824a615955f57e082c8a5ee122d2d5368e80084f2834e6f4feced/frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b", size = 51868, upload-time = "2023-12-15T08:41:19.371Z" }, { url = "https://files.pythonhosted.org/packages/a9/b8/438cfd92be2a124da8259b13409224d9b19ef8f5a5b2507174fc7e7ea18f/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86", size = 280652, upload-time = "2023-12-15T08:41:20.602Z" }, { url = "https://files.pythonhosted.org/packages/54/72/716a955521b97a25d48315c6c3653f981041ce7a17ff79f701298195bca3/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480", size = 286739, upload-time = "2023-12-15T08:41:21.991Z" }, { url = "https://files.pythonhosted.org/packages/65/d8/934c08103637567084568e4d5b4219c1016c60b4d29353b1a5b3587827d6/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09", size = 289447, upload-time = "2023-12-15T08:41:23.307Z" }, { url = "https://files.pythonhosted.org/packages/70/bb/d3b98d83ec6ef88f9bd63d77104a305d68a146fd63a683569ea44c3085f6/frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a", size = 265466, upload-time = "2023-12-15T08:41:24.785Z" }, { url = "https://files.pythonhosted.org/packages/0b/f2/b8158a0f06faefec33f4dff6345a575c18095a44e52d4f10c678c137d0e0/frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd", size = 281530, upload-time = "2023-12-15T08:41:26.113Z" }, { url = "https://files.pythonhosted.org/packages/ea/a2/20882c251e61be653764038ece62029bfb34bd5b842724fff32a5b7a2894/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6", size = 281295, upload-time = "2023-12-15T08:41:27.623Z" }, { url = "https://files.pythonhosted.org/packages/4c/f9/8894c05dc927af2a09663bdf31914d4fb5501653f240a5bbaf1e88cab1d3/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1", size = 268054, upload-time = "2023-12-15T08:41:28.912Z" }, { url = "https://files.pythonhosted.org/packages/37/ff/a613e58452b60166507d731812f3be253eb1229808e59980f0405d1eafbf/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b", size = 286904, upload-time = "2023-12-15T08:41:30.309Z" }, { url = "https://files.pythonhosted.org/packages/cc/6e/0091d785187f4c2020d5245796d04213f2261ad097e0c1cf35c44317d517/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e", size = 290754, upload-time = "2023-12-15T08:41:31.587Z" }, { url = "https://files.pythonhosted.org/packages/a5/c2/e42ad54bae8bcffee22d1e12a8ee6c7717f7d5b5019261a8c861854f4776/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8", size = 282602, upload-time = "2023-12-15T08:41:32.902Z" }, { url = "https://files.pythonhosted.org/packages/b6/61/56bad8cb94f0357c4bc134acc30822e90e203b5cb8ff82179947de90c17f/frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89", size = 44063, upload-time = "2023-12-15T08:41:34.599Z" }, { url = "https://files.pythonhosted.org/packages/3e/dc/96647994a013bc72f3d453abab18340b7f5e222b7b7291e3697ca1fcfbd5/frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5", size = 50452, upload-time = "2023-12-15T08:41:36.278Z" }, { url = "https://files.pythonhosted.org/packages/83/10/466fe96dae1bff622021ee687f68e5524d6392b0a2f80d05001cd3a451ba/frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7", size = 11552, upload-time = "2023-12-15T08:42:22.294Z" }, ] [[package]] name = "idna" version = "3.8" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e8/ac/e349c5e6d4543326c6883ee9491e3921e0d07b55fdf3cce184b40d63e72a/idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603", size = 189467, upload-time = "2024-08-23T16:01:51.339Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/22/7e/d71db821f177828df9dea8c42ac46473366f191be53080e552e628aad991/idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac", size = 66894, upload-time = "2024-08-23T16:01:49.963Z" }, ] [[package]] name = "iniconfig" version = "2.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646, upload-time = "2023-01-07T11:08:11.254Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892, upload-time = "2023-01-07T11:08:09.864Z" }, ] [[package]] name = "multidict" version = "6.0.5" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f9/79/722ca999a3a09a63b35aac12ec27dfa8e5bb3a38b0f857f7a1a209a88836/multidict-6.0.5.tar.gz", hash = "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da", size = 59867, upload-time = "2024-02-01T20:46:01.455Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b7/36/48097b96135017ed1b806c5ea27b6cdc2ed3a6861c5372b793563206c586/multidict-6.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9", size = 50955, upload-time = "2024-02-01T20:43:20.237Z" }, { url = "https://files.pythonhosted.org/packages/d9/48/037440edb5d4a1c65e002925b2f24071d6c27754e6f4734f63037e3169d6/multidict-6.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604", size = 30361, upload-time = "2024-02-01T20:43:22.428Z" }, { url = "https://files.pythonhosted.org/packages/a4/eb/d8e7693c9064554a1585698d1902839440c6c695b0f53c9a8be5d9d4a3b8/multidict-6.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600", size = 30508, upload-time = "2024-02-01T20:43:24.451Z" }, { url = "https://files.pythonhosted.org/packages/f3/7d/fe7648d4b2f200f8854066ce6e56bf51889abfaf859814c62160dd0e32a9/multidict-6.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c", size = 126318, upload-time = "2024-02-01T20:43:26.251Z" }, { url = "https://files.pythonhosted.org/packages/8d/ea/0230b6faa9a5bc10650fd50afcc4a86e6c37af2fe05bc679b74d79253732/multidict-6.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5", size = 133998, upload-time = "2024-02-01T20:43:27.694Z" }, { url = "https://files.pythonhosted.org/packages/36/6d/d2f982fb485175727a193b4900b5f929d461e7aa87d6fb5a91a377fcc9c0/multidict-6.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f", size = 129150, upload-time = "2024-02-01T20:43:29.33Z" }, { url = "https://files.pythonhosted.org/packages/33/62/2c9085e571318d51212a6914566fe41dd0e33d7f268f7e2f23dcd3f06c56/multidict-6.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae", size = 124266, upload-time = "2024-02-01T20:43:31.331Z" }, { url = "https://files.pythonhosted.org/packages/ce/e2/88cdfeaf03eab3498f688a19b62ca704d371cd904cb74b682541ca7b20a7/multidict-6.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182", size = 116637, upload-time = "2024-02-01T20:43:32.831Z" }, { url = "https://files.pythonhosted.org/packages/12/4d/99dfc36872dcc53956879f5da80a6505bbd29214cce90ce792a86e15fddf/multidict-6.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf", size = 155908, upload-time = "2024-02-01T20:43:34.275Z" }, { url = "https://files.pythonhosted.org/packages/c2/5c/1e76b2c742cb9e0248d1e8c4ed420817879230c833fa27d890b5fd22290b/multidict-6.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442", size = 147111, upload-time = "2024-02-01T20:43:36.501Z" }, { url = "https://files.pythonhosted.org/packages/bc/84/9579004267e1cc5968ef2ef8718dab9d8950d99354d85b739dd67b09c273/multidict-6.0.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a", size = 160502, upload-time = "2024-02-01T20:43:38.761Z" }, { url = "https://files.pythonhosted.org/packages/11/b7/bef33e84e3722bc42531af020d7ae8c31235ce8846bacaa852b6484cf868/multidict-6.0.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef", size = 156587, upload-time = "2024-02-01T20:43:40.345Z" }, { url = "https://files.pythonhosted.org/packages/26/ce/f745a2d6104e56f7fa0d7d0756bb9ed27b771dd7b8d9d7348cd7f0f7b9de/multidict-6.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc", size = 151948, upload-time = "2024-02-01T20:43:42.309Z" }, { url = "https://files.pythonhosted.org/packages/f1/50/714da64281d2b2b3b4068e84f115e1ef3bd3ed3715b39503ff3c59e8d30d/multidict-6.0.5-cp310-cp310-win32.whl", hash = "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319", size = 25734, upload-time = "2024-02-01T20:43:43.796Z" }, { url = "https://files.pythonhosted.org/packages/ef/3d/ba0dc18e96c5d83731c54129819d5892389e180f54ebb045c6124b2e8b87/multidict-6.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8", size = 28182, upload-time = "2024-02-01T20:43:45.478Z" }, { url = "https://files.pythonhosted.org/packages/5f/da/b10ea65b850b54f44a6479177c6987f456bc2d38f8dc73009b78afcf0ede/multidict-6.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba", size = 50815, upload-time = "2024-02-01T20:43:46.755Z" }, { url = "https://files.pythonhosted.org/packages/21/db/3403263f158b0bc7b0d4653766d71cb39498973f2042eead27b2e9758782/multidict-6.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e", size = 30269, upload-time = "2024-02-01T20:43:48.39Z" }, { url = "https://files.pythonhosted.org/packages/02/c1/b15ecceb6ffa5081ed2ed450aea58d65b0e0358001f2b426705f9f41f4c2/multidict-6.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd", size = 30500, upload-time = "2024-02-01T20:43:49.671Z" }, { url = "https://files.pythonhosted.org/packages/3f/e1/7fdd0f39565df3af87d6c2903fb66a7d529fbd0a8a066045d7a5b6ad1145/multidict-6.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3", size = 130751, upload-time = "2024-02-01T20:43:51.238Z" }, { url = "https://files.pythonhosted.org/packages/76/bc/9f593f9e38c6c09bbf0344b56ad67dd53c69167937c2edadee9719a5e17d/multidict-6.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf", size = 138185, upload-time = "2024-02-01T20:43:52.78Z" }, { url = "https://files.pythonhosted.org/packages/28/32/d7799a208701d537b92705f46c777ded812a6dc139c18d8ed599908f6b1c/multidict-6.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29", size = 133585, upload-time = "2024-02-01T20:43:55.089Z" }, { url = "https://files.pythonhosted.org/packages/52/ec/be54a3ad110f386d5bd7a9a42a4ff36b3cd723ebe597f41073a73ffa16b8/multidict-6.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed", size = 128684, upload-time = "2024-02-01T20:43:57.078Z" }, { url = "https://files.pythonhosted.org/packages/36/e1/a680eabeb71e25d4733276d917658dfa1cd3a99b1223625dbc247d266c98/multidict-6.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733", size = 120994, upload-time = "2024-02-01T20:43:58.481Z" }, { url = "https://files.pythonhosted.org/packages/ef/08/08f4f44a8a43ea4cee13aa9cdbbf4a639af8db49310a0637ca389c4cf817/multidict-6.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f", size = 159689, upload-time = "2024-02-01T20:43:59.979Z" }, { url = "https://files.pythonhosted.org/packages/aa/a9/46cdb4cb40bbd4b732169413f56b04a6553460b22bd914f9729c9ba63761/multidict-6.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4", size = 150611, upload-time = "2024-02-01T20:44:02.214Z" }, { url = "https://files.pythonhosted.org/packages/e9/32/35668bb3e6ab2f12f4e4f7f4000f72f714882a94f904d4c3633fbd036753/multidict-6.0.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1", size = 164444, upload-time = "2024-02-01T20:44:03.752Z" }, { url = "https://files.pythonhosted.org/packages/fa/10/f1388a91552af732d8ec48dab928abc209e732767e9e8f92d24c3544353c/multidict-6.0.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc", size = 160158, upload-time = "2024-02-01T20:44:05.288Z" }, { url = "https://files.pythonhosted.org/packages/14/c3/f602601f1819983e018156e728e57b3f19726cb424b543667faab82f6939/multidict-6.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e", size = 156072, upload-time = "2024-02-01T20:44:07.073Z" }, { url = "https://files.pythonhosted.org/packages/82/a6/0290af8487326108c0d03d14f8a0b8b1001d71e4494df5f96ab0c88c0b88/multidict-6.0.5-cp311-cp311-win32.whl", hash = "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c", size = 25731, upload-time = "2024-02-01T20:44:09.12Z" }, { url = "https://files.pythonhosted.org/packages/88/aa/ea217cb18325aa05cb3e3111c19715f1e97c50a4a900cbc20e54648de5f5/multidict-6.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea", size = 28176, upload-time = "2024-02-01T20:44:10.595Z" }, { url = "https://files.pythonhosted.org/packages/90/9c/7fda9c0defa09538c97b1f195394be82a1f53238536f70b32eb5399dfd4e/multidict-6.0.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e", size = 49575, upload-time = "2024-02-01T20:44:11.928Z" }, { url = "https://files.pythonhosted.org/packages/be/21/d6ca80dd1b9b2c5605ff7475699a8ff5dc6ea958cd71fb2ff234afc13d79/multidict-6.0.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b", size = 29638, upload-time = "2024-02-01T20:44:14.173Z" }, { url = "https://files.pythonhosted.org/packages/9c/18/9565f32c19d186168731e859692dfbc0e98f66a1dcf9e14d69c02a78b75a/multidict-6.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5", size = 29874, upload-time = "2024-02-01T20:44:15.768Z" }, { url = "https://files.pythonhosted.org/packages/4e/4e/3815190e73e6ef101b5681c174c541bf972a1b064e926e56eea78d06e858/multidict-6.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450", size = 129914, upload-time = "2024-02-01T20:44:17.303Z" }, { url = "https://files.pythonhosted.org/packages/0c/08/bb47f886457e2259aefc10044e45c8a1b62f0c27228557e17775869d0341/multidict-6.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496", size = 134589, upload-time = "2024-02-01T20:44:18.95Z" }, { url = "https://files.pythonhosted.org/packages/d5/2f/952f79b5f0795cf4e34852fc5cf4dfda6166f63c06c798361215b69c131d/multidict-6.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a", size = 133259, upload-time = "2024-02-01T20:44:20.603Z" }, { url = "https://files.pythonhosted.org/packages/24/1f/af976383b0b772dd351210af5b60ff9927e3abb2f4a103e93da19a957da0/multidict-6.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226", size = 130779, upload-time = "2024-02-01T20:44:22.2Z" }, { url = "https://files.pythonhosted.org/packages/fc/b1/b0a7744be00b0f5045c7ed4e4a6b8ee6bde4672b2c620474712299df5979/multidict-6.0.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271", size = 120125, upload-time = "2024-02-01T20:44:23.803Z" }, { url = "https://files.pythonhosted.org/packages/d0/bf/2a1d667acf11231cdf0b97a6cd9f30e7a5cf847037b5cf6da44884284bd0/multidict-6.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb", size = 167095, upload-time = "2024-02-01T20:44:25.679Z" }, { url = "https://files.pythonhosted.org/packages/5e/e8/ad6ee74b1a2050d3bc78f566dabcc14c8bf89cbe87eecec866c011479815/multidict-6.0.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef", size = 155823, upload-time = "2024-02-01T20:44:27.148Z" }, { url = "https://files.pythonhosted.org/packages/45/7c/06926bb91752c52abca3edbfefac1ea90d9d1bc00c84d0658c137589b920/multidict-6.0.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24", size = 170233, upload-time = "2024-02-01T20:44:28.663Z" }, { url = "https://files.pythonhosted.org/packages/3c/29/3dd36cf6b9c5abba8b97bba84eb499a168ba59c3faec8829327b3887d123/multidict-6.0.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6", size = 169035, upload-time = "2024-02-01T20:44:30.738Z" }, { url = "https://files.pythonhosted.org/packages/60/47/9a0f43470c70bbf6e148311f78ef5a3d4996b0226b6d295bdd50fdcfe387/multidict-6.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda", size = 166229, upload-time = "2024-02-01T20:44:32.222Z" }, { url = "https://files.pythonhosted.org/packages/1d/23/c1b7ae7a0b8a3e08225284ef3ecbcf014b292a3ee821bc4ed2185fd4ce7d/multidict-6.0.5-cp312-cp312-win32.whl", hash = "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5", size = 25840, upload-time = "2024-02-01T20:44:35.583Z" }, { url = "https://files.pythonhosted.org/packages/4a/68/66fceb758ad7a88993940dbdf3ac59911ba9dc46d7798bf6c8652f89f853/multidict-6.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556", size = 27905, upload-time = "2024-02-01T20:44:36.883Z" }, { url = "https://files.pythonhosted.org/packages/fa/a2/17e1e23c6be0a916219c5292f509360c345b5fa6beeb50d743203c27532c/multidict-6.0.5-py3-none-any.whl", hash = "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7", size = 9729, upload-time = "2024-02-01T20:45:59.309Z" }, ] [[package]] name = "packaging" version = "24.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/51/65/50db4dda066951078f0a96cf12f4b9ada6e4b811516bf0262c0f4f7064d4/packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", size = 148788, upload-time = "2024-06-09T23:19:24.956Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985, upload-time = "2024-06-09T23:19:21.909Z" }, ] [[package]] name = "pluggy" version = "1.5.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload-time = "2024-04-20T21:34:42.531Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload-time = "2024-04-20T21:34:40.434Z" }, ] [[package]] name = "pydantic" version = "2.8.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, { name = "pydantic-core" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/8c/99/d0a5dca411e0a017762258013ba9905cd6e7baa9a3fd1fe8b6529472902e/pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a", size = 739834, upload-time = "2024-07-04T02:59:49.416Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/1f/fa/b7f815b8c9ad021c07f88875b601222ef5e70619391ade4a49234d12d278/pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8", size = 423875, upload-time = "2024-07-04T02:59:45.33Z" }, ] [[package]] name = "pydantic-core" version = "2.20.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/12/e3/0d5ad91211dba310f7ded335f4dad871172b9cc9ce204f5a56d76ccd6247/pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4", size = 388371, upload-time = "2024-07-03T17:04:13.963Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/6b/9d/f30f080f745682e762512f3eef1f6e392c7d74a102e6e96de8a013a5db84/pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3", size = 1837257, upload-time = "2024-07-03T17:00:00.937Z" }, { url = "https://files.pythonhosted.org/packages/f2/89/77e7aebdd4a235497ac1e07f0a99e9f40e47f6e0f6783fe30500df08fc42/pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6", size = 1776715, upload-time = "2024-07-03T17:00:12.346Z" }, { url = "https://files.pythonhosted.org/packages/18/50/5a4e9120b395108c2a0441a425356c0d26a655d7c617288bec1c28b854ac/pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a", size = 1789023, upload-time = "2024-07-03T17:00:15.542Z" }, { url = "https://files.pythonhosted.org/packages/c7/e5/f19e13ba86b968d024b56aa53f40b24828652ac026e5addd0ae49eeada02/pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3", size = 1775598, upload-time = "2024-07-03T17:00:18.332Z" }, { url = "https://files.pythonhosted.org/packages/c9/c7/f3c29bed28bd022c783baba5bf9946c4f694cb837a687e62f453c81eb5c6/pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1", size = 1977691, upload-time = "2024-07-03T17:00:21.723Z" }, { url = "https://files.pythonhosted.org/packages/41/3e/f62c2a05c554fff34570f6788617e9670c83ed7bc07d62a55cccd1bc0be6/pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953", size = 2693214, upload-time = "2024-07-03T17:00:25.34Z" }, { url = "https://files.pythonhosted.org/packages/ae/49/8a6fe79d35e2f3bea566d8ea0e4e6f436d4f749d7838c8e8c4c5148ae706/pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98", size = 2061047, upload-time = "2024-07-03T17:00:29.176Z" }, { url = "https://files.pythonhosted.org/packages/51/c6/585355c7c8561e11197dbf6333c57dd32f9f62165d48589b57ced2373d97/pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a", size = 1895106, upload-time = "2024-07-03T17:00:31.501Z" }, { url = "https://files.pythonhosted.org/packages/ce/23/829f6b87de0775919e82f8addef8b487ace1c77bb4cb754b217f7b1301b6/pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a", size = 1968506, upload-time = "2024-07-03T17:00:33.586Z" }, { url = "https://files.pythonhosted.org/packages/ca/2f/f8ca8f0c40b3ee0a4d8730a51851adb14c5eda986ec09f8d754b2fba784e/pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840", size = 2110217, upload-time = "2024-07-03T17:00:36.08Z" }, { url = "https://files.pythonhosted.org/packages/bb/a0/1876656c7b17eb69cc683452cce6bb890dd722222a71b3de57ddb512f561/pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250", size = 1709669, upload-time = "2024-07-03T17:00:38.853Z" }, { url = "https://files.pythonhosted.org/packages/be/4a/576524eefa9b301c088c4818dc50ff1c51a88fe29efd87ab75748ae15fd7/pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c", size = 1902386, upload-time = "2024-07-03T17:00:41.491Z" }, { url = "https://files.pythonhosted.org/packages/61/db/f6a724db226d990a329910727cfac43539ff6969edc217286dd05cda3ef6/pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312", size = 1834507, upload-time = "2024-07-03T17:00:44.754Z" }, { url = "https://files.pythonhosted.org/packages/9b/83/6f2bfe75209d557ae1c3550c1252684fc1827b8b12fbed84c3b4439e135d/pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88", size = 1773527, upload-time = "2024-07-03T17:00:47.141Z" }, { url = "https://files.pythonhosted.org/packages/93/ef/513ea76d7ca81f2354bb9c8d7839fc1157673e652613f7e1aff17d8ce05d/pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc", size = 1787879, upload-time = "2024-07-03T17:00:49.729Z" }, { url = "https://files.pythonhosted.org/packages/31/0a/ac294caecf235f0cc651de6232f1642bb793af448d1cfc541b0dc1fd72b8/pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43", size = 1774694, upload-time = "2024-07-03T17:00:52.201Z" }, { url = "https://files.pythonhosted.org/packages/46/a4/08f12b5512f095963550a7cb49ae010e3f8f3f22b45e508c2cb4d7744fce/pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6", size = 1976369, upload-time = "2024-07-03T17:00:55.025Z" }, { url = "https://files.pythonhosted.org/packages/15/59/b2495be4410462aedb399071c71884042a2c6443319cbf62d00b4a7ed7a5/pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121", size = 2691250, upload-time = "2024-07-03T17:00:57.166Z" }, { url = "https://files.pythonhosted.org/packages/3c/ae/fc99ce1ba791c9e9d1dee04ce80eef1dae5b25b27e3fc8e19f4e3f1348bf/pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1", size = 2061462, upload-time = "2024-07-03T17:00:59.381Z" }, { url = "https://files.pythonhosted.org/packages/44/bb/eb07cbe47cfd638603ce3cb8c220f1a054b821e666509e535f27ba07ca5f/pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b", size = 1893923, upload-time = "2024-07-03T17:01:01.943Z" }, { url = "https://files.pythonhosted.org/packages/ce/ef/5a52400553b8faa0e7f11fd7a2ba11e8d2feb50b540f9e7973c49b97eac0/pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27", size = 1966779, upload-time = "2024-07-03T17:01:04.864Z" }, { url = "https://files.pythonhosted.org/packages/4c/5b/fb37fe341344d9651f5c5f579639cd97d50a457dc53901aa8f7e9f28beb9/pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b", size = 2109044, upload-time = "2024-07-03T17:01:07.241Z" }, { url = "https://files.pythonhosted.org/packages/70/1a/6f7278802dbc66716661618807ab0dfa4fc32b09d1235923bbbe8b3a5757/pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a", size = 1708265, upload-time = "2024-07-03T17:01:11.061Z" }, { url = "https://files.pythonhosted.org/packages/35/7f/58758c42c61b0bdd585158586fecea295523d49933cb33664ea888162daf/pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2", size = 1901750, upload-time = "2024-07-03T17:01:13.335Z" }, { url = "https://files.pythonhosted.org/packages/6f/47/ef0d60ae23c41aced42921728650460dc831a0adf604bfa66b76028cb4d0/pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231", size = 1839225, upload-time = "2024-07-03T17:01:15.981Z" }, { url = "https://files.pythonhosted.org/packages/6a/23/430f2878c9cd977a61bb39f71751d9310ec55cee36b3d5bf1752c6341fd0/pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9", size = 1768604, upload-time = "2024-07-03T17:01:18.188Z" }, { url = "https://files.pythonhosted.org/packages/9e/2b/ec4e7225dee79e0dc80ccc3c35ab33cc2c4bbb8a1a7ecf060e5e453651ec/pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f", size = 1789767, upload-time = "2024-07-03T17:01:20.86Z" }, { url = "https://files.pythonhosted.org/packages/64/b0/38b24a1fa6d2f96af3148362e10737ec073768cd44d3ec21dca3be40a519/pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52", size = 1772061, upload-time = "2024-07-03T17:01:23.9Z" }, { url = "https://files.pythonhosted.org/packages/5e/da/bb73274c42cb60decfa61e9eb0c9029da78b3b9af0a9de0309dbc8ff87b6/pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237", size = 1974573, upload-time = "2024-07-03T17:01:26.318Z" }, { url = "https://files.pythonhosted.org/packages/c8/65/41693110fb3552556180460daffdb8bbeefb87fc026fd9aa4b849374015c/pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe", size = 2625596, upload-time = "2024-07-03T17:01:28.775Z" }, { url = "https://files.pythonhosted.org/packages/09/b3/a5a54b47cccd1ab661ed5775235c5e06924753c2d4817737c5667bfa19a8/pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e", size = 2099064, upload-time = "2024-07-03T17:01:30.962Z" }, { url = "https://files.pythonhosted.org/packages/52/fa/443a7a6ea54beaba45ff3a59f3d3e6e3004b7460bcfb0be77bcf98719d3b/pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24", size = 1900345, upload-time = "2024-07-03T17:01:33.634Z" }, { url = "https://files.pythonhosted.org/packages/8e/e6/9aca9ffae60f9cdf0183069de3e271889b628d0fb175913fcb3db5618fb1/pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1", size = 1968252, upload-time = "2024-07-03T17:01:36.291Z" }, { url = "https://files.pythonhosted.org/packages/46/5e/6c716810ea20a6419188992973a73c2fb4eb99cd382368d0637ddb6d3c99/pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd", size = 2119191, upload-time = "2024-07-03T17:01:38.905Z" }, { url = "https://files.pythonhosted.org/packages/06/fc/6123b00a9240fbb9ae0babad7a005d51103d9a5d39c957a986f5cdd0c271/pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688", size = 1717788, upload-time = "2024-07-03T17:01:41.329Z" }, { url = "https://files.pythonhosted.org/packages/d5/36/e61ad5a46607a469e2786f398cd671ebafcd9fb17f09a2359985c7228df5/pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d", size = 1898188, upload-time = "2024-07-03T17:01:44.155Z" }, { url = "https://files.pythonhosted.org/packages/49/75/40b0e98b658fdba02a693b3bacb4c875a28bba87796c7b13975976597d8c/pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686", size = 1838688, upload-time = "2024-07-03T17:01:46.508Z" }, { url = "https://files.pythonhosted.org/packages/75/02/d8ba2d4a266591a6a623c68b331b96523d4b62ab82a951794e3ed8907390/pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a", size = 1768409, upload-time = "2024-07-03T17:01:49.013Z" }, { url = "https://files.pythonhosted.org/packages/91/ae/25ecd9bc4ce4993e99a1a3c9ab111c082630c914260e129572fafed4ecc2/pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b", size = 1789317, upload-time = "2024-07-03T17:01:51.78Z" }, { url = "https://files.pythonhosted.org/packages/7a/80/72057580681cdbe55699c367963d9c661b569a1d39338b4f6239faf36cdc/pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19", size = 1771949, upload-time = "2024-07-03T17:01:53.881Z" }, { url = "https://files.pythonhosted.org/packages/a2/be/d9bbabc55b05019013180f141fcaf3b14dbe15ca7da550e95b60c321009a/pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac", size = 1974392, upload-time = "2024-07-03T17:01:56.005Z" }, { url = "https://files.pythonhosted.org/packages/79/2d/7bcd938c6afb0f40293283f5f09988b61fb0a4f1d180abe7c23a2f665f8e/pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703", size = 2625565, upload-time = "2024-07-03T17:01:58.508Z" }, { url = "https://files.pythonhosted.org/packages/ac/88/ca758e979457096008a4b16a064509028e3e092a1e85a5ed6c18ced8da88/pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c", size = 2098784, upload-time = "2024-07-03T17:02:01.13Z" }, { url = "https://files.pythonhosted.org/packages/eb/de/2fad6d63c3c42e472e985acb12ec45b7f56e42e6f4cd6dfbc5e87ee8678c/pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83", size = 1900198, upload-time = "2024-07-03T17:02:04.348Z" }, { url = "https://files.pythonhosted.org/packages/fe/50/077c7f35b6488dc369a6d22993af3a37901e198630f38ac43391ca730f5b/pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203", size = 1968005, upload-time = "2024-07-03T17:02:06.737Z" }, { url = "https://files.pythonhosted.org/packages/5d/1f/f378631574ead46d636b9a04a80ff878b9365d4b361b1905ef1667d4182a/pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0", size = 2118920, upload-time = "2024-07-03T17:02:09.976Z" }, { url = "https://files.pythonhosted.org/packages/7a/ea/e4943f17df7a3031d709481fe4363d4624ae875a6409aec34c28c9e6cf59/pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e", size = 1717397, upload-time = "2024-07-03T17:02:12.495Z" }, { url = "https://files.pythonhosted.org/packages/13/63/b95781763e8d84207025071c0cec16d921c0163c7a9033ae4b9a0e020dc7/pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20", size = 1898013, upload-time = "2024-07-03T17:02:15.157Z" }, { url = "https://files.pythonhosted.org/packages/73/73/0c7265903f66cce39ed7ca939684fba344210cefc91ccc999cfd5b113fd3/pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906", size = 1828190, upload-time = "2024-07-03T17:03:24.111Z" }, { url = "https://files.pythonhosted.org/packages/27/55/60b8b0e58b49ee3ed36a18562dd7c6bc06a551c390e387af5872a238f2ec/pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94", size = 1715252, upload-time = "2024-07-03T17:03:27.308Z" }, { url = "https://files.pythonhosted.org/packages/28/3d/d66314bad6bb777a36559195a007b31e916bd9e2c198f7bb8f4ccdceb4fa/pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f", size = 1782641, upload-time = "2024-07-03T17:03:29.777Z" }, { url = "https://files.pythonhosted.org/packages/9e/f5/f178f4354d0d6c1431a8f9ede71f3c4269ac4dc55d314fdb7555814276dc/pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482", size = 1928788, upload-time = "2024-07-03T17:03:32.365Z" }, { url = "https://files.pythonhosted.org/packages/9c/51/1f5e27bb194df79e30b593b608c66e881ed481241e2b9ed5bdf86d165480/pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6", size = 1886116, upload-time = "2024-07-03T17:03:35.19Z" }, { url = "https://files.pythonhosted.org/packages/ac/76/450d9258c58dc7c70b9e3aadf6bebe23ddd99e459c365e2adbde80e238da/pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc", size = 1960125, upload-time = "2024-07-03T17:03:38.093Z" }, { url = "https://files.pythonhosted.org/packages/dd/9e/0309a7a4bea51771729515e413b3987be0789837de99087f7415e0db1f9b/pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99", size = 2100407, upload-time = "2024-07-03T17:03:40.882Z" }, { url = "https://files.pythonhosted.org/packages/af/93/06d44e08277b3b818b75bd5f25e879d7693e4b7dd3505fde89916fcc9ca2/pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6", size = 1914966, upload-time = "2024-07-03T17:03:45.039Z" }, ] [[package]] name = "pytest" version = "8.3.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b4/8c/9862305bdcd6020bc7b45b1b5e7397a6caf1a33d3025b9a003b39075ffb2/pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce", size = 1439314, upload-time = "2024-07-25T10:40:00.159Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/0f/f9/cf155cf32ca7d6fa3601bc4c5dd19086af4b320b706919d48a4c79081cf9/pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5", size = 341802, upload-time = "2024-07-25T10:39:57.834Z" }, ] [[package]] name = "pytest-asyncio" version = "0.24.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] sdist = { url = "https://files.pythonhosted.org/packages/52/6d/c6cf50ce320cf8611df7a1254d86233b3df7cc07f9b5f5cbcb82e08aa534/pytest_asyncio-0.24.0.tar.gz", hash = "sha256:d081d828e576d85f875399194281e92bf8a68d60d72d1a2faf2feddb6c46b276", size = 49855, upload-time = "2024-08-22T08:03:18.145Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/96/31/6607dab48616902f76885dfcf62c08d929796fc3b2d2318faf9fd54dbed9/pytest_asyncio-0.24.0-py3-none-any.whl", hash = "sha256:a811296ed596b69bf0b6f3dc40f83bcaf341b155a269052d82efa2b25ac7037b", size = 18024, upload-time = "2024-08-22T08:03:15.536Z" }, ] [[package]] name = "pytouchlinesl" version = "0.4.0" source = { editable = "." } dependencies = [ { name = "aiohttp" }, { name = "pydantic" }, ] [package.optional-dependencies] dev = [ { name = "pytest" }, { name = "pytest-asyncio" }, { name = "ruff" }, ] [package.dev-dependencies] dev = [ { name = "pytest" }, { name = "pytest-asyncio" }, { name = "ruff" }, ] [package.metadata] requires-dist = [ { name = "aiohttp" }, { name = "pydantic", specifier = ">=2" }, { name = "pytest", marker = "extra == 'dev'" }, { name = "pytest-asyncio", marker = "extra == 'dev'" }, { name = "ruff", marker = "extra == 'dev'" }, ] provides-extras = ["dev"] [package.metadata.requires-dev] dev = [ { name = "pytest", specifier = ">=8.3.2" }, { name = "pytest-asyncio", specifier = ">=0.24.0" }, { name = "ruff", specifier = ">=0.6.2" }, ] [[package]] name = "ruff" version = "0.6.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/23/f4/279d044f66b79261fd37df76bf72b64471afab5d3b7906a01499c4451910/ruff-0.6.2.tar.gz", hash = "sha256:239ee6beb9e91feb8e0ec384204a763f36cb53fb895a1a364618c6abb076b3be", size = 2460281, upload-time = "2024-08-22T13:47:24.093Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/72/4b/47dd7a69287afb4069fa42c198e899463605460a58120196711bfcf0446b/ruff-0.6.2-py3-none-linux_armv6l.whl", hash = "sha256:5c8cbc6252deb3ea840ad6a20b0f8583caab0c5ef4f9cca21adc5a92b8f79f3c", size = 9695871, upload-time = "2024-08-22T13:46:20.015Z" }, { url = "https://files.pythonhosted.org/packages/ae/c3/8aac62ac4638c14a740ee76a755a925f2d0d04580ab790a9887accb729f6/ruff-0.6.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:17002fe241e76544448a8e1e6118abecbe8cd10cf68fde635dad480dba594570", size = 9459354, upload-time = "2024-08-22T13:46:24.217Z" }, { url = "https://files.pythonhosted.org/packages/2f/cf/77fbd8d4617b9b9c503f9bffb8552c4e3ea1a58dc36975e7a9104ffb0f85/ruff-0.6.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3dbeac76ed13456f8158b8f4fe087bf87882e645c8e8b606dd17b0b66c2c1158", size = 9163871, upload-time = "2024-08-22T13:46:27.996Z" }, { url = "https://files.pythonhosted.org/packages/05/1c/765192bab32b79efbb498b06f0b9dcb3629112b53b8777ae1d19b8209e09/ruff-0.6.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:094600ee88cda325988d3f54e3588c46de5c18dae09d683ace278b11f9d4d534", size = 10096250, upload-time = "2024-08-22T13:46:31.036Z" }, { url = "https://files.pythonhosted.org/packages/08/d0/86f3cb0f6934c99f759c232984a5204d67a26745cad2d9edff6248adf7d2/ruff-0.6.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:316d418fe258c036ba05fbf7dfc1f7d3d4096db63431546163b472285668132b", size = 9475376, upload-time = "2024-08-22T13:46:36.913Z" }, { url = "https://files.pythonhosted.org/packages/cd/cc/4c8d0e225b559a3fae6092ec310d7150d3b02b4669e9223f783ef64d82c0/ruff-0.6.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d72b8b3abf8a2d51b7b9944a41307d2f442558ccb3859bbd87e6ae9be1694a5d", size = 10295634, upload-time = "2024-08-22T13:46:39.952Z" }, { url = "https://files.pythonhosted.org/packages/db/96/d2699cfb1bb5a01c68122af43454c76c31331e1c8a9bd97d653d7c82524b/ruff-0.6.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2aed7e243be68487aa8982e91c6e260982d00da3f38955873aecd5a9204b1d66", size = 11024941, upload-time = "2024-08-22T13:46:44.348Z" }, { url = "https://files.pythonhosted.org/packages/8b/a9/6ecd66af8929e0f2a1ed308a4137f3521789f28f0eb97d32c2ca3aa7000c/ruff-0.6.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d371f7fc9cec83497fe7cf5eaf5b76e22a8efce463de5f775a1826197feb9df8", size = 10606894, upload-time = "2024-08-22T13:46:48.722Z" }, { url = "https://files.pythonhosted.org/packages/e4/73/2ee4cd19f44992fedac1cc6db9e3d825966072f6dcbd4032f21cbd063170/ruff-0.6.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8f310d63af08f583363dfb844ba8f9417b558199c58a5999215082036d795a1", size = 11552886, upload-time = "2024-08-22T13:46:51.908Z" }, { url = "https://files.pythonhosted.org/packages/60/4c/c0f1cd35ce4a93c54a6bb1ee6934a3a205fa02198dd076678193853ceea1/ruff-0.6.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7db6880c53c56addb8638fe444818183385ec85eeada1d48fc5abe045301b2f1", size = 10264945, upload-time = "2024-08-22T13:46:55.101Z" }, { url = "https://files.pythonhosted.org/packages/c4/89/e45c9359b9cdd4245512ea2b9f2bb128a997feaa5f726fc9e8c7a66afadf/ruff-0.6.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1175d39faadd9a50718f478d23bfc1d4da5743f1ab56af81a2b6caf0a2394f23", size = 10100007, upload-time = "2024-08-22T13:47:00.389Z" }, { url = "https://files.pythonhosted.org/packages/06/74/0bd4e0a7ed5f6908df87892f9bf60a2356c0fd74102d8097298bd9b4f346/ruff-0.6.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:5b939f9c86d51635fe486585389f54582f0d65b8238e08c327c1534844b3bb9a", size = 9559267, upload-time = "2024-08-22T13:47:03.973Z" }, { url = "https://files.pythonhosted.org/packages/54/03/3dc6dc9419f276f05805bf888c279e3e0b631284abd548d9e87cebb93aec/ruff-0.6.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d0d62ca91219f906caf9b187dea50d17353f15ec9bb15aae4a606cd697b49b4c", size = 9905304, upload-time = "2024-08-22T13:47:08.582Z" }, { url = "https://files.pythonhosted.org/packages/5c/5b/d6a72a6a6bbf097c09de468326ef5fa1c9e7aa5e6e45979bc0d984b0dbe7/ruff-0.6.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7438a7288f9d67ed3c8ce4d059e67f7ed65e9fe3aa2ab6f5b4b3610e57e3cb56", size = 10341480, upload-time = "2024-08-22T13:47:11.91Z" }, { url = "https://files.pythonhosted.org/packages/79/a9/0f2f21fe15ba537c46598f96aa9ae4a3d4b9ec64926664617ca6a8c772f4/ruff-0.6.2-py3-none-win32.whl", hash = "sha256:279d5f7d86696df5f9549b56b9b6a7f6c72961b619022b5b7999b15db392a4da", size = 7961901, upload-time = "2024-08-22T13:47:15.168Z" }, { url = "https://files.pythonhosted.org/packages/b0/80/fff12ffe11853d9f4ea3e5221e6dd2e93640a161c05c9579833e09ad40a7/ruff-0.6.2-py3-none-win_amd64.whl", hash = "sha256:d9f3469c7dd43cd22eb1c3fc16926fb8258d50cb1b216658a07be95dd117b0f2", size = 8783320, upload-time = "2024-08-22T13:47:17.889Z" }, { url = "https://files.pythonhosted.org/packages/56/91/577cdd64cce5e74d3f8b5ecb93f29566def569c741eb008aed4f331ef821/ruff-0.6.2-py3-none-win_arm64.whl", hash = "sha256:f28fcd2cd0e02bdf739297516d5643a945cc7caf09bd9bcb4d932540a5ea4fa9", size = 8225886, upload-time = "2024-08-22T13:47:20.844Z" }, ] [[package]] name = "tomli" version = "2.0.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f", size = 15164, upload-time = "2022-02-08T10:54:04.006Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", size = 12757, upload-time = "2022-02-08T10:54:02.017Z" }, ] [[package]] name = "typing-extensions" version = "4.12.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321, upload-time = "2024-06-07T18:52:15.995Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438, upload-time = "2024-06-07T18:52:13.582Z" }, ] [[package]] name = "yarl" version = "1.9.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e0/ad/bedcdccbcbf91363fd425a948994f3340924145c2bc8ccb296f4a1e52c28/yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf", size = 141869, upload-time = "2023-12-06T12:53:04.652Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/6c/27/cda5a927df3a894eddfee4efacdd230c2d8486e322fc672194fd651f82c5/yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e", size = 129061, upload-time = "2023-12-06T12:49:47.429Z" }, { url = "https://files.pythonhosted.org/packages/d5/fc/40b85bea1f5686092ea37f472c94c023d6347266852ffd55baa01c40f596/yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2", size = 81246, upload-time = "2023-12-06T12:49:50.489Z" }, { url = "https://files.pythonhosted.org/packages/81/c6/06938036ea48fa74521713499fba1459b0eb60af9b9afbe8e0e9e1a96c36/yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66", size = 79176, upload-time = "2023-12-06T12:49:52.828Z" }, { url = "https://files.pythonhosted.org/packages/30/b5/215d586d5cb17ca9748d7a2d597c07147f210c0c0785257492094d083b65/yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234", size = 297669, upload-time = "2023-12-06T12:49:55.665Z" }, { url = "https://files.pythonhosted.org/packages/dd/90/2958ae9f2e12084d616eef95b6a48c8e6d96448add04367c20dc53a33ff2/yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392", size = 311909, upload-time = "2023-12-06T12:49:58.131Z" }, { url = "https://files.pythonhosted.org/packages/0b/58/dd3c69651381a57ac991dba54b20ae2da359eb4b03a661e71c451d6525c6/yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551", size = 308690, upload-time = "2023-12-06T12:50:00.082Z" }, { url = "https://files.pythonhosted.org/packages/c3/a0/0ade1409d184cbc9e85acd403a386a7c0563b92ff0f26d138ff9e86e48b4/yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455", size = 301580, upload-time = "2023-12-06T12:50:02.587Z" }, { url = "https://files.pythonhosted.org/packages/6d/a1/db0bdf8cc48515e9c02daf04ae2916fc27ce6498eca21432fc9ffa63f71b/yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c", size = 291231, upload-time = "2023-12-06T12:50:05.101Z" }, { url = "https://files.pythonhosted.org/packages/b2/4f/796b0c73e9ff30a1047a7ee3390e157ab8424d4401b9f32a2624013a5b39/yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53", size = 301079, upload-time = "2023-12-06T12:50:07.822Z" }, { url = "https://files.pythonhosted.org/packages/0b/a3/7774786ec6e2dca0bb38b286f12a11af97957546e5fbcce71752a8d2cf07/yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385", size = 295202, upload-time = "2023-12-06T12:50:10.442Z" }, { url = "https://files.pythonhosted.org/packages/70/a9/ef6d69ce9a4e82080290bcb6db735bb8a6d6db92f2bbb92b6951bde97e7c/yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863", size = 311784, upload-time = "2023-12-06T12:50:13.057Z" }, { url = "https://files.pythonhosted.org/packages/44/ae/fdbc9965ef69e650c3b5b04d60badef90ff0cde21a30770f0700e148b12f/yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b", size = 311134, upload-time = "2023-12-06T12:50:15.008Z" }, { url = "https://files.pythonhosted.org/packages/cc/2a/abbaf1460becba856e163f2a1274f5d34b1969d476da8e68a8fc2aeb5661/yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541", size = 304584, upload-time = "2023-12-06T12:50:18.491Z" }, { url = "https://files.pythonhosted.org/packages/a3/73/dd7ced8d9731bd2ef4fdff5da23ce2f772ca04e8ddee886a6b15248d9e65/yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d", size = 70175, upload-time = "2023-12-06T12:50:20.575Z" }, { url = "https://files.pythonhosted.org/packages/31/d4/2085272a5ccf87af74d4e02787c242c5d60367840a4637b2835565264302/yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b", size = 76402, upload-time = "2023-12-06T12:50:23.005Z" }, { url = "https://files.pythonhosted.org/packages/12/65/4c7f3676209a569405c9f0f492df2bc3a387c253f5d906e36944fdd12277/yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099", size = 132836, upload-time = "2023-12-06T12:50:24.778Z" }, { url = "https://files.pythonhosted.org/packages/3b/c5/81e3dbf5271ab1510860d2ae7a704ef43f93f7cb9326bf7ebb1949a7260b/yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c", size = 83215, upload-time = "2023-12-06T12:50:26.684Z" }, { url = "https://files.pythonhosted.org/packages/20/3d/7dabf580dfc0b588e48830486b488858122b10a61f33325e0d7cf1d6180b/yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0", size = 81237, upload-time = "2023-12-06T12:50:28.927Z" }, { url = "https://files.pythonhosted.org/packages/38/45/7c669999f5d350f4f8f74369b94e0f6705918eee18e38610bfe44af93d4f/yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525", size = 324181, upload-time = "2023-12-06T12:50:30.845Z" }, { url = "https://files.pythonhosted.org/packages/50/49/aa04effe2876cced8867bf9d89b620acf02b733c62adfe22a8218c35d70b/yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8", size = 339412, upload-time = "2023-12-06T12:50:32.721Z" }, { url = "https://files.pythonhosted.org/packages/7d/95/4310771fb9c71599d8466f43347ac18fafd501621e65b93f4f4f16899b1d/yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9", size = 337973, upload-time = "2023-12-06T12:50:34.84Z" }, { url = "https://files.pythonhosted.org/packages/9f/ea/94ad7d8299df89844e666e4aa8a0e9b88e02416cd6a7dd97969e9eae5212/yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42", size = 328126, upload-time = "2023-12-06T12:50:36.713Z" }, { url = "https://files.pythonhosted.org/packages/6d/be/9d4885e2725f5860833547c9e4934b6e0f44a355b24ffc37957264761e3e/yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe", size = 316677, upload-time = "2023-12-06T12:50:38.867Z" }, { url = "https://files.pythonhosted.org/packages/4a/70/5c744d67cad3d093e233cb02f37f2830cb89abfcbb7ad5b5af00ff21d14d/yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce", size = 324243, upload-time = "2023-12-06T12:50:40.887Z" }, { url = "https://files.pythonhosted.org/packages/c2/80/8b38d8fed958ac37afb8b81a54bf4f767b107e2c2004dab165edb58fc51b/yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9", size = 318099, upload-time = "2023-12-06T12:50:42.846Z" }, { url = "https://files.pythonhosted.org/packages/59/50/715bbc7bda65291f9295e757f67854206f4d8be9746d39187724919ac14d/yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572", size = 334924, upload-time = "2023-12-06T12:50:45.33Z" }, { url = "https://files.pythonhosted.org/packages/a8/af/ca9962488027576d7162878a1864cbb1275d298af986ce96bdfd4807d7b2/yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958", size = 335060, upload-time = "2023-12-06T12:50:47.445Z" }, { url = "https://files.pythonhosted.org/packages/28/c7/249a3a903d500ca7369eb542e2847a14f12f249638dcc10371db50cd17ff/yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98", size = 326689, upload-time = "2023-12-06T12:50:49.343Z" }, { url = "https://files.pythonhosted.org/packages/ec/0c/f02dd0b875a7a460f95dc7cf18983ed43c693283d6ab92e0ad71b9e0de8f/yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31", size = 70407, upload-time = "2023-12-06T12:50:51.947Z" }, { url = "https://files.pythonhosted.org/packages/27/41/945ae9a80590e4fb0be166863c6e63d75e4b35789fa3a61ff1dbdcdc220f/yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1", size = 76719, upload-time = "2023-12-06T12:50:53.694Z" }, { url = "https://files.pythonhosted.org/packages/7b/cd/a921122610dedfed94e494af18e85aae23e93274c00ca464cfc591c8f4fb/yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81", size = 129561, upload-time = "2023-12-06T12:50:56.081Z" }, { url = "https://files.pythonhosted.org/packages/7c/a0/887c93020c788f249c24eaab288c46e5fed4d2846080eaf28ed3afc36e8d/yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142", size = 81595, upload-time = "2023-12-06T12:50:57.786Z" }, { url = "https://files.pythonhosted.org/packages/54/99/ed3c92c38f421ba6e36caf6aa91c34118771d252dce800118fa2f44d7962/yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074", size = 79400, upload-time = "2023-12-06T12:50:59.518Z" }, { url = "https://files.pythonhosted.org/packages/ea/45/65801be625ef939acc8b714cf86d4a198c0646e80dc8970359d080c47204/yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129", size = 317397, upload-time = "2023-12-06T12:51:01.711Z" }, { url = "https://files.pythonhosted.org/packages/06/91/9696601a8ba674c8f0c15035cc9e94ca31f541330364adcfd5a399f598bf/yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2", size = 327246, upload-time = "2023-12-06T12:51:04.251Z" }, { url = "https://files.pythonhosted.org/packages/da/3e/bf25177b3618889bf067aacf01ef54e910cd569d14e2f84f5e7bec23bb82/yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78", size = 327321, upload-time = "2023-12-06T12:51:06.594Z" }, { url = "https://files.pythonhosted.org/packages/28/1c/bdb3411467b805737dd2720b85fd082e49f59bf0cc12dc1dfcc80ab3d274/yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4", size = 322424, upload-time = "2023-12-06T12:51:08.727Z" }, { url = "https://files.pythonhosted.org/packages/41/e9/53bc89f039df2824a524a2aa03ee0bfb8f0585b08949e7521f5eab607085/yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0", size = 310868, upload-time = "2023-12-06T12:51:11.18Z" }, { url = "https://files.pythonhosted.org/packages/79/cd/a78c3b0304a4a970b5ae3993f4f5f649443bc8bfa5622f244aed44c810ed/yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51", size = 323452, upload-time = "2023-12-06T12:51:13.382Z" }, { url = "https://files.pythonhosted.org/packages/2e/5e/1c78eb05ae0efae08498fd7ab939435a29f12c7f161732e7fe327e5b8ca1/yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff", size = 313554, upload-time = "2023-12-06T12:51:15.812Z" }, { url = "https://files.pythonhosted.org/packages/04/e0/0029563a8434472697aebb269fdd2ffc8a19e3840add1d5fa169ec7c56e3/yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7", size = 331029, upload-time = "2023-12-06T12:51:18.066Z" }, { url = "https://files.pythonhosted.org/packages/de/1b/7e6b1ad42ccc0ed059066a7ae2b6fd4bce67795d109a99ccce52e9824e96/yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc", size = 333839, upload-time = "2023-12-06T12:51:19.991Z" }, { url = "https://files.pythonhosted.org/packages/85/8a/c364d6e2eeb4e128a5ee9a346fc3a09aa76739c0c4e2a7305989b54f174b/yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10", size = 328251, upload-time = "2023-12-06T12:51:22.047Z" }, { url = "https://files.pythonhosted.org/packages/ec/9d/0da94b33b9fb89041e10f95a14a55b0fef36c60b6a1d5ff85a0c2ecb1a97/yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7", size = 70195, upload-time = "2023-12-06T12:51:24.441Z" }, { url = "https://files.pythonhosted.org/packages/c5/f4/2fdc5a11503bc61818243653d836061c9ce0370e2dd9ac5917258a007675/yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984", size = 76397, upload-time = "2023-12-06T12:51:26.722Z" }, { url = "https://files.pythonhosted.org/packages/4d/05/4d79198ae568a92159de0f89e710a8d19e3fa267b719a236582eee921f4a/yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad", size = 31638, upload-time = "2023-12-06T12:53:02.709Z" }, ]