pip install tif1
```bash
For the polars lib (recommended for performance):
```bash
pip install tif1[polars]
```yaml
### What Python version do I need?
Python 3.10 or higher is required.
### Do I need an API key?
No, tif1 doesn't require any API keys or authentication. All data is publicly available via the TracingInsights CDN.
### Where is data cached?
By default, data is cached in `~/.tif1/cache/`. You can change this in your `.tif1rc` configuration file or via the `TIF1_CACHE_DIR` environment variable.
---
## Data Access
### Why is my first load slow?
The first time you access a session, tif1 needs to download data from the CDN. Subsequent loads are instant from the cache. Use `laps_async()` for 4-5x faster initial loads.
### How do I load data faster?
1. Use async loading: `await session.laps_async()`
2. Enable the polars lib: `lib="polars"`
3. Use batch telemetry fetching: `session.get_fastest_laps_tels()`
4. Keep caching enabled (default)
### Can I access live timing data?
No, tif1 focuses on historical data (2018-current). For live timing, use fastf1.
### How recent is the data?
Data is typically available 30 minutes after a session ends. This is slightly longer than fastf1 (~20-25 minutes) because tif1 includes additional enriched data.
### Why am I getting DataNotFoundError?
Common causes:
- Event name is misspelled (use `get_events()` to check)
- Session name is misspelled (use `get_sessions()` to check)
- Data hasn't been published yet (check if session ended recently)
- Session didn't take place (cancelled/postponed)
---
## Performance
### How can I reduce memory usage?
1. Use the polars lib (50% less memory)
2. Process drivers one at a time instead of loading all at once
3. Delete DataFrames when done: `del laps`
4. Use categorical dtypes (automatic in tif1)
### Why is polars faster?
Polars is written in Rust and uses:
- Better parallelization across CPU cores
- More efficient memory layout
- Lazy evaluation for query optimization
- Native Arrow format
### Can I use multiple backends in one script?
Yes, you can specify different backends for different sessions:
```python
session1 = tif1.get_session(2025, "Monaco", "Race", lib="pandas")
session2 = tif1.get_session(2025, "Monza", "Race", lib="polars")
```yaml
---
## Errors & Troubleshooting
### I'm getting NetworkError
Possible causes:
- Internet connection issues
- CDN is temporarily down (rare)
- Firewall blocking jsDelivr
Try:
1. Check your internet connection
2. Reset the circuit breaker: `tif1.reset_circuit_breaker()`
3. Enable debug logging: `tif1.setup_logging(logging.DEBUG)`
### Cache is corrupted
Clear the cache and re-download:
```python
tif1.get_cache().clear()
```bash
### Column names don't match fastf1
tif1 uses PascalCase for all columns (e.g., `LapTime`, not `time`). This is intentional for consistency. Use the exact column names shown in the data schema reference.
### Polars not available error
Install the polars extra:
```bash
pip install tif1[polars]
```yaml
---
## API & Usage
### Do I need to call session.load()?
No, tif1 uses lazy loading. Data is automatically fetched when you access it:
```python
session = tif1.get_session(2025, "Monaco", "Race")
laps = session.laps # Data fetched here
```yaml
However, you can use `session.load()` for explicit control over what data to fetch.
### How do I get telemetry for all drivers?
Use the optimized batch method:
```python
# 28x faster than sequential loading
tels = session.get_fastest_laps_tels(by_driver=True)
```yaml
### Can I filter by lap number?
Yes, use standard DataFrame filtering:
```python
# Pandas
lap_10 = laps[laps["LapNumber"] == 10]
# Polars
lap_10 = laps.filter(pl.col("LapNumber") == 10)
```python ### How do I get weather data?
Weather is automatically included in the laps DataFrame:
```python
laps = session.laps
print(laps[["LapNumber", "Driver", "AirTemp", "TrackTemp"]])
```yaml
Or access it directly:
```python
weather = session.weather
```bash
---
## Data Quality
### Are lap times accurate?
Yes, lap times come from official timing data. Missing lap times are filled from Ergast/Jolpica where available.
### Why are some lap times missing?
Lap times can be missing due to:
- Pit stops
- Track limits violations (deleted laps)
- Timing system issues
- Very slow laps (> 2m30s in some sources)
tif1 fills gaps where possible using alternative data sources.
### Is telemetry data validated?
Yes, tif1 includes optional Pydantic validation (enabled by default). Invalid data raises `InvalidDataError`.
---
## Advanced Usage
### Can I use tif1 in production?
Yes, tif1 is designed for production use with:
- Robust error handling
- Circuit breaker pattern
- Automatic retries
- SQLite caching for reliability
### How do I export data?
tif1 DataFrames support all standard export formats:
```python
laps.to_csv("data.csv")
laps.to_parquet("data.parquet")
laps.to_json("data.json")
laps.to_sql("laps", connection)
```yaml
### Can I use tif1 with Jupyter?
Yes, tif1 has built-in Jupyter support with rich HTML displays for Session, Driver, and Lap objects.
### Does tif1 work with async frameworks?
Yes, tif1 uses asyncio internally and provides async methods:
```python
laps = await session.laps_async()
```yaml
---
### How do I analyze tire degradation?
Tire degradation analysis requires tracking lap times over tire life:
```python
import tif1
import matplotlib.pyplot as plt
from scipy import stats
session = tif1.get_session(2025, "Bahrain", "Race")
laps = session.laps
# Filter for a specific driver and stint
driver_laps = laps[
(laps["Driver"] == "VER") &
(laps["Stint"] == 2) &
(laps["PitInTime"].isna())
]
# Plot lap time vs tire life
plt.scatter(driver_laps["TyreLife"], driver_laps["LapTime"])
# Add trend line
slope, intercept, r_value, _, _ = stats.linregress(
driver_laps["TyreLife"],
driver_laps["LapTime"]
)
print(f"Degradation: {slope:.3f} seconds per lap")
print(f"R²: {r_value**2:.3f}")
plt.xlabel("Tire Life (laps)")
plt.ylabel("Lap Time (s)")
plt.title(f"Tire Degradation - {driver_laps['Compound'].iloc[0]} Compound")
plt.show()