Skip to content

robertZaufall/amadeus-seatmap-bc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

281 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Business Class Seatmap Generator w/ Amadeus API

CLI utility for browsing Amadeus seat-map availability across a set of long-haul trips. It pulls live data from the Amadeus Self-Service APIs and caches each day's responses under data/<YYYYMMDD> so you can re-render the output without hitting the API again.

Example

Highlights

  • Builds ASCII seat maps with wide-character awareness so layouts stay aligned even when using emoji markers.
  • Highlights the lowest fare per route with a green border so deals stand out immediately.
  • Caches availability, pricing, and seatmap responses by run date (data/<YYYYMMDD>) for quick offline replays.
  • Prints a week-by-week grid plus per-day window-seat summaries with optional pricing pulled from flight offers.
  • Generates calendar heatmaps (per route and round-trip) to make fare trends obvious when scanning many dates.

Requirements

  • Python 3.11+ (tested locally with 3.11)
  • pip install -r requirements.txt
  • Amadeus Self-Service API credentials (test and/or production)
  • Pillow (for PNG export; included in requirements.txt so GitHub Actions can commit PNGs)

Local setup

python -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
cp .env.template .env

Fill in the .env file with the credentials from your Amadeus developer account:

TEST_AMADEUS_CLIENT_ID=...
TEST_AMADEUS_CLIENT_SECRET=...
AMADEUS_CLIENT_ID=...
AMADEUS_CLIENT_SECRET=...

The script reads these via python-dotenv, so the .env file only needs to exist in the repo root.

Configuration

Most runtime knobs live in config.py, so you rarely need to edit flight_search.py directly. Notable settings:

  • ENVIRONMENT picks the Amadeus host and must be either production or test for the fetch scripts.
  • TRAVEL_WINDOWS lists the routes/date ranges that should be fetched and rendered.
  • FLIGHT_SEARCH_FILTERS stores the request arguments (travel_class, non_stop, included_airline_codes, etc.) passed to the Amadeus flight_offers_search endpoint.
  • Visual toggles such as SEATMAP_OUTPUT_STYLE, SHOW_SEATMAP_PRICE, HEATMAP_EMPHASIS_STYLES, STATUS_SYMBOLS, and WINDOW_AVAILABLE_SYMBOL control how the ASCII/emoji output looks.
  • Currency/price decoration (CURRENCY_SYMBOLS, BORDER_COLORS, etc.) reference the semantic tokens defined in colors.py; extend colors.TOKEN_MAP if you need custom ANSI sequences.

Automation & publishing

  • Seatmap pipeline – Manually runnable via GitHub Actions (Run Seatmap Pipeline). It installs deps, runs run_pipeline.py, and commits the refreshed PNGs in docs/ back to the repo.
  • Static site deployDeploy static content to Pages publishes the contents of docs/ to GitHub Pages at https://robertzaufall.github.io/amadeus-seatmap-bc/. It triggers on master when files in docs/**/*.png or docs/**/*.html change, and can also be dispatched manually.
  • Local runs still work the same way; the automation just keeps the hosted artifacts current.

Travel windows & filters

Define the routes and date ranges you care about by editing the TRAVEL_WINDOWS list inside config.py. Each window is inclusive, so the scripts request seat maps for every day in the range. The first two windows drive the combined round-trip heatmaps (outbound vs. return).

Flight-offer search filters live in config.FLIGHT_SEARCH_FILTERS, so you can tweak cabin class, airline, or connection rules without touching the main script. Any key/value pairs in this dict get splatted into the SeatMaps.fetch call.

Workflow

  1. Configure config.py (set ENVIRONMENT to test or production, define TRAVEL_WINDOWS, adjust FLIGHT_SEARCH_FILTERS).
  2. Load environment variables from .env (see above).
  3. Fetch and cache data for today's run:
    python get_availability.py       # builds travel_dates.json + availability_responses.json
    python get_prices_oneway.py      # per-leg pricing -> pricing_responses_*oneway*.json
    python get_prices_return.py      # round-trip pricing -> pricing_responses*.json
    python get_seatmaps.py           # seat-map payloads -> seatmap_responses.json
    Each script reuses the existing files for today's date unless you flip refresh_data = True near the top of the file.
  4. Render the reports from the cached data:
    python flight_search.py

One-off seatmap lookup

Use flight_offer_seatmaps.py to fetch seatmaps for a single flight offer without running the full pipeline. It searches /v2/shopping/flight-offers, requests seatmaps for the result, and caches everything under data/flights/<ENV>-<FROM>-<TO>-<DATE>-<TIME>-<CLASS>-<AIRLINE>-<CURRENCY>/.

Example (queries business class; omit --class to fetch both cabins):

python flight_offer_seatmaps.py \
  --date 2024-12-05 \
  --time 22:25 \
  --from BKK \
  --to FRA \
  --airline TG \
  --class BUSINESS \
  --currency EUR

Example

Notes:

  • Seatmaps print to the terminal and save as seatmaps.png plus JSON files (flight_offers.json, seatmaps.json, metadata.json) in the cache folder.
  • Seatmaps are fetched when the flight-offer search yields exactly one matching offer per requested cabin; tweak --max-offers or specify --class if you get multiple hits.
  • Cached responses stay fresh for 4 hours by default (--cache-ttl-hours 0 or --force-refresh to bypass); diffs for seatmaps write to seatmaps.diff when content changes.
  • Use --environment test|production to select the Amadeus host; credentials are read from .env just like the main pipeline.

Data directory layout

All generated API responses are timestamped by run date: data/<YYYYMMDD>/. Common files include:

  • travel_dates.json: cleaned list of dates per travel window (from availability checks).
  • availability_responses.json/unavailable_flights.json: raw availability responses and filtered-out flights.
  • pricing_responses_oneway.json and pricing_responses_simple_oneway.json: leg-level pricing used for labels and price lookups.
  • pricing_responses.json and pricing_responses_simple.json: round-trip pricing used to build seatmap requests.
  • seatmap_responses.json: raw seatmap payloads consumed by flight_search.py.

If you want to re-render a prior run, copy its dated folder to today's date inside data/ so flight_search.py can find the JSON files.

Output details

  • Weekly seat-map grid – One block per day, grouped by week. Missing data shows a NO DATA placeholder, and the absolute lowest fare per route gets a green border plus a rounded price label at the bottom of the block.
  • Route availability boxes – After the grid, every route receives a bordered box that lists the available window seats per date, prefixed with a relative fare symbol and paired with a mini calendar heatmap for additional visual context.
  • Round-trip price heatmaps – If you provide at least two travel windows (outbound + inbound), the script prints two combined matrices: one based on window-seat fares only and another that considers any price returned by the offer search.

Contributing

No special tooling is required beyond standard linting/formatting for Python scripts. Please keep fixtures anonymized and avoid committing sensitive traveler data.

License

This project is released under the MIT License. See LICENSE for the full text.

About

Business Class Seatmap Generator w/ Amadeus API

Topics

Resources

License

Stars

Watchers

Forks

Contributors 2

  •  
  •