weathr 1.0.0__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.
- weathr-1.0.0/PKG-INFO +202 -0
- weathr-1.0.0/README.md +172 -0
- weathr-1.0.0/pyproject.toml +74 -0
- weathr-1.0.0/pyproject.toml.orig +66 -0
- weathr-1.0.0/src/weather/__init__.py +1 -0
- weathr-1.0.0/src/weather/__main__.py +4 -0
- weathr-1.0.0/src/weather/app.py +74 -0
- weathr-1.0.0/src/weather/cache.py +139 -0
- weathr-1.0.0/src/weather/cli.py +157 -0
- weathr-1.0.0/src/weather/config.py +77 -0
- weathr-1.0.0/src/weather/exceptions.py +14 -0
- weathr-1.0.0/src/weather/logging.py +26 -0
- weathr-1.0.0/src/weather/models.py +84 -0
- weathr-1.0.0/src/weather/onboarding.py +83 -0
- weathr-1.0.0/src/weather/providers/__init__.py +3 -0
- weathr-1.0.0/src/weather/providers/aqi/__init__.py +5 -0
- weathr-1.0.0/src/weather/providers/aqi/base.py +9 -0
- weathr-1.0.0/src/weather/providers/aqi/openmeteo.py +55 -0
- weathr-1.0.0/src/weather/providers/aqi/openweather.py +52 -0
- weathr-1.0.0/src/weather/providers/base.py +32 -0
- weathr-1.0.0/src/weather/providers/geocoding/__init__.py +5 -0
- weathr-1.0.0/src/weather/providers/geocoding/base.py +9 -0
- weathr-1.0.0/src/weather/providers/geocoding/nominatim.py +47 -0
- weathr-1.0.0/src/weather/providers/geocoding/openmeteo.py +59 -0
- weathr-1.0.0/src/weather/providers/geolocation/__init__.py +7 -0
- weathr-1.0.0/src/weather/providers/geolocation/base.py +9 -0
- weathr-1.0.0/src/weather/providers/geolocation/countryis.py +43 -0
- weathr-1.0.0/src/weather/providers/geolocation/freeipapi.py +36 -0
- weathr-1.0.0/src/weather/providers/geolocation/ipinfo.py +43 -0
- weathr-1.0.0/src/weather/providers/geolocation/ipwhois.py +38 -0
- weathr-1.0.0/src/weather/providers/weather/__init__.py +4 -0
- weathr-1.0.0/src/weather/providers/weather/base.py +11 -0
- weathr-1.0.0/src/weather/providers/weather/openmeteo.py +134 -0
- weathr-1.0.0/src/weather/services/__init__.py +6 -0
- weathr-1.0.0/src/weather/services/aqi.py +42 -0
- weathr-1.0.0/src/weather/services/geocoding.py +35 -0
- weathr-1.0.0/src/weather/services/geolocation.py +37 -0
- weathr-1.0.0/src/weather/services/weather.py +43 -0
- weathr-1.0.0/src/weather/ui/conditions.py +281 -0
- weathr-1.0.0/src/weather/ui/presentation.py +114 -0
- weathr-1.0.0/src/weather/ui/render.py +66 -0
- weathr-1.0.0/src/weather/ui/themes/__init__.py +3 -0
- weathr-1.0.0/src/weather/ui/themes/base.py +17 -0
- weathr-1.0.0/src/weather/ui/themes/default.py +71 -0
- weathr-1.0.0/src/weather/utils.py +56 -0
weathr-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: weathr
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A fast terminal weather client
|
|
5
|
+
Keywords: weather,cli,terminal,air-quality
|
|
6
|
+
Author: Harshit Pawar
|
|
7
|
+
Author-email: Harshit Pawar <hpchess64@gmail.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Topic :: Utilities
|
|
18
|
+
Requires-Dist: httpx>=0.28.1
|
|
19
|
+
Requires-Dist: msgspec>=0.21.1
|
|
20
|
+
Requires-Dist: platformdirs>=4.11.2
|
|
21
|
+
Requires-Dist: rich>=15.0.0
|
|
22
|
+
Requires-Dist: tomli-w>=1.2.0
|
|
23
|
+
Requires-Dist: typer>=0.27.1
|
|
24
|
+
Requires-Python: >=3.12
|
|
25
|
+
Project-URL: Homepage, https://github.com/harshitpawar64/weather
|
|
26
|
+
Project-URL: Repository, https://github.com/harshitpawar64/weather
|
|
27
|
+
Project-URL: Issues, https://github.com/harshitpawar64/weather/issues
|
|
28
|
+
Project-URL: Changelog, https://github.com/harshitpawar64/weather/blob/main/CHANGELOG.md
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# weather ⛅
|
|
32
|
+
|
|
33
|
+
[](https://github.com/harshitpawar64/weather/actions/workflows/ci.yml)
|
|
34
|
+
[](https://www.python.org/)
|
|
35
|
+
|
|
36
|
+
[](https://docs.astral.sh/uv/)
|
|
37
|
+
[](https://docs.astral.sh/ruff/)
|
|
38
|
+
[](https://docs.astral.sh/ty/)
|
|
39
|
+
[](https://docs.pytest.org/)
|
|
40
|
+
|
|
41
|
+
A fast, beautiful terminal weather client with multi-provider fallbacks, AQI metrics, and smart caching.
|
|
42
|
+
|
|
43
|
+

|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Install
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# With uv (recommended)
|
|
51
|
+
uv tool install weathr
|
|
52
|
+
|
|
53
|
+
# With pipx
|
|
54
|
+
pipx install weathr
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## First-Run Onboarding
|
|
60
|
+
|
|
61
|
+
On your first launch (or at any time by running `weather setup`), `weather` launches an interactive onboarding flow. It detects your location using IP geolocation, asks to confirm your preferred city, and lets you pick your default unit system.
|
|
62
|
+
|
|
63
|
+

|
|
64
|
+
|
|
65
|
+
Your preferences are saved locally (`config.toml`). After setup, simply running `weather` displays your local forecast instantly.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Usage
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Check current weather + 6-day forecast for your saved location
|
|
73
|
+
weather
|
|
74
|
+
|
|
75
|
+
# Check weather for any city, landmark, address or postal codes
|
|
76
|
+
weather -l Tokyo
|
|
77
|
+
weather -l "Berlin, Germany"
|
|
78
|
+
weather -l 94103
|
|
79
|
+
|
|
80
|
+
# Specify total days of forecast (1 to 16 days)
|
|
81
|
+
weather -d 3
|
|
82
|
+
weather -l London -d 10
|
|
83
|
+
|
|
84
|
+
# Override unit system
|
|
85
|
+
weather --metric # °C, km/h, mm
|
|
86
|
+
weather --imperial # °F, mph, in
|
|
87
|
+
|
|
88
|
+
# Output JSON for scripting
|
|
89
|
+
weather --json
|
|
90
|
+
weather -l "Reykjavik" --json | jq .weather.current.temperature
|
|
91
|
+
|
|
92
|
+
# Verbose logging
|
|
93
|
+
weather -l "Berlin" -v
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## CLI Options & Subcommands
|
|
99
|
+
|
|
100
|
+
### Options
|
|
101
|
+
|
|
102
|
+
| **Flag** | **Short** | **Default** | **Description** |
|
|
103
|
+
|--------------|:---------:|:--------------:|-------------------------------------------------|
|
|
104
|
+
| `--location` | `-l` | Saved location | City, landmark, address or postal codes. |
|
|
105
|
+
| `--days` | `-d` | `7` | Total days of forecast, including today. (1-16) |
|
|
106
|
+
| `--metric` | | | Use metric units (°C, km/h, mm) |
|
|
107
|
+
| `--imperial` | | | Use imperial units (°F, mph, in) |
|
|
108
|
+
| `--json` | | `False` | Output result in JSON format. |
|
|
109
|
+
| `--theme` | `-t` | `default` | Theme to use for rendering output. |
|
|
110
|
+
| `--verbose` | `-v` | `False` | Enable verbose debug logging. |
|
|
111
|
+
| `--version` | | | Show version and exit. |
|
|
112
|
+
|
|
113
|
+
### Default File Paths
|
|
114
|
+
|
|
115
|
+
| **OS** | **Config Path (`weather config path`)** | **Cache Path (`weather cache path`)** |
|
|
116
|
+
|---------|-----------------------------------------------------|-------------------------------------------|
|
|
117
|
+
| Linux | `~/.config/weather/config.toml` | `~/.cache/weather/cache.bin` |
|
|
118
|
+
| macOS | `~/Library/Application Support/weather/config.toml` | `~/Library/Caches/weather/cache.bin` |
|
|
119
|
+
| Windows | `%LOCALAPPDATA%\weather\config.toml` | `%LOCALAPPDATA%\weather\Cache\cache.bin` |
|
|
120
|
+
|
|
121
|
+
### Cache Management
|
|
122
|
+
|
|
123
|
+
`weather` maintains a fast binary msgpack cache to eliminate redundant network calls:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# View cache file location
|
|
127
|
+
weather cache path
|
|
128
|
+
|
|
129
|
+
# Remove expired entries (>1 week old)
|
|
130
|
+
weather cache prune
|
|
131
|
+
|
|
132
|
+
# Wipe the cache entirely
|
|
133
|
+
weather cache clear
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Configuration Management
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Run interactive setup at any time
|
|
140
|
+
weather setup
|
|
141
|
+
|
|
142
|
+
# Display config file path
|
|
143
|
+
weather config path
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Config file example (`config.toml`):
|
|
147
|
+
|
|
148
|
+
```toml
|
|
149
|
+
unit_system = "metric"
|
|
150
|
+
theme = "default"
|
|
151
|
+
|
|
152
|
+
[location]
|
|
153
|
+
latitude = 37.774929
|
|
154
|
+
longitude = -122.419416
|
|
155
|
+
display_name = "San Francisco, California, United States"
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Optional: OpenWeather API Key
|
|
161
|
+
|
|
162
|
+
`weather` works out of the box with **zero configuration** using Open-Meteo. If you want [OpenWeather](https://openweathermap.org/) as an automatic secondary fallback for Air Quality (AQI) data, [obtain a free API key](https://openweathermap.org/api) and set the `OPENWEATHER_API_KEY` environment variable:
|
|
163
|
+
|
|
164
|
+
### Linux & macOS (Bash / Zsh)
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
echo 'export OPENWEATHER_API_KEY="your_api_key_here"' >> ~/.bashrc # or ~/.zshrc
|
|
168
|
+
source ~/.bashrc # or source ~/.zshrc
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Windows (Powershell)
|
|
172
|
+
|
|
173
|
+
```powershell
|
|
174
|
+
[System.Environment]::SetEnvironmentVariable('OPENWEATHER_API_KEY', 'your_api_key_here', 'User')
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Attributions & Data Sources
|
|
180
|
+
|
|
181
|
+
This project is powered by several free and open data providers:
|
|
182
|
+
|
|
183
|
+
- **Weather Forecast**:
|
|
184
|
+
- [Open-Meteo](https://open-meteo.com/en/docs/) (Weather Forecast API) under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
|
|
185
|
+
|
|
186
|
+
- **Air Quality**:
|
|
187
|
+
- [Open-Meteo](https://open-meteo.com/en/docs/air-quality-api/) (Air Quality API) under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
|
|
188
|
+
- [OpenWeather](https://openweathermap.org/) (Air Pollution API).
|
|
189
|
+
- **Geocoding**:
|
|
190
|
+
- [Nominatim](https://nominatim.org/) (Data © [OpenStreetMap contributors](https://www.openstreetmap.org/copyright)).
|
|
191
|
+
- [Open-Meteo](https://open-meteo.com/en/docs/geocoding-api/) (Geocoding API) under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
|
|
192
|
+
- **IP Geolocation**:
|
|
193
|
+
- [IPWhoIs](https://ipwhois.io/)
|
|
194
|
+
- [FreeIPAPI](https://freeipapi.com/)
|
|
195
|
+
- [CountryIs](https://country.is/)
|
|
196
|
+
- [IPInfo](https://ipinfo.io/)
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## License
|
|
201
|
+
|
|
202
|
+
This project is licensed under the [MIT License](LICENSE).
|
weathr-1.0.0/README.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# weather ⛅
|
|
2
|
+
|
|
3
|
+
[](https://github.com/harshitpawar64/weather/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.python.org/)
|
|
5
|
+
|
|
6
|
+
[](https://docs.astral.sh/uv/)
|
|
7
|
+
[](https://docs.astral.sh/ruff/)
|
|
8
|
+
[](https://docs.astral.sh/ty/)
|
|
9
|
+
[](https://docs.pytest.org/)
|
|
10
|
+
|
|
11
|
+
A fast, beautiful terminal weather client with multi-provider fallbacks, AQI metrics, and smart caching.
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# With uv (recommended)
|
|
21
|
+
uv tool install weathr
|
|
22
|
+
|
|
23
|
+
# With pipx
|
|
24
|
+
pipx install weathr
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## First-Run Onboarding
|
|
30
|
+
|
|
31
|
+
On your first launch (or at any time by running `weather setup`), `weather` launches an interactive onboarding flow. It detects your location using IP geolocation, asks to confirm your preferred city, and lets you pick your default unit system.
|
|
32
|
+
|
|
33
|
+

|
|
34
|
+
|
|
35
|
+
Your preferences are saved locally (`config.toml`). After setup, simply running `weather` displays your local forecast instantly.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Check current weather + 6-day forecast for your saved location
|
|
43
|
+
weather
|
|
44
|
+
|
|
45
|
+
# Check weather for any city, landmark, address or postal codes
|
|
46
|
+
weather -l Tokyo
|
|
47
|
+
weather -l "Berlin, Germany"
|
|
48
|
+
weather -l 94103
|
|
49
|
+
|
|
50
|
+
# Specify total days of forecast (1 to 16 days)
|
|
51
|
+
weather -d 3
|
|
52
|
+
weather -l London -d 10
|
|
53
|
+
|
|
54
|
+
# Override unit system
|
|
55
|
+
weather --metric # °C, km/h, mm
|
|
56
|
+
weather --imperial # °F, mph, in
|
|
57
|
+
|
|
58
|
+
# Output JSON for scripting
|
|
59
|
+
weather --json
|
|
60
|
+
weather -l "Reykjavik" --json | jq .weather.current.temperature
|
|
61
|
+
|
|
62
|
+
# Verbose logging
|
|
63
|
+
weather -l "Berlin" -v
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## CLI Options & Subcommands
|
|
69
|
+
|
|
70
|
+
### Options
|
|
71
|
+
|
|
72
|
+
| **Flag** | **Short** | **Default** | **Description** |
|
|
73
|
+
|--------------|:---------:|:--------------:|-------------------------------------------------|
|
|
74
|
+
| `--location` | `-l` | Saved location | City, landmark, address or postal codes. |
|
|
75
|
+
| `--days` | `-d` | `7` | Total days of forecast, including today. (1-16) |
|
|
76
|
+
| `--metric` | | | Use metric units (°C, km/h, mm) |
|
|
77
|
+
| `--imperial` | | | Use imperial units (°F, mph, in) |
|
|
78
|
+
| `--json` | | `False` | Output result in JSON format. |
|
|
79
|
+
| `--theme` | `-t` | `default` | Theme to use for rendering output. |
|
|
80
|
+
| `--verbose` | `-v` | `False` | Enable verbose debug logging. |
|
|
81
|
+
| `--version` | | | Show version and exit. |
|
|
82
|
+
|
|
83
|
+
### Default File Paths
|
|
84
|
+
|
|
85
|
+
| **OS** | **Config Path (`weather config path`)** | **Cache Path (`weather cache path`)** |
|
|
86
|
+
|---------|-----------------------------------------------------|-------------------------------------------|
|
|
87
|
+
| Linux | `~/.config/weather/config.toml` | `~/.cache/weather/cache.bin` |
|
|
88
|
+
| macOS | `~/Library/Application Support/weather/config.toml` | `~/Library/Caches/weather/cache.bin` |
|
|
89
|
+
| Windows | `%LOCALAPPDATA%\weather\config.toml` | `%LOCALAPPDATA%\weather\Cache\cache.bin` |
|
|
90
|
+
|
|
91
|
+
### Cache Management
|
|
92
|
+
|
|
93
|
+
`weather` maintains a fast binary msgpack cache to eliminate redundant network calls:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# View cache file location
|
|
97
|
+
weather cache path
|
|
98
|
+
|
|
99
|
+
# Remove expired entries (>1 week old)
|
|
100
|
+
weather cache prune
|
|
101
|
+
|
|
102
|
+
# Wipe the cache entirely
|
|
103
|
+
weather cache clear
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Configuration Management
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Run interactive setup at any time
|
|
110
|
+
weather setup
|
|
111
|
+
|
|
112
|
+
# Display config file path
|
|
113
|
+
weather config path
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Config file example (`config.toml`):
|
|
117
|
+
|
|
118
|
+
```toml
|
|
119
|
+
unit_system = "metric"
|
|
120
|
+
theme = "default"
|
|
121
|
+
|
|
122
|
+
[location]
|
|
123
|
+
latitude = 37.774929
|
|
124
|
+
longitude = -122.419416
|
|
125
|
+
display_name = "San Francisco, California, United States"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Optional: OpenWeather API Key
|
|
131
|
+
|
|
132
|
+
`weather` works out of the box with **zero configuration** using Open-Meteo. If you want [OpenWeather](https://openweathermap.org/) as an automatic secondary fallback for Air Quality (AQI) data, [obtain a free API key](https://openweathermap.org/api) and set the `OPENWEATHER_API_KEY` environment variable:
|
|
133
|
+
|
|
134
|
+
### Linux & macOS (Bash / Zsh)
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
echo 'export OPENWEATHER_API_KEY="your_api_key_here"' >> ~/.bashrc # or ~/.zshrc
|
|
138
|
+
source ~/.bashrc # or source ~/.zshrc
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Windows (Powershell)
|
|
142
|
+
|
|
143
|
+
```powershell
|
|
144
|
+
[System.Environment]::SetEnvironmentVariable('OPENWEATHER_API_KEY', 'your_api_key_here', 'User')
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Attributions & Data Sources
|
|
150
|
+
|
|
151
|
+
This project is powered by several free and open data providers:
|
|
152
|
+
|
|
153
|
+
- **Weather Forecast**:
|
|
154
|
+
- [Open-Meteo](https://open-meteo.com/en/docs/) (Weather Forecast API) under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
|
|
155
|
+
|
|
156
|
+
- **Air Quality**:
|
|
157
|
+
- [Open-Meteo](https://open-meteo.com/en/docs/air-quality-api/) (Air Quality API) under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
|
|
158
|
+
- [OpenWeather](https://openweathermap.org/) (Air Pollution API).
|
|
159
|
+
- **Geocoding**:
|
|
160
|
+
- [Nominatim](https://nominatim.org/) (Data © [OpenStreetMap contributors](https://www.openstreetmap.org/copyright)).
|
|
161
|
+
- [Open-Meteo](https://open-meteo.com/en/docs/geocoding-api/) (Geocoding API) under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
|
|
162
|
+
- **IP Geolocation**:
|
|
163
|
+
- [IPWhoIs](https://ipwhois.io/)
|
|
164
|
+
- [FreeIPAPI](https://freeipapi.com/)
|
|
165
|
+
- [CountryIs](https://country.is/)
|
|
166
|
+
- [IPInfo](https://ipinfo.io/)
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## License
|
|
171
|
+
|
|
172
|
+
This project is licensed under the [MIT License](LICENSE).
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "weathr"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "A fast terminal weather client"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
requires-python = ">=3.12"
|
|
8
|
+
dependencies = [
|
|
9
|
+
"httpx>=0.28.1",
|
|
10
|
+
"msgspec>=0.21.1",
|
|
11
|
+
"platformdirs>=4.11.2",
|
|
12
|
+
"rich>=15.0.0",
|
|
13
|
+
"tomli-w>=1.2.0",
|
|
14
|
+
"typer>=0.27.1",
|
|
15
|
+
]
|
|
16
|
+
keywords = [
|
|
17
|
+
"weather",
|
|
18
|
+
"cli",
|
|
19
|
+
"terminal",
|
|
20
|
+
"air-quality",
|
|
21
|
+
]
|
|
22
|
+
classifiers = [
|
|
23
|
+
"Development Status :: 5 - Production/Stable",
|
|
24
|
+
"Environment :: Console",
|
|
25
|
+
"Intended Audience :: End Users/Desktop",
|
|
26
|
+
"Operating System :: OS Independent",
|
|
27
|
+
"Programming Language :: Python :: 3",
|
|
28
|
+
"Programming Language :: Python :: 3.12",
|
|
29
|
+
"Programming Language :: Python :: 3.13",
|
|
30
|
+
"Programming Language :: Python :: 3.14",
|
|
31
|
+
"Topic :: Utilities",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[[project.authors]]
|
|
35
|
+
name = "Harshit Pawar"
|
|
36
|
+
email = "hpchess64@gmail.com"
|
|
37
|
+
|
|
38
|
+
[project.urls]
|
|
39
|
+
Homepage = "https://github.com/harshitpawar64/weather"
|
|
40
|
+
Repository = "https://github.com/harshitpawar64/weather"
|
|
41
|
+
Issues = "https://github.com/harshitpawar64/weather/issues"
|
|
42
|
+
Changelog = "https://github.com/harshitpawar64/weather/blob/main/CHANGELOG.md"
|
|
43
|
+
|
|
44
|
+
[project.scripts]
|
|
45
|
+
weather = "weather.cli:app"
|
|
46
|
+
|
|
47
|
+
[build-system]
|
|
48
|
+
requires = ["uv_build>=0.12.3,<0.13.0"]
|
|
49
|
+
build-backend = "uv_build"
|
|
50
|
+
|
|
51
|
+
[dependency-groups]
|
|
52
|
+
dev = [
|
|
53
|
+
"pytest>=9.1.1",
|
|
54
|
+
"pytest-asyncio>=1.4.0",
|
|
55
|
+
"pytest-cov>=7.1.0",
|
|
56
|
+
"ruff>=0.16.2",
|
|
57
|
+
"ty>=0.0.71",
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
[tool.uv.build-backend]
|
|
61
|
+
module-name = "weather"
|
|
62
|
+
|
|
63
|
+
[tool.ruff.format]
|
|
64
|
+
skip-magic-trailing-comma = true
|
|
65
|
+
|
|
66
|
+
[tool.ruff.lint]
|
|
67
|
+
extend-select = ["I"]
|
|
68
|
+
|
|
69
|
+
[tool.ruff.lint.isort]
|
|
70
|
+
split-on-trailing-comma = false
|
|
71
|
+
|
|
72
|
+
[tool.pytest.ini_options]
|
|
73
|
+
asyncio_mode = "auto"
|
|
74
|
+
addopts = "--cov=weather --cov-report=term-missing --cov-branch -v"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "weathr"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "A fast terminal weather client"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
authors = [{ name = "Harshit Pawar", email = "hpchess64@gmail.com" }]
|
|
8
|
+
requires-python = ">=3.12"
|
|
9
|
+
dependencies = [
|
|
10
|
+
"httpx>=0.28.1",
|
|
11
|
+
"msgspec>=0.21.1",
|
|
12
|
+
"platformdirs>=4.11.2",
|
|
13
|
+
"rich>=15.0.0",
|
|
14
|
+
"tomli-w>=1.2.0",
|
|
15
|
+
"typer>=0.27.1",
|
|
16
|
+
]
|
|
17
|
+
keywords = ["weather", "cli", "terminal", "air-quality"]
|
|
18
|
+
classifiers = [
|
|
19
|
+
"Development Status :: 5 - Production/Stable",
|
|
20
|
+
"Environment :: Console",
|
|
21
|
+
"Intended Audience :: End Users/Desktop",
|
|
22
|
+
"Operating System :: OS Independent",
|
|
23
|
+
"Programming Language :: Python :: 3",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Programming Language :: Python :: 3.14",
|
|
27
|
+
"Topic :: Utilities",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
Homepage = "https://github.com/harshitpawar64/weather"
|
|
32
|
+
Repository = "https://github.com/harshitpawar64/weather"
|
|
33
|
+
Issues = "https://github.com/harshitpawar64/weather/issues"
|
|
34
|
+
Changelog = "https://github.com/harshitpawar64/weather/blob/main/CHANGELOG.md"
|
|
35
|
+
|
|
36
|
+
[project.scripts]
|
|
37
|
+
weather = "weather.cli:app"
|
|
38
|
+
|
|
39
|
+
[build-system]
|
|
40
|
+
requires = ["uv_build>=0.12.3,<0.13.0"]
|
|
41
|
+
build-backend = "uv_build"
|
|
42
|
+
|
|
43
|
+
[dependency-groups]
|
|
44
|
+
dev = [
|
|
45
|
+
"pytest>=9.1.1",
|
|
46
|
+
"pytest-asyncio>=1.4.0",
|
|
47
|
+
"pytest-cov>=7.1.0",
|
|
48
|
+
"ruff>=0.16.2",
|
|
49
|
+
"ty>=0.0.71",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
[tool.uv.build-backend]
|
|
53
|
+
module-name = "weather"
|
|
54
|
+
|
|
55
|
+
[tool.ruff.format]
|
|
56
|
+
skip-magic-trailing-comma = true
|
|
57
|
+
|
|
58
|
+
[tool.ruff.lint]
|
|
59
|
+
extend-select = ["I"]
|
|
60
|
+
|
|
61
|
+
[tool.ruff.lint.isort]
|
|
62
|
+
split-on-trailing-comma = false
|
|
63
|
+
|
|
64
|
+
[tool.pytest.ini_options]
|
|
65
|
+
asyncio_mode = "auto"
|
|
66
|
+
addopts = "--cov=weather --cov-report=term-missing --cov-branch -v"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.0.0" # x-release-please-version
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
|
|
3
|
+
import httpx
|
|
4
|
+
import msgspec
|
|
5
|
+
|
|
6
|
+
from weather.cache import Cache
|
|
7
|
+
from weather.config import Config
|
|
8
|
+
from weather.models import Theme, UnitSystem, WeatherResponse
|
|
9
|
+
from weather.onboarding import onboarding
|
|
10
|
+
from weather.services import (
|
|
11
|
+
AQIService,
|
|
12
|
+
GeocodingService,
|
|
13
|
+
GeolocationService,
|
|
14
|
+
WeatherService,
|
|
15
|
+
)
|
|
16
|
+
from weather.ui.render import render_weather
|
|
17
|
+
|
|
18
|
+
cache = Cache()
|
|
19
|
+
config = Config()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
async def run(
|
|
23
|
+
query: str | None,
|
|
24
|
+
unit_system: UnitSystem,
|
|
25
|
+
theme: Theme,
|
|
26
|
+
days: int,
|
|
27
|
+
json_output: bool,
|
|
28
|
+
) -> None:
|
|
29
|
+
async with httpx.AsyncClient(timeout=10.0) as client:
|
|
30
|
+
if query:
|
|
31
|
+
geocoder = GeocodingService(client, cache)
|
|
32
|
+
location = await geocoder.geocode(query)
|
|
33
|
+
elif config.location:
|
|
34
|
+
location = config.location
|
|
35
|
+
else:
|
|
36
|
+
location, unit_system = await onboarding(
|
|
37
|
+
GeolocationService(client), GeocodingService(client, cache)
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
config.save(location, unit_system)
|
|
41
|
+
|
|
42
|
+
weather_service = WeatherService(client, cache)
|
|
43
|
+
aqi_service = AQIService(client, cache)
|
|
44
|
+
|
|
45
|
+
weather, aqi = await asyncio.gather(
|
|
46
|
+
weather_service.get_weather(location, unit_system),
|
|
47
|
+
aqi_service.get_aqi(location),
|
|
48
|
+
return_exceptions=True,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
if isinstance(weather, BaseException):
|
|
52
|
+
raise weather
|
|
53
|
+
|
|
54
|
+
if isinstance(aqi, BaseException):
|
|
55
|
+
aqi = None
|
|
56
|
+
|
|
57
|
+
cache.save(location, weather, aqi, query)
|
|
58
|
+
|
|
59
|
+
response = WeatherResponse(location, weather, aqi)
|
|
60
|
+
|
|
61
|
+
if json_output:
|
|
62
|
+
print(msgspec.json.encode(response).decode())
|
|
63
|
+
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
render_weather(response, theme, days)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
async def run_setup() -> None:
|
|
70
|
+
async with httpx.AsyncClient(timeout=10.0) as client:
|
|
71
|
+
location, unit_system = await onboarding(
|
|
72
|
+
GeolocationService(client), GeocodingService(client, cache)
|
|
73
|
+
)
|
|
74
|
+
config.save(location, unit_system)
|