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:
  • 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_*_KEY with valid API keys obtained from each provider.
  • HOME_CITY is used as a convenient default location for weather queries.
  • Latitude and longitude are optional but allow more precise positioning if desired.
  • The .env file 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
  • --unitsimperial or metric
  • --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 .env file 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 .env file, 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 (imperial or metric).

This output demonstrates the core functionality of the CLI: comparing weather metrics across multiple sources in a single, easy-to-read table.