Skip to content

fix(weather): render readable WMO conditions - #85

Merged
IceCodeNew merged 2 commits into
masterfrom
codex/readable-wmo-weather
Jul 21, 2026
Merged

fix(weather): render readable WMO conditions#85
IceCodeNew merged 2 commits into
masterfrom
codex/readable-wmo-weather

Conversation

@IceCodeNew

@IceCodeNew IceCodeNew commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Summary

  • translate Open-Meteo WMO weather codes into readable conditions in the provider's fixed zh-CN source context
  • keep the complete mapping in validated packaged reference data
  • use a readable fallback and safe warning for unknown or malformed provider values

Root cause

Open-Meteo's numeric weather_code was copied directly into the source document as WMO天气代码<n>. The model could then repeat that provider-level representation in a user-facing message, including incorrectly describing code 53 as light rain instead of moderate drizzle.

Language behavior

OpenMeteoProvider produces a fixed zh-CN source document, matching its existing deterministic weather fields. The source document retains that actual language, and the model translates the complete source into each location's configured output language. The Chinese mapping therefore does not restrict the final briefing to Chinese or mix languages within one provider document.

User impact

Provider context now contains readable conditions such as 中等强度毛毛雨 instead of internal WMO codes. Final briefings continue to follow the location's configured output language. Unknown future codes remain readable without exposing the numeric identifier in the message.

Validation

  • prek run --all-files
  • uv run --with pytest --with pytest-cov -- pytest --cov --cov-branch --cov-report=xml (845 passed)
  • line coverage: 99.85% (master: 99.85%)
  • branch coverage: 99.52% (master: 99.52%)
  • CodeRabbit CLI review after fixes: 0 issues

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5bc893df-c9c0-45c4-9c26-729b7191e1c7

📥 Commits

Reviewing files that changed from the base of the PR and between d72be71 and e5a3f0c.

📒 Files selected for processing (6)
  • docs/design.md
  • tests/test_reference_data.py
  • tests/test_weather_context.py
  • weather_briefing/data/open_meteo_weather_codes.json
  • weather_briefing/reference_data.py
  • weather_briefing/weather_context.py

📝 Walkthrough

Walkthrough

新增 Open-Meteo 天气代码中文参考数据及严格校验逻辑。天气预报输出现在使用可读描述,未知或无效代码记录警告并回退为“未识别天气现象”,同时补充测试和设计文档。

Changes

Open-Meteo weather descriptions

Layer / File(s) Summary
Reference data contract
weather_briefing/data/open_meteo_weather_codes.json, weather_briefing/reference_data.py, tests/test_reference_data.py
新增中文天气代码映射;加载函数校验数据结构、代码格式和描述内容,并返回缓存的只读整数映射。测试覆盖有效数据及无效数据异常。
Weather output integration
weather_briefing/weather_context.py, tests/test_weather_context.py, docs/design.md
天气预报格式化使用中文天气描述;未知或无效代码记录警告并返回“未识别天气现象”。相关输出、回退行为和设计说明同步更新。

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested labels: 🕐 40+ Minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: rendering readable WMO weather conditions instead of raw codes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/readable-wmo-weather

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Checkov (3.3.8)
weather_briefing/data/open_meteo_weather_codes.json

Traceback (most recent call last):
File "/usr/local/bin/checkov", line 2, in
from checkov.main import Checkov
ModuleNotFoundError: No module named 'checkov'


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Render readable Chinese conditions for Open-Meteo WMO codes

🐞 Bug fix 🧪 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Translate Open-Meteo numeric WMO weather_code into readable Chinese conditions.
• Store and validate the full code→description mapping as packaged reference data.
• Add safe fallbacks and warnings for unknown or malformed provider values.
Diagram

graph TD
  A["OpenMeteoProvider"] --> B["weather_context.py"] --> C("WMO→中文描述") --> D["reference_data.py"] --> E[("open_meteo_weather_codes.json")]
  C --> F["Warning logs"]
  subgraph Legend
    direction LR
    _svc[Service] ~~~ _fn("Function") ~~~ _data[(Reference data)]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Hardcode an enum/dict mapping in Python
  • ➕ No runtime JSON parsing/validation path
  • ➕ Simpler packaging and fewer moving parts
  • ➖ Harder to update/extend without code changes
  • ➖ More likely to mix data maintenance with logic changes
  • ➖ Less reusable if other locales are added later
2. Use provider-supplied text (if available) and localize separately
  • ➕ Avoids maintaining a canonical WMO table in-repo
  • ➕ Keeps semantics aligned with upstream provider changes
  • ➖ Provider may not return Chinese text consistently
  • ➖ Localization/consistency becomes harder to control
  • ➖ Still needs safe fallback logic for missing/unknown values

Recommendation: Keep the PR’s approach: a packaged, validated reference-data mapping plus a safe fallback. It cleanly separates data from formatting logic, prevents leaking provider-internal codes into user output, and makes future maintenance (including adding locales) straightforward while keeping behavior predictable.

Files changed (6) +154 / -4

Enhancement (1) +32 / -0
open_meteo_weather_codes.jsonAdd packaged Chinese descriptions for Open-Meteo WMO weather codes +32/-0

Add packaged Chinese descriptions for Open-Meteo WMO weather codes

• Introduces a JSON reference dataset mapping supported WMO numeric weather codes to Chinese condition strings for Open-Meteo.

weather_briefing/data/open_meteo_weather_codes.json

Bug fix (2) +45 / -2
reference_data.pyLoad and validate Open-Meteo weather code descriptions as cached reference data +26/-0

Load and validate Open-Meteo weather code descriptions as cached reference data

• Adds a cached loader that reads open_meteo_weather_codes.json and validates structure, key format, and non-empty descriptions. Returns an immutable MappingProxyType to prevent accidental mutation at runtime.

weather_briefing/reference_data.py

weather_context.pyRender Open-Meteo weather_code using readable Chinese descriptions +19/-2

Render Open-Meteo weather_code using readable Chinese descriptions

• Replaces the previous 'WMO天气代码<n>' rendering with a description lookup via reference data. Adds a helper that logs warnings for unknown or invalid values and returns a readable fallback string.

weather_briefing/weather_context.py

Tests (2) +76 / -1
test_reference_data.pyAdd reference-data coverage for Open-Meteo weather code mapping +53/-0

Add reference-data coverage for Open-Meteo weather code mapping

• Extends packaged reference-data availability tests to assert the expected Open-Meteo WMO code set and a known translation (code 53). Adds parametrized tests ensuring invalid/malformed mapping structures are rejected with ReferenceDataError.

tests/test_reference_data.py

test_weather_context.pyVerify Open-Meteo forecasts render readable conditions and safe fallbacks +23/-1

Verify Open-Meteo forecasts render readable conditions and safe fallbacks

• Updates snapshot expectations to ensure WMO codes no longer appear in rendered forecasts. Adds unit tests for known code translation, unknown-code fallback with warning, and invalid-type fallback with warning.

tests/test_weather_context.py

Documentation (1) +1 / -1
design.mdDocument Open-Meteo WMO code translation and fallback behavior +1/-1

Document Open-Meteo WMO code translation and fallback behavior

• Updates the OpenMeteoProvider design note to describe translating WMO weather codes into readable Chinese conditions and logging a safe warning when unknown codes are encountered.

docs/design.md

@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.79%. Comparing base (d72be71) to head (e5a3f0c).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##           master      #85   +/-   ##
=======================================
  Coverage   99.79%   99.79%           
=======================================
  Files          45       45           
  Lines        8755     8800   +45     
  Branches      520      526    +6     
=======================================
+ Hits         8737     8782   +45     
  Misses         13       13           
  Partials        5        5           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@IceCodeNew
IceCodeNew merged commit 6c3c662 into master Jul 21, 2026
18 checks passed
@IceCodeNew
IceCodeNew deleted the codex/readable-wmo-weather branch July 21, 2026 12:22
@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 39 rules
✅ REVIEW.md

Grey Divider


Remediation recommended

1. Uncaught reference-data failure 🐞 Bug ☼ Reliability
Description
_open_meteo_weather_description() calls open_meteo_weather_code_descriptions() without handling
ReferenceDataError, so missing/malformed packaged data can raise an uncaught exception during
OpenMeteoProvider.fetch(). This makes the provider fail with a generic exception path (not
WeatherContextError) and can surface as late runtime failures instead of deterministic startup
validation or a readable fallback.
Code

weather_briefing/weather_context.py[R1043-1051]

+def _open_meteo_weather_description(value: object) -> str:
+    descriptions = open_meteo_weather_code_descriptions()
+    if type(value) is int and value in descriptions:
+        return descriptions[value]
+    if type(value) is int:
+        _LOGGER.warning("Unknown Open-Meteo weather code code=%d", value)
+    else:
+        _LOGGER.warning("Invalid Open-Meteo weather code value_type=%s", type(value).__name__)
+    return "未识别天气现象"
Relevance

⭐⭐⭐ High

PR #23 handled ReferenceDataError via warning+fallback; PR #77 emphasizes validated packaged
reference data boundaries.

PR-#23
PR-#77

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new formatting path depends on reference data that can raise ReferenceDataError; this exception
is not handled in OpenMeteoProvider.fetch(), which only translates _OpenMeteoResponseError and
common parsing/HTTP exceptions into WeatherContextError. As a result, reference-data failures will
bubble up as generic exceptions (and are logged/re-raised as such by LoggedWeatherContextProvider),
causing late runtime failures.

weather_briefing/weather_context.py[1043-1051]
weather_briefing/reference_data.py[145-168]
weather_briefing/weather_context.py[481-509]
weather_briefing/weather_context.py[111-138]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`_open_meteo_weather_description()` unconditionally calls `open_meteo_weather_code_descriptions()`, which can raise `ReferenceDataError` if `open_meteo_weather_codes.json` is missing/malformed. That exception is not caught in the Open-Meteo fetch path, so it can escape as a non-`WeatherContextError` and fail late (first Open-Meteo request) rather than deterministically at startup.

## Issue Context
Other critical reference data (e.g., localization tables) is loaded at module import time, which effectively “fails fast”. This new mapping is instead loaded lazily from inside formatting.

## Fix Focus Areas
Choose one of:
1) **Fail fast**: eager-load the mapping at module import time (similar to `_WEATHER_DOCUMENT_LABELS` / `_QWEATHER_FORMATS`).
2) **Degrade gracefully**: catch `ReferenceDataError` inside `_open_meteo_weather_description()` (or around forecast formatting) and return the readable fallback while logging once.

- weather_briefing/weather_context.py[51-54]
- weather_briefing/weather_context.py[1026-1051]
- weather_briefing/reference_data.py[145-168]
- weather_briefing/weather_context.py[481-509]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread weather_briefing/weather_context.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant