refactor(weather): remove OpenWeather, standardize README, fix infra #23

Merged
slaid098 merged 5 commits from refactor/readme-standardize-openweather into master 2026-08-12 14:20:28 +03:00
Owner

Что сделано

  • OpenWeather полностью выпилен: из weather.py удалены _GEOCODE_URL, _WEATHER_URL, _get_openweather_text(), _resolve_city_openweather(), _fetch_weather_openweather(), _format_weather(). В get_weather_text() убрана ветка выбора провайдера — всегда Open-Meteo. Обновлён docstring.
  • config.py: убрано поле openweather_api_key из Settings и из _load_settings().
  • .env.template: убран блок OPENWEATHER_API_KEY (строки 65-67), секция «Погода» оставлена только с WEATHER_DEFAULT_CITY.
  • tests/test_weather.py: убран api_key параметр из FakeSettings, удалены все OpenWeather-тесты (test_openweather_*, test_uses_openweather_when_key_set, test_fallback_to_open_meteo_when_no_key), все FakeSettings(api_key="")FakeSettings(). Добавлен test_default_city_used_when_no_arg взамен удалённого fallback-теста.
  • tests/test_config.py: убран assert s.openweather_api_key == "" и весь test_settings_openweather_key_from_env.
  • tests/conftest.py: убран os.environ.pop("OPENWEATHER_API_KEY", None). Заодно убраны unnecessary default type args (Generator[None, None, None]Generator[None]) — правило UP043 активировалось после поднятия target-version до py313.
  • README.md: полная переработка через create-readme tool — bilingual (EN/RU) с delimiter tags, features table, commands, configuration, quick start steps (download release zip).
  • assets/cover.png: сгенерирован через draw-image (template=cover, icon=mic, sub-icon=opencode).
  • pyproject.toml: target-version = "py312""py313" (ruff), python_version = "3.12""3.13" (mypy) — приведено в соответствие с requires-python = ">=3.13".
  • .python-version: создан, содержимое 3.13.
  • .github/dependabot.yml: создан (pip + github-actions, weekly).
  • AGENTS.md: убрано упоминание OPENWEATHER_API_KEY из секции Configuration.

Почему

Issue #22 — стандартизация README и зачистка legacy OpenWeather API. OpenWeather требовал регистрации и API-ключа, что противоречит принципу «работает из коробки» для незрячего пользователя. Open-Meteo бесплатен и не требует ключа — единственный провайдер погоды теперь. Также исправлены рассинхроны pyproject (requires-python>=3.13 при target-version=py312) и добавлен dependabot для актуальности зависимостей.

Watch out

  • uv.lock модифицирован (был до начала работы, не из этого PR) — не закоммичен.
  • assets/cover.meta.json (sidecar от draw-image) — не закоммичен, это metadata генерации.
  • Тестов стало 211 (было ~217) — удалено 6 OpenWeather-тестов, добавлен 1 новый test_default_city_used_when_no_arg.

Pending

Closes #22

Closes #22

## Что сделано - **OpenWeather полностью выпилен**: из `weather.py` удалены `_GEOCODE_URL`, `_WEATHER_URL`, `_get_openweather_text()`, `_resolve_city_openweather()`, `_fetch_weather_openweather()`, `_format_weather()`. В `get_weather_text()` убрана ветка выбора провайдера — всегда Open-Meteo. Обновлён docstring. - **config.py**: убрано поле `openweather_api_key` из `Settings` и из `_load_settings()`. - **.env.template**: убран блок `OPENWEATHER_API_KEY` (строки 65-67), секция «Погода» оставлена только с `WEATHER_DEFAULT_CITY`. - **tests/test_weather.py**: убран `api_key` параметр из `FakeSettings`, удалены все OpenWeather-тесты (`test_openweather_*`, `test_uses_openweather_when_key_set`, `test_fallback_to_open_meteo_when_no_key`), все `FakeSettings(api_key="")` → `FakeSettings()`. Добавлен `test_default_city_used_when_no_arg` взамен удалённого fallback-теста. - **tests/test_config.py**: убран `assert s.openweather_api_key == ""` и весь `test_settings_openweather_key_from_env`. - **tests/conftest.py**: убран `os.environ.pop("OPENWEATHER_API_KEY", None)`. Заодно убраны unnecessary default type args (`Generator[None, None, None]` → `Generator[None]`) — правило UP043 активировалось после поднятия target-version до py313. - **README.md**: полная переработка через `create-readme` tool — bilingual (EN/RU) с delimiter tags, features table, commands, configuration, quick start steps (download release zip). - **assets/cover.png**: сгенерирован через `draw-image` (template=cover, icon=mic, sub-icon=opencode). - **pyproject.toml**: `target-version = "py312"` → `"py313"` (ruff), `python_version = "3.12"` → `"3.13"` (mypy) — приведено в соответствие с `requires-python = ">=3.13"`. - **.python-version**: создан, содержимое `3.13`. - **.github/dependabot.yml**: создан (pip + github-actions, weekly). - **AGENTS.md**: убрано упоминание `OPENWEATHER_API_KEY` из секции Configuration. ## Почему Issue #22 — стандартизация README и зачистка legacy OpenWeather API. OpenWeather требовал регистрации и API-ключа, что противоречит принципу «работает из коробки» для незрячего пользователя. Open-Meteo бесплатен и не требует ключа — единственный провайдер погоды теперь. Также исправлены рассинхроны pyproject (`requires-python>=3.13` при `target-version=py312`) и добавлен dependabot для актуальности зависимостей. ## Watch out - `uv.lock` модифицирован (был до начала работы, не из этого PR) — не закоммичен. - `assets/cover.meta.json` (sidecar от `draw-image`) — не закоммичен, это metadata генерации. - Тестов стало 211 (было ~217) — удалено 6 OpenWeather-тестов, добавлен 1 новый `test_default_city_used_when_no_arg`. ## Pending — Closes #22 Closes #22
slaid098 merged commit aeba5faa35 into master 2026-08-12 14:20:28 +03:00
slaid098 deleted branch refactor/readme-standardize-openweather 2026-08-12 14:20:28 +03:00
Author
Owner

Code Review Summary

Чистый рефакторинг: полное удаление legacy-провайдера OpenWeather (код, конфиг, тесты, доки), стандартизация README через create-readme tool, фикс рассинхрона Python-версии в pyproject (py312→py313), добавлен dependabot. CI green, PR уже смержен.

Positives

  • Полная зачистка OpenWeather: rg openweather по всему репо — 0 совпадений. Удалены: _GEOCODE_URL, _WEATHER_URL, _get_openweather_text(), _resolve_city_openweather(), _fetch_weather_openweather(), _format_weather(), поле openweather_api_key в Settings, блок в .env.template, упоминание в AGENTS.md, 6 тестов. Чисто, без orphan-ссылок.
  • Cross-file consistency: get_weather_text() сигнатура не изменилась — все callers (nlu/handlers.py:26, tests/test_handlers.py:53, tests/test_workflow.py:76,261) работают без правок. Writer+reader paired update не нужен (удаление ветки, не смена контракта).
  • Python version sync: requires-python=">=3.13"target-version="py313" (ruff) ↔ python_version="3.13" (mypy) ↔ .python-version=3.13 — все 4 точки согласованы. Рассинхрон py312/py313 устранён.
  • conftest.py UP043: Generator[None, None, None]Generator[None] — корректное применение правила после поднятия target-version до py313.
  • README: все 6 delimiter tags присутствуют (tagline-en/ru, summary-en/ru, features-en/ru), bilingual EN/RU, features table, quick start steps (download release zip — правильно для desktop-приложения без install-команды).
  • Тесты: test_default_city_used_when_no_arg корректно заменяет удалённый test_fallback_to_open_meteo_when_no_key — проверяет реальное поведение (default city из settings при get_weather_text() без аргумента). 10 тестов в test_weather.py покрывают: success, city_not_found, network_error, format_missing_data, 5 WMO-code tests, default-city fallback.
  • weather.py после рефакторинга: 130 строк, все импорты используются (Any, requests, logger, settings), try/except/else pattern сохранён, loguru logging, приватные функции с _ prefix. Соответствует code-standards.
  • dependabot.yml: pip + github-actions, weekly — стандартная конфигурация.
  • PR body: 4 heading'а (Что сделано, Почему, Watch out, Pending) заполнены осмысленно, Closes #22 присутствует, Watch out прозрачно описывает незакоммиченные uv.lock и cover.meta.json.

Suggestions (info, not blocking)

  • .github/dependabot.yml [style] Нет trailing newline (EOF) — \ No newline at end of file в diff. То же для .python-version. POSIX-конвенция — файл должен заканчиваться newline. Не критично, но ruff/pre-commit могут ругаться на YAML в будущем.
  • assets/cover.meta.json [hygiene] Файл untracked (не в git, не в .gitignore) — будет постоянно светиться в git status. Стоит добавить cover.meta.json или *.meta.json в .gitignore, чтобы не мешать. Сейчас это просто noise, но при следующих PR будет отвлекать.
  • tests/test_weather.py:16,55,69,122 [style] import voice_assistant.services.weather as weather_mod повторяется в 4 тестах внутри функций. Можно вынести на module-level (после from unittest.mock import MagicMock) — ruff isort не против, тесты станут чище. Не блокирующее, текущий стиль работает.

Verdict: APPROVE

## Code Review Summary Чистый рефакторинг: полное удаление legacy-провайдера OpenWeather (код, конфиг, тесты, доки), стандартизация README через `create-readme` tool, фикс рассинхрона Python-версии в pyproject (py312→py313), добавлен dependabot. CI green, PR уже смержен. ### Positives - **Полная зачистка OpenWeather**: `rg openweather` по всему репо — 0 совпадений. Удалены: `_GEOCODE_URL`, `_WEATHER_URL`, `_get_openweather_text()`, `_resolve_city_openweather()`, `_fetch_weather_openweather()`, `_format_weather()`, поле `openweather_api_key` в Settings, блок в `.env.template`, упоминание в AGENTS.md, 6 тестов. Чисто, без orphan-ссылок. - **Cross-file consistency**: `get_weather_text()` сигнатура не изменилась — все callers (`nlu/handlers.py:26`, `tests/test_handlers.py:53`, `tests/test_workflow.py:76,261`) работают без правок. Writer+reader paired update не нужен (удаление ветки, не смена контракта). - **Python version sync**: `requires-python=">=3.13"` ↔ `target-version="py313"` (ruff) ↔ `python_version="3.13"` (mypy) ↔ `.python-version=3.13` — все 4 точки согласованы. Рассинхрон py312/py313 устранён. - **conftest.py UP043**: `Generator[None, None, None]` → `Generator[None]` — корректное применение правила после поднятия target-version до py313. - **README**: все 6 delimiter tags присутствуют (tagline-en/ru, summary-en/ru, features-en/ru), bilingual EN/RU, features table, quick start steps (download release zip — правильно для desktop-приложения без install-команды). - **Тесты**: `test_default_city_used_when_no_arg` корректно заменяет удалённый `test_fallback_to_open_meteo_when_no_key` — проверяет реальное поведение (default city из settings при `get_weather_text()` без аргумента). 10 тестов в test_weather.py покрывают: success, city_not_found, network_error, format_missing_data, 5 WMO-code tests, default-city fallback. - **weather.py после рефакторинга**: 130 строк, все импорты используются (`Any`, `requests`, `logger`, `settings`), try/except/else pattern сохранён, loguru logging, приватные функции с `_` prefix. Соответствует code-standards. - **dependabot.yml**: pip + github-actions, weekly — стандартная конфигурация. - **PR body**: 4 heading'а (Что сделано, Почему, Watch out, Pending) заполнены осмысленно, `Closes #22` присутствует, Watch out прозрачно описывает незакоммиченные `uv.lock` и `cover.meta.json`. ### Suggestions (info, not blocking) - **.github/dependabot.yml** [style] Нет trailing newline (EOF) — `\ No newline at end of file` в diff. То же для `.python-version`. POSIX-конвенция — файл должен заканчиваться newline. Не критично, но `ruff`/`pre-commit` могут ругаться на YAML в будущем. - **assets/cover.meta.json** [hygiene] Файл untracked (не в git, не в .gitignore) — будет постоянно светиться в `git status`. Стоит добавить `cover.meta.json` или `*.meta.json` в `.gitignore`, чтобы не мешать. Сейчас это просто noise, но при следующих PR будет отвлекать. - **tests/test_weather.py:16,55,69,122** [style] `import voice_assistant.services.weather as weather_mod` повторяется в 4 тестах внутри функций. Можно вынести на module-level (после `from unittest.mock import MagicMock`) — ruff isort не против, тесты станут чище. Не блокирующее, текущий стиль работает. ### Verdict: APPROVE
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
slaid098/voice_assistant!23
No description provided.