feat(yandexweather): add yandexweather api

This commit is contained in:
2026-08-28 10:01:49 +03:00
parent a92b63b855
commit 50c4221b8d
33 changed files with 506 additions and 74 deletions
+15 -2
View File
@@ -1,6 +1,8 @@
from pathlib import Path
from typing import TypeVar
from gallery.sketch.source import ApiSource
from gallery.sketch.api import Api, S
from gallery.sketch.source import DEFAULT_REQUEST_MODE, ApiSource, RequestMode
class MockSource(ApiSource):
@@ -10,8 +12,19 @@ class MockSource(ApiSource):
self._path = path
self._mapping = mapping
async def request(self, endpoint: str) -> str:
async def request(self, endpoint: str, /, mode: RequestMode = DEFAULT_REQUEST_MODE) -> str:
for pattern, filename in self._mapping.items():
if pattern in endpoint:
return (self._path / filename).read_text()
raise ValueError(endpoint)
API = Api[S]
A = TypeVar("A", bound=API)
def create_mock_api(api_type: type[A], mock_source: MockSource) -> A:
api = api_type()
# pylint: disable=protected-access
api._build_source = lambda: mock_source
return api
+7 -1
View File
@@ -1,8 +1,14 @@
from pathlib import Path
from gallery.painting.openweather.openweather import OpenWeather
from tests.common.mock import MockSource
OPENWEATHER_MOCK_SOURCE = MockSource(
class OpenWeatherMockSource(MockSource, OpenWeather):
pass
OPENWEATHER_MOCK_SOURCE = OpenWeatherMockSource(
Path(__file__).parent,
{
"forecast": "forecast.json",
+57
View File
@@ -0,0 +1,57 @@
[
{
"title": "Орёл",
"description": "Орёл",
"coords": { "lat": 52.97075653, "lon": 36.06435776 },
"uri": "//yandex.ru/pogoda?name=%D0%9E%D1%80%D1%91%D0%BB&kind=locality",
"geoId": 10,
"slug": "10",
"kind": "locality",
"distance": { "value": null, "text": "" },
"url": "//yandex.ru/pogoda?name=%D0%9E%D1%80%D1%91%D0%BB&kind=locality"
},
{
"title": "село Орёл-Изумруд",
"description": "Краснодарский край",
"coords": { "lat": 43.46733475, "lon": 39.92550659 },
"uri": "//yandex.ru/pogoda?name=%D0%9A%D1%80%D0%B0%D1%81%D0%BD%D0%BE%D0%B4%D0%B0%D1%80%D1%81%D0%BA%D0%B8%D0%B9+%D0%BA%D1%80%D0%B0%D0%B9%2C+%D0%B3%D0%BE%D1%80%D0%BE%D0%B4%D1%81%D0%BA%D0%BE%D0%B9+%D0%BE%D0%BA%D1%80%D1%83%D0%B3+%D0%A1%D0%BE%D1%87%D0%B8%2C+%D1%81%D0%B5%D0%BB%D0%BE+%D0%9E%D1%80%D1%91%D0%BB-%D0%98%D0%B7%D1%83%D0%BC%D1%80%D1%83%D0%B4&kind=locality",
"geoId": 211278,
"slug": "211278",
"kind": "locality",
"distance": { "value": null, "text": "" },
"url": "//yandex.ru/pogoda?name=%D0%9A%D1%80%D0%B0%D1%81%D0%BD%D0%BE%D0%B4%D0%B0%D1%80%D1%81%D0%BA%D0%B8%D0%B9+%D0%BA%D1%80%D0%B0%D0%B9%2C+%D0%B3%D0%BE%D1%80%D0%BE%D0%B4%D1%81%D0%BA%D0%BE%D0%B9+%D0%BE%D0%BA%D1%80%D1%83%D0%B3+%D0%A1%D0%BE%D1%87%D0%B8%2C+%D1%81%D0%B5%D0%BB%D0%BE+%D0%9E%D1%80%D1%91%D0%BB-%D0%98%D0%B7%D1%83%D0%BC%D1%80%D1%83%D0%B4&kind=locality"
},
{
"title": "деревня Орёл",
"description": "Республика Татарстан (Татарстан)",
"coords": { "lat": 55.56605148, "lon": 49.06790161 },
"uri": "//yandex.ru/pogoda?name=%D0%A0%D0%B5%D1%81%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0+%D0%A2%D0%B0%D1%82%D0%B0%D1%80%D1%81%D1%82%D0%B0%D0%BD+%28%D0%A2%D0%B0%D1%82%D0%B0%D1%80%D1%81%D1%82%D0%B0%D0%BD%29%2C+%D0%9B%D0%B0%D0%B8%D1%88%D0%B5%D0%B2%D1%81%D0%BA%D0%B8%D0%B9+%D1%80%D0%B0%D0%B9%D0%BE%D0%BD%2C+%D0%9E%D1%80%D0%BB%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B5+%D1%81%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%BE%D0%B5+%D0%BF%D0%BE%D1%81%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5%2C+%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BD%D1%8F+%D0%9E%D1%80%D1%91%D0%BB&kind=locality",
"geoId": 140917,
"slug": "140917",
"kind": "locality",
"distance": { "value": null, "text": "" },
"url": "//yandex.ru/pogoda?name=%D0%A0%D0%B5%D1%81%D0%BF%D1%83%D0%B1%D0%BB%D0%B8%D0%BA%D0%B0+%D0%A2%D0%B0%D1%82%D0%B0%D1%80%D1%81%D1%82%D0%B0%D0%BD+%28%D0%A2%D0%B0%D1%82%D0%B0%D1%80%D1%81%D1%82%D0%B0%D0%BD%29%2C+%D0%9B%D0%B0%D0%B8%D1%88%D0%B5%D0%B2%D1%81%D0%BA%D0%B8%D0%B9+%D1%80%D0%B0%D0%B9%D0%BE%D0%BD%2C+%D0%9E%D1%80%D0%BB%D0%BE%D0%B2%D1%81%D0%BA%D0%BE%D0%B5+%D1%81%D0%B5%D0%BB%D1%8C%D1%81%D0%BA%D0%BE%D0%B5+%D0%BF%D0%BE%D1%81%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5%2C+%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BD%D1%8F+%D0%9E%D1%80%D1%91%D0%BB&kind=locality"
},
{
"title": "посёлок Орёл",
"description": "Пермский край",
"coords": { "lat": 59.33684921, "lon": 56.58647919 },
"uri": "//yandex.ru/pogoda?name=%D0%9F%D0%B5%D1%80%D0%BC%D1%81%D0%BA%D0%B8%D0%B9+%D0%BA%D1%80%D0%B0%D0%B9%2C+%D0%BC%D1%83%D0%BD%D0%B8%D1%86%D0%B8%D0%BF%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9+%D0%BE%D0%BA%D1%80%D1%83%D0%B3+%D0%91%D0%B5%D1%80%D0%B5%D0%B7%D0%BD%D0%B8%D0%BA%D0%B8%2C+%D0%BF%D0%BE%D1%81%D1%91%D0%BB%D0%BE%D0%BA+%D0%9E%D1%80%D1%91%D0%BB&kind=locality",
"geoId": 135862,
"slug": "135862",
"kind": "locality",
"distance": { "value": null, "text": "" },
"url": "//yandex.ru/pogoda?name=%D0%9F%D0%B5%D1%80%D0%BC%D1%81%D0%BA%D0%B8%D0%B9+%D0%BA%D1%80%D0%B0%D0%B9%2C+%D0%BC%D1%83%D0%BD%D0%B8%D1%86%D0%B8%D0%BF%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9+%D0%BE%D0%BA%D1%80%D1%83%D0%B3+%D0%91%D0%B5%D1%80%D0%B5%D0%B7%D0%BD%D0%B8%D0%BA%D0%B8%2C+%D0%BF%D0%BE%D1%81%D1%91%D0%BB%D0%BE%D0%BA+%D0%9E%D1%80%D1%91%D0%BB&kind=locality"
},
{
"title": "Пуэрто-Франсиско-де-Орельяна",
"description": "Провинция Орельяна",
"coords": { "lat": -0.4602830112, "lon": -76.99185944 },
"uri": "//yandex.ru/pogoda?name=%D0%9F%D1%80%D0%BE%D0%B2%D0%B8%D0%BD%D1%86%D0%B8%D1%8F+%D0%9E%D1%80%D0%B5%D0%BB%D1%8C%D1%8F%D0%BD%D0%B0%2C+%D0%9F%D1%83%D1%8D%D1%80%D1%82%D0%BE-%D0%A4%D1%80%D0%B0%D0%BD%D1%81%D0%B8%D1%81%D0%BA%D0%BE-%D0%B4%D0%B5-%D0%9E%D1%80%D0%B5%D0%BB%D1%8C%D1%8F%D0%BD%D0%B0&kind=weather",
"geoId": 111891,
"slug": "111891",
"kind": "weather",
"distance": { "value": null, "text": "" },
"url": "//yandex.ru/pogoda?name=%D0%9F%D1%80%D0%BE%D0%B2%D0%B8%D0%BD%D1%86%D0%B8%D1%8F+%D0%9E%D1%80%D0%B5%D0%BB%D1%8C%D1%8F%D0%BD%D0%B0%2C+%D0%9F%D1%83%D1%8D%D1%80%D1%82%D0%BE-%D0%A4%D1%80%D0%B0%D0%BD%D1%81%D0%B8%D1%81%D0%BA%D0%BE-%D0%B4%D0%B5-%D0%9E%D1%80%D0%B5%D0%BB%D1%8C%D1%8F%D0%BD%D0%B0&kind=weather"
}
]
+2 -3
View File
@@ -3,14 +3,13 @@ import datetime
import pytest
from gallery.painting.gismeteo.api import GismeteoApi
from tests.common.mock import create_mock_api
from tests.data.gismeteo import GISMETEO_MOCK_SOURCE
@pytest.fixture(name="gismeteo_api", scope="module")
def gismeteo_api_fixture() -> GismeteoApi:
api = GismeteoApi()
api.SOURCE = GISMETEO_MOCK_SOURCE
return api
return create_mock_api(GismeteoApi, GISMETEO_MOCK_SOURCE)
async def test_search(gismeteo_api: GismeteoApi):
+2 -3
View File
@@ -3,14 +3,13 @@ import datetime
import pytest
from gallery.painting.matchtv.api import MatchTvApi
from tests.common.mock import create_mock_api
from tests.data.matchtv import MATCHTV_MOCK_SOURCE
@pytest.fixture(name="matchtv_api", scope="module")
def matchtv_api_fixture() -> MatchTvApi:
api = MatchTvApi()
api.SOURCE = MATCHTV_MOCK_SOURCE
return api
return create_mock_api(MatchTvApi, MATCHTV_MOCK_SOURCE)
async def test_search(matchtv_api: MatchTvApi):
+2 -9
View File
@@ -3,20 +3,13 @@ import datetime
import pytest
from gallery.painting.openweather.api import OpenWeatherApi
from gallery.painting.openweather.openweather import OpenWeather
from tests.common.mock import create_mock_api
from tests.data.openweather import OPENWEATHER_MOCK_SOURCE
@pytest.fixture(name="openweather_api", scope="module")
def openweather_api_fixture() -> OpenWeatherApi:
class MockOpenWeather(OpenWeather):
def __init__(self):
super().__init__("")
self._source = OPENWEATHER_MOCK_SOURCE
api = OpenWeatherApi()
api.SOURCE = MockOpenWeather()
return api
return create_mock_api(OpenWeatherApi, OPENWEATHER_MOCK_SOURCE)
async def test_search(openweather_api: OpenWeatherApi):
+2 -3
View File
@@ -3,14 +3,13 @@ import datetime
import pytest
from gallery.painting.yandextv.api import YandexTvApi
from tests.common.mock import create_mock_api
from tests.data.yandextv import YANDEXTV_MOCK_SOURCE
@pytest.fixture(name="yandextv_api", scope="module")
def yandextv_api_fixture() -> YandexTvApi:
api = YandexTvApi()
api.SOURCE = YANDEXTV_MOCK_SOURCE
return api
return create_mock_api(YandexTvApi, YANDEXTV_MOCK_SOURCE)
async def test_search(yandextv_api: YandexTvApi):