Overview
The Mapping API provides normalization services for league names and market result mapping, ensuring consistent data across different data sources.
LeagueNormalizer
Normalize League Names
from PROPPR .SharedServices.mapping.league_normalizer import LeagueNormalizer
normalized = LeagueNormalizer.normalize( "LaLiga" )
# Returns: "La Liga"
normalized = LeagueNormalizer.normalize( "Primera Division" )
# Returns: "La Liga"
Canonical league name, or original if no mapping exists
League Normalization Map
The normalization map resolves data source inconsistencies:
LEAGUE_NORMALIZATION_MAP = {
# Spain
"LaLiga" : "La Liga" ,
"LaLiga 2" : "La Liga 2" ,
# Portugal
"Liga Portugal" : "Primeira Liga" ,
# England
"Enterprise National League" : "National League" ,
# Europe
"UEFA Conference League" : "Europa Conference League" ,
# Australia
"A-League Men" : "A-League" ,
# Japan
"J.League" : "J-League" ,
# Greece
"Super League Greece" : "Super League" ,
# Austria
"Admiral Bundesliga" : "Bundesliga" ,
# Argentina
"Liga Profesional de Futbol" : "Liga Profesional" ,
# Brazil
"Brasileiro Serie A" : "Serie A" ,
# Bolivia
"Division Profesional" : "Liga De Futbol Prof" ,
"División Profesional" : "Liga De Futbol Prof"
}
MarketResultMapper
Get Market Mapping
from PROPPR .SharedServices.mapping.market_result_mapper import MarketResultMapper
mapping = MarketResultMapper.get_mapping_for_market( "Team Total Away" )
# Returns: {'type_id': 52, 'location': 'away', 'stat_type': 'goals'}
Market name (e.g., “Team Total Away”, “Corners Totals”)
API type ID for statistic
Location: “home”, “away”, “total”, or “team_based”
Stat type: “goals”, “corners”, “cards”, “shots”, etc.
Supported Markets
{
"Team Total Home" : { "type_id" : 52 , "location" : "home" , "stat_type" : "goals" },
"Team Total Away" : { "type_id" : 52 , "location" : "away" , "stat_type" : "goals" },
"Match Goals" : { "type_id" : 52 , "location" : "total" , "stat_type" : "goals" }
}
{
"Corners Totals" : { "type_id" : 34 , "location" : "total" , "stat_type" : "corners" },
"Match Corners" : { "type_id" : 34 , "location" : "total" , "stat_type" : "corners" },
"Team Corners Home" : { "type_id" : 34 , "location" : "home" , "stat_type" : "corners" },
"Team Corners Away" : { "type_id" : 34 , "location" : "away" , "stat_type" : "corners" }
}
{
"Bookings Totals" : { "type_id" : 84 , "location" : "total" , "stat_type" : "cards" },
"Total Cards" : { "type_id" : 84 , "location" : "total" , "stat_type" : "cards" },
"Match Cards" : { "type_id" : 84 , "location" : "total" , "stat_type" : "cards" }
}
{
"Total Shots" : { "type_id" : 42 , "location" : "total" , "stat_type" : "shots" },
"Team Shots On Target Home" : { "type_id" : 86 , "location" : "home" , "stat_type" : "shots_on_target" },
"Match Shots On Target" : { "type_id" : 86 , "location" : "total" , "stat_type" : "shots_on_target" }
}
actual_value = MarketResultMapper.extract_stat_value(
statistics = fixture_statistics,
type_id = 52 ,
location = "away" ,
team_id = 55 ,
suppress_warnings = False
)
List of statistics from API response
API type ID for statistic
“home”, “away”, or “total”
Team ID for team-specific stats
Suppress warning logs (useful for live grading)
Actual statistic value, or None if not found
Location Priority : Match by location (“home”/“away”) first
Participant ID Fallback : Match by participant_id if location fails
Total Calculation : Sum home + away for total markets
Zero Default : Return 0.0 for missing stats in common types
Calculate Results
Calculate Bet Result
result = MarketResultMapper.calculate_bet_result(
actual_value = 3.0 ,
threshold = 2.5 ,
direction = "over" ,
market_name = "Totals"
)
# Returns: "won"
Market name to determine handicap type
“won”, “lost”, “refund”, “half_win”, or “half_loss”
Result Logic
Standard Handicaps (0.5, 1.5, 2.5):
Over: actual > threshold → Won, actual <= threshold → Lost
Under: actual < threshold → Won, actual >= threshold → Lost
Whole Number Handicaps (1.0, 2.0, 3.0):
Over: actual > threshold → Won, actual == threshold → Refund, actual < threshold → Lost
Under: actual < threshold → Won, actual == threshold → Refund, actual > threshold → Lost
Quarter Handicaps (1.25, 1.75, 2.25, 2.75):
Split into two half bets:
1.75 = Half on 1.5 + Half on 2.0
2.25 = Half on 2.0 + Half on 2.5
Results:
Both halves win → Won
Both halves lose → Lost
One wins, one refunds → Half Win
One loses, one refunds → Half Loss
Both refund → Refund
Prepare for Tracking
Add Result Tracking
alert_doc = MarketResultMapper.prepare_alert_for_tracking(alert_doc)
Result tracking metadata {
'api_type_id' : 52 ,
'api_location' : 'away' ,
'stat_type' : 'goals' ,
'expected_threshold' : 1.5 ,
'market_direction' : 'over' ,
'result_status' : 'pending' ,
'actual_value' : None ,
'calculated_at' : None ,
'api_response_id' : None
}
Early Grading
Check Early Grade
can_grade = MarketResultMapper.can_grade_early(
alert_doc = alert_doc,
actual_value = 3.0
)
Alert document with result tracking
True if over bet exceeded threshold (can grade as won early)
Early Grading Rules:
Only “over” bets can be graded early
Only when actual_value > threshold
“Under” bets must wait until match ends
Helper Functions
Get Market Mapping
from PROPPR .SharedServices.mapping.market_result_mapper import get_market_mapping
mapping = get_market_mapping( "Team Total Away" )
Calculate Result
from PROPPR .SharedServices.mapping.market_result_mapper import calculate_result
result = calculate_result(
actual_value = 3.0 ,
threshold = 2.5 ,
direction = "over" ,
market_name = "Totals"
)
Check Supported Market
from PROPPR .SharedServices.mapping.market_result_mapper import is_supported_market
supported = is_supported_market( "Team Total Away" )
# Returns: True
Example Usage
Complete Mapping Flow
# Normalize league name
league = LeagueNormalizer.normalize( "LaLiga" )
# "La Liga"
# Get market mapping
mapping = MarketResultMapper.get_mapping_for_market( "Team Total Away" )
# {'type_id': 52, 'location': 'away', 'stat_type': 'goals'}
# Extract actual value
actual_value = MarketResultMapper.extract_stat_value(
statistics = fixture_statistics,
type_id = mapping[ 'type_id' ],
location = mapping[ 'location' ]
)
# 2.0
# Calculate result
result = MarketResultMapper.calculate_bet_result(
actual_value = actual_value,
threshold = 1.5 ,
direction = "over"
)
# "won"
References
Source: SharedServices/mapping/league_normalizer.py
Source: SharedServices/mapping/market_result_mapper.py
Related: Grading API
Related: Fixture Model