Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/TracingInsights/tif1/llms.txt

Use this file to discover all available pages before exploring further.

Quick Start

The fastest way to get started with tif1:
import tif1

# Get a session
session = tif1.get_session(2025, "Abu Dhabi Grand Prix", "Practice 1")

# Get all laps
laps = session.laps
print(f"Total laps: {len(laps)}")

# Get specific driver
ver = session.get_driver("VER")
ver_laps = ver.laps
print(f"VER laps: {len(ver_laps)}")

# Get telemetry for a lap
lap = ver.get_lap(19)
telemetry = lap.telemetry
print(f"Telemetry points: {len(telemetry)}")

Data Analysis Examples

Fastest Laps Analysis

Analyze fastest laps across drivers and compare performance:
import tif1

session = tif1.get_session(2025, "Abu Dhabi Grand Prix", "Qualifying")

# Get fastest lap per driver
fastest_by_driver = session.get_fastest_laps(by_driver=True)
fastest_sorted = fastest_by_driver.sort_values("LapTime")
print("\nFastest lap times:")
print(fastest_sorted[["Driver", "Team", "LapTime", "Compound"]].head(10))

# Get overall fastest lap
overall_fastest = session.get_fastest_laps(by_driver=False)
driver = overall_fastest["Driver"].iloc[0]
time = overall_fastest["LapTime"].iloc[0]
print(f"\nOverall fastest: {driver} - {time:.3f}s")

# Compare teammates
ham = session.get_driver("HAM")
rus = session.get_driver("RUS")

ham_fastest = ham.get_fastest_lap()["LapTime"].iloc[0]
rus_fastest = rus.get_fastest_lap()["LapTime"].iloc[0]

delta = abs(ham_fastest - rus_fastest)
faster = "HAM" if ham_fastest < rus_fastest else "RUS"

print(f"\nMercedes comparison:")
print(f"  HAM: {ham_fastest:.3f}s")
print(f"  RUS: {rus_fastest:.3f}s")
print(f"  Delta: {delta:.3f}s ({faster} faster)")

Telemetry Comparison

Compare telemetry between drivers:
import tif1
import matplotlib.pyplot as plt

session = tif1.get_session(2025, "Abu Dhabi Grand Prix", "Qualifying")

# Get fastest laps for two drivers
ver = session.get_driver("VER")
ham = session.get_driver("HAM")

ver_fastest_lap = ver.get_fastest_lap()
ham_fastest_lap = ham.get_fastest_lap()

# Get telemetry
ver_lap_num = int(ver_fastest_lap["lap"].iloc[0])
ham_lap_num = int(ham_fastest_lap["lap"].iloc[0])

ver_tel = ver.get_lap(ver_lap_num).telemetry
ham_tel = ham.get_lap(ham_lap_num).telemetry

# Plot speed comparison
plt.figure(figsize=(12, 6))
plt.plot(ver_tel["Distance"], ver_tel["Speed"], label="VER")
plt.plot(ham_tel["Distance"], ham_tel["Speed"], label="HAM")
plt.xlabel("Distance (m)")
plt.ylabel("Speed (km/h)")
plt.title("Speed Comparison - Fastest Laps")
plt.legend()
plt.grid(True)
plt.show()

Tire Strategy Analysis

Analyze tire compound usage and stint performance:
import tif1
import pandas as pd

session = tif1.get_session(2025, "Abu Dhabi Grand Prix", "Race")
laps = session.laps

# Tire compound usage by driver
compound_usage = laps.groupby(["Driver", "Compound"]).size().reset_index(name="Laps")
print("\nTire compound usage:")
print(compound_usage)

# Average lap time by compound
avg_times = laps.groupby("Compound")["LapTime"].mean().sort_values()
print("\nAverage lap time by compound:")
for compound, time in avg_times.items():
    print(f"  {compound}: {time:.3f}s")

# Stint analysis for specific driver
ver = session.get_driver("VER")
ver_laps = ver.laps

stint_summary = ver_laps.groupby("Stint").agg({
    "LapNumber": ["min", "max", "count"],
    "Compound": "first",
    "LapTime": ["mean", "min"]
})

print("\nVER stint summary:")
print(stint_summary)

Performance Examples

Async vs Sync Loading

Compare loading performance:
import tif1
import asyncio
import time

# Clear cache for fair comparison
cache = tif1.get_cache()
cache.clear()

# Async loading
async def load_async():
    session = tif1.get_session(2025, "Abu Dhabi Grand Prix", "Practice 1")
    start = time.time()
    laps = await session.laps_async()
    elapsed = time.time() - start
    print(f"Async: {elapsed:.2f}s for {len(laps)} laps")
    return elapsed

async_time = asyncio.run(load_async())

# Clear cache again
cache.clear()

# Sync loading
session = tif1.get_session(2025, "Abu Dhabi Grand Prix", "Practice 1")
start = time.time()
laps = session.laps
sync_time = time.time() - start
print(f"Sync:  {sync_time:.2f}s for {len(laps)} laps")

# Show speedup
speedup = sync_time / async_time
print(f"\nSpeedup: {speedup:.1f}x faster with async")

Cache Management

Optimize performance with caching:
import tif1
import time

cache = tif1.get_cache()
print(f"Cache location: {cache.cache_dir}")

# First load (cold cache)
start = time.time()
session = tif1.get_session(2025, "Abu Dhabi Grand Prix", "Practice 1")
laps = session.laps
first_load = time.time() - start
print(f"First load: {first_load:.2f}s")

# Second load (warm cache)
start = time.time()
session2 = tif1.get_session(2025, "Abu Dhabi Grand Prix", "Practice 1")
laps2 = session2.laps
second_load = time.time() - start
print(f"Cached load: {second_load:.2f}s")

speedup = first_load / second_load
print(f"Speedup: {speedup:.1f}x faster from cache")

# Clear cache when needed
cache.clear()
print("Cache cleared")

Polars Backend

Use Polars for faster data processing:
import tif1
import polars as pl

# Use Polars backend (2x faster for large datasets)
session = tif1.get_session(
    2025, 
    "Abu Dhabi Grand Prix", 
    "Practice 1",
    lib="polars"
)

laps = session.laps  # Returns Polars DataFrame
print(f"DataFrame type: {type(laps).__name__}")

# Polars operations are faster
fastest_by_driver = (
    laps.group_by("Driver")
    .agg([
        pl.col("LapTime").min().alias("fastest_time"),
        pl.col("LapNumber").count().alias("lap_count")
    ])
    .sort("fastest_time")
)

print("\nFastest laps by driver:")
print(fastest_by_driver.head(10))

# Convert to pandas if needed
laps_pandas = laps.to_pandas()

Error Handling Examples

Robust Error Handling

Handle errors gracefully in production code:
import tif1
import logging

# Enable logging for debugging
tif1.setup_logging(logging.INFO)

try:
    # Validate event exists
    events = tif1.get_events(2025)
    if "Abu Dhabi Grand Prix" not in events:
        print("Event not found")
        exit(1)
    
    # Validate session exists
    sessions = tif1.get_sessions(2025, "Abu Dhabi Grand Prix")
    if "Practice 1" not in sessions:
        print("Session not found")
        exit(1)
    
    # Get session
    session = tif1.get_session(2025, "Abu Dhabi Grand Prix", "Practice 1")
    
    # Check driver exists
    drivers = session.drivers_df
    if "VER" not in drivers["Driver"].values:
        print("Driver not in session")
        exit(1)
    
    # Get driver data
    ver = session.get_driver("VER")
    ver_laps = ver.laps
    
    if len(ver_laps) == 0:
        print("No laps available")
        exit(1)
    
    # Get telemetry
    first_lap_num = int(ver_laps["lap"].iloc[0])
    lap = ver.get_lap(first_lap_num)
    telemetry = lap.telemetry
    
    print(f"✓ Successfully loaded {len(telemetry)} telemetry points")
    
except tif1.DataNotFoundError as e:
    print(f"Data not found: {e}")
except tif1.DriverNotFoundError as e:
    print(f"Driver not found: {e}")
except tif1.NetworkError as e:
    print(f"Network error: {e}")
except tif1.TIF1Error as e:
    print(f"tif1 error: {e}")
except Exception as e:
    print(f"Unexpected error: {e}")

Circuit Breaker and CDN Fallback

Monitor and manage network resilience:
import tif1

# Check circuit breaker status
cb = tif1.get_circuit_breaker()
print(f"Circuit breaker state: {cb.state}")

# Check available CDN sources
cdn = tif1.get_cdn_manager()
sources = cdn.get_sources()
print(f"Available CDN sources: {len(sources)}")

# Reset circuit breaker if needed
if cb.state == "open":
    print("Circuit breaker is open - resetting...")
    tif1.reset_circuit_breaker()
    print("Circuit breaker reset")

# Load data with automatic retry and fallback
try:
    session = tif1.get_session(2025, "Abu Dhabi Grand Prix", "Practice 1")
    laps = session.laps
    print(f"✓ Loaded {len(laps)} laps")
except tif1.NetworkError:
    print("All CDN sources failed")

Configuration Examples

Configuration File

Use .tif1rc for persistent configuration:
import tif1

# Get configuration
config = tif1.get_config()
print(f"Max retries: {config.get('max_retries')}")
print(f"Validate data: {config.get('validate_data')}")
print(f"Backend: {config.get('backend')}")

# Update configuration
config.set("max_retries", 5)
config.set("validate_data", True)
config.set("backend", "polars")

# Save to ~/.tif1rc
config.save()
print("Configuration saved")
Example .tif1rc file:
~/.tif1rc
{
  "max_retries": 5,
  "validate_data": true,
  "backend": "polars",
  "cache_enabled": true,
  "log_level": "INFO"
}

Data Exploration

Discover Available Data

Explore what data is available:
import tif1

# List available years and events
events_2025 = tif1.get_events(2025)
print(f"2025 Events ({len(events_2025)}):")
for event in events_2025[:5]:
    print(f"  • {event}")

# List sessions for an event
sessions = tif1.get_sessions(2025, "Abu Dhabi Grand Prix")
print(f"\nAbu Dhabi Sessions:")
for session in sessions:
    print(f"  • {session}")

# Explore session data structure
session = tif1.get_session(2025, "Abu Dhabi Grand Prix", "Practice 1")

print(f"\nDrivers ({len(session.drivers_df)}):")
for _, driver in session.drivers_df.head(5).iterrows():
    print(f"  {driver['Driver']:3s} - {driver['Team']}")

# Explore lap data columns
laps = session.laps
print(f"\nLap data shape: {laps.shape}")
print(f"Columns: {list(laps.columns)}")

# Explore telemetry columns
ver = session.get_driver("VER")
lap = ver.get_lap(1)
telemetry = lap.telemetry
print(f"\nTelemetry shape: {telemetry.shape}")
print(f"Columns: {list(telemetry.columns)}")

Next Steps

API Reference

Explore the complete API documentation

Architecture

Learn about tif1’s system design

Contributing

Contribute to the project

Compatibility

Check fastf1 compatibility status
All examples are available in the examples/ directory of the repository.

Build docs developers (and LLMs) love