Weather App (CLI + Backend Core)
Summary
The Weather App is a command-line–driven weather reporting tool designed to aggregate, normalize, and present weather data from multiple public APIs. The project focuses on clean backend architecture, consistent data modeling, and a user-friendly CLI experience rather than a graphical interface.
This first official release represents a completed “core + interface” milestone: a reusable backend weather engine paired with an interactive command-line application. While intentionally lightweight on UI, the project emphasizes correctness, extensibility, and thoughtful API integration—making it a strong foundation for future frontends or automation use cases.
Links
Source Code (GitHub): https://github.com/bbornino/weather_backend
Tools & Tech Stack
- Language: Python 3
- Interface: Command-Line Interface (CLI)
- APIs Integrated:
- National Weather Service (NWS)
- OpenWeatherMap
- WeatherAPI
- OpenMeteo
- WeatherBit (Started, needs paid API service to finish)
- AccuWeather (Started, needs paid API service to finish)
- Data Handling:
- Unified internal weather data model
- JSON normalization across providers
- JSON User-level settings file
- Architecture:
- Modular scrapers per provider
- Shared utilities and formatting helpers
- Provider-agnostic core logic
Project Goals
This project was built with several deliberate goals in mind:
- Abstract away API differences
Each weather provider exposes different field names, units, and levels of detail. The app normalizes these into a consistent internal representation so downstream code never needs to care which API is in use. - Keep the CLI intuitive but powerful
The CLI is meant to be discoverable and readable, even for users who don’t live in terminals every day. - Design for extensibility
Adding a new weather provider should require minimal changes: implement a scraper, map fields, and plug it into the existing system. - Treat documentation and structure as first-class features
Clear naming, predictable behavior, and well-documented configuration are considered part of the deliverable—not afterthoughts.
Role & Responsibilities
This was a solo project covering the full development lifecycle, from initial design through implementation and documentation. The work focused on backend architecture, multi-API integration, data normalization, and building a clear, user-friendly command-line interface.
Challenges
Avoiding over-coupling between core logic and the CLI
Care was taken to keep the backend weather engine independent of the command-line interface so future frontends could be added without reworking the core.
Normalizing inconsistent API schemas
Each weather provider exposes overlapping but non-identical fields, units, and optional data. Designing a canonical weather model required balancing completeness with simplicity while ensuring missing or unsupported metrics could be handled safely.
Maintaining consistent output across providers
Presenting uniform CLI output despite differing data availability meant building defensive formatting and display logic that could gracefully adapt to partial responses.
Late-discovered integration issues
Some issues only surfaced once multiple providers were fully integrated into the shared reporting pipeline, prompting targeted refactors to utilities and data mappings. Full integration revealed that some providers required paid access for critical endpoints, leading to a conscious decision to deprioritize those integrations while preserving a flexible, provider-agnostic core.
Impact
This project resulted in a reusable, provider-agnostic weather core capable of aggregating and presenting data from multiple public APIs through a consistent interface. It serves as a practical foundation for future frontends or automation use cases, and as a concrete demonstration of designing around external dependencies, evolving requirements, and real-world API constraints.
Lessons Learned
- Identical weather metrics can vary significantly between providers due to differing measurement methods, timing, and derivation formulas.
- Evaluating API tier limitations and data semantics earlier would reduce rework during later integration stages.
Future Enhancements
Planned or potential next steps include:
- A lightweight web or TUI frontend using the existing core
- AWS Lambda Service
- Expanded forecast data
User Guide
Setup & Installation
Clone the repository and install the required dependencies:
git clone https://github.com/bbornino/weather_app.git
cd weather_app
pip install -r requirements.txt
The application runs on Python 3 and requires an internet connection for API access.
Environment Configuration
The Weather App can load sensitive values such as API keys and default locations from a .env file. Create a file named .env in the project root with the following format:
# API Keys for weather providers (replace with your own keys)
ACCUWEATHER_API_KEY=YOUR_ACCUWEATHER_KEY
WEATHERBIT_API_KEY=YOUR_WEATHERBIT_KEY
WEATHERAPI_API_KEY=YOUR_WEATHERAPI_KEY
OPENWEATHERMAP_API_KEY=YOUR_OPENWEATHERMAP_KEY
# Default home location (optional)
HOME_CITY="City, State"
HOME_LATITUDE=00.0000
HOME_LONGITUDE=-00.0000
Notes:
- Replace
YOUR_*_KEYwith valid API keys obtained from each provider. HOME_CITYis used as a convenient default location for weather queries.- Latitude and longitude are optional but allow more precise positioning if desired.
- The
.envfile is automatically loaded when running the CLI; no additional setup is required.
Running the Application
By default, the Weather App runs in interactive mode, providing a guided menu for exploring locations, APIs, units, fields, and forecasts.
Interactive Mode (Default)
Simply run:
python weather_cli.py
This launches the CLI menu, where you can:
- Add, remove, or select locations
- Enable or disable weather providers
- Choose units (imperial or metric)
- Select which fields to display
- Set forecast type (hours or days)
- Run the weather comparison
Non-Interactive Mode
For scripted or automated use, you can bypass the interactive menu by passing command-line arguments:
python weather_cli.py --no-interactive [options]
Options include:
location– select a named location--apis– comma-separated list of APIs to use--only– use only the specified APIs--units–imperialormetric--show– comma-separated fields--forecast-days/--forecast-hours– forecast duration
All settings are merged with defaults and any saved configuration.
Main Menu
By default, the application enters interactive mode and displays the main menu:
Weather CLI - Interactive Mode
Settings file - weather_settings.json
Selected location - home_city: Sacramento, California
Default location - home: 38.1,-121.3
Units - Temp: °F Speed: mph Distance: mi Pressure: inHg
Fields to show - temp, humidity
Forecast - None (0)
Enabled APIs - open_meteo, weatherapi, open_weather, national_weather_service
Menu:
L) Select location
A) Select APIs
U) Units
F) Fields to display
O) Forecast options
R) Run weather comparison
X) Exit
Menu Options
- L) Select location: Add, remove, or select which saved location to use.
- A) Select APIs: Enable or disable which weather providers to use. Providers that require API keys will display
[OFF] (API KEY ISSUE)if a valid key is not configured. - U) Units: Choose between imperial or metric units.
- F) Fields to display: Select which weather metrics (temperature, humidity, wind, etc.) to show in the output.
- O) Forecast options: Set forecast type (hours or days) or disable it.
- R) Run weather comparison: Fetch and display weather data from enabled APIs for the active location.
- X) Exit: Quit the CLI.
Location Auto-Detection
The Weather App uses saved locations and default settings to determine which location to fetch weather for:
- Default Location: If you have a default location configured in the
.envfile or through the CLI, it will automatically be selected when starting the application. - Active Location: During interactive mode, you can choose a different location for the current session. This overrides the default but does not permanently change it unless you save it.
- Latitude/Longitude: If provided in the
.envfile, these values are used for more precise positioning. Otherwise, the app falls back to city/state strings.
Note: There is currently no automatic geolocation based on IP or device location. Users must define a location manually or via configuration.
Example: Locations Menu
Selecting L brings up the interactive location management:
Locations:
- home: 38.1,-121.3 (default)
- home_city: Sacramento, California (active)
Options:
a) Add location
r) Remove location
s) Set default location
c) Set active location for this session
d) Done
- You can add new locations, remove old ones, or switch the default/active location for the session.
Example: APIs Menu
Selecting A shows the list of APIs and their status:
APIs (toggle by letter):
[a] accuweather [OFF] (API KEY ISSUE)
[n] national_weather_service [ON] (TBD)
[o] open_meteo [ON] (OK)
[w] open_weather [ON] (OK)
[p] weatherapi [ON] (OK)
[b] weatherbit [OFF] (API KEY ISSUE)
[?] View API descriptions
[d] Done
[?] shows a brief description of each provider.
Use the corresponding letter to toggle each API on or off.
ON means the API is enabled and ready, OFF (API KEY ISSUE) indicates that a key is missing or invalid.
Running a Weather Comparison
Once you have configured your locations and APIs, you can run a weather comparison by selecting R – Run weather comparison from the main menu. The CLI will fetch data from all enabled providers and display it in a table format.
Example Output
Displaying the Weather
Monday, January 12, 2026 at 08:58 AM
nws open_meteo open_weather WeatherApi
Temperature 39.2°F 39.6°F 43.97°F 39.6°F
Feels Like -- -- 42.84°F 38.9°F
Wind Chill -- -- -- 34.5°F
Heat Index -- -- -- 35.9°F
Dew Point 39.2°F -- -- 33.0°F
Wind Speed 0.0mph 1.7mph 3.02mph 2.2mph
Wind Gust -- -- -- 6.7mph
Wind Degree 0° 337° 342° 15°
Wind Direction N NNW NNW NNE
Humidity 100% -- 92% 100%
Pressure 30.36inHg -- 30.36inHg 30.36inHg
Visibility 8.0mi -- 6.21mi 8.0mi
Cloud Cover 0% -- 0% 0%
UV Index -- -- -- 0.2
Alerts / Extra Information
[nws]
- Condition: Clear
[open_meteo]
- Condition: State of sky on the whole unchanged
[open_weather]
- Condition: clear sky
[WeatherApi]
- Condition: Partly Cloudy
- Sunrise: 06:44 AM
- Sunset: 04:54 PM
- Moonrise: No moonrise
- Moonset: 01:25 PM
- Moon phase: Waning Crescent
Notes:
- Each column corresponds to a different weather provider.
- Missing values are displayed as
--. - Alerts and extra information (conditions, astronomical data) are displayed per provider.
- Units reflect the system selected in the Units menu (
imperialormetric).
This output demonstrates the core functionality of the CLI: comparing weather metrics across multiple sources in a single, easy-to-read table.