feat: Playtomic pricing/occupancy pipeline + email i18n + audience restructure
Three workstreams:
1. Playtomic full data extraction & transform pipeline:
- Expand venue bounding boxes from 4 to 23 regions (global coverage)
- New staging models for court resources, opening hours, and slot-level
availability with real prices from the Playtomic API
- Foundation fact tables for venue capacity and daily occupancy/revenue
- City-level pricing benchmarks replacing hardcoded country estimates
- Planner defaults now use 3-tier cascade: city data → country → fallback
2. Transactional email i18n:
- _t() helper in worker.py with ~70 translation keys (EN + DE)
- All 8 email handlers translated, lang passed in task payloads
3. Resend audiences restructured to 3 named audiences (free plan limit)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -28,7 +28,7 @@ logger = setup_logging("padelnomics.extract.playtomic_availability")
|
||||
EXTRACTOR_NAME = "playtomic_availability"
|
||||
AVAILABILITY_URL = "https://api.playtomic.io/v1/availability"
|
||||
|
||||
THROTTLE_SECONDS = 2
|
||||
THROTTLE_SECONDS = 1
|
||||
MAX_VENUES_PER_RUN = 10_000
|
||||
MAX_RETRIES_PER_VENUE = 2
|
||||
|
||||
|
||||
@@ -24,16 +24,89 @@ EXTRACTOR_NAME = "playtomic_tenants"
|
||||
PLAYTOMIC_TENANTS_URL = "https://api.playtomic.io/v1/tenants"
|
||||
|
||||
THROTTLE_SECONDS = 2
|
||||
PAGE_SIZE = 20
|
||||
PAGE_SIZE = 100
|
||||
MAX_PAGES_PER_BBOX = 500 # safety bound — prevents infinite pagination
|
||||
MAX_STALE_PAGES = 3 # stop after N consecutive pages with zero new results
|
||||
|
||||
# Target markets: Spain, UK/Ireland, Germany, France
|
||||
# Global padel markets — bounding boxes sized to stay under API's internal result cap.
|
||||
# Large countries (Spain, Italy, USA) are split into sub-regions.
|
||||
BBOXES = [
|
||||
{"min_latitude": 35.95, "min_longitude": -9.39, "max_latitude": 43.79, "max_longitude": 4.33},
|
||||
# Spain — south (Andalusia, Murcia, Valencia)
|
||||
{"min_latitude": 35.95, "min_longitude": -9.39, "max_latitude": 39.87, "max_longitude": 4.33},
|
||||
# Spain — north (Madrid, Catalonia, Basque Country)
|
||||
{"min_latitude": 39.87, "min_longitude": -9.39, "max_latitude": 43.79, "max_longitude": 4.33},
|
||||
# UK & Ireland
|
||||
{"min_latitude": 49.90, "min_longitude": -8.62, "max_latitude": 60.85, "max_longitude": 1.77},
|
||||
# Germany
|
||||
{"min_latitude": 47.27, "min_longitude": 5.87, "max_latitude": 55.06, "max_longitude": 15.04},
|
||||
# France
|
||||
{"min_latitude": 41.36, "min_longitude": -5.14, "max_latitude": 51.09, "max_longitude": 9.56},
|
||||
# Italy — south (Rome, Naples, Sicily, Sardinia)
|
||||
{"min_latitude": 36.35, "min_longitude": 6.62, "max_latitude": 42.00, "max_longitude": 18.51},
|
||||
# Italy — north (Milan, Turin, Venice, Bologna)
|
||||
{"min_latitude": 42.00, "min_longitude": 6.62, "max_latitude": 47.09, "max_longitude": 18.51},
|
||||
# Portugal
|
||||
{"min_latitude": 37.00, "min_longitude": -9.50, "max_latitude": 42.15, "max_longitude": -6.19},
|
||||
# Netherlands
|
||||
{"min_latitude": 50.75, "min_longitude": 3.37, "max_latitude": 53.47, "max_longitude": 7.21},
|
||||
# Belgium
|
||||
{"min_latitude": 49.50, "min_longitude": 2.55, "max_latitude": 51.50, "max_longitude": 6.40},
|
||||
# Austria
|
||||
{"min_latitude": 46.37, "min_longitude": 9.53, "max_latitude": 49.02, "max_longitude": 17.16},
|
||||
# Switzerland
|
||||
{"min_latitude": 45.82, "min_longitude": 5.96, "max_latitude": 47.80, "max_longitude": 10.49},
|
||||
# Sweden
|
||||
{"min_latitude": 55.34, "min_longitude": 11.11, "max_latitude": 69.06, "max_longitude": 24.16},
|
||||
# Denmark
|
||||
{"min_latitude": 54.56, "min_longitude": 8.09, "max_latitude": 57.75, "max_longitude": 12.69},
|
||||
# Norway
|
||||
{"min_latitude": 57.97, "min_longitude": 4.50, "max_latitude": 71.19, "max_longitude": 31.17},
|
||||
# Finland
|
||||
{"min_latitude": 59.81, "min_longitude": 20.55, "max_latitude": 70.09, "max_longitude": 31.59},
|
||||
# Mexico
|
||||
{
|
||||
"min_latitude": 14.53,
|
||||
"min_longitude": -118.37,
|
||||
"max_latitude": 32.72,
|
||||
"max_longitude": -86.71,
|
||||
},
|
||||
# Argentina
|
||||
{
|
||||
"min_latitude": -55.06,
|
||||
"min_longitude": -73.56,
|
||||
"max_latitude": -21.78,
|
||||
"max_longitude": -53.63,
|
||||
},
|
||||
# Middle East (UAE, Qatar, Saudi Arabia, Bahrain)
|
||||
{"min_latitude": 21.00, "min_longitude": 38.00, "max_latitude": 32.00, "max_longitude": 56.50},
|
||||
# USA — southwest (California, Arizona, Texas west)
|
||||
{
|
||||
"min_latitude": 24.50,
|
||||
"min_longitude": -125.00,
|
||||
"max_latitude": 37.00,
|
||||
"max_longitude": -100.00,
|
||||
},
|
||||
# USA — southeast (Florida, Texas east, Georgia)
|
||||
{
|
||||
"min_latitude": 24.50,
|
||||
"min_longitude": -100.00,
|
||||
"max_latitude": 37.00,
|
||||
"max_longitude": -66.95,
|
||||
},
|
||||
# USA — northwest
|
||||
{
|
||||
"min_latitude": 37.00,
|
||||
"min_longitude": -125.00,
|
||||
"max_latitude": 49.38,
|
||||
"max_longitude": -100.00,
|
||||
},
|
||||
# USA — northeast (New York, Chicago, Boston)
|
||||
{
|
||||
"min_latitude": 37.00,
|
||||
"min_longitude": -100.00,
|
||||
"max_latitude": 49.38,
|
||||
"max_longitude": -66.95,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user