The schedule_schema module validates the internal schedule data structure used by tif1. It ensures schedule payloads conform to the expected schema before being used by get_events() and get_sessions().
This module is used internally. Most users don’t need to interact with it directly.
Schema Validation
validate_schedule_payload
def validate_schedule_payload(payload: Any) -> dict[str, Any]
Validate that a schedule payload conforms to the expected internal schema.
Parameters:
payload: Decoded schedule payload (dict with schema_version and years)
Returns:
- The validated payload (same as input if valid)
Raises:
InvalidDataError: If the payload structure is invalid
Example:
from tif1.schedule_schema import validate_schedule_payload
from tif1.exceptions import InvalidDataError
payload = {
"schema_version": 1,
"years": {
"2021": {
"events": ["Bahrain Grand Prix", "Belgian Grand Prix"],
"sessions": {
"Bahrain Grand Prix": ["Practice 1", "Practice 2", "Practice 3", "Qualifying", "Race"],
"Belgian Grand Prix": ["Practice 1", "Practice 2", "Practice 3", "Qualifying", "Race"]
}
}
}
}
try:
validated = validate_schedule_payload(payload)
print("Schedule is valid")
except InvalidDataError as e:
print(f"Invalid schedule: {e}")
Schedule Schema
The internal schedule data follows this structure:
{
"schema_version": 1,
"years": {
"2021": {
"events": [
"Bahrain Grand Prix",
"Belgian Grand Prix",
"Abu Dhabi Grand Prix"
],
"sessions": {
"Bahrain Grand Prix": [
"Practice 1",
"Practice 2",
"Practice 3",
"Qualifying",
"Race"
],
"Belgian Grand Prix": [
"Practice 1",
"Practice 2",
"Practice 3",
"Qualifying",
"Race"
]
},
"metadata": {
"Belgian Grand Prix": {
"RoundNumber": 12,
"EventDate": "2021-08-29T17:00:00",
"Location": "Spa-Francorchamps",
"Country": "Belgium",
"OfficialEventName": "FORMULA 1 ROLEX BELGIAN GRAND PRIX 2021",
"EventFormat": "conventional",
"GmtOffset": "+02:00",
"F1ApiSupport": true,
"Session1Date": "2021-08-27T11:30:00",
"Session2Date": "2021-08-27T15:00:00",
"Session3Date": "2021-08-28T12:00:00",
"Session4Date": "2021-08-28T15:00:00",
"Session5Date": "2021-08-29T15:00:00"
}
}
}
}
}
Schema Version
The schema_version field indicates the structure version. Currently, only version 1 is supported.
Future versions may:
- Add new metadata fields
- Support additional event formats
- Include circuit information
Validation Rules
The validator checks:
-
Top-level structure
- Payload must be a dictionary
- Must contain
schema_version field
- Must contain
years dictionary
-
Schema version
- Must be exactly
1
- Other versions raise
InvalidDataError
-
Year structure
- Each year key must be a string of digits (e.g., “2021”)
- Each year value must be a dictionary
- Must contain
events list and sessions dictionary
-
Events list
- Must be a list of strings
- Each event name must be a non-empty string (e.g., “Belgian Grand Prix”)
-
Sessions dictionary
- Keys must match event names from
events list
- Values must be lists of session names
- Session names must be strings (e.g., “Practice 1”, “Qualifying”, “Race”)
Error Messages
The validator provides detailed error messages:
# Missing schema version
InvalidDataError: Unsupported schedule schema version: None
# Invalid year key
InvalidDataError: Invalid year key: 'twenty-twenty-one'
# Missing events list
InvalidDataError: Invalid events list for year=2021
# Invalid session list
InvalidDataError: Invalid session list for year=2021 event='Belgian Grand Prix'
# Not a dictionary
InvalidDataError: Schedule payload must be an object
Usage in tif1
The schedule validation is used internally by:
get_events()
import tif1
# Internally validates schedule before returning events
events = tif1.get_events(2021)
get_sessions()
import tif1
# Internally validates schedule before returning sessions
sessions = tif1.get_sessions(2021, "Belgian Grand Prix")
# Returns: ['Practice 1', 'Practice 2', 'Practice 3', 'Qualifying', 'Race']
Custom Schedule Data
If you’re working with custom schedule data, you can validate it manually:
from tif1.schedule_schema import validate_schedule_payload
from tif1.exceptions import InvalidDataError
custom_schedule = {
"schema_version": 1,
"years": {
"2021": {
"events": ["Custom Event"],
"sessions": {
"Custom Event": ["Practice", "Qualifying", "Race"]
}
}
}
}
try:
validated = validate_schedule_payload(custom_schedule)
print("Custom schedule is valid")
except InvalidDataError as e:
print(f"Validation failed: {e}")
Internal Data Flow
The schedule system works as follows:
- Raw f1schedule data: Vendored JSON files in
src/tif1/data/schedules/f1schedule/ contain per-year schedule data in columnar format
- Conversion:
_convert_f1schedule_year() transforms raw data into the internal schema
- Validation:
validate_schedule_payload() ensures the converted data is valid
- Caching: Validated schedule is cached for performance
- API exposure:
get_events() and get_sessions() use the validated data
The raw f1schedule format uses columnar data (like pandas DataFrames stored as JSON), while the internal format uses event-centric structure for easier querying.
Schedule validation is fast:
- Typical validation time: <1ms
- Schedule data is cached after first load
- Validation only runs once per session
- No network requests (data is vendored)
Complete Example
import tif1
from tif1.schedule_schema import validate_schedule_payload
from tif1.exceptions import InvalidDataError
# Get the 2021 Belgian Grand Prix Race
event = tif1.get_event(2021, "Belgian Grand Prix")
print(f"Event: {event['EventName']}")
print(f"Location: {event['Location']}")
print(f"Round: {event['RoundNumber']}")
# Get all sessions for this event
sessions = tif1.get_sessions(2021, "Belgian Grand Prix")
print(f"Sessions: {sessions}")
# Load the race session
race = event.get_session("Race")
race.load()
print(f"Drivers: {race.drivers}")
# Manual validation (internal use)
from tif1.events import _load_vendored_f1schedule_years
years = _load_vendored_f1schedule_years()
payload = {"schema_version": 1, "years": years}
try:
validated = validate_schedule_payload(payload)
print(f"Validated {len(validated['years'])} years")
except InvalidDataError as e:
print(f"Validation failed: {e}")
Events & Schedule
Event discovery and session access
Core API
Load and work with session data