Spaces:
Sleeping
A newer version of the Gradio SDK is available: 6.12.0
Hotel Search App β Architect Plan
Intent (Definition of Done)
A deployable Hugging Face Gradio application that accepts a free-form natural language hotel query (including location, dates, budget, required/desired features, and features to avoid), searches for matching hotels via the SerpApi Google Hotels engine, and returns the top 15 results with direct links to each hotel's own website β never to a travel agency.
Task Decomposition
Step 1: Input Parsing
Parse the user's free-form text to extract structured search parameters:
| Parameter | Extraction Method |
|---|---|
| Location | Regex for phrases after "in", "near", "around", "at", proper-noun sequences |
| Check-in / Check-out dates | dateutil.parser with regex pre-extraction for common date formats |
| Price range | Regex for dollar-amount patterns ("under $200", "$100-$200", "budget of $150") |
| Number of adults | Regex for digit + "adults/guests/people" |
| Required features | Keywords preceded by "must have", "require", "need" |
| Desired features | Keywords preceded by "would like", "prefer", "nice to have" |
| Features to avoid | Keywords preceded by "no", "don't want", "avoid", "without" |
Default values when not specified: adults = 2, check-in = tomorrow, check-out = day after check-in.
Step 2: SerpApi Hotel Search
Call the SerpApi google_hotels engine with the extracted parameters:
engine = "google_hotels"
q = <location>
check_in_date = <YYYY-MM-DD>
check_out_date= <YYYY-MM-DD>
adults = <int>
min_price = <int | omitted>
max_price = <int | omitted>
currency = "USD"
gl = "us"
hl = "en"
Step 3: Result Filtering & Ranking
- Remove any results whose link domain matches a known travel-agency list (Expedia, Booking.com, Hotels.com, Trivago, Kayak, Priceline, Orbitz, Travelocity, Agoda, etc.).
- Prioritize the hotel's official website link. Fallback: construct a Google search URL
https://www.google.com/search?q=<hotel name> official site. - Retain the top 15 results.
Step 4: Output Rendering
Display results as styled HTML cards inside Gradio, each showing:
- Hotel name, star rating, overall rating, review count
- Nightly rate and total rate
- Thumbnail image
- Top amenities as tags
- "Visit Hotel Website" button linking to the hotel's own site
Step 5: Deployment
Package as a Hugging Face Space (Gradio SDK) with:
app.pyβ application coderequirements.txtβ dependenciesREADME.mdβ Hugging Face Space metadata + user guide- SerpApi key stored as a Hugging Face Space Secret (
SERPAPI_KEY)
Tool Requirements (Builder Instructions)
| Tool / Package | Purpose |
|---|---|
gradio >= 4.0 |
Web UI framework, Hugging Face Spaces compatible |
google-search-results >= 2.4.2 |
Official SerpApi Python client (from serpapi import GoogleSearch) |
python-dateutil >= 2.8.2 |
Robust date parsing from natural language |
Builder must:
- Keep all logic in a single
app.pyfile for Hugging Face compatibility. - Use
os.environ.get("SERPAPI_KEY")as fallback when the user does not enter a key in the UI. - Never hard-code API keys.
- Handle all exceptions gracefully and return user-friendly HTML error messages.
Coordination (JSON Interface Between Agents)
Parser β Search API (internal dict)
{
"location": "Austin, TX",
"check_in": "2026-03-15",
"check_out": "2026-03-18",
"adults": 2,
"min_price": null,
"max_price": 200,
"required_features": ["non-smoking", "free parking"],
"desired_features": ["pool", "fitness center"],
"avoid_features": ["highway noise"]
}
Search API β Renderer (SerpApi response subset)
{
"properties": [
{
"name": "Hotel Name",
"overall_rating": 4.5,
"reviews": 1234,
"rate_per_night": { "lowest": "$149" },
"hotel_class": "4-star hotel",
"amenities": ["Free Wi-Fi", "Pool", "Parking"],
"images": [{ "thumbnail": "https://..." }],
"link": "https://hotelwebsite.com"
}
]
}
Success Criteria for QA
| Metric | Target |
|---|---|
| Location accuracy | Search results are geographically relevant to the stated location |
| Date handling | At least 5 common date formats parse correctly (MM/DD/YYYY, Month Day Year, YYYY-MM-DD, relative like "next Friday", range like "March 15-18") |
| Price filtering | Results respect min/max price when specified |
| Travel-agency exclusion | Zero results link to known travel-agency domains |
| Result count | Returns up to 15 results per query |
| Error resilience | Empty input, missing API key, invalid dates, gibberish text all produce friendly error messages instead of stack traces |
| Link validity | Every hotel card has a clickable link that opens in a new tab |
| Deployment | App launches on Hugging Face Spaces without errors |