isobar-cli 1.3.3__tar.gz → 1.3.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. {isobar_cli-1.3.3/src/isobar_cli.egg-info → isobar_cli-1.3.5}/PKG-INFO +6 -49
  2. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/README.md +5 -48
  3. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/pyproject.toml +1 -1
  4. isobar_cli-1.3.5/src/isobar_cli/__init__.py +1 -0
  5. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/src/isobar_cli/api.py +13 -13
  6. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/src/isobar_cli/main.py +18 -10
  7. {isobar_cli-1.3.3 → isobar_cli-1.3.5/src/isobar_cli.egg-info}/PKG-INFO +6 -49
  8. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/tests/test_isobar_extra.py +34 -2
  9. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/tests/test_main.py +16 -0
  10. isobar_cli-1.3.3/src/isobar_cli/__init__.py +0 -1
  11. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/LICENSE +0 -0
  12. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/setup.cfg +0 -0
  13. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/src/isobar_cli/config.py +0 -0
  14. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/src/isobar_cli/location.py +0 -0
  15. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/src/isobar_cli/logic.py +0 -0
  16. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/src/isobar_cli/models.py +0 -0
  17. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/src/isobar_cli/ui.py +0 -0
  18. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/src/isobar_cli.egg-info/SOURCES.txt +0 -0
  19. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/src/isobar_cli.egg-info/dependency_links.txt +0 -0
  20. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/src/isobar_cli.egg-info/entry_points.txt +0 -0
  21. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/src/isobar_cli.egg-info/requires.txt +0 -0
  22. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/src/isobar_cli.egg-info/top_level.txt +0 -0
  23. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/tests/test_api.py +0 -0
  24. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/tests/test_location.py +0 -0
  25. {isobar_cli-1.3.3 → isobar_cli-1.3.5}/tests/test_ui.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: isobar-cli
3
- Version: 1.3.3
3
+ Version: 1.3.5
4
4
  Summary: A terminal weather tool with industrial aesthetic, focusing on Real Feel and Windchill.
5
5
  Author: Beau Bremer / KnowOneActual
6
6
  License-Expression: MIT
@@ -44,13 +44,15 @@ Dynamic: license-file
44
44
  ![License](https://img.shields.io/badge/license-MIT-green)
45
45
  ![Security Scan](https://github.com/KnowOneActual/isobar-cli/actions/workflows/security.yml/badge.svg)
46
46
 
47
+ **I'm currently working on improving the layout. Thanks so much for your patience with any little hiccups that might come up along the way!**
48
+
47
49
  A terminal weather tool designed to provide a fast, clean sense of what the weather **feels like** outside; right now and for the week ahead. Built with Python and Rich.
48
50
 
49
51
  ## Philosophy
50
52
 
51
53
  Isobar CLI answers a simple question: **"What does it feel like outside right now, and do I need a jacket?"**
52
54
 
53
- Most weather apps overwhelm with data. Isobar strips away everything except what matters when deciding how to prepare for the day.
55
+ Most weather apps are overwhelmed with data. Isobar strips away everything except what matters when deciding how to prepare for the day.
54
56
 
55
57
  ### Design Principles
56
58
  - **Essential over comprehensive** — Show Real Feel, not 47 data points.
@@ -214,52 +216,8 @@ isobar --install-completion bash
214
216
  ### Industrial Aesthetic (v1.3.0+)
215
217
 
216
218
  ```
217
- ┌─ WEATHER OBSERVATORY ─┐
218
- CHICAGO
219
- ┌─────┬──────────────────────┬────────────────┬────────────────┐
220
- │ │ METRIC │ READING │ STATUS │
221
- ├─────┼──────────────────────┼────────────────┼────────────────┤
222
- │ ☀️ │ CONDITIONS │ MAINLY CLEAR │ ◇ │
223
- │ 🌡️ │ TEMPERATURE │ 75.2°F │ [███░░░░░░░] │
224
- │ 🤔 │ REAL FEEL │ 78.5°F │ ▲ 3.3°F │
225
- │ 💨 │ WIND SPEED │ 12.4 mph │ GENTLE │
226
- │ 💧 │ HUMIDITY │ 65% │ [▓▓▓░░] │
227
- │ 😷 │ AIR QUALITY │ 45 │ GOOD ◇ │
228
- │ ☔ │ PRECIPITATION │ 30% (6h) │ [▓░░] │
229
- │ │ FORECAST │ LIGHT RAIN LIKELY │ │
230
- │ 🌅 │ SUNRISE │ 06:29 │ DAWN │
231
- │ 🌇 │ SUNSET │ 17:37 │ DUSK │
232
- │ ☀️ │ UV INDEX │ 6.5 │ HIGH ☀️☀️☀️ │
233
- │ ⚡ │ GUST ALERT │ 25 mph │ ⚠️ SEVERE │
234
- └─────┴──────────────────────┴────────────────┴────────────────┘
235
-
236
- ┌─ TREND ANALYSIS ─┐
237
- ↑ 5.2°F WARMER THAN YESTERDAY
238
- └──────────────────┘
239
-
240
- ┌─ PREPARATION PROTOCOL ─┐
241
- ⚠️ HIGH PRIORITY
242
- ▶ Wind gusts up to 25 mph - secure loose items
243
- ▲ RECOMMENDED
244
- ▶ Light jacket recommended
245
- ▶ Sunscreen recommended (UV: High)
246
- ○ ADVISORY
247
- ▶ Sunglasses recommended for glare
248
- └─────────────────────────┘
249
-
250
- ┌─ FORECAST PANEL ─┐
251
- CHICAGO
252
- ┌──────┬──┬────────────────────┬───────┬───────┬───────┬────────┐
253
- │ DAY │ │ CONDITIONS │ HIGH │ LOW │ RAIN% │ STATUS │
254
- ├──────┼──┼────────────────────┼───────┼───────┼───────┼────────┤
255
- │ TODAY│☀️│ MAINLY CLEAR │ 78.7°F│ 63.9°F│ 30% │ ○ │
256
- │ TUE │⛅│ PARTLY CLOUDY │ 82.4°F│ 65.4°F│ 20% │ ○ │
257
- │ WED │🌦️│ LIGHT DRIZZLE │ 76.8°F│ 60.9°F│ 45% │ ● │
258
- │ THU │☀️│ CLEAR SKY │ 80.3°F│ 63.5°F│ 10% │ ○ │
259
- └──────┴──┴────────────────────┴───────┴───────┴───────┴────────┘
260
- ```
219
+ Coming soon..
261
220
  ```
262
-
263
221
  ## 🛠 Tech Stack
264
222
 
265
223
  | Tool | Purpose |
@@ -273,7 +231,7 @@ CHICAGO
273
231
  | [requests-mock](https://requests-mock.readthedocs.io/) | API testing |
274
232
  | [Ruff](https://docs.astral.sh/ruff/) | Linting and formatting |
275
233
  | [pip-audit](https://github.com/pypa/pip-audit) | Dependency security scanning |
276
- | **Phase 7 Features** | **Intuition & Analysis** |
234
+ | New improvemets | **Intuition & Analysis** |
277
235
  | `config.py` | Persistent home city configuration |
278
236
  | Enhanced `logic.py` | Preparation guidance, UV monitoring, gust alerts |
279
237
  | Updated `ui.py` | Contextual display of insights |
@@ -281,7 +239,6 @@ CHICAGO
281
239
  | Configurable API Endpoints | Environment variable support for custom APIs |
282
240
  | Enhanced Error Handling | Specific exception catching with timeouts |
283
241
  | Timezone Support | Optional `pytz` dependency for local time display |
284
- | **v1.3.0 Features** | **Industrial Aesthetic** |
285
242
  | Industrial UI Design | Retro-futuristic weather observatory dashboard |
286
243
  | Visual Gauges | Temperature and humidity gauge visualizations |
287
244
  | Severity Indicators | Weather condition severity classification |
@@ -9,13 +9,15 @@
9
9
  ![License](https://img.shields.io/badge/license-MIT-green)
10
10
  ![Security Scan](https://github.com/KnowOneActual/isobar-cli/actions/workflows/security.yml/badge.svg)
11
11
 
12
+ **I'm currently working on improving the layout. Thanks so much for your patience with any little hiccups that might come up along the way!**
13
+
12
14
  A terminal weather tool designed to provide a fast, clean sense of what the weather **feels like** outside; right now and for the week ahead. Built with Python and Rich.
13
15
 
14
16
  ## Philosophy
15
17
 
16
18
  Isobar CLI answers a simple question: **"What does it feel like outside right now, and do I need a jacket?"**
17
19
 
18
- Most weather apps overwhelm with data. Isobar strips away everything except what matters when deciding how to prepare for the day.
20
+ Most weather apps are overwhelmed with data. Isobar strips away everything except what matters when deciding how to prepare for the day.
19
21
 
20
22
  ### Design Principles
21
23
  - **Essential over comprehensive** — Show Real Feel, not 47 data points.
@@ -179,52 +181,8 @@ isobar --install-completion bash
179
181
  ### Industrial Aesthetic (v1.3.0+)
180
182
 
181
183
  ```
182
- ┌─ WEATHER OBSERVATORY ─┐
183
- CHICAGO
184
- ┌─────┬──────────────────────┬────────────────┬────────────────┐
185
- │ │ METRIC │ READING │ STATUS │
186
- ├─────┼──────────────────────┼────────────────┼────────────────┤
187
- │ ☀️ │ CONDITIONS │ MAINLY CLEAR │ ◇ │
188
- │ 🌡️ │ TEMPERATURE │ 75.2°F │ [███░░░░░░░] │
189
- │ 🤔 │ REAL FEEL │ 78.5°F │ ▲ 3.3°F │
190
- │ 💨 │ WIND SPEED │ 12.4 mph │ GENTLE │
191
- │ 💧 │ HUMIDITY │ 65% │ [▓▓▓░░] │
192
- │ 😷 │ AIR QUALITY │ 45 │ GOOD ◇ │
193
- │ ☔ │ PRECIPITATION │ 30% (6h) │ [▓░░] │
194
- │ │ FORECAST │ LIGHT RAIN LIKELY │ │
195
- │ 🌅 │ SUNRISE │ 06:29 │ DAWN │
196
- │ 🌇 │ SUNSET │ 17:37 │ DUSK │
197
- │ ☀️ │ UV INDEX │ 6.5 │ HIGH ☀️☀️☀️ │
198
- │ ⚡ │ GUST ALERT │ 25 mph │ ⚠️ SEVERE │
199
- └─────┴──────────────────────┴────────────────┴────────────────┘
200
-
201
- ┌─ TREND ANALYSIS ─┐
202
- ↑ 5.2°F WARMER THAN YESTERDAY
203
- └──────────────────┘
204
-
205
- ┌─ PREPARATION PROTOCOL ─┐
206
- ⚠️ HIGH PRIORITY
207
- ▶ Wind gusts up to 25 mph - secure loose items
208
- ▲ RECOMMENDED
209
- ▶ Light jacket recommended
210
- ▶ Sunscreen recommended (UV: High)
211
- ○ ADVISORY
212
- ▶ Sunglasses recommended for glare
213
- └─────────────────────────┘
214
-
215
- ┌─ FORECAST PANEL ─┐
216
- CHICAGO
217
- ┌──────┬──┬────────────────────┬───────┬───────┬───────┬────────┐
218
- │ DAY │ │ CONDITIONS │ HIGH │ LOW │ RAIN% │ STATUS │
219
- ├──────┼──┼────────────────────┼───────┼───────┼───────┼────────┤
220
- │ TODAY│☀️│ MAINLY CLEAR │ 78.7°F│ 63.9°F│ 30% │ ○ │
221
- │ TUE │⛅│ PARTLY CLOUDY │ 82.4°F│ 65.4°F│ 20% │ ○ │
222
- │ WED │🌦️│ LIGHT DRIZZLE │ 76.8°F│ 60.9°F│ 45% │ ● │
223
- │ THU │☀️│ CLEAR SKY │ 80.3°F│ 63.5°F│ 10% │ ○ │
224
- └──────┴──┴────────────────────┴───────┴───────┴───────┴────────┘
225
- ```
184
+ Coming soon..
226
185
  ```
227
-
228
186
  ## 🛠 Tech Stack
229
187
 
230
188
  | Tool | Purpose |
@@ -238,7 +196,7 @@ CHICAGO
238
196
  | [requests-mock](https://requests-mock.readthedocs.io/) | API testing |
239
197
  | [Ruff](https://docs.astral.sh/ruff/) | Linting and formatting |
240
198
  | [pip-audit](https://github.com/pypa/pip-audit) | Dependency security scanning |
241
- | **Phase 7 Features** | **Intuition & Analysis** |
199
+ | New improvemets | **Intuition & Analysis** |
242
200
  | `config.py` | Persistent home city configuration |
243
201
  | Enhanced `logic.py` | Preparation guidance, UV monitoring, gust alerts |
244
202
  | Updated `ui.py` | Contextual display of insights |
@@ -246,7 +204,6 @@ CHICAGO
246
204
  | Configurable API Endpoints | Environment variable support for custom APIs |
247
205
  | Enhanced Error Handling | Specific exception catching with timeouts |
248
206
  | Timezone Support | Optional `pytz` dependency for local time display |
249
- | **v1.3.0 Features** | **Industrial Aesthetic** |
250
207
  | Industrial UI Design | Retro-futuristic weather observatory dashboard |
251
208
  | Visual Gauges | Temperature and humidity gauge visualizations |
252
209
  | Severity Indicators | Weather condition severity classification |
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "isobar-cli"
7
- version = "1.3.3"
7
+ version = "1.3.5"
8
8
  description = "A terminal weather tool with industrial aesthetic, focusing on Real Feel and Windchill."
9
9
  authors = [
10
10
  { name="Beau Bremer / KnowOneActual" },
@@ -0,0 +1 @@
1
+ __version__ = "1.3.5"
@@ -15,6 +15,12 @@ CACHE_DIR = Path.home() / ".cache" / "isobar"
15
15
  CACHE_DIR.mkdir(parents=True, exist_ok=True)
16
16
 
17
17
 
18
+ class WeatherAPIError(Exception):
19
+ """Raised when the weather or geocoding API request fails."""
20
+ pass
21
+
22
+
23
+
18
24
  class GeocodingClient:
19
25
  @classmethod
20
26
  def get_base_url(cls) -> str:
@@ -31,17 +37,9 @@ class GeocodingClient:
31
37
  response.raise_for_status()
32
38
  return response.json().get("results", [])
33
39
  except requests.exceptions.RequestException as e:
34
- # Log error for debugging but don't crash
35
- import sys
36
-
37
- print(f"Geocoding error for '{city}': {e}", file=sys.stderr)
38
- return []
40
+ raise WeatherAPIError(f"Geocoding error for '{city}': {e}") from e
39
41
  except Exception as e:
40
- # Catch-all for unexpected errors
41
- import sys
42
-
43
- print(f"Unexpected geocoding error for '{city}': {e}", file=sys.stderr)
44
- return []
42
+ raise WeatherAPIError(f"Unexpected geocoding error for '{city}': {e}") from e
45
43
 
46
44
 
47
45
  class WeatherClient:
@@ -128,7 +126,10 @@ def get_cached_cities() -> list[str]:
128
126
 
129
127
  def get_city_suggestions(city: str) -> list[str]:
130
128
  """Fetches a list of likely city name matches for a given input string."""
131
- results = GeocodingClient.search(city, count=5)
129
+ try:
130
+ results = GeocodingClient.search(city, count=5)
131
+ except WeatherAPIError:
132
+ return []
132
133
  suggestions = []
133
134
  for loc in results:
134
135
  region = loc.get("admin1", loc.get("country", ""))
@@ -175,8 +176,7 @@ def get_weather_data(city: str, metric: bool = False) -> Optional[WeatherData]:
175
176
  api_data = weather_client.fetch()
176
177
  aqi_value = AirQualityClient.get_aqi(lat, lon)
177
178
  except requests.RequestException as e:
178
- print(f"Error fetching weather: {e}")
179
- return None
179
+ raise WeatherAPIError(f"Error fetching weather: {e}") from e
180
180
 
181
181
  current = api_data["current"]
182
182
  hourly = api_data["hourly"]
@@ -3,7 +3,12 @@ from typing import Annotated, Optional
3
3
  import typer
4
4
  from rich.console import Console
5
5
 
6
- from isobar_cli.api import get_cached_cities, get_city_suggestions, get_weather_data
6
+ from isobar_cli.api import (
7
+ WeatherAPIError,
8
+ get_cached_cities,
9
+ get_city_suggestions,
10
+ get_weather_data,
11
+ )
7
12
  from isobar_cli.config import clear_home_city, get_home_city, set_home_city
8
13
  from isobar_cli.location import get_auto_location
9
14
  from isobar_cli.ui import (
@@ -161,15 +166,18 @@ def _run_weather_logic(
161
166
  results = []
162
167
  for city_name in cities_to_fetch:
163
168
  full_city = city_name.replace("_", " ")
164
- weather = get_weather_data(full_city, metric=metric)
165
- if weather:
166
- results.append(weather)
167
- else:
168
- console.print(f"[bold red]❌ '{full_city}' not found.[/bold red]")
169
- suggestions = get_city_suggestions(full_city)
170
- if suggestions:
171
- suggest_str = ", ".join(suggestions[:3])
172
- console.print(f"[dim]Did you mean: {suggest_str}?[/dim]")
169
+ try:
170
+ weather = get_weather_data(full_city, metric=metric)
171
+ if weather:
172
+ results.append(weather)
173
+ else:
174
+ console.print(f"[bold red]❌ '{full_city}' not found.[/bold red]")
175
+ suggestions = get_city_suggestions(full_city)
176
+ if suggestions:
177
+ suggest_str = ", ".join(suggestions[:3])
178
+ console.print(f"[dim]Did you mean: {suggest_str}?[/dim]")
179
+ except WeatherAPIError as e:
180
+ console.print(f"[bold red]❌ {e}[/bold red]")
173
181
 
174
182
  if not results:
175
183
  raise typer.Exit(code=1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: isobar-cli
3
- Version: 1.3.3
3
+ Version: 1.3.5
4
4
  Summary: A terminal weather tool with industrial aesthetic, focusing on Real Feel and Windchill.
5
5
  Author: Beau Bremer / KnowOneActual
6
6
  License-Expression: MIT
@@ -44,13 +44,15 @@ Dynamic: license-file
44
44
  ![License](https://img.shields.io/badge/license-MIT-green)
45
45
  ![Security Scan](https://github.com/KnowOneActual/isobar-cli/actions/workflows/security.yml/badge.svg)
46
46
 
47
+ **I'm currently working on improving the layout. Thanks so much for your patience with any little hiccups that might come up along the way!**
48
+
47
49
  A terminal weather tool designed to provide a fast, clean sense of what the weather **feels like** outside; right now and for the week ahead. Built with Python and Rich.
48
50
 
49
51
  ## Philosophy
50
52
 
51
53
  Isobar CLI answers a simple question: **"What does it feel like outside right now, and do I need a jacket?"**
52
54
 
53
- Most weather apps overwhelm with data. Isobar strips away everything except what matters when deciding how to prepare for the day.
55
+ Most weather apps are overwhelmed with data. Isobar strips away everything except what matters when deciding how to prepare for the day.
54
56
 
55
57
  ### Design Principles
56
58
  - **Essential over comprehensive** — Show Real Feel, not 47 data points.
@@ -214,52 +216,8 @@ isobar --install-completion bash
214
216
  ### Industrial Aesthetic (v1.3.0+)
215
217
 
216
218
  ```
217
- ┌─ WEATHER OBSERVATORY ─┐
218
- CHICAGO
219
- ┌─────┬──────────────────────┬────────────────┬────────────────┐
220
- │ │ METRIC │ READING │ STATUS │
221
- ├─────┼──────────────────────┼────────────────┼────────────────┤
222
- │ ☀️ │ CONDITIONS │ MAINLY CLEAR │ ◇ │
223
- │ 🌡️ │ TEMPERATURE │ 75.2°F │ [███░░░░░░░] │
224
- │ 🤔 │ REAL FEEL │ 78.5°F │ ▲ 3.3°F │
225
- │ 💨 │ WIND SPEED │ 12.4 mph │ GENTLE │
226
- │ 💧 │ HUMIDITY │ 65% │ [▓▓▓░░] │
227
- │ 😷 │ AIR QUALITY │ 45 │ GOOD ◇ │
228
- │ ☔ │ PRECIPITATION │ 30% (6h) │ [▓░░] │
229
- │ │ FORECAST │ LIGHT RAIN LIKELY │ │
230
- │ 🌅 │ SUNRISE │ 06:29 │ DAWN │
231
- │ 🌇 │ SUNSET │ 17:37 │ DUSK │
232
- │ ☀️ │ UV INDEX │ 6.5 │ HIGH ☀️☀️☀️ │
233
- │ ⚡ │ GUST ALERT │ 25 mph │ ⚠️ SEVERE │
234
- └─────┴──────────────────────┴────────────────┴────────────────┘
235
-
236
- ┌─ TREND ANALYSIS ─┐
237
- ↑ 5.2°F WARMER THAN YESTERDAY
238
- └──────────────────┘
239
-
240
- ┌─ PREPARATION PROTOCOL ─┐
241
- ⚠️ HIGH PRIORITY
242
- ▶ Wind gusts up to 25 mph - secure loose items
243
- ▲ RECOMMENDED
244
- ▶ Light jacket recommended
245
- ▶ Sunscreen recommended (UV: High)
246
- ○ ADVISORY
247
- ▶ Sunglasses recommended for glare
248
- └─────────────────────────┘
249
-
250
- ┌─ FORECAST PANEL ─┐
251
- CHICAGO
252
- ┌──────┬──┬────────────────────┬───────┬───────┬───────┬────────┐
253
- │ DAY │ │ CONDITIONS │ HIGH │ LOW │ RAIN% │ STATUS │
254
- ├──────┼──┼────────────────────┼───────┼───────┼───────┼────────┤
255
- │ TODAY│☀️│ MAINLY CLEAR │ 78.7°F│ 63.9°F│ 30% │ ○ │
256
- │ TUE │⛅│ PARTLY CLOUDY │ 82.4°F│ 65.4°F│ 20% │ ○ │
257
- │ WED │🌦️│ LIGHT DRIZZLE │ 76.8°F│ 60.9°F│ 45% │ ● │
258
- │ THU │☀️│ CLEAR SKY │ 80.3°F│ 63.5°F│ 10% │ ○ │
259
- └──────┴──┴────────────────────┴───────┴───────┴───────┴────────┘
260
- ```
219
+ Coming soon..
261
220
  ```
262
-
263
221
  ## 🛠 Tech Stack
264
222
 
265
223
  | Tool | Purpose |
@@ -273,7 +231,7 @@ CHICAGO
273
231
  | [requests-mock](https://requests-mock.readthedocs.io/) | API testing |
274
232
  | [Ruff](https://docs.astral.sh/ruff/) | Linting and formatting |
275
233
  | [pip-audit](https://github.com/pypa/pip-audit) | Dependency security scanning |
276
- | **Phase 7 Features** | **Intuition & Analysis** |
234
+ | New improvemets | **Intuition & Analysis** |
277
235
  | `config.py` | Persistent home city configuration |
278
236
  | Enhanced `logic.py` | Preparation guidance, UV monitoring, gust alerts |
279
237
  | Updated `ui.py` | Contextual display of insights |
@@ -281,7 +239,6 @@ CHICAGO
281
239
  | Configurable API Endpoints | Environment variable support for custom APIs |
282
240
  | Enhanced Error Handling | Specific exception catching with timeouts |
283
241
  | Timezone Support | Optional `pytz` dependency for local time display |
284
- | **v1.3.0 Features** | **Industrial Aesthetic** |
285
242
  | Industrial UI Design | Retro-futuristic weather observatory dashboard |
286
243
  | Visual Gauges | Temperature and humidity gauge visualizations |
287
244
  | Severity Indicators | Weather condition severity classification |
@@ -198,14 +198,46 @@ def test_get_weather_data_hourly_index_error(requests_mock):
198
198
 
199
199
 
200
200
  def test_get_weather_data_request_exception(requests_mock):
201
+ import pytest
201
202
  import requests
202
203
 
204
+ from isobar_cli.api import WeatherAPIError
205
+
203
206
  requests_mock.get(
204
207
  "https://geocoding-api.open-meteo.com/v1/search",
205
208
  exc=requests.exceptions.RequestException("Connection error"),
206
209
  )
207
- result = get_weather_data("FailCity")
208
- assert result is None
210
+ with pytest.raises(WeatherAPIError):
211
+ get_weather_data("FailCity")
212
+
213
+
214
+ def test_get_weather_data_forecast_request_exception(requests_mock):
215
+ import pytest
216
+ import requests
217
+
218
+ from isobar_cli.api import WeatherAPIError
219
+
220
+ geo_data = {
221
+ "results": [
222
+ {
223
+ "name": "Chicago",
224
+ "latitude": 41.85,
225
+ "longitude": -87.65,
226
+ "admin1": "Illinois",
227
+ "country": "United States",
228
+ }
229
+ ]
230
+ }
231
+ requests_mock.get(
232
+ "https://geocoding-api.open-meteo.com/v1/search",
233
+ json=geo_data,
234
+ )
235
+ requests_mock.get(
236
+ "https://api.open-meteo.com/v1/forecast",
237
+ exc=requests.exceptions.RequestException("Weather connection error"),
238
+ )
239
+ with pytest.raises(WeatherAPIError):
240
+ get_weather_data("Chicago")
209
241
 
210
242
 
211
243
  # --- Main Tests ---
@@ -109,3 +109,19 @@ def test_main_not_found_with_suggestions(mock_api):
109
109
  assert result.exit_code == 1
110
110
  assert "'Unknown' not found" in result.output
111
111
  assert "Did you mean: Suggested City?" in result.output
112
+
113
+
114
+ def test_main_weather_api_error(monkeypatch):
115
+ from isobar_cli.api import WeatherAPIError
116
+
117
+ def mock_get_weather_data(city, metric=False):
118
+ raise WeatherAPIError("Mocked API connection timeout")
119
+
120
+ monkeypatch.setattr("isobar_cli.main.get_weather_data", mock_get_weather_data)
121
+
122
+ result = runner.invoke(
123
+ app, ["Chicago"], color=False, env={"TERM": "dumb", "NO_COLOR": "1"}
124
+ )
125
+ assert result.exit_code == 1
126
+ assert "Mocked API connection timeout" in result.output
127
+ assert "not found" not in result.output
@@ -1 +0,0 @@
1
- __version__ = "1.3.3"
File without changes
File without changes
File without changes
File without changes