Files
promptfoo--promptfoo/examples/redteam-api-top-10/mock_services/weather.py
T
wehub-resource-sync 0d3cb498a3
CI / Shell Format Check (push) Has been cancelled
CI / Check Ruby (3.4) (push) Has been cancelled
CI / CI Config (push) Has been cancelled
CI / Test on Node ${{ matrix.node }} and ${{ matrix.os }}${{ matrix.shard && format(' (shard {0}/3)', matrix.shard) || '' }} (push) Has been cancelled
CI / Build on Node ${{ matrix.node }} (push) Has been cancelled
CI / Style Check (push) Has been cancelled
CI / Generate Assets (push) Has been cancelled
CI / Check Python (3.14) (push) Has been cancelled
CI / Check Python (3.9) (push) Has been cancelled
CI / Build Docs (push) Has been cancelled
CI / Code Scan Action (push) Has been cancelled
CI / Site tests (push) Has been cancelled
CI / webui tests (push) Has been cancelled
CI / Run Integration Tests (push) Has been cancelled
CI / Run Smoke Tests (push) Has been cancelled
CI / Go Tests (push) Has been cancelled
CI / Share Test (push) Has been cancelled
CI / Redteam (Production API) (push) Has been cancelled
CI / Redteam (Staging API) (push) Has been cancelled
CI / GitHub Actions Lint (push) Has been cancelled
CI / Check Ruby (3.0) (push) Has been cancelled
release-please / release-please (push) Has been cancelled
release-please / build (push) Has been cancelled
release-please / publish-npm (push) Has been cancelled
release-please / publish-npm-backfill (push) Has been cancelled
release-please / docker (push) Has been cancelled
release-please / publish-code-scan-action (push) Has been cancelled
release-please / attest-code-scan-action (push) Has been cancelled
Deploy local.promptfoo.app / Deploy to Cloudflare Pages (push) Has been cancelled
Test and Publish Multi-arch Docker Image / test (push) Has been cancelled
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-amd64 platform:linux/amd64 runner:ubuntu-latest]) (push) Has been cancelled
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-arm64 platform:linux/arm64 runner:ubuntu-24.04-arm]) (push) Has been cancelled
Test and Publish Multi-arch Docker Image / merge-docker-digests (push) Has been cancelled
Test and Publish Multi-arch Docker Image / Attest Multi-arch Image (push) Has been cancelled
Validate Renovate Config / Validate Renovate Configuration (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:24:08 +08:00

205 lines
6.2 KiB
Python

"""
Mock Weather Service
Provides weather data for user locations to enable product recommendations.
"""
from datetime import datetime
# Mock weather data by city
WEATHER_DATA = {
"san francisco, ca": {
"city": "San Francisco",
"state": "CA",
"temperature_f": 58,
"condition": "Foggy",
"humidity": 78,
"wind_mph": 12,
"feels_like_f": 54,
"forecast": "Typical foggy morning, clearing to partly cloudy by afternoon",
"weather_tags": ["cold", "mild"],
"recommendations": [
"Perfect hoodie weather! Check out our CloudCo Zip Hoodie.",
"A warm coffee mug would be great for foggy mornings.",
],
},
"new york, ny": {
"city": "New York",
"state": "NY",
"temperature_f": 35,
"condition": "Cold & Clear",
"humidity": 45,
"wind_mph": 18,
"feels_like_f": 28,
"forecast": "Clear but cold with strong winds. Bundle up!",
"weather_tags": ["cold", "outdoor"],
"recommendations": [
"Definitely beanie weather! Our CloudCo Beanie will keep you warm.",
"Layer up with a hoodie under your coat.",
],
},
"chicago, il": {
"city": "Chicago",
"state": "IL",
"temperature_f": 28,
"condition": "Snow Flurries",
"humidity": 65,
"wind_mph": 25,
"feels_like_f": 15,
"forecast": "Light snow with gusty winds. The Windy City living up to its name!",
"weather_tags": ["cold", "outdoor"],
"recommendations": [
"Bundle up! Our warmest hoodie is the CloudCo Zip Hoodie.",
"Don't forget a beanie - you'll need it in that wind!",
"Hot coffee in a CloudCo mug is essential today.",
],
},
"austin, tx": {
"city": "Austin",
"state": "TX",
"temperature_f": 72,
"condition": "Sunny",
"humidity": 55,
"wind_mph": 8,
"feels_like_f": 72,
"forecast": "Beautiful day ahead! Sunny with light breeze.",
"weather_tags": ["mild", "sunny", "outdoor"],
"recommendations": [
"Perfect t-shirt weather! Check out our CloudCo Logo Tee.",
"Don't forget your snapback for the sun!",
"Stay hydrated with our insulated water bottle.",
],
},
"seattle, wa": {
"city": "Seattle",
"state": "WA",
"temperature_f": 48,
"condition": "Rainy",
"humidity": 85,
"wind_mph": 10,
"feels_like_f": 44,
"forecast": "Classic Seattle weather - overcast with steady rain.",
"weather_tags": ["cold", "indoor"],
"recommendations": [
"Hoodie weather for sure! Stay warm and dry.",
"A travel tumbler keeps your coffee warm between rain sprints.",
"Work from home? Our desk pad makes rainy days cozier.",
],
},
# Default for unknown locations
"default": {
"city": "Unknown",
"state": "NA",
"temperature_f": 65,
"condition": "Partly Cloudy",
"humidity": 50,
"wind_mph": 10,
"feels_like_f": 65,
"forecast": "Moderate conditions expected.",
"weather_tags": ["mild"],
"recommendations": [
"A classic CloudCo Logo Tee works in any weather!",
"Can't go wrong with our versatile Travel Tumbler.",
],
},
}
def normalize_location(location: str) -> str:
"""Normalize location string for lookup."""
return location.lower().strip()
def get_weather(location: str) -> dict:
"""
Get current weather and product recommendations for a location.
Args:
location: City name or "City, State" format
Returns:
Weather data with product recommendations
"""
normalized = normalize_location(location)
# Try exact match first
if normalized in WEATHER_DATA:
data = WEATHER_DATA[normalized]
else:
# Try partial match
matched = None
for key in WEATHER_DATA.keys():
if key != "default":
city_name = key.split(",")[0]
if city_name in normalized or normalized in city_name:
matched = key
break
if matched:
data = WEATHER_DATA[matched]
else:
data = WEATHER_DATA["default"]
data = {
**data,
"city": location,
"note": "Weather data approximated for unknown location",
}
now = datetime.now()
return {
"location": f"{data['city']}, {data['state']}",
"temperature": data["temperature_f"],
"temperature_unit": "F",
"feels_like": data["feels_like_f"],
"condition": data["condition"],
"humidity": data["humidity"],
"humidity_unit": "%",
"wind": data["wind_mph"],
"wind_unit": "mph",
"forecast": data["forecast"],
"weather_tags": data["weather_tags"],
"product_recommendations": data["recommendations"],
"updated_at": now.strftime("%Y-%m-%d %H:%M:%S"),
}
def get_weather_recommendations(location: str) -> dict:
"""
Get just the product recommendations for a location.
Args:
location: City name or "City, State" format
Returns:
Product recommendations based on weather
"""
weather = get_weather(location)
return {
"location": weather["location"],
"condition": weather["condition"],
"temperature": weather["temperature"],
"recommendations": weather["product_recommendations"],
"suggested_categories": get_categories_for_weather(weather["weather_tags"]),
}
def get_categories_for_weather(tags: list) -> list:
"""Map weather tags to product categories."""
category_map = {
"cold": ["hoodies", "beanies", "mugs"],
"hot": ["water bottles", "t-shirts"],
"sunny": ["snapbacks", "water bottles"],
"mild": ["t-shirts", "accessories"],
"indoor": ["mugs", "mousepad", "stickers"],
"outdoor": ["backpack", "water bottles", "snapbacks"],
}
categories = set()
for tag in tags:
if tag in category_map:
categories.update(category_map[tag])
return list(categories)