summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanglewood <85772166+deeleeramone@users.noreply.github.com>2024-02-05 01:22:08 -0800
committerGitHub <noreply@github.com>2024-02-05 09:22:08 +0000
commitb4649b375e120bd2e677b7f3939b8cb8e2a05b1f (patch)
tree319f68edf36f0954726ff1c6809d8c6daee478f8
parent3de1bddc2de0a76439e4bc3b09aa9d7ff9ef68a3 (diff)
feature/commodities-lbma-fixing: Adds Commodity Extension and LBMA Gold/Silver daily fixing levels (#5760)
* add commodity extension and add lbma fixing endpoint * dev_install.py * readme url * renovate the standard model * makes a query_params model for nasdaq data link * literal not optional * unused imports * missing test params * test cassette * DataLink query param description * test file import * actually fix import * from openbb_core.provider..... * ruff * another import statement * black * async router * move query_params * update version * version numbers * extension_map * satisfy pylint? * pylint * Update pyproject.toml * black * poetry lock * Update extension_map.json * Update __extensions__.py * Update module_map.json * clean descriptions --------- Co-authored-by: Pratyush Shukla <ps4534@nyu.edu>
-rw-r--r--openbb_platform/core/openbb_core/provider/standard_models/lbma_fixing.py87
-rw-r--r--openbb_platform/dev_install.py1
-rw-r--r--openbb_platform/extensions/commodity/README.md15
-rw-r--r--openbb_platform/extensions/commodity/integration/test_commodity_api.py55
-rw-r--r--openbb_platform/extensions/commodity/integration/test_commodity_python.py50
-rw-r--r--openbb_platform/extensions/commodity/openbb_commodity/__init__.py0
-rw-r--r--openbb_platform/extensions/commodity/openbb_commodity/commodity_router.py26
-rw-r--r--openbb_platform/extensions/commodity/poetry.lock1412
-rw-r--r--openbb_platform/extensions/commodity/pyproject.toml18
-rw-r--r--openbb_platform/extensions/regulators/integration/test_regulators_api.py1
-rw-r--r--openbb_platform/extensions/regulators/integration/test_regulators_python.py1
-rw-r--r--openbb_platform/openbb/package/__extensions__.py35
-rw-r--r--openbb_platform/openbb/package/extension_map.json3
-rw-r--r--openbb_platform/openbb/package/module_map.json3
-rw-r--r--openbb_platform/poetry.lock780
-rw-r--r--openbb_platform/providers/nasdaq/openbb_nasdaq/__init__.py2
-rw-r--r--openbb_platform/providers/nasdaq/openbb_nasdaq/models/cot.py19
-rw-r--r--openbb_platform/providers/nasdaq/openbb_nasdaq/models/lbma_fixing.py80
-rw-r--r--openbb_platform/providers/nasdaq/openbb_nasdaq/models/sp500_multiples.py17
-rw-r--r--openbb_platform/providers/nasdaq/openbb_nasdaq/utils/query_params.py30
-rw-r--r--openbb_platform/providers/nasdaq/tests/record/http/test_nasdaq_fetchers/test_nasdaq_cot_fetcher.yaml2207
-rw-r--r--openbb_platform/providers/nasdaq/tests/record/http/test_nasdaq_fetchers/test_nasdaq_lbma_fixing_fetcher.yaml4820
-rw-r--r--openbb_platform/providers/nasdaq/tests/record/http/test_nasdaq_fetchers/test_nasdaq_sp500_multiples_fetcher.yaml427
-rw-r--r--openbb_platform/providers/nasdaq/tests/test_nasdaq_fetchers.py10
-rw-r--r--openbb_platform/pyproject.toml1
25 files changed, 8495 insertions, 1605 deletions
diff --git a/openbb_platform/core/openbb_core/provider/standard_models/lbma_fixing.py b/openbb_platform/core/openbb_core/provider/standard_models/lbma_fixing.py
new file mode 100644
index 00000000000..fe997156578
--- /dev/null
+++ b/openbb_platform/core/openbb_core/provider/standard_models/lbma_fixing.py
@@ -0,0 +1,87 @@
+"""LBMA Fixing Standard Model."""
+
+from datetime import (
+ date as dateType,
+ datetime,
+)
+from typing import Literal, Optional
+
+from pydantic import Field, field_validator
+
+from openbb_core.provider.abstract.data import Data
+from openbb_core.provider.abstract.query_params import QueryParams
+from openbb_core.provider.utils.descriptions import (
+ DATA_DESCRIPTIONS,
+ QUERY_DESCRIPTIONS,
+)
+
+
+class LbmaFixingQueryParams(QueryParams):
+ """
+ LBMA Fixing Query.
+
+ Source: https://www.lbma.org.uk/prices-and-data/precious-metal-prices#/table
+ """
+
+ asset: Literal["gold", "silver"] = Field(
+ description="The metal to get price fixing rates for.",
+ default="gold",
+ )
+ start_date: Optional[dateType] = Field(
+ default=None,
+ description=QUERY_DESCRIPTIONS.get("start_date", ""),
+ )
+ end_date: Optional[dateType] = Field(
+ default=None,
+ description=QUERY_DESCRIPTIONS.get("end_date", ""),
+ )
+
+
+class LbmaFixingData(Data):
+ """LBMA Fixing Data. Historical fixing prices in USD, GBP and EUR."""
+
+ date: dateType = Field(description=DATA_DESCRIPTIONS.get("date", ""))
+ usd_am: Optional[float] = Field(
+ default=None,
+ description="AM fixing price in USD.",
+ )
+ usd_pm: Optional[float] = Field(
+ default=None,
+ description="PM fixing price in USD.",
+ )
+ gbp_am: Optional[float] = Field(
+ default=None,
+ description="AM fixing price in GBP.",
+ )
+ gbp_pm: Optional[float] = Field(
+ default=None,
+ description="PM fixing price in GBP.",
+ )
+ euro_am: Optional[float] = Field(
+ default=None,
+ description="AM fixing price in EUR.",
+ )
+ euro_pm: Optional[float] = Field(
+ default=None,
+ description="PM fixing price in EUR.",
+ )
+ usd: Optional[float] = Field(
+ default=None,
+ description="Daily fixing price in USD.",
+ )
+ gbp: Optional[float] = Field(
+ default=None,
+ description="Daily fixing price in GBP.",
+ )
+ eur: Optional[float] = Field(
+ default=None,
+ description="Daily fixing price in EUR.",
+ )
+
+ @field_validator("date", mode="before", check_fields=False)
+ @classmethod
+ def validate_date(cls, v) -> dateType:
+ """Validate date."""
+ if isinstance(v, datetime):
+ return v.date()
+ return datetime.strptime(v, "%Y-%m-%d").date()
diff --git a/openbb_platform/dev_install.py b/openbb_platform/dev_install.py
index 5b859edd921..3bc15416828 100644
--- a/openbb_platform/dev_install.py
+++ b/openbb_platform/dev_install.py
@@ -29,6 +29,7 @@ openbb-tiingo = { path = "./providers/tiingo", develop = true }
openbb-tradingeconomics = { path = "./providers/tradingeconomics", develop = true }
openbb-yfinance = { path = "./providers/yfinance", develop = true }
+openbb-commodity = { path = "./extensions/commodity", develop = true }
openbb-crypto = { path = "./extensions/crypto", develop = true }
openbb-currency = { path = "./extensions/currency", develop = true }
openbb-derivatives = { path = "./extensions/derivatives", develop = true }
diff --git a/openbb_platform/extensions/commodity/README.md b/openbb_platform/extensions/commodity/README.md
new file mode 100644
index 00000000000..0d127596d9a
--- /dev/null
+++ b/openbb_platform/extensions/commodity/README.md
@@ -0,0 +1,15 @@
+# Commodity Extension for OpenBB Platform
+
+This extension provides a set of commands for commodity-related data.
+
+## Installation
+
+To install the extension, run the following command in this folder:
+
+```bash
+pip install openbb-commodity
+```
+
+For development please check [Contribution Guidelines](https://github.com/OpenBB-finance/OpenBBTerminal/blob/develop/openbb_platform/CONTRIBUTING.md).
+
+Documentation available [here](https://docs.openbb.co/platform).
diff --git a/openbb_platform/extensions/commodity/integration/test_commodity_api.py b/openbb_platform/extensions/commodity/integration/test_commodity_api.py
new file mode 100644
index 00000000000..89f22935c9c
--- /dev/null
+++ b/openbb_platform/extensions/commodity/integration/test_commodity_api.py
@@ -0,0 +1,55 @@
+"""Test Commodity API endpoints."""
+
+import base64
+
+import pytest
+import requests
+from openbb_core.env import Env
+from openbb_core.provider.utils.helpers import get_querystring
+
+# pylint: disable=redefined-outer-name
+
+
+@pytest.fixture(scope="session")
+def headers():
+ userpass = f"{Env().API_USERNAME}:{Env().API_PASSWORD}"
+ userpass_bytes = userpass.encode("ascii")
+ base64_bytes = base64.b64encode(userpass_bytes)
+
+ return {"Authorization": f"Basic {base64_bytes.decode('ascii')}"}
+
+
+@pytest.mark.parametrize(
+ "params",
+ [
+ (
+ {
+ "asset": "gold",
+ "start_date": None,
+ "end_date": None,
+ "collapse": None,
+ "transform": None,
+ "provider": "nasdaq",
+ }
+ ),
+ (
+ {
+ "asset": "silver",
+ "start_date": "1990-01-01",
+ "end_date": "2023-01-01",
+ "collapse": "monthly",
+ "transform": "diff",
+ "provider": "nasdaq",
+ }
+ ),
+ ],
+)
+@pytest.mark.integration
+def test_commodity_lbma_fixing(params, headers):
+ params = {p: v for p, v in params.items() if v}
+
+ query_str = get_querystring(params, [])
+ url = f"http://0.0.0.0:8000/api/v1/commodity/lbma_fixing?{query_str}"
+ result = requests.get(url, headers=headers, timeout=10)
+ assert isinstance(result, requests.Response)
+ assert result.status_code == 200
diff --git a/openbb_platform/extensions/commodity/integration/test_commodity_python.py b/openbb_platform/extensions/commodity/integration/test_commodity_python.py
new file mode 100644
index 00000000000..c805ffcb269
--- /dev/null
+++ b/openbb_platform/extensions/commodity/integration/test_commodity_python.py
@@ -0,0 +1,50 @@
+"""Test Commodity extension."""
+
+import pytest
+from openbb_core.app.model.obbject import OBBject
+
+# pylint: disable=redefined-outer-name
+
+
+@pytest.fixture(scope="session")
+def obb(pytestconfig): # pylint: disable=inconsistent-return-statements
+ """Fixture to setup obb."""
+ if pytestconfig.getoption("markexpr") != "not integration":
+ import openbb # pylint: disable=import-outside-toplevel
+
+ return openbb.obb
+
+
+@pytest.mark.parametrize(
+ "params",
+ [
+ (
+ {
+ "asset": "gold",
+ "start_date": None,
+ "end_date": None,
+ "collapse": None,
+ "transform": None,
+ "provider": "nasdaq",
+ }
+ ),
+ (
+ {
+ "asset": "silver",
+ "start_date": "1990-01-01",
+ "end_date": "2023-01-01",
+ "collapse": "monthly",
+ "transform": "diff",
+ "provider": "nasdaq",
+ }
+ ),
+ ],
+)
+@pytest.mark.integration
+def test_commodity_lbma_fixing(params, obb):
+ params = {p: v for p, v in params.items() if v}
+
+ result = obb.commodity.lbma_fixing(**params)
+ assert result
+ assert isinstance(result, OBBject)
+ assert len(result.results) > 0
diff --git a/openbb_platform/extensions/commodity/openbb_commodity/__init__.py b/openbb_platform/extensions/commodity/openbb_commodity/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/openbb_platform/extensions/commodity/openbb_commodity/__init__.py
diff --git a/openbb_platform/extensions/commodity/openbb_commodity/commodity_router.py b/openbb_platform/extensions/commodity/openbb_commodity/commodity_router.py
new file mode 100644
index 00000000000..6d9a7e63b86
--- /dev/null
+++ b/openbb_platform/extensions/commodity/openbb_commodity/commodity_router.py
@@ -0,0 +1,26 @@
+"""The Commodity router."""
+
+from openbb_core.app.model.command_context import CommandContext
+from openbb_core.app.model.obbject import OBBject
+from openbb_core.app.provider_interface import (
+ ExtraParams,
+ ProviderChoices,
+ StandardParams,
+)
+from openbb_core.app.query import Query
+from openbb_core.app.router import Router
+from pydantic import BaseModel
+
+router = Router(prefix="")
+
+
+# pylint: disable=unused-argument
+@router.command(model="LbmaFixing")
+async def lbma_fixing(
+ cc: CommandContext,
+ provider_choices: ProviderChoices,
+ standard_params: StandardParams,
+ extra_params: ExtraParams,
+) -> OBBject[BaseModel]:
+ """Daily LBMA Fixing Prices in USD/EUR/GBP."""
+ return await OBBject.from_query(Query(**locals()))
diff --git a/openbb_platform/extensions/commodity/poetry.lock b/openbb_platform/extensions/commodity/poetry.lock
new file mode 100644
index 00000000000..ea090945d4c
--- /dev/null
+++ b/openbb_platform/extensions/commodity/poetry.lock
@@ -0,0 +1,1412 @@
+# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
+
+[[package]]
+name = "aiohttp"
+version = "3.9.3"
+description = "Async http client/server framework (asyncio)"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "aiohttp-3.9.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:939677b61f9d72a4fa2a042a5eee2a99a24001a67c13da113b2e30396567db54"},
+ {file = "aiohttp-3.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1f5cd333fcf7590a18334c90f8c9147c837a6ec8a178e88d90a9b96ea03194cc"},
+ {file = "aiohttp-3.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:82e6aa28dd46374f72093eda8bcd142f7771ee1eb9d1e223ff0fa7177a96b4a5"},
+ {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f56455b0c2c7cc3b0c584815264461d07b177f903a04481dfc33e08a89f0c26b"},
+ {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bca77a198bb6e69795ef2f09a5f4c12758487f83f33d63acde5f0d4919815768"},
+ {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e083c285857b78ee21a96ba1eb1b5339733c3563f72980728ca2b08b53826ca5"},
+ {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab40e6251c3873d86ea9b30a1ac6d7478c09277b32e14745d0d3c6e76e3c7e29"},
+ {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df822ee7feaaeffb99c1a9e5e608800bd8eda6e5f18f5cfb0dc7eeb2eaa6bbec"},
+ {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:acef0899fea7492145d2bbaaaec7b345c87753168589cc7faf0afec9afe9b747"},
+ {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cd73265a9e5ea618014802ab01babf1940cecb90c9762d8b9e7d2cc1e1969ec6"},
+ {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:a78ed8a53a1221393d9637c01870248a6f4ea5b214a59a92a36f18151739452c"},
+ {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:6b0e029353361f1746bac2e4cc19b32f972ec03f0f943b390c4ab3371840aabf"},
+ {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7cf5c9458e1e90e3c390c2639f1017a0379a99a94fdfad3a1fd966a2874bba52"},
+ {file = "aiohttp-3.9.3-cp310-cp310-win32.whl", hash = "sha256:3e59c23c52765951b69ec45ddbbc9403a8761ee6f57253250c6e1536cacc758b"},
+ {file = "aiohttp-3.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:055ce4f74b82551678291473f66dc9fb9048a50d8324278751926ff0ae7715e5"},
+ {file = "aiohttp-3.9.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6b88f9386ff1ad91ace19d2a1c0225896e28815ee09fc6a8932fded8cda97c3d"},
+ {file = "aiohttp-3.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c46956ed82961e31557b6857a5ca153c67e5476972e5f7190015018760938da2"},
+ {file = "aiohttp-3.9.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07b837ef0d2f252f96009e9b8435ec1fef68ef8b1461933253d318748ec1acdc"},
+ {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad46e6f620574b3b4801c68255492e0159d1712271cc99d8bdf35f2043ec266"},
+ {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ed3e046ea7b14938112ccd53d91c1539af3e6679b222f9469981e3dac7ba1ce"},
+ {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:039df344b45ae0b34ac885ab5b53940b174530d4dd8a14ed8b0e2155b9dddccb"},
+ {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7943c414d3a8d9235f5f15c22ace69787c140c80b718dcd57caaade95f7cd93b"},
+ {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84871a243359bb42c12728f04d181a389718710129b36b6aad0fc4655a7647d4"},
+ {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5eafe2c065df5401ba06821b9a054d9cb2848867f3c59801b5d07a0be3a380ae"},
+ {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9d3c9b50f19704552f23b4eaea1fc082fdd82c63429a6506446cbd8737823da3"},
+ {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:f033d80bc6283092613882dfe40419c6a6a1527e04fc69350e87a9df02bbc283"},
+ {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:2c895a656dd7e061b2fd6bb77d971cc38f2afc277229ce7dd3552de8313a483e"},
+ {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1f5a71d25cd8106eab05f8704cd9167b6e5187bcdf8f090a66c6d88b634802b4"},
+ {file = "aiohttp-3.9.3-cp311-cp311-win32.whl", hash = "sha256:50fca156d718f8ced687a373f9e140c1bb765ca16e3d6f4fe116e3df7c05b2c5"},
+ {file = "aiohttp-3.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:5fe9ce6c09668063b8447f85d43b8d1c4e5d3d7e92c63173e6180b2ac5d46dd8"},
+ {file = "aiohttp-3.9.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:38a19bc3b686ad55804ae931012f78f7a534cce165d089a2059f658f6c91fa60"},
+ {file = "aiohttp-3.9.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:770d015888c2a598b377bd2f663adfd947d78c0124cfe7b959e1ef39f5b13869"},
+ {file = "aiohttp-3.9.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee43080e75fc92bf36219926c8e6de497f9b247301bbf88c5c7593d931426679"},
+ {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52df73f14ed99cee84865b95a3d9e044f226320a87af208f068ecc33e0c35b96"},
+ {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc9b311743a78043b26ffaeeb9715dc360335e5517832f5a8e339f8a43581e4d"},
+ {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b955ed993491f1a5da7f92e98d5dad3c1e14dc175f74517c4e610b1f2456fb11"},
+ {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:504b6981675ace64c28bf4a05a508af5cde526e36492c98916127f5a02354d53"},
+ {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6fe5571784af92b6bc2fda8d1925cccdf24642d49546d3144948a6a1ed58ca5"},
+ {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ba39e9c8627edc56544c8628cc180d88605df3892beeb2b94c9bc857774848ca"},
+ {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e5e46b578c0e9db71d04c4b506a2121c0cb371dd89af17a0586ff6769d4c58c1"},
+ {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:938a9653e1e0c592053f815f7028e41a3062e902095e5a7dc84617c87267ebd5"},
+ {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:c3452ea726c76e92f3b9fae4b34a151981a9ec0a4847a627c43d71a15ac32aa6"},
+ {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ff30218887e62209942f91ac1be902cc80cddb86bf00fbc6783b7a43b2bea26f"},
+ {file = "aiohttp-3.9.3-cp312-cp312-win32.whl", hash = "sha256:38f307b41e0bea3294a9a2a87833191e4bcf89bb0365e83a8be3a58b31fb7f38"},
+ {file = "aiohttp-3.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:b791a3143681a520c0a17e26ae7465f1b6f99461a28019d1a2f425236e6eedb5"},
+ {file = "aiohttp-3.9.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0ed621426d961df79aa3b963ac7af0d40392956ffa9be022024cd16297b30c8c"},
+ {file = "aiohttp-3.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7f46acd6a194287b7e41e87957bfe2ad1ad88318d447caf5b090012f2c5bb528"},
+ {file = "aiohttp-3.9.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:feeb18a801aacb098220e2c3eea59a512362eb408d4afd0c242044c33ad6d542"},
+ {file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f734e38fd8666f53da904c52a23ce517f1b07722118d750405af7e4123933511"},
+ {file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b40670ec7e2156d8e57f70aec34a7216407848dfe6c693ef131ddf6e76feb672"},
+ {file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fdd215b7b7fd4a53994f238d0f46b7ba4ac4c0adb12452beee724ddd0743ae5d"},
+ {file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:017a21b0df49039c8f46ca0971b3a7fdc1f56741ab1240cb90ca408049766168"},
+ {file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e99abf0bba688259a496f966211c49a514e65afa9b3073a1fcee08856e04425b"},
+ {file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:648056db9a9fa565d3fa851880f99f45e3f9a771dd3ff3bb0c048ea83fb28194"},
+ {file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8aacb477dc26797ee089721536a292a664846489c49d3ef9725f992449eda5a8"},
+ {file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:522a11c934ea660ff8953eda090dcd2154d367dec1ae3c540aff9f8a5c109ab4"},
+ {file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:5bce0dc147ca85caa5d33debc4f4d65e8e8b5c97c7f9f660f215fa74fc49a321"},
+ {file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b4af9f25b49a7be47c0972139e59ec0e8285c371049df1a63b6ca81fdd216a2"},
+ {file = "aiohttp-3.9.3-cp38-cp38-win32.whl", hash = "sha256:298abd678033b8571995650ccee753d9458dfa0377be4dba91e4491da3f2be63"},
+ {file = "aiohttp-3.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:69361bfdca5468c0488d7017b9b1e5ce769d40b46a9f4a2eed26b78619e9396c"},
+ {file = "aiohttp-3.9.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0fa43c32d1643f518491d9d3a730f85f5bbaedcbd7fbcae27435bb8b7a061b29"},
+ {file = "aiohttp-3.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:835a55b7ca49468aaaac0b217092dfdff370e6c215c9224c52f30daaa735c1c1"},
+ {file = "aiohttp-3.9.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06a9b2c8837d9a94fae16c6223acc14b4dfdff216ab9b7202e07a9a09541168f"},
+ {file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abf151955990d23f84205286938796c55ff11bbfb4ccfada8c9c83ae6b3c89a3"},
+ {file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59c26c95975f26e662ca78fdf543d4eeaef70e533a672b4113dd888bd2423caa"},
+ {file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f95511dd5d0e05fd9728bac4096319f80615aaef4acbecb35a990afebe953b0e"},
+ {file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:595f105710293e76b9dc09f52e0dd896bd064a79346234b521f6b968ffdd8e58"},
+ {file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7c8b816c2b5af5c8a436df44ca08258fc1a13b449393a91484225fcb7545533"},
+ {file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f1088fa100bf46e7b398ffd9904f4808a0612e1d966b4aa43baa535d1b6341eb"},
+ {file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f59dfe57bb1ec82ac0698ebfcdb7bcd0e99c255bd637ff613760d5f33e7c81b3"},
+ {file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:361a1026c9dd4aba0109e4040e2aecf9884f5cfe1b1b1bd3d09419c205e2e53d"},
+ {file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:363afe77cfcbe3a36353d8ea133e904b108feea505aa4792dad6585a8192c55a"},
+ {file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e2c45c208c62e955e8256949eb225bd8b66a4c9b6865729a786f2aa79b72e9d"},
+ {file = "aiohttp-3.9.3-cp39-cp39-win32.whl", hash = "sha256:f7217af2e14da0856e082e96ff637f14ae45c10a5714b63c77f26d8884cf1051"},
+ {file = "aiohttp-3.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:27468897f628c627230dba07ec65dc8d0db566923c48f29e084ce382119802bc"},
+ {file = "aiohttp-3.9.3.tar.gz", hash = "sha256:90842933e5d1ff760fae6caca4b2b3edba53ba8f4b71e95dacf2818a2aca06f7"},
+]
+
+[package.dependencies]
+aiosignal = ">=1.1.2"
+async-timeout = {version = ">=4.0,<5.0", markers = "python_version < \"3.11\""}
+attrs = ">=17.3.0"
+frozenlist = ">=1.1.1"
+multidict = ">=4.5,<7.0"
+yarl = ">=1.0,<2.0"
+
+[package.extras]
+speedups = ["Brotli", "aiodns", "brotlicffi"]
+
+[[package]]
+name = "aiosignal"
+version = "1.3.1"
+description = "aiosignal: a list of registered asynchronous callbacks"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"},
+ {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"},
+]
+
+[package.dependencies]
+frozenlist = ">=1.1.0"
+
+[[package]]
+name = "annotated-types"
+version = "0.6.0"
+description = "Reusable constraint types to use with typing.Annotated"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"},
+ {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"},
+]
+
+[package.dependencies]
+typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""}
+
+[[package]]
+name = "anyio"
+version = "3.7.1"
+description = "High level compatibility layer for multiple asynchronous event loop implementations"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"},
+ {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"},
+]
+
+[package.dependencies]
+exceptiongroup = {version = "*", markers = "python_version < \"3.11\""}
+idna = ">=2.8"
+sniffio = ">=1.1"
+
+[package.extras]
+doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"]
+test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
+trio = ["trio (<0.22)"]
+
+[[package]]
+name = "async-timeout"
+version = "4.0.3"
+description = "Timeout context manager for asyncio programs"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0