Skip to content

Surface OTA seller diversity in booking results (fixture, tests, example, docs)#25

Merged
saraswatayu merged 4 commits into
mainfrom
docs/booking-ota-examples
Jun 2, 2026
Merged

Surface OTA seller diversity in booking results (fixture, tests, example, docs)#25
saraswatayu merged 4 commits into
mainfrom
docs/booking-ota-examples

Conversation

@saraswatayu

Copy link
Copy Markdown
Owner

Why

Closes #24. A user asked whether get_booking_results() can surface the full OTA seller list (Expedia, FlightHub, …) that the Google Flights web UI shows, or whether swoop is limited to airline-direct fares.

It already works correctly — the parser surfaces every seller Google returns via opt[1]. The catch: Google only includes OTAs for itineraries it offers them on (international economy on foreign carriers). Every one of the 10 booking corpus fixtures was a premium-cabin / major-carrier itinerary, which are all airline-direct, so nothing in the repo demonstrated the OTA path — and the option[21] null-brand fallback (added in b9dfd7d) had no fixture coverage.

Verified live: SFO→MNL economy on Philippine Airlines returns 1 airline-direct (PR) + 14 OTAs (EXPEDIA, FLIGHTHUB, CHEAPOAIR, BYOJET, …), each with its own booking_url.

What

  • tests/test_booking.py — corpus-backed regression tests: the OTA list is surfaced, is_airline_direct splits the operating carrier from resellers, null-brand options are kept (not dropped), and OTA options carry google.com/travel/clk redirects.
  • tests/fixtures/corpus/booking_intl_economy_ota_response.txt + manifest case booking_intl_economy_ota_v1 — a real captured OTA-bearing response, replayed offline. Locks in seller_codes / is_airline_direct so a future opt[1] reshape fails loudly.
  • examples/booking_options.py — runnable: splits airline-direct from OTAs, prints price/seller/brand per channel, surfaces the cheapest booking_url. Defaults to an OTA-rich route so seller diversity shows out of the box.
  • README / examples/README / booking proto notes — document that each BookingOption is a booking channel and that OTA visibility is Google's call, not a swoop limit.
  • pyproject.toml / .gitignore — exclude transient .claude/worktrees checkouts from pyright (they duplicated the repo tree and produced phantom errors) and gitignore the scaffolding.

Test plan

  • make check1420 passed, 54 skipped, typecheck 0 errors.
  • python examples/booking_options.py SFO MNL <date> --cabin economy → printed 15 distinct sellers (PR + 14 OTAs) with booking URLs.

🤖 Generated with Claude Code

saraswatayu and others added 4 commits June 2, 2026 11:21
Issue #24 asked whether get_booking_results() can surface the full OTA
seller list (Expedia, FlightHub, ...) or only airline-direct fares. The
parser already surfaces every seller Google returns, but the entire booking
corpus was premium-cabin / major-carrier itineraries, which are all
airline-direct — so nothing exercised the OTA path (including the option[21]
null-brand fallback added in b9dfd7d).

Captures a real OTA-bearing response (SFO->MNL economy on Philippine
Airlines: PR airline-direct + 14 OTAs, all null-brand) as a contract-corpus
fixture, and adds tests/test_booking.py asserting the OTA list is surfaced,
airline-direct splits cleanly from resellers, null-brand options are kept
not dropped, and OTA options carry booking URLs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Answers issue #24 for users: get_booking_results() returns one BookingOption
per booking channel (airline-direct + OTAs), and whether OTAs appear is
Google's call (premium/major-carrier US = airline-direct only; international
economy on foreign carriers = OTA wall).

- examples/booking_options.py: runnable script that splits airline-direct
  from OTAs, prints price/seller/brand per channel, and surfaces the cheapest
  booking_url. Defaults to an OTA-rich route so diversity shows out of the box.
- README + examples/README: document the channel model and when OTAs appear.
- proto notes: record observed OTA seller codes and the null-brand behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Transient agent worktree checkouts under .claude/worktrees/ duplicate the
whole repo tree (swoop/ + tests/), so pyright was scanning a second copy and
reporting hundreds of errors from the excluded tests/ directory. Exclude
.claude/worktrees from pyright and gitignore it so the scaffolding never
pollutes the typecheck gate or gets staged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The full 'when do OTAs appear' explanation already lives in the example
docstring and booking proto notes; the README only needs to orient and
link out. Drops the second code snippet and the premium-vs-international
paragraph.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@saraswatayu saraswatayu merged commit 8fe062e into main Jun 2, 2026
5 checks passed
@saraswatayu saraswatayu deleted the docs/booking-ota-examples branch June 2, 2026 15:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can we get the full OTA vendor list via get_booking_results()?

1 participant