Skip to main content
The core_utils package provides internal utilities used throughout tif1. While these are primarily internal APIs, they can be useful for advanced use cases.

Lib Conversion

Functions for converting DataFrames between pandas and polars backends.

pandas_to_polars

def pandas_to_polars(
    df: pd.DataFrame,
    *,
    rechunk: bool = False
) -> pl.DataFrame
Convert a pandas DataFrame to polars DataFrame. Parameters:
  • df: pandas DataFrame to convert
  • rechunk: If True, rechunk the DataFrame for optimal memory layout
Returns:
  • polars DataFrame
Example:
from tif1.core_utils.backend_conversion import pandas_to_polars
import pandas as pd

df_pandas = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
df_polars = pandas_to_polars(df_pandas)

polars_to_pandas

def polars_to_pandas(
    df: pl.DataFrame,
    *,
    use_pyarrow: bool = True
) -> pd.DataFrame
Convert a polars DataFrame to pandas DataFrame. Parameters:
  • df: polars DataFrame to convert
  • use_pyarrow: If True, use PyArrow for zero-copy conversion
Returns:
  • pandas DataFrame
Example:
from tif1.core_utils.backend_conversion import polars_to_pandas
import polars as pl

df_polars = pl.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
df_pandas = polars_to_pandas(df_polars)

convert_backend

def convert_backend(
    df: DataFrame,
    target_backend: str
) -> DataFrame
Convert a DataFrame to the target lib (pandas or polars). Parameters:
  • df: DataFrame to convert (pandas or polars)
  • target_backend: Target lib (“pandas” or “polars”)
Returns:
  • DataFrame in the target library
Example:
from tif1.core_utils.backend_conversion import convert_backend
import pandas as pd

df = pd.DataFrame({"A": [1, 2, 3]})

# Convert to polars
df_polars = convert_backend(df, "polars")

# Convert back to pandas
df_pandas = convert_backend(df_polars, "pandas")

JSON Utilities

High-performance JSON parsing using orjson.

json_loads

def json_loads(payload: str | bytes | bytearray | memoryview) -> Any
Parse JSON string/bytes to Python object using orjson. Parameters:
  • payload: JSON string or bytes to parse
Returns:
  • Parsed Python object (dict, list, etc.)
Example:
from tif1.core_utils.json_utils import json_loads

json_str = '{"driver": "VER", "team": "Red Bull Racing"}'
data = json_loads(json_str)
print(data["driver"])  # "VER"
json_loads uses orjson for 2-3x faster parsing than stdlib json. It automatically handles both strings and bytes.

json_dumps

def json_dumps(data: Any) -> str
Serialize Python object to JSON string using orjson. Parameters:
  • data: Python object to serialize
Returns:
  • JSON string
Example:
from tif1.core_utils.json_utils import json_dumps

data = {"driver": "VER", "team": "Red Bull Racing"}
json_str = json_dumps(data)

Validation Helpers

Internal validation functions for data integrity.

_validate_year

def _validate_year(year: int, min_year: int, max_year: int) -> None
Validate that a year is within the supported range. Parameters:
  • year: Year to validate
  • min_year: Minimum supported year
  • max_year: Maximum supported year
Raises:
  • ValueError: If year is out of range

_validate_drivers_list

def _validate_drivers_list(drivers: list[str] | None) -> None
Validate that a drivers list contains valid 3-letter codes. Parameters:
  • drivers: List of driver codes to validate
Raises:
  • ValueError: If any driver code is invalid

_validate_lap_number

def _validate_lap_number(lap_number: int) -> None
Validate that a lap number is positive. Parameters:
  • lap_number: Lap number to validate
Raises:
  • ValueError: If lap number is not positive

_validate_string_param

def _validate_string_param(param: str, param_name: str) -> None
Validate that a string parameter is non-empty. Parameters:
  • param: String parameter to validate
  • param_name: Parameter name for error messages
Raises:
  • ValueError: If parameter is empty

_encode_url_component

def _encode_url_component(component: str) -> str
URL-encode a component for use in CDN URLs. Parameters:
  • component: String to encode
Returns:
  • URL-encoded string
Example:
from tif1.core_utils.helpers import _encode_url_component

encoded = _encode_url_component("Belgian Grand Prix")
# "Belgian%20Grand%20Prix"

Constants

Column name mappings and constants used throughout the library.

Column rename maps

The constants module defines mappings for renaming columns from CDN format to user-facing format:
# Lap data column renames
LAP_RENAME_MAP = {
    "time": "LapTime",
    "lap": "LapNumber",
    "s1": "Sector1Time",
    "s2": "Sector2Time",
    "s3": "Sector3Time",
    "compound": "Compound",
    "stint": "Stint",
    "life": "TyreLife",
    # ... more mappings
}

# Telemetry column renames
TELEMETRY_RENAME_MAP = {
    "time": "Time",
    "speed": "Speed",
    "rpm": "RPM",
    "gear": "nGear",
    "throttle": "Throttle",
    "brake": "Brake",
    "drs": "DRS",
    # ... more mappings
}

Standard column order

# FastF1-compatible column order for Laps DataFrame
FASTF1_LAPS_COLUMN_ORDER = [
    "index",
    "Time",
    "Driver",
    "DriverNumber",
    "LapTime",
    "LapNumber",
    "Stint",
    "PitOutTime",
    "PitInTime",
    "Sector1Time",
    "Sector2Time",
    "Sector3Time",
    "Sector1SessionTime",
    "Sector2SessionTime",
    "Sector3SessionTime",
    "SpeedI1",
    "SpeedI2",
    "SpeedFL",
    "SpeedST",
    "IsPersonalBest",
    "Compound",
    "TyreLife",
    "FreshTyre",
    "Team",
    "LapStartTime",
    "LapStartDate",
    "TrackStatus",
    "Position",
    # ... more columns
]

# Categorical columns for optimization
CATEGORICAL_COLS = ["Driver", "Team", "Compound", "TrackStatus"]

Resource Manager

Context manager for automatic resource cleanup.

ResourceManager

class ResourceManager:
    def __enter__(self) -> ResourceManager:
        ...

    def __exit__(self, exc_type, exc_val, exc_tb):
        ...
Manages resources like HTTP sessions, cache connections, and file handles with automatic cleanup. Example:
from tif1.core_utils.resource_manager import ResourceManager

with ResourceManager() as manager:
    # Resources are automatically cleaned up on exit
    pass
ResourceManager is used internally by the library. Most users don’t need to interact with it directly.

Performance Considerations

JSON Parsing

The library uses orjson for JSON parsing, which provides:
  • 2-3x faster parsing than stdlib json
  • Lower memory usage
  • Native support for bytes input
  • Automatic handling of numpy types

Lib Conversion

When converting between backends:
  • pandas → polars: Uses PyArrow for zero-copy when possible
  • polars → pandas: Uses PyArrow by default for efficiency
  • Rechunking: Optional for polars to optimize memory layout
Benchmark results:
# pandas → polars conversion
# 1M rows: ~50ms (zero-copy via PyArrow)

# polars → pandas conversion
# 1M rows: ~100ms (with PyArrow)

Advanced Usage

Custom lib conversion

from tif1.core_utils.backend_conversion import convert_backend
import tif1

# Load 2021 Belgian Grand Prix Race with pandas
session = tif1.get_session(2021, "Belgian Grand Prix", "Race", lib="pandas")
laps_pandas = session.laps

# Convert to polars for analysis
laps_polars = convert_backend(laps_pandas, "polars")

# Perform polars operations
import polars as pl
fast_laps = laps_polars.filter(pl.col("LapTimeSeconds") < 120.0)

# Convert back to pandas if needed
fast_laps_pandas = convert_backend(fast_laps, "pandas")

Custom JSON Processing

from tif1.core_utils.json_utils import json_loads, json_dumps

# Parse JSON from CDN
json_data = '{"laps": [{"lap": 1, "time": 90.5}]}'
data = json_loads(json_data)

# Modify data
data["laps"][0]["time"] = 89.5

# Serialize back
modified_json = json_dumps(data)

Best Practices

  1. Use orjson for JSON: Always use json_loads/json_dumps for performance
  2. Prefer PyArrow conversion: Keep use_pyarrow=True for lib conversion
  3. Validate early: Use validation helpers to catch errors early
  4. Let the library handle resources: ResourceManager is automatic
  5. Use constants for column names: Reference standard column names from constants

Summary

The core_utils package provides:
  • High-performance JSON parsing with orjson
  • Efficient lib conversion (pandas ↔ polars)
  • Data validation utilities
  • Column name standardization
  • Resource management
  • Internal helpers for DataFrame operations
These utilities enable the library’s focus on performance and reliability.
Last modified on March 5, 2026