Metadata-Version: 2.4
Name: f1verse
Version: 0.3.0
Summary: The story layer for Formula 1 data — zero-dependency race narratives: lead changes, stints, race pace, live championship projection, team radio index. Optional FastF1 adapter.
Author: f1verse contributors
License: MIT
Project-URL: Homepage, https://github.com/f1verse/f1verse
Keywords: f1,formula1,formula-1,fastf1,openf1,motorsport,racing,telemetry,live-timing,race-analysis,data-analysis,grand-prix
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: fastf1
Requires-Dist: fastf1>=3.4; extra == "fastf1"
Dynamic: license-file

# f1verse

**The story layer for Formula 1 data.** Data libraries fetch and tidy —
f1verse tells you *what happened*: lead changes, laps led, event timelines,
stint strategy, true race pace, and the live championship projection that
broadcasts never show.

**Zero dependencies.** Standard library only, seasons 2023+.

```bash
pip install f1verse
```

```python
import f1verse

race = f1verse.load(2026, 12)        # year, round — no other library needed

race.laps_led()      # {'ANT': 32, 'NOR': 31, 'HAM': 9}
race.leader_runs()   # [{'abbr': 'NOR', 'from': 1, 'to': 4}, ...]
race.results()[7]    # {'abbr': 'HUL', 'gap': '+1 LAP', ...}
race.race_pace()     # median pace — pit/SC/VSC laps excluded by default
race.story()         # one call, whole story, plain JSON

race.championship_prediction()   # per-lap "if it ended now" title projection
race.team_radio()                # timestamped clip URLs (nothing downloaded)
```

Using FastF1 already? Keep your workflow — the adapter takes a loaded
session (`pip install f1verse[fastf1]`, adds telemetry & pre-2023 seasons):

```python
story = f1verse.analyze(fastf1_session)
```

## Why this exists

Everyone who builds on FastF1 rediscovers the same traps, and each fixes
them slightly differently:

- **`results['Time']` is not a gap for lapped cars.** The raw value can be
  *smaller* than a car that finished ahead (`P7 +1:19.915` vs `P8 +36.049`).
  No error, no warning — naive tables are silently wrong.
  → `f1verse.format_gap` applies the broadcast convention (`+1 LAP`).
- **There is no API for "who led the race".** Lead changes, laps led,
  overtake-for-the-lead moments — every notebook reinvents them.
  → `leader_runs`, `laps_led`, `timeline`.
- **Race pace needs domain rules**, not just a quicklap threshold: in/out
  laps, SC/VSC laps, and laps failing FastF1's own 4-way accuracy check
  must go. → `race_pace` applies all of it by default.
- **numpy scalars break `json.dumps`.** Every f1verse output is plain
  JSON-safe Python. → pipe results straight into web or video pipelines.
- **Data-quality warnings are only logged as text.**
  → `integrity_report` returns them as structured data your pipeline can
  act on (hold publication, exclude laps, annotate).

## The feeds FastF1 throws away

The official live-timing archive contains more than FastF1 parses.
f1verse harvests three of the dropped feeds (through FastF1's own cache,
same rate-limit etiquette):

```python
f1verse.championship_prediction(session)
# per-lap "if the race ended now" projection of both championships,
# including the moments the projected champion changed

f1verse.team_radio(session)
# timestamped team-radio clips: [{'t', 'utc', 'driver_number', 'url'}]
# URLs only — nothing is downloaded or redistributed

f1verse.timing_stats(session)
# personal bests, best sectors, speed-trap figures
```

## Design rules

1. **Zero required dependencies.** The native loader speaks to public REST
   endpoints (OpenF1) and the official live-timing archive directly, with
   its own on-disk cache and polite pacing.
2. **FastF1 is respected, not replaced** — optional adapter for telemetry,
   qualifying segments and pre-2023 history.
3. **Everything returned is plain JSON-safe Python.**
4. **F1 domain rules are defaults, not options.**
5. **Cross-checked where possible** — e.g. lapped-car gaps are computed by
   convention *and* confirmed against a second source.
6. **Code only.** No timing data, media, or images are bundled or
   redistributed; data is fetched by the end user.

## Roadmap

- Full cross-validation layer (publish only when two sources agree)
- Overtake timeline ([OpenF1](https://openf1.org) `/overtakes`) & undercut/overcut detection
- Circuit & driver metadata joins ([Jolpica](https://github.com/jolpica/jolpica-f1), [f1db](https://github.com/f1db/f1db))
- Korean localization package (`f1verse-ko`)
- Chart & vertical-video templates consuming f1verse JSON

---

*Unofficial fan project. Not affiliated with, endorsed by, or associated
with Formula 1, FIA, FOM, or any F1 team. F1, FORMULA 1 and related marks
are trademarks of Formula One Licensing BV. This library contains code
only — no timing data, media, or images are included or redistributed;
data is fetched by the end user from publicly accessible endpoints,
subject to the respective providers' terms. Built on
[FastF1](https://github.com/theOehrly/Fast-F1) (MIT).*
