Technical Documentation: theOehrly/Fast-F1
ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference
Overview (`README.md`)
A python package for accessing and analyzing Formula 1 results, schedules, timing data and telemetry.Main Features
- Access to F1 timing data, telemetry, sessions results and more
- Full support for the Ergast compatible jolpica-f1 API to access current and
historical F1 data - All data is provided in the form of extended Pandas DataFrames to make
working with the data easy while having powerful tools available - Adds custom functions to the Pandas objects specifically to make working
with F1 data quick and simple - Integration with Matplotlib to facilitate data visualization
- Implements caching for all API requests to speed up your scripts
Installation
It is recommended to install FastF1 using pip:
pip install fastf1Alternatively, a wheel or a source distribution can be downloaded from Pypi.
You can also install using conda:
conda install -c conda-forge fastf1Installation in Pyodide, JupyterLite and other WASM-based environments
FastF1 should be mostly compatible with Pyodide and other WASM-based
environments, although this is not extensively tested. Currently, the
installation and usage require some additional steps. You can find more
information and a guide in
this external repository
and the discussion in this issue.
Third-party packages
- R package that wraps FastF1: https://cran.r-project.org/package=f1dataR
Third-party packages are not directly related to the FastF1 project. Questions
and suggestions regarding these packages need to be directed at their
respective maintainers.
Documentation
The official documentation can be found here:
docs.fastf1.dev
Supporting the Project
If you want to support the continuous development of FastF1, you can sponsor me
on GitHub or buy me a coffee.
https://github.com/sponsors/theOehrly
Notice
FastF1 and this website are unofficial and are not associated in any way with
the Formula 1 companies. F1, FORMULA ONE, FORMULA 1, FIA FORMULA ONE WORLD
CHAMPIONSHIP, GRAND PRIX and related marks are trade marks of Formula One
Licensing B.V.
Index (`docs/index.rst`)
######################
Introduction to FastF1
######################
.. toctree::
:hidden:
getting_started/index
gen_modules/examples_gallery/index
api_reference/index
data_reference/index
changelog/index
contributing/index
FastF1 gives you access to F1 lap timing, car telemetry and position,
tyre data, weather data, the event schedule and session results.
.. raw:: html
<style>
.doc-tile-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 16px;
margin: 30px 0;
}
.doc-tile {
width: 165px;
box-shadow: 0 4px 8px var(--pst-color-shadow, rgba(0, 0, 0, 0.1));
border-radius: 5px;
padding: 10px 16px 10px 16px;
text-align: center;
background-color: var(--pst-color-surface, var(--pst-color-background, white));
transition: transform 0.3s, box-shadow 0.3s;
text-decoration: none !important;
color: inherit !important;
display: block;
}
.doc-tile:hover {
transform: translateY(-5px);
box-shadow: 0 8px 16px var(--pst-color-shadow, rgba(0, 0, 0, 0.2));
}
.doc-tile h2 {
margin-top: 0;
font-size: 1.2rem;
margin-bottom: 5px;
color: var(--pst-color-text-base);
}
.doc-tile p {
margin: 0;
font-size: 0.9rem;
color: var(--pst-color-text-muted, #666);
}
.doc-tile-icon {
font-size: 3rem;
margin-bottom: 15px;
color: #e74c3c;
}
</style>
<a href="getting_started/index.html" class="doc-tile">
📚
<h2>GettingStarted</h2>
Examples and tutorials to help you get started
</a>
<a href="api_reference/index.html" class="doc-tile">
🔍
<h2>APIReference</h2>
Documentation of classes and functions
</a>
<a href="data_reference/index.html" class="doc-tile">
📊
<h2>DataReference</h2>
Documentation of the available data
</a>
<a href="gen_modules/examples_gallery/index.html" class="doc-tile">
🖼️
<h2>ExampleGallery</h2>
Examples showing FastF1's capabilities
</a>
<a href="contributing/index.html" class="doc-tile">
⚙️
<h2>Development </h2>
How to contribute and help improve FastF1
</a>======== Features
- Access to F1 timing data, telemetry, sessions results and more
- Full support for the Ergast compatible
jolpica-f1 <https://github.com/jolpica/jolpica-f1/blob/main/docs/README.md>_ API to access current and
historical F1 data - All data is provided in the form of extended Pandas DataFrames to make
working with the data easy while having powerful tools available - Adds custom functions to the Pandas objects specifically to make working
with F1 data quick and simple - Integration with Matplotlib to facilitate data visualization
- Implements caching for all API requests to speed up your scripts
..
To get a quick overview over how to use FastF1, check out
:doc:examples/index or the :doc:gen_modules/examples_gallery/index.
Note that FastF1 handles big chunks of data (~50-100mb per session). To improve
performance, data is per default cached locally. The default placement
of the cache is operating system specific. A custom location can be set if
desired. For more information see :class:`~fastf1.req.Cache`.================= Third-party Tools
These packages are not directly related to the FastF1 project. Questions and
suggestions regarding these packages need to be directed at their respective
maintainers.
SDKs
- f1dataR: R package that wraps FastF1 (https://cran.r-project.org/package=f1dataR)
Websites
- GP Tempo: Web App for exploring F1 Telemetry Data (https://www.gp-tempo.com/)
- Armchair Strategist: Strategy dashboard for all F1 races since 2018 (https://armchair-strategist.dev/)
======================================================== Questions, Contacting the Maintainer and Code of Conduct
For questions that may be of interest to the whole community, please use the
Github Discussions <https://github.com/theOehrly/Fast-F1/discussions>_
section to ask for help. This includes general support questions.
In case of questions that you need to discuss privately, feel free to contact
me via email at [email protected]. Any requests to this address will be
treated with confidentiality, if desired. Do not use this email address for
general support requests! Such requests will likely be ignored.
FastF1 has a Code of Conduct <https://github.com/theOehrly/Fast-F1/blob/main/CODE_OF_CONDUCT.md>.
Complaints about a perceived breach of this code of conduct should be sent to
[email protected], in almost all cases. Please refer to the Code of Conduct,
available through the main page of the GitHub repository (or clickhere <https://github.com/theOehrly/Fast-F1/blob/main/CODE_OF_CONDUCT.md>),
for information on how breaches are reported, how the
Code of Conduct is enforced and what values FastF1 encourages.
====== Notice
FastF1 and this website are unofficial and are not associated in any way with
the Formula 1 companies. F1, FORMULA ONE, FORMULA 1, FIA FORMULA ONE WORLD
CHAMPIONSHIP, GRAND PRIX and related marks are trade marks of Formula One
Licensing B.V.
Templates Class Summary Noinherited (`docs/_templates/class_summary_noinherited.rst`)
``{{ name }}``
.. currentmodule:: {{ module }}
.. autoclass:: {{ objname }}
:members:
:autosummary:
:show-inheritance:
Templates Function (`docs/_templates/function.rst`)
``{{ name }}``
.. currentmodule:: {{ module }}
.. auto{{ objtype }}:: {{ objname }}
Api Reference Accounts Auth (`docs/api_reference/accounts_auth.rst`)
.. _accounts-auth:
F1TV Account Authentication
F1TV Account Usage
FastF1 can require an active F1TV Access/Pro/Premium subscription to access certain data.
Currently, authentication is only required when using the :ref:livetiming.
All data that is obtained after the session has ended can be accessed without authentication.
When FastF1 encounters a feature that requires authentication, it will automatically prompt
you to authenticate with your F1TV account if you haven't done so already.
Authentication Workflow
When authentication is required, FastF1 will:
- Check for an existing valid authentication token
- If no valid token exists, sign in to your Formula 1 account with the selected sign-in method
- After successful login, store the authentication token locally
- Use this token for subsequent data requests
The stored token is independent of the sign-in method that was used to obtain it.
Sign-in Methods
FastF1 supports two sign-in methods.
password (default)
FastF1 signs in directly with your Formula 1 account email and password. The credentials
are read from the environment variables F1_USERNAME and F1_PASSWORD. If they are
not set and the session is interactive, you are prompted for them. Your credentials are
only sent to Formula 1 and are never stored by FastF1.
browser
FastF1 provides a URL that you need to open in a browser to login to F1TV.
A browser addon is required for FastF1 to perform this login. If you have not already
installed this addon, you will be redirected to a page that offers download options for
the addon. You can also visit f1login.fastf1.dev directly. If the addon is installed and
working correctly, you will be redirected to see a success status message. Else, you will
be provided with download options for the addon.
.. note::
This method is not supported in hosted environments like Google Colab or in
WebAssembly based environments like Jupyter Lite.The sign-in method is selected, in order of precedence:
- by calling :func:
fastf1.set_auth_methodin your script, e.g.fastf1.set_auth_method('browser') - by setting the environment variable
FASTF1_AUTH_METHODtopasswordorbrowser - else,
passwordis used
.. autofunction:: fastf1.set_auth_method
Command Line Interface
FastF1 also provides command line options for managing F1TV authentication:
.. code-block:: console
python -m fastf1 auth f1tv [--authenticate] [--clear] [--status] [--method {password,browser}]Options:
--authenticate Start the authentication process manually
--clear Remove stored authentication token
--status Display current authentication status
--method Sign-in method to use with --authenticate
Api Reference Cache And Rate Limits (`docs/api_reference/cache_and_rate_limits.rst`)
.. _rate_limits-caching:
Rate Limits and Caching
All HTTP requests that are performed by FastF1 go through its caching and
rate limiting system.
Caching is enabled by default in FastF1 and most of the time, you do not need
to worry about caching at all. It will simply happen automatically in the
background and speed up your programs. Disabling the cache is highly
discouraged and will generally slow down your programs.
Rate limits are applied at all times. Requests that can be served from the
cache do not count towards any rate limits. Having the cache enabled can
therefore virtually increase the rate limits.
When rate limits are exceeded, FastF1 will either...
throttle the rate of requests, if small delays are sufficient to stay within
the limit (soft rate limit)raise a :class:
fastf1.exceptions.RateLimitExceededError(hard rate limit)
Rate Limits
ToDo explain rate limits
Cache Configuration
.. currentmodule:: fastf1
.. autoclass:: Cache
:members:
:undoc-members:
:autosummary:
Api Reference Circuit Info (`docs/api_reference/circuit_info.rst`)
.. _circuit_info:
Circuit Information
.. autoclass:: fastf1.mvapi.CircuitInfo
:members:
Api Reference Deprecated Legacy (`docs/api_reference/deprecated_legacy.rst`)
.. _deprecated-legacy-api:
Deprecated Legacy API
.. toctree::
legacy/f1_api.. toctree::
legacy/legacyApi Reference Ergast (`docs/api_reference/ergast.rst`)
Ergast API Interface
See :ref:jolpica
Api Reference Events (`docs/api_reference/events.rst`)
.. _event-schedule:
Event Schedule
.. currentmodule:: fastf1.events
Events and the Event Schedule are represented using the following objects.
To access schedule data, see :ref:loading-data.
.. autosummary::
:toctree: api_autogen/
:template: class_summary_noinherited.rst
EventSchedule
EventThe :class:EventSchedule provides information about past and upcoming
Formula 1 events.
An :class:Event can be a race weekend or a testing event. Each event
consists of multiple :class:~fastf1.core.Session.
The event schedule objects are built on top of pandas'
:class:pandas.DataFrame (event schedule) and :class:pandas.Series (event).
Therefore, the usual methods of these pandas objects can be used in addition
to the special methods described here.
.. _event-schedule-data:
Event Schedule Data
The event schedule and each event provide the following information as
DataFrame columns or Series values:
.. list-table::
:widths: 20 20 60
:header-rows: 1
- Name
- Data Type
- Description
- RoundNumber
- :class:
int - The number of the championship round. This is unique for race weekends, while testing events all share the round number zero.
- Country
- :class:
str - The country in which the event is held.
- Location
- :class:
str - The event location; usually the city or region in which the track is situated.
- OfficialEventName
- :class:
str - The official event name as advertised, including sponsor names and stuff.
- EventName
- :class:
str - A shorter event name usually containing the country or location but no no sponsor names. This name is required internally for proper api access.
- EventDate
- :class:
pd.Timestamp - The events reference date and time. This is used mainly internally. Usually, this is the same as the date of the last session.
- EventFormat
- :class:
str - The format of the event. One of 'conventional', 'sprint', 'sprint_shootout', 'sprint_qualifying', 'testing'. See :ref:
event-formats
- Session[1-5]
- :class:
str - The name of the session. One of 'Practice 1', 'Practice 2', 'Practice 3', 'Qualifying', 'Sprint', 'Sprint Shootout' or 'Race'. Testing sessions are considered practice.
- Session[1-5]Date
- :class:
pd.Timestamp - The date and time at which the session is scheduled to start or was scheduled to start as timezone-aware local timestamp. (Timezone-aware local timestamps are not available when the
'ergast'backend is used.)
- Session[1-5]DateUtc
- :class:
pd.Timestamp - The date and time at which the session is scheduled to start or was scheduled to start as non-timezone-aware UTC timestamp.
- F1ApiSupport
- :class:
bool - Denotes whether this session is supported by the official F1 API. Lap timing data and telemetry data can only be loaded if this is true.
.. _event-supported-seasons:
Supported Seasons
.................
FastF1 provides its own event schedule for the 2018 season and all later
seasons. The schedule for all seasons before 2018 is built using data from
the Ergast API. Only limited data is available for these seasons. Usage of the
Ergast API can be enforced for all seasons by setting backend='ergast',
in which case the same limitations apply for the more recent seasons too.
Exact scheduled starting times for all sessions:
Supported starting with the 2018 season.
Starting dates for sessions before 2018 (or when enforcing usage of the Ergast
API) assume that each race weekend was held according to the 'conventional'
schedule (Practice 1/2 on friday, Practice 3/Qualifying on Saturday, Race on
Sunday). A starting date and time can only be provided for the race session.
All other sessions are calculated from this and no starting times can be
provided for these. These assumptions will be incorrect for certain events!
Testing events: Supported for the 2020 season and later seasons. Not
supported if usage of the Ergast API is enforced.
.. _event-formats:
Event Formats
.............
"conventional": Practice 1, Practice 2, Practice 3, Qualifying, Race"sprint": Practice 1, Qualifying, Practice 2, Sprint, RaceThis is the original sprint format that was used in some races in 2021 and
- The Qualifying on friday set the grid for the Sprint on saturday.
The results from the Sprint set the grid for the Race on sunday.
- The Qualifying on friday set the grid for the Sprint on saturday.
"sprint_shootout": Practice 1, Qualifying, Sprint Shootout, Sprint, RaceThis format was used in 2023. The Qualifying on friday sets the grid for the
main Race on sunday. The Sprint Shootout on saturday is held in similar
fashion to a normal Qualifying session and sets the grid for the Sprint that
takes place on saturday as well."sprint_qualifying": Practice 1, Sprint Qualifying, Sprint, Qualifying,
RaceThis format is used starting from 2024. In general, it is similar to the
previous 'sprint_shootout' format, but the order of the sessions was changed
and 'Sprint Shootout' is renamed to 'Sprint Qualifying'. This means that
the Sprint Qualifying on friday is held in similar fashion to a normal
Qualifying and sets the grid for the Sprint on saturday. The Qualifying later
on saturday then sets the grid for the race on Sunday."testing": no fixed session orderusually three practice sessions on three separate days
.. _event-session-identifier:
Session identifiers
...................
Multiple event (schedule) related functions and methods make use of a session
identifier to differentiate between the various sessions of one event.
This identifier can currently be one of the following:
- session name abbreviation:
'FP1', 'FP2', 'FP3', 'Q', 'S', 'SS', 'SQ', 'R' - full session name:
'Practice 1', 'Practice 2', 'Practice 3', 'Sprint', 'Sprint Shootout', 'Sprint Qualifying', 'Qualifying', 'Race';
provided names will be normalized, so that the name is
case-insensitive - number of the session:
1, 2, 3, 4, 5
.. note::
The old 'sprint' event format from 2021 and 2022 originally
used the name 'Sprint Qualifying' before renaming these sessions to just
'Sprint'. The official schedule for 2021 now lists all these sessions as
'Sprint' and FastF1 will therefore return all these sessions as 'Sprint'.
When querying for a specific session, FastF1 will also accept the
'Sprint Qualifying'/'SQ' identifier instead of only 'Sprint'/'S' for
backwards compatibility.
Api Reference Exceptions (`docs/api_reference/exceptions.rst`)
.. _exceptions:
Exceptions
Generic Exceptions
.. autoclass:: fastf1.exceptions.FastF1CriticalError
:show-inheritance:
.. autoclass:: fastf1.exceptions.RateLimitExceededError
:show-inheritance:
Data Loading Exceptions
.. autoclass:: fastf1.exceptions.DataNotLoadedError
:show-inheritance:
.. autoclass:: fastf1.exceptions.FuzzyMatchError
:show-inheritance:
.. autoclass:: fastf1.exceptions.NoLapDataError
:show-inheritance:
.. autoclass:: fastf1.exceptions.F1AuthError
:show-inheritance:
Jolpica-F1 (Ergast) Specific Exceptions
.. _jolpica-excpetions:
.. autoclass:: fastf1.exceptions.ErgastError
:show-inheritance:
.. autoclass:: fastf1.exceptions.ErgastJsonError
:show-inheritance:
.. autoclass:: fastf1.exceptions.ErgastInvalidRequestError
:show-inheritance:
Legacy Exceptions (deprecated)
.. autoclass:: fastf1._api.SessionNotAvailableError
.. autoclass:: fastf1.exceptions.InvalidSessionError
Api Reference Index (`docs/api_reference/index.rst`)
API Reference
This page gives an overview of all public FastF1 objects, functions and methods.
All classes and functions exposed in fastf1.* namespace are public.
The following subpackages are public.
fastf1.corefastf1.ergastfastf1.eventsfastf1.legacyfastf1.livetimingfastf1.plottingfastf1.utils
.. toctree::
:maxdepth: 1
:caption: Functions
loading_data
plotting_data.. toctree::
:maxdepth: 1
:caption: Objects
events
session
timing_data
telemetry
results
circuit_info.. toctree::
:maxdepth: 1
:caption: External APIs
jolpica
ergast.. toctree::
:maxdepth: 1
:caption: Advanced
accounts_auth
cache_and_rate_limits
exceptions
logging
livetiming
utils
deprecated_legacyApi Reference Jolpica (`docs/api_reference/jolpica.rst`)
.. _jolpica:
.. currentmodule:: fastf1.ergast
Jolpica-F1 API Interface
.. note::
This API was previously provided by the Ergast motor racing database (Ergast MRD).
Ergast was shutdown at the beginning of 2025 and
`Jolpica-F1 <https://github.com/jolpica/jolpica-f1>`__ took over
as its successor, providing a replacement API that is drop-in compatible.
While the module names here have not been changed for backwards
compatibility, all data is now obtained from Jolpica-F1.Introduction
This module can be used to interface with theJolpica-F1 <https://github.com/jolpica/jolpica-f1>__ API (previously Ergast).
The :class:Ergast object provides access to all Endpoints of the
Jolpica-F1 API.
The Rate Limits <https://github.com/jolpica/jolpica-f1/blob/main/docs/rate_limits.md>__
of Jolpica-F1 apply.
FastF1 will handle caching and it will try to enforce rate limits where
possible. For more information on how FastF1 handles caching and rate
limiting see :ref:rate_limits-caching.
Result Types
..............
Data can be returned in two different formats:
Raw Response
.. autosummary::
:nosignatures:
~interface.ErgastRawResponse
This format is a JSON-like representation of the original JSON data (usingjson.load).
Flattened into Pandas DataFrames
.. autosummary::
:nosignatures:
~interface.ErgastSimpleResponse
~interface.ErgastMultiResponse
The complexity of the data that is returned by the API endpoint determines
the exact result type. The return type is documented for each endpoint.
An :class:~fastf1.ergast.interface.ErgastSimpleResponse wraps a PandasDataFrame directly.
An :class:~fastf1.ergast.interface.ErgastMultiResponse consists of a
descriptive DataFrame
(:attr:~fastf1.ergast.interface.ErgastMultiResponse.description)
and a list of DataFrames that contain the main content of the response
(:attr:~fastf1.ergast.interface.ErgastMultiResponse.content).
General Options
...............
The following arguments are available as default values on :class:Ergast or
individually for each endpoint method:
- ``result_type`` ('raw' or 'pandas'): Select between RAW responses or
Pandas DataFrame responses.
- ``auto_cast`` (`bool`): Select whether all values are automatically
cast from their default string representation to the most appropriate
data type.
- ``limit`` (`int`): Set the limit for the maximum number of results that
are returned in one request. The server default (30 results) applies
if this value is not set. The maximum allowed value is 1000 results.Common Surprises
................
This is a list of things that may be surprising or unexpected for first-time
users.
API results are always returned in ascending order. As a result, for
example, if you query the race schedule without specifying a season, you
will receive the schedule for the oldest seasons first, starting in 1950.Only some combinations of filter parameters are possible and those vary for
each API endpoint. FastF1 does not impose restrictions on these
combinations as the relationships are fairly complex. Instead, an
:class:~fastf1.exceptions.ErgastInvalidRequestErrorwill
be raised in such a case. The exception will contain the error response
of the server.
Examples
........
First, import :class:~fastf1.ergast.Ergast and create and interface with
all default arguments.
.. doctest::
>>> from fastf1.ergast import Ergast
>>> ergast = Ergast()Simple DataFrame Responses
::::::::::::::::::::::::::
Get information about all circuits that hosted a Grand Prix in 2022.
This is an endpoint that returns an
:class:~fastf1.ergast.interface.ErgastSimpleResponse, meaning one single
DataFrame.
.. doctest::
>>> response_frame = ergast.get_circuits(season=2022)
>>> response_frame
circuitId ... country
0 albert_park ... Australia
1 americas ... USA
2 bahrain ... Bahrain
...
19 villeneuve ... Canada
20 yas_marina ... UAE
21 zandvoort ... Netherlands
[22 rows x 7 columns]Raw Responses
:::::::::::::
To get the raw data instead of the DataFrame result, specify the return type
as 'raw':
.. doctest::
ergast.get_circuits(season=2022, result_type='raw') # doctest: +NORMALIZE_WHITESPACE
[{'circuitId': 'albert_park',
'url': 'https://en.wikipedia.org/wiki/Albert_Park_Circuit',
'circuitName': 'Albert Park Grand Prix Circuit',
'Location': {'lat': -37.8497,
'long': 144.968,
'locality': 'Melbourne',
'country': 'Australia'}},
...]
Note that FastF1's "raw" response is not actually the complete JSON response
that the API provides. Instead, only the actual data part of the response is
returned while metadata (version, query parameters, response length, ...)
are not included.
Renamed Keys and Type Casting
:::::::::::::::::::::::::::::
In the response DataFrame, some keys are renamed from the raw result
so that all column names are unique when flattening more complex responses.
Compare the column names from the result data frame with the raw response above
and note that 'url' has changed to 'circuitUrl' (Responses can include other
URLs as well).
.. doctest::
response_frame.columns
Index(['circuitId', 'circuitUrl', 'circuitName', 'lat', 'long', 'locality',
'country'],
dtype='object')
Also note, that by default all values will automatically be cast to the most
suitable data type. Ergast itself does provide all values as string, though.
Automatic type casting can be very useful because most of the time it will
make it easier to work with the data. But it is possible to disable automatic
type casting by setting auto_cast=False. For example, by default auto
casting is enabled and 'lat' and 'long' will be cast to float,
.. doctest::
ergast.get_circuits(season=2022, result_type='raw')[0]['Location']
{'lat': -37.8497, 'long': 144.968, 'locality': 'Melbourne', 'country': 'Australia'}
but with auto_cast=False both values remain str.
.. doctest::
ergast.get_circuits(season=2022, result_type='raw', auto_cast=False)[0]['Location']
{'lat': '-37.8497', 'long': '144.968', 'locality': 'Melbourne', 'country': 'Australia'}
The documentation for each API endpoint includes an "API Mapping" that
shows the structure of the raw response, the updated key names for flattening
and the data types for automatic type casting. Additionally, there is a
"DataFrame Description" that shows which column names will be present in the
result frame. This way it easy to see which keys are renamed.
Additionally, both the "API Mapping" and the "DataFrame Description" will
show the data type to which a value is cast when auto_cast=True.
.. note::
-1 is used to indicate missing values for int-type values (int
does not support a proper NaN value)
MultiResponse DataFrames
::::::::::::::::::::::::
There are API endpoints that return complex data structures as a
response. When 'pandas' is selected as result type, these endpoints return a
:class:~fastf1.ergast.interface.ErgastMultiResponse. One such endpoint is
the constructor standings endpoint.
.. TODO: the following doctests are skipped because of the broken Ergast API
.. doctest::
standings = ergast.get_constructor_standings() # doctest: +SKIP
Called without any 'season' specifier, it returns standings for multiple
seasons. An overview over the returned data is available as a .description
of the response:
.. doctest::
standings.description # doctest: +SKIP
season round
0 1958 11
1 1959 9
2 1960 10
Note that the API always returns results in an ascending order.
Therefore, when no season is specified, the constructor standings are returned
for the oldest available seasons.
Due to the maximum number of returned results being limited, only data for
three seasons is returned, as can be seen.
The actual standings information is available in separate DataFrames for
each season. These can be accessed as .content of the response.
The first element in .content is associated with the first row of the.description and so on.
.. doctest::
standings.content[0] # doctest: +SKIP
position positionText ... constructorName constructorNationality
0 1 1 ... Vanwall British
1 2 2 ... Ferrari Italian
...
7 8 8 ... Connaught British
8 9 9 ... OSCA Italian
[9 rows x 8 columns]
Pagination
::::::::::
All Ergast response objects inherit from
:class:~fastf1.ergast.interface.ErgastResponseMixin. This object provides
support for pagination on all response objects. Ergast uses pagination
to serve results for specific requests on multiple 'pages' when the response
exceeds the limit for the maximum number of results.
For example, when limiting the sesason list to three results, Ergast
responds with:
.. doctest::
seasons = ergast.get_seasons(limit=3)
seasons
season seasonUrl
0 1950 https://en.wikipedia.org/wiki/1950_Formula_One...
1 1951 https://en.wikipedia.org/wiki/1951_Formula_One...
2 1952 https://en.wikipedia.org/wiki/1952_Formula_One...
It is possible to check whether a response contains all results and to obtain
the total number of results:
.. doctest::
seasons.is_complete
False
seasons.total_results # doctest: +SKIP
74
Now, the builtin pagination can be used to obtain the next result page. The
same limit as before is used.
.. doctest::
seasons.get_next_result_page()
season seasonUrl
0 1953 https://en.wikipedia.org/wiki/1953_Formula_One...
1 1954 https://en.wikipedia.org/wiki/1954_Formula_One...
2 1955 https://en.wikipedia.org/wiki/1955_Formula_One...
It is also possible to manually specify an offset into the dataset:
.. doctest::
ergast.get_seasons(limit=3, offset=6)
season seasonUrl
0 1956 https://en.wikipedia.org/wiki/1956_Formula_One...
1 1957 https://en.wikipedia.org/wiki/1957_Formula_One...
2 1958 https://en.wikipedia.org/wiki/1958_Formula_One...
API Summary
Main Interface
..............
.. autosummary::
:toctree: api_autogen/
:template: class_summary_noinherited.rst
ErgastResponse Objects
................
.. autosummary::
:toctree: api_autogen/
:template: class_summary_noinherited.rst
interface.ErgastRawResponse
interface.ErgastSimpleResponse
interface.ErgastMultiResponse
interface.ErgastResultFrame
interface.ErgastResponseMixinApi Reference Livetiming (`docs/api_reference/livetiming.rst`)
.. _livetiming:
Live Timing Client
This module can be used to save live timing data during a session.
It is not possible to do real-time processing of the data.
.. note::
Usage of the live timing client requires an active F1TV Access/Pro/Premium subscription.
FastF1 will direct you to sign in to you F1TV account if you have not already done so.
You can get more information about the authentication flow in the :ref:`accounts-auth` section.
Use ``--no-auth`` to connect without signing in, in which case data may be incomplete or
missing, and ``--auth-method {password,browser}`` to select the sign-in method.There are two ways to interact with this module.
- From a python script by creating an instance of
:class:`.SignalRClient`
- From the command line by calling ``python -m fastf1.livetiming``Usage Example
- Record live timing data during a session
.. code-block:: console
python -m fastf1.livetiming save saved_data.txtor alternatively create a Python script to run the SignalR client
.. code-block:: python
from fastf1.livetiming.client import SignalRClient
client = SignalRClient(filename="saved_data.txt")
client.start()- Load this data into FastF1 after the session has finished
.. code-block::
import fastf1
from fastf1.livetiming.data import LiveTimingData
livedata = LiveTimingData('saved_data.txt')
session = fastf1.get_testing_session(2021, 1, 1)
session.load(livedata=livedata)optionally you can load live timing data from two or more files
.. code-block::
livedata = LiveTimingData('saved_data_1.txt', 'saved_data_2.txt')Important Notes
You should try to record a full session whenever possible. Recording may need
to start up to one hour before the start of the session to capture all data.
The api parser may not be able to deal with the data correctly if the
beginning of a session is missing. Your mileage may vary depending on what
and how much data is missing.You should not mix recorded live timing data and data requested from the api
after a session. The data will likely not be synchronized correctly.You should use the cache with saved live timing data too. This will speed up
loading of the data considerably after the first run.You need to use different cache directories if you want to cache
saved live timing data and api data for the same session!
The cache cannot tell the data sources apart. If cached data from one source
already exists it will not be reloaded automatically from a different source.
See :class:fastf1.req.Cachefor details on how to configure a custom
cache directory. One simple way is to add the following line to your code::fastf1.Cache.configure(cache_dir='path/to/cache/directory')
You need to force a cache update if you modify the
:class:~fastf1.livetiming.data.LiveTimingData(e.g. by adding a second
file). The cache cannot tell that the input source was modified and will
still use the old cached data.You can force-refresh the cache::
fastf1.Cache.configure(cache_dir='path/to/cache/directory', force_renew=True)
You only need to use
forece_renew=Trueonce after modifying the
input data.The SignalR Client seems to get disconnected after 2 hours of recording. It
looks like the connection is terminated by the server. You need to manually
start a second recording before the first one disconnects if you want to
have no gap in your recording.Use a different output file name for the second (or any subsequent)
recording. You can then load :class:.data.LiveTimingDatafrom multiple
files. The files need to be provided in chronological order. The content of
the files may overlap. Data from overlapping recordings is recognized and
will not be loaded as a duplicate.
Command Line Interface
Available commands and options when calling python -m fastf1.livetiming
The module has two main commands
.. code-block:: console
{save,extract}
save Save live timing data
extract Extract messages from saved debug-mode dataSave
^^^^
The main command for recording live timing data during a session
.. code-block:: console
usage: python -m fastf1.livetiming save [-h] [--append] [--debug]
[--timeout TIMEOUT] file
positional arguments:
file Output file name
optional arguments:
-h, --help show this help message and exit
--append Append to output file. By default the file is
overwritten if it exists already.
--debug Enable debug mode: save full SignalR message, not
just the data.
--timeout TIMEOUT Timeout in seconds after which the client will
automatically exit if no data is receivedExtract
^^^^^^^
Only for when data was saved with the optional '--debug' argument
Recording in debug mode saves the full SignalR messages as received. The non
debug mode saves only the important data part of a message. The data part of
each message needs to be extracted to utilize the debug-mode data.
The extracted data is the same data you get when saving without the '--debug'
argument.
.. code-block:: console
usage: python -m fastf1.livetiming extract [-h] input output
positional arguments:
input Input file name
output Output file name
optional arguments:
-h, --help show this help message and exitAPI Summary
Live Timing Client
^^^^^^^^^^^^^^^^^^
.. currentmodule:: fastf1.livetiming.client
.. autosummary::
:toctree: api_autogen/
:template: class_summary_noinherited.rst
SignalRClient
messages_from_rawLive Timing Data Object
^^^^^^^^^^^^^^^^^^^^^^^
.. currentmodule:: fastf1.livetiming.data
.. autosummary::
:toctree: api_autogen/
:template: class_summary_noinherited.rst
LiveTimingDataApi Reference Loading Data (`docs/api_reference/loading_data.rst`)
.. _loading-data:
Loading Data
.. currentmodule:: fastf1
Accessing Events and Sessions
When using FastF1, you usually start by loading an event or a
session. This can be done with one of the following functions.
.. autosummary::
:toctree: api_autogen/
:template: function.rst
get_session
get_testing_session
get_event
get_events_remaining
get_event_schedule
get_testing_eventApi Reference Logging (`docs/api_reference/logging.rst`)
.. _logging:
Logging
.. currentmodule:: fastf1
Configure Logging Verbosity
All parts of FastF1 generally log at the log level 'INFO'.
The reason for this is that many data loading processes take multiple
seconds to complete. Logging is used to give progress information here as well
as for showing warnings and non-terminal errors.
The logging level for FastF1 can be easily customized::
import fastf1
fastf1.set_log_level('WARNING')
# ... your code here ... #The available levels are (in order of increasing severity): DEBUG, INFO,
WARNING, ERROR and CRITICAL.
.. autofunction:: set_log_level
Advanced Logging API
.. _advanced-logging:
This section is usually only relevant for developers and contains information
that is useful for debugging and for implementing logging in FastF1 internal
code.
FastF1 uses loggers for each submodule. All loggers are child loggers of
FastF1's base logger. The log level is usually configured equally for all parts
of FastF1. The :class:~fastf1.logger.LoggingManager or the direct access
functions should commonly be used for this.
Note to developers: some parts of FastF1's data loading are wrapped in generic
catch-all error handling to prevent errors in individual data loading tasks to
make FastF1 completely unusable. Instead, unhandled exceptions will be caught,
short error message is logged in level INFO, the full traceback is logged on
level DEBUG and execution will continue as good as possible. This system can
make debugging more difficult because errors are not raised. To circumvent
this, there are two possible ways to disable the catch-all error handling for
data loading:
- explicitly set :attr:
fastf1.logger.LoggingManager.debugtoTrue - set the environment variable
FASTF1_DEBUG=1
Logging Manager
...............
.. autoclass:: fastf1.logger.LoggingManager
:members:
Functions for direct access
...........................
.. automethod:: fastf1.logger.set_log_level
.. automethod:: fastf1.logger.get_logger
.. automethod:: fastf1.logger.soft_exceptions
.. automodule:: fastf1.logger
:show-inheritance:
Api Reference Plotting Colormaps (`docs/api_reference/plotting_colormaps.rst`)
:orphan:
.. _Team-Colormaps-Overview:
Overview over Team Colormaps
Note that the "official" colors that are shown here may be different from
those that are returned by FastF1 at runtime since they are updated from via
the F1 API for each session and may change during the season.
(Colors in the image below are only displayed accurately, when the
documentation website is viewed in light color mode. Use the switcher in the
top right corner to change between light and dark mode.)
.. plot:: _plots/colormap_overview.py
:include-source: False
Api Reference Plotting Data (`docs/api_reference/plotting_data.rst`)
.. _plotting-data:
Plotting Data
The fastf1.plotting submodule contains helper functions for creating data plots.
This submodule mainly offers:
- team names and colors
- driver names and driver abbreviations
- Matplotlib integration and helper functions
FastF1 focuses on plotting with Matplotlib or related libraries like Seaborn.
If you wish to use these libraries, it is highly recommended to enable
extend support for these by calling :func:~fastf1.plotting.setup_mpl.
Team Colormaps
Currently, two team colormaps are supported. Each colormap provides one color
for each team. All functions that return colors for teams or drivers accept an
optional colormap argument. If this argument is not provided, the default
colormap is used. The default colormap can be changed by using
:func:~fastf1.plotting.set_default_colormap.
The 'fastf1' colormap is FastF1's default colormap. These colors are teams'
primary colors or accent colors as they are used by the teams on their website
or in promotional material. The colors are chosen to maximize readability in
plots by creating a stronger contrast while still being associated with the
team. Colors are constant over the course of a season.
The 'official' colormap contains the colors exactly as they are used by
F1 in official graphics and in the TV broadcast. Those colors are often
slightly muted. While that makes them more pleasing to look at in some graphics,
it also reduces the contrast between colors which is often bad for
readability of plots. These colors may change during the season if they are
updated by F1.
See here for a complete list of all colors: :ref:Team-Colormaps-Overview
.. note:: Driver Colors
Previously, individual colors for each driver were provided. This is no
longer the case. The driver color is now equivalent to the team color,
meaning that drivers from the same team have the exact same color. This
change was made because different colors for 20 drivers end up looking
very similar in a lot of cases. Therefore, it is not a good solution to
use driver specific colors to distinguish between different drivers. Other
means of plot styling should be used instead.API Summary
.. currentmodule:: fastf1.plotting
Configuration and Setup
^^^^^^^^^^^^^^^^^^^^^^^
.. autosummary::
:toctree: api_autogen/
:template: function.rst
setup_mplGet Colors, Names and Abbreviations for Drivers or Teams
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autosummary::
:toctree: api_autogen/
:template: function.rst
get_compound_color
get_driver_abbreviation
get_driver_abbreviations_by_team
get_driver_color
get_driver_name
get_driver_names_by_team
get_driver_style
get_team_color
get_team_name
get_team_name_by_driverList all Names and Abbreviations for Drivers/Teams in a Session
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autosummary::
:toctree: api_autogen/
:template: function.rst
get_compound_mapping
get_driver_color_mapping
list_compounds
list_driver_abbreviations
list_driver_names
list_team_namesPlot Styling
^^^^^^^^^^^^
.. autosummary::
:toctree: api_autogen/
:template: function.rst
add_sorted_driver_legend
set_default_colormapAdvanced Functionality
^^^^^^^^^^^^^^^^^^^^^^
.. autosummary::
:toctree: api_autogen/
:template: function.rst
override_team_constantsApi Reference Results (`docs/api_reference/results.rst`)
Results Data
.. currentmodule:: fastf1.core
Results data is represented using the following objects. It can be accessed
through the :attr:Session.results attribute. To load a session, see :ref:loading-data.
.. autosummary::
:toctree: api_autogen/
:template: class_summary_noinherited.rst
SessionResults
DriverResultApi Reference Session (`docs/api_reference/session.rst`)
Session
.. currentmodule:: fastf1.core
The :class:Session is a core part of FastF1 and serves as a starting point
for accessing various data. A :class:Session object represents a specific
race, qualifying, sprint or other Formula 1 session and all data related to
such a session can be accessed through it.
.. autoclass:: Session
:members:
:autosummary:
Api Reference Telemetry (`docs/api_reference/telemetry.rst`)
Car Telemetry
.. currentmodule:: fastf1.core
The :class:Telemetry object is used to provide car telemetry and position data.
.. autoclass:: Telemetry
:members:
:autosummary:
Api Reference Timing Data (`docs/api_reference/timing_data.rst`)
Timing Data
.. currentmodule:: fastf1.core
Timing data is represented using the following objects. It can be accessed
through the :attr:Session.laps attribute. To load a session,
see :ref:loading-data.
.. autosummary::
:toctree: api_autogen/
:template: class_summary_noinherited.rst
Laps
LapLap Timing Data
The following information is available per lap (one DataFrame column
for each):
.. list-table::
:widths: 20 20 60
:header-rows: 1
- Name
- Data Type
- Description
- Time
pandas.Timedelta- Session time when the lap time was set (end of lap)
- Driver
str- Three letter driver identifier
- DriverNumber
str- Driver number
- LapTime
pandas.Timedelta- Recorded lap time. To see if a lap time was deleted, check the Deleted column.
- LapNumber
float- Recorded lap number
- Stint
float- Stint number
- PitOutTime
pandas.Timedelta- Session time when car exited the pit
- PitInTime
pandas.Timedelta- Session time when car entered the pit
- Sector1Time
pandas.Timedelta- Sector 1 recorded time
- Sector2Time
pandas.Timedelta- Sector 2 recorded time
- Sector3Time
pandas.Timedelta- Sector 3 recorded time
- Sector1SessionTime
pandas.Timedelta- Session time when the Sector 1 time was set
- Sector2SessionTime
pandas.Timedelta- Session time when the Sector 2 time was set
- Sector3SessionTime
pandas.Timedelta- Session time when the Sector 3 time was set
- SpeedI1
float- Speedtrap sector 1 [km/h] (missing under red flag)
- SpeedI2
float- Speedtrap sector 2 [km/h] (missing under red flag)
- SpeedFL
float- Speedtrap at finish line [km/h] (missing under red flag and missing on laps where a driver enters the pits)
- SpeedST
float- Speedtrap on longest straight or at a select high speed point, dependent on the circuit [km/h] (missing under red flag)
- IsPersonalBest
bool- Flag that indicates whether this lap is the official personal best lap of a driver. If any lap of a driver is quicker than their respective personal best lap, this means that the quicker lap is invalid and not counted. For example, this can happen if the track limits were exceeded.
- Compound
str- Tyres event specific compound name: SOFT, MEDIUM, HARD, INTERMEDIATE, WET, TEST_UNKNOWN, UNKNOWN. The actual underlying compounds C1 to C5 are not differentiated. TEST_UNKNOWN compounds can appear in the data during pre-season testing and in-season Pirelli tyre tests.
- TyreLife
float- Laps driven on this tire (includes laps in other sessions for used sets of tires)
- FreshTyre
bool- Tyre had TyreLife=0 at stint start, i.e. was a new tire
- Team
str- Team name
- LapStartTime
pandas.Timedelta- Session time at the start of the lap
- LapStartDate
pandas.Timestamp- Timestamp at the start of the lap
- TrackStatus
str- A string that contains track status numbers for all track status that occurred during this lap. The meaning of the track status numbers is explained in :func:
fastf1.api.track_status_data. For filtering laps by track status, you may want to use :func:Laps.pick_track_status.
- Position
float- Position of the driver at the end of each lap. This value is NaN for FP1, FP2, FP3, Sprint Shootout, and Qualifying as well as for crash laps.
- Deleted
Optional[bool]- Indicates that a lap was deleted by the stewards, for example because of a track limits violation. This data is only available when race control messages are loaded.
- DeletedReason
str- Gives the reason for a lap time deletion. This data is only available when race control messages are loaded.
- FastF1Generated
bool- Indicates that this lap was added by FastF1. Such a lap will generally have very limited information available and information is partly interpolated or based on reasonable assumptions. Cases were this is used are, for example, when a partial last lap is added for drivers that retired on track.
- IsAccurate
bool- Indicates that the lap start and end time are synced correctly with other laps. Do not confuse this with the accuracy of the lap time or sector times. They are always considered to be accurate if they exist! If this value is True, the lap has passed as basic accuracy check for timing data. This does not guarantee accuracy but laps marked as inaccurate need to be handled with caution. They might contain errors which can not be spotted easily. Laps need to satisfy the following criteria to be marked as accurate:
- not an inlap or outlap
- set under green or yellow flag (the api sometimes has issues
with data from SC/VSC laps) - is not the first lap after a safety car period
(issues with SC/VSC might still appear on the first lap
after it has ended) - has a value for lap time and all sector times
- the sum of the sector times matches the lap time
(If this were to ever occur, it would also be logged separately
as a data integrity error. You usually don't need to worry about
this.)
Api Reference Utils (`docs/api_reference/utils.rst`)
Utils
.. automodule:: fastf1.utils
:members:
:show-inheritance:
Changelog Current (`docs/changelog/current.rst`)
What's new in v3.9.0
(in development)
Behaviour Changes
^^^^^^^^^^^^^^^^^
Changes to
Session.resultsfor Qualifying and Sprint Qualifying:- If a driver was eliminated in Q1 and did not pass the 107% rule, their
best Q1 time will now be included in the result. - The "ClassifiedPosition" column will be populated with the drivers'
respective classified positions. If a driver was eliminated in Q1, the
value will be set to "N" for "Not Classified". - The old behaviour was for the "ClassifiedPosition" column to not be
used. Drivers who failed the 107% rule had their time excluded from the
results. The new behaviour follows partially from a change in the data
that is returned by the Jolpica-F1 API. Further, the new behaviour
provides more informative data and better matches the behaviour that
was already described in the documentation.
- If a driver was eliminated in Q1 and did not pass the 107% rule, their
Updated internal rate limits for Jolpica-F1 to match changed server
side limits.
New Features
^^^^^^^^^^^^
SessionResultsnow includesTime(best lap time) andPosition
for practice sessions ('Practice 1', 'Practice 2', 'Practice 3').
Previously, both columns wereNaT/NaNfor these sessions.The new method
Cache.configurereplacesCache.enable_cache. All
arguments are keyword arguments and all of them are optional, so that
individual cache settings can be changed easily. This also add the option to
change settings while keeping the default cache location.Cache.disabledandCache.set_disablednow accept the keyword
argumentsdisable_http_cacheanddisable_func_cache. This makes it
possible to disable the HTTP cache (stage 1) and the parsed-data cache
(stage 2) separately. By default, both are disabled, as before.
Deprecations
^^^^^^^^^^^^
fastf1.utils.recursive_dict_get,fastf1.utils.to_datetimeandfastf1.utils.to_timedeltaare deprecated. They were never intended to
be part of the public API. The implementations have been moved to the
internalfastf1.internals.parsing_helpersmodule. The public names
continue to work and forward to the internal implementations, but emit aDeprecationWarning
and will be removed in a future release (#884).The
roundkeyword argument ofEventSchedule.get_event_by_roundis
deprecated and will be removed in a future version. Useround_number
instead. (#890)Cache.enable_cacheis deprecated and will be removed in a future
version. UseCache.configureinstead.Cache.ci_modeis deprecated and will be removed in a future version. UseCache.offline_modeinstead.
Removals
^^^^^^^^
- The deprecated function
fastf1.utils.delta_timehas been removed. It
was deprecated in v3.0.0 because it produced inaccurate results (#884).
Increased minimum versions for dependencies
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- The minimum supported version of
requests-cacheis now 1.3.0.
What's new in v3.8.3
(released 29/04/2026)
Bug Fixes
^^^^^^^^^
Fixed a bug that caused a non-existent first lap to be added for some drivers that did not start a race. This
was observed in the 2026 Chinese Grand Prix. (#899)Fixed an issue that lead to missing tyre data for some laps when the source tyre data was delayed at the start
of a session. This was for example observed in the 2018 Azerbaijan Grand Prix. (#893)Fixed an issue where unexpected driver data from a support race altered the F1 driver data.
(#908) (by @Casper-Guo)
What's new in v3.8.2
(released 29/03/2026)
Bug Fixes
^^^^^^^^^
Fixed a bug that caused crash laps to be duplicated when telemetry data was loaded separately after laps
data had already been loaded (#852) (by @sheehanr).Cleanly handle empty timestamps in responses from the Jolpica-F1 API (#868).
What's new in v3.8.1
(released 11/02/2026)
Bug Fixes
^^^^^^^^^
- Patches to support 2026 Pre-Season Testing
What's new in v3.8.0
(released 10/02/2026)
Dependency Changes
^^^^^^^^^^^^^^^^^^
Support for Python 3.9 is dropped. Python 3.10 is the new minimum version.
Pydantic is added as a new dependency.
The minimum required versions for selected dependencies are increased as follows:
- matplotlib>=3.8.0
- numpy>=1.26.0
- pandas>=2.1.1
- requests>=2.30.0
- scipy>=1.11.0
New Features
^^^^^^^^^^^^
Missing speed trap values are now filled in by FastF1 when possible (#834).
A new submodule
fastf1.exceptionsis introduced. This submodule contains all public
custom exceptions going forward. Importing exceptions from other parts of FastF1 is deprecated.FastF1 is now able to auto-generate (with limitations) team name and color constants that are
required for full functionality of thefastf1.plottingsubmodule. This is done based on
data from the F1 API. It serves as a fallback in case of team (name) changes or when plotting
data of a future season where FastF1 has no built-in constants (yet).
Note that auto-generated team name constants may be imperfect. When auto-generated,
all color schemes will follow the 'official' color scheme. (#848)Preliminary team name and color constants for 2026 have been added. Further changes may be
made at the beginning of the season to better capture the teams identities and branding and
to make the color palette more distinguishable. (#848)
Bug Fixes
^^^^^^^^^
Prevent support race drivers from being included in the driver list and result data. This
previously occurred in some edge cases due to bad source data. (#836)RateLimitExceededErroris now raised as intended an no longer captured and hidden by
internal error handling (#748, #842).
Deprecations
^^^^^^^^^^^^
Importing
ErgastError,ErgastJsonErrorandErgastInvalidRequestErrorfromfastf1.ergast.interfaceis deprecate. Import fromfastf1.exceptionsinstead.Importing
NoLapDataError,DataNotLoadedErrorandInvalidSessionErrorfromfastf1.coreis deprecate. Import fromfastf1.exceptionsinstead.Importing
RateLimitExceededErrorfromfastf1is deprecated. Import fromfastf1.exceptionsinstead.
Note: Deprecated API is removed two minor releases after its deprecation.
Changelog Index (`docs/changelog/index.rst`)
Release Notes
Looking for :ref:previous-release-notes?
.. include:: current.rst
Changelog Previous (`docs/changelog/previous.rst`)
:orphan:
.. _previous-release-notes:
Release Notes for Older Versions
.. toctree::
:maxdepth: 1
v3.7.x
v3.6.x
v3.5.x
v3.4.x
v3.3.x
v3.2.x
v3.1.x
v3.0.x
v2.3.2
v2.3.1
v2.3.0
v2.2.9
v2.2.8
v2.2.7
v2.2.6
v2.2.5
v2.2.4
v2.2.3
v2.2.2
v2.2.1
v2.2.0
v2.1.13
v2.1.12
v2.1.11
v2.1.10
v2.1.9
v2.1.8
v2.1.7
v2.1.6
v2.1.5
v2.1.4
v2.1.3
v2.1.2
v2.1.1
v2.1.0
v2.0.2
v2.0.1
v2.0.0
v1.5.1
Changelog V2.0.0 (`docs/changelog/v2.0.0.rst`)
v2.0.0
first release of this fork
Changes:
fixed a bug where pandas.DataFrame functionality did not properly work with
theLaps classadditional fixes for some minor bugs in
core.get_session
New:
track: module for track and track position related stuffexperimental.syncsolver: an attempt at better data synchronization
Changelog V2.0.1 (`docs/changelog/v2.0.1.rst`)
v2.0.1
Integration of a newer version of Ax6's old repository
This integrates a more recent version of the old repository.
See Issue #1
Possibly breaking changes
:mod:
fastf1.plotting: access to team colors changeduse new function :func:
fastf1.plotting.team_color:mod:
fastf1.core.Laps: :func:pick_driver_numberand :func:pick_driver_numbershave been removed.:func:
fastf1.core.Laps.pick_driverand :func:fastf1.core.Laps.pick_driversdo now accept driver numbers a drivers'
three letter identifiers. Number and letter identifiers can be mixed in a single function call.
Changes:
An error that previously resulted in the loading of laps failing completely is now handled slightly better.
Data loading will now only fail for a driver which is actually concerned by this error and not for all drivers.See: https://github.com/theOehrly/Fast-F1/issues/1#issuecomment-670712178
This still needs to be fixed properly at some point.Fix crash if cache dir does not exist
Some under the hood cleanups and improvements
Somewhat improved documentation
New:
:func:
fastf1.utils.delta_timefor comparing lost/gained time between two driversmanual patch file for Bottas in testing
Changelog V2.0.2 (`docs/changelog/v2.0.2.rst`)
v2.0.2: API code overhaul
This version integrates a major overhaul of the api code (:mod:fastf1.api)
Possibly breaking changes:
Renamed dataframe column 'LastLapTime' to 'LapTime' for the dataframe returned by :func:
api.timing_data
First, this makes more sense.
Second, this column is currently already renamed to 'LapTime' later and already accessible under this name
in the dataframe returned by :func:core.Session.load_laps. Therefore the renaming makes the column name
be consistent between api and core.(This also applies to the dictionary returned by the private function :func:
api._laps_data_driver),Data types in dataframes may have changed
Some private functions (prefixed by '_') may have a different name, parameters and return value now
Changes:
rewrote large parts of :mod:
fastf1.apiwith a somewhat cleaner implementationmore stability
better/more correct PitIn/PitOut and general lap data in some sessions (was missing last lap sometimes but had
a first lap that didn't actually existapi.timing_data and thereby also session.load_laps will raise api.SessionNotAvailableError
if the api request returned no data. This usually happens if the session never took place because it was cancelled.Attempted to fix a bug where timing data from two sources can not be merged. This is caused by the received API
data going backwards in time by one lap. This causes data to be added to the wrong lap.
This problem was the reason for having patch files for some drivers/sessions. The patch files have now been
removed as they are no longer necessary.improved documentation a bit
light cleanup and light documentation improvements of :mod:
fastf1.coresuppressed python-levenshtein warning; it is really not necessary to have it installed for this module
changed logging format for hopefully better readability
tried to fix lap time axis again; hopefully this time I got it right
Changelog V2.1.0 (`docs/changelog/v2.1.0.rst`)
v2.1.0: Refactoring, accuracy improvements and a more accessible interface
Possibly breaking changes:
The 'Space' column has been renamed to 'Distance' as this makes more sense
:func:
fastf1.utils.delta_timenow returns two values; see explanation in the documentationLap telemetry is no longer precalculated and no longer saved in a separate column of the :class:
LapsDataFrame.
This telemetry is now a computed property of :class:Lapsand :class:Lapcalculated property
.telemetry: This contains position and car data merged into one instance of
:class:Telemetry(instance ofDataFrame). The data is comparable to the previous 'telemetry' column.
This data is intended for easy plotting. It should not be used for any further calculations as it
contains interpolated values... code-block::
laps = session.load_laps()
fastest = laps.pick_fastest()tel = fastest['telemetry'] # will now fail as telemetry is no longer saved in DataFrame/Series
tel = fastest.telemetry # will (still) work as this now accesses the computed propertyfunction
get_car_data,get_pos_data: These functions are available for :class:Lapand :class:Laps.
They return the telemetry data as received from the api with minimal postprocessing and crucially
unmerged and without any interpolated values. This data should be used if you intend to do any further
calculations with it.Also read the new documentation section about doing accurate calculations: :ref:
howto_accurate_calculations
Patches and color scheme changes which were automatically applied when importing :mod:
fastf1.plotting
now need to be enabled explicitly. This is done by calling :func:fasf1.plotting.setup_mpl.
This function offers configuration through keyword arguments. The defaults are equal to what was done
automatically before.
It is highly recommended that you call this function to set up your matplotlib plotting environment.The formatting of timedelta values in matplotlib plots is now handled by an external module called 'Timple'.
As part of this change, the function :func:fastf1.plotting.laptime_axishas been removed. Timedelta data
is now detected automatically if matplotlib timedelta support is enabled through :func:fastf1.plotting.setup_mpl.
This will hopefully make the plotting of timedelta values considerably more reliable.The computed telemetry channels 'Distance' (before: 'Space'), 'DriverAhead' and 'DistanceToDriverAhead' are no
longer added to the telemetry data by default. This is done for speed and accuracy reasons. These channels can now
be added by calling the appropriate :meth:Telemetry.add_*methods of the new :class:fastf1.core.Telemetryclass.The cache has been completely rewritten. It is now fully supported again and can detect version updates which
require updating the cached data.
Enabling the cache is now done using :func:fastf1.api.Cache.enable_cache
Changes:
Accuracy improvement: Changes to some parts of the general flow of processing data to reduce calculation errors
Accuracy improvement: slightly better determination of the time at which a lap starts
Speed improvement: Faster parsing of API data
Added track status information to laps data
Added lap accuracy validation as a boolean 'IsAccurate' value for each lap. This is set based on track status,
availability of some required lap data, pit stopsAdded 'Source' to telemetry data to indicate whether a value is original ('car' or 'pos' depending on source)
or interpolatedAdded the class :class:
fastf1.core.Lapwhich subclasses :class:pd.Series. :class:Lapis now the result of
slicing :class:fastf1.core.Laps.Added additional
pick_*()functions to :class:fastf1.core.LapsAdded :class:
fastf1.core.Telemetrywhich subclasses :class:pd.DataFrame. This class offers various methods
for working with the telemetry data and should make it easier to work with the data. Previously inaccessible
functionality is now accessible in a more DataFrame-like style.Added various slicing capabilities for :class:
fastf1.core.TelemetryTelemetry data can be sliced at any point and calculated telemetry channels (Distance, Driver Ahead, ...)
can be added to this slice specifically.Example usages:
'Distance' can be calculated continuously over multiple laps (starts at zero on the first lap
and increases all the time).'DriverAhead' can now be calculated for small telemetry slices more efficiently
DistanceToDriverAhead is reimplemented and returns a considerably smoother result now. This is at the cost of
increasing integration error when used over longer periods of time (i.e. over multiple laps). To work around this,
it should be applied to laps individually. Additionally, the old implementation is still available in
:mod:fastf1.legacy.Add a SignalR client for receiving and saving live timing and telemetry data during a session.
Fixed:
fix: SessionNotAvailableError is now raised as Exception instead of BaseException
fix a crash when there is no valid car telemetry data at all (2019, Australia, FP3)
fix a crash caused by the resampling progressbar when there are very few laps in a session (2019, Azerbaijan, FP1)
fix a crash in _inject_position when some telemetry data is missing (2019, Silverstone, FP1)
fix a crash when data for a session can be requested but the data does not contain any useful values at
all (2020, Styria, 'FP3')
Changelog V2.1.1 (`docs/changelog/v2.1.1.rst`)
v2.1.1
Add support for recording and using live timing data
Possibly breaking changes:
- :meth:
fastf1.Session.load_laps: Data will now be loaded without
telemetry by default, i.e. only timing data is loaded.
Telemetry data is usually not available anyways, therefore this prevents
a confusing error.
- :meth:
Changes:
- Possibility to record live timing data
- Possibility to use recorded live timing data as a data source
Changelog V2.1.10 (`docs/changelog/v2.1.10.rst`)
v2.1.10
Ergast compatibility
- introduce a custom user agent to identify FastF1 when requesting data from the Ergast API
Changelog V2.1.11 (`docs/changelog/v2.1.11.rst`)
v2.1.11
- Fix: last inlap missing from
Laps - Add schedule patch for Sprint Race Weekend at Brazil GP
Changelog V2.1.12 (`docs/changelog/v2.1.12.rst`)
v2.1.12
- fix: crash in lap data parser if a driver did not do any proper laps in a
session - fix: crash in :func:
fastf1.core.Telemetry.calculate_driver_aheadif a
driver did not participate in the session (by @bambz96) - enable automatic cache expiration for requests-cache (#57)
- fix: requests cache not cleared if
force_renew=Trueis used with
:func:fastf1.api.Cache.enable_cache
Changelog V2.1.13 (`docs/changelog/v2.1.13.rst`)
v2.1.13
- fixed issue #74: don't assume that a further session status change
(e.g. ended, finalized) exists after the last lap - improved error handling if there exists no usable lap data for any
driver (#73, e.g. Imola 2021 FP1) - :func:
fastf1.core.get_sessionshould not quietly return
:class:fastf1.core.Weekendinstead of :class:fastf1.core.Session
if an invalid event name is given.
Changelog V2.1.2 (`docs/changelog/v2.1.2.rst`)
v2.1.2
Hotfixes for loading live timing data
Fix failure to load live timing data due to an error in the
api cache function wrapper.Improve track status loading
Changelog V2.1.3 (`docs/changelog/v2.1.3.rst`)
v2.1.3
Improved error handling
Added error handling for partially invalid data when loading car data
and position data.
Changelog V2.1.4 (`docs/changelog/v2.1.4.rst`)
v2.1.4
Bug fixes and various minor improvements
Fix a bug introduced in v2.1.3 which prevented the loading of
any data from the apiMake the api parser more robust and tolerant against invalid data
various small improvements
Changelog V2.1.5 (`docs/changelog/v2.1.5.rst`)
v2.1.5
Improved robustness and minor fixes
Make the data parsing in :class:
fastf1.livetiming.data.LiveTimingDatamore
robust and tolerant against unexpected data.some more small improvements regarding logging and other stuff
Changelog V2.1.6 (`docs/changelog/v2.1.6.rst`)
v2.1.6
Added weather data, general improvements and bug fixes
- Add weather data (#26)
See: :meth:.core.Lap.get_weather_data, :meth:.core.Laps.get_weather_data,
:attr:.core.Session.weather_data - Fix: error when calling :meth:
.core.Laps.get_pos_data(#22) - Fix: error when calling
get_telemetryon the first lap (or a set of laps
containing the first lap) - Make the live timing client exit more cleanly
Changelog V2.1.7 (`docs/changelog/v2.1.7.rst`)
v2.1.7
- fix crash when loading cached data after dependencies have been updated
- specify minimum versions for pandas and numpy
- fix incorrect Alpine team name
- fix future warnings and deprecation warnings caused by Pandas 1.3.0
Changelog V2.1.8 (`docs/changelog/v2.1.8.rst`)
v2.1.8
Add temporary support for sprint qualifying
- This release adds a temporary patch to support weekends with sprint
sprint qualifying and their changed order of sessions.
To get data for sprint qualifying, you can use thefastf1.get_session
function with the argumentevent='SQ'.
Also remember that FP2 is on a Saturday on these weekends. FP3 does
not exist.
Changelog V2.1.9 (`docs/changelog/v2.1.9.rst`)
v2.1.9
- switch renamed dependency 'fuzzywuzzy' to new name 'thefuzz'
- add support for getting team colors from incomplete or partial team
names or from team names containing typos or extra words - make fuzzy string matching for event names case-insensitive
- set missing lap start times to pit out time where possible (fixes issue #29),
- add new api function :func:
fastf1.api.driver_info - support incomplete laps (not timed) caused by drivers crashing/retiring
during a lap: infer as much information as possible so that telemetry
can be accessed easily (fixes issues #36 and #41)
Changelog V2.2.0 (`docs/changelog/v2.2.0.rst`)
v2.2.0
This release introduces a range of new features, bug fixes and improvements.
While backwards compatibility has been kept in mind, some breaking changes
are required.
Changes and New Features:
New :class:
fastf1.events.EventSchedule: The event schedule provides
information about session start times, event format, name and location of
upcoming events as well as previous event. The schedule data for the
current season is pulled from an external source that is updated regularly.
This should solve issues caused by schedule changes during the seasons
or even during a race weekend.New :class:
fastf1.events.Event: This object represents a single event
and holds the same information as the event schedule, but for individual
events.New methods :meth:
fastf1.get_testing_session,
:meth:fastf1.get_event, :meth:fastf1.get_testing_eventand
:meth:fastf1.get_event_scheduleThe cache now implements better automatic cache control and is used for
all requests throughout FastF1.The combination of improved caching and the implementation of the new
event schedule now allow fastf1 to be used even if the Ergast API is not
accessible. This improves reliability in case of temporary server or
network problems.Full offline support: Scripts can be run offline if they have been run
at least once with an active internet connection and caching enabled.Introduces the new objects :class:
fastf1.core.SessionResultsand
:class:fastf1.core.DriverResult. These classes are built on top of
:class:pandas.DataFrameand :class:pandas.Series. They provide
information about all drivers that participated in a session.
This information includes driver numbers, names, team names, finishing
results, ...
Session results are available for all sessions supported by the
Ergast database.A hard coded list of drivers is no longer required for testing sessions.
This data can now be pulled from the api as well.A more understandable error will be raised if properties of the
:class:~fastf1.core.Sessionobject are accessed which are not yet
available because the relevant data has not been loaded.
Bug Fixes:
- Fixed a bug that caused rain fall to always be true in weather data (#76)
Breaking Changes:
For testing events, :class:
fastf1.core.Sessionobjects can no longer be
created through :func:fastf1.get_session. You need to use
:func:fastf1.get_testing_sessioninstead.:attr:
fastf1.core.Session.dateis now a :class:pandas.Timestamp
instead of a string.The signature
fastf1.core.Session.__init__(weekend, session_name)
has been changed tofastf1.core.Session.__init__(event, session_name)to adhere to
new naming conventions. This is a breaking change if the arguments are
given as keyword arguments.:func:
fastf1.get_sessionmay return a different session now for some
edge cases, if you load sessions by name instead of by round number.The property :attr:
fastf1.core.Session.resultsis now an instance of
:class:fastf1.core.SessionResultsinstead of :class:dict. Most of the
previously available data is accessible through the new data replacement
object. Some special information like GPS coordinates and altitude are no
longer available though. If you think that this data should still be
provided by FastF1 in the future, please open an issue for that.The datatype of the telemetry 'Brake' data channel is changed from
inttobool, as brake data was never actually more accurate
than this. The representation as integer (percentage) values was
misleading.
Deprecations:
(Objects, methods and attributes deprecated in v2.2 will be removed
in v2.3. Until then, accessing them will still work but a FutureWarning
is shown, reminding you of the deprecation.)
Removal has been delayed for user convenience and because
there exist no problems currently which make a removal immediately necessary.
The new removal target is v3.0.0
:class:
fastf1.core.Weekendhas been replaced with
:class:fastf1.events.Event. All previously available methods and
properties are implemented by the replacement object, although they have
been partially deprecated.The attributes
name,dateandgpof
:class:fastf1.core.Weekendhave been deprecated.
The replacement object :class:fastf1.events.Eventsubclasses
:class:pandas.Series. The standard ways for accessing pandas Series'
values should be used. The attributes have been additionally renamed in
their Series representation.
For example:Weekend.name-->Event.EventNameorEvent['EventName']Weekend.date-->Event.EventDateorEvent['EventDate']Weekend.gp-->Event.RoundNumberorEvent['RoundNumber']
The attribute :attr:
fastf1.core.Session.weekendhas been replaced by
:attr:fastf1.core.Session.eventto adhere to new naming conventions.The function :func:
fastf1.core.get_roundhas been deprecated and will be
removed without replacement in v2.3. Use :func:fastf1.get_event
instead and and get the round number from the returned event object.:func:
fastf1.core.Session.load_lapshas been deprecated. Use
:func:fastf1.core.Session.loadinstead, which offers more flexibility
for deciding which data should be loaded. The new method will no longer
return a :class:~fastf1.core.Lapsobject! You should access the
:class:~fastf1.core.Lapsobject through
:attr:fastf1.core.Session.laps:class:
fastf1.core.Driverhas been replace with
:class:fastf1.core.DriverResultwhich has a different signature.The attributes
grid,position,name,familynameandteamof :class:fastf1.core.Driverhave been deprecated.
The replacement object :class:fastf1.core.DriverResultsubclasses
:class:pandas.Series. The standard ways for accessing pandas Series'
values should be used. The attributes have been additionally renamed in
their Series representation.
For example:Driver.name-->DriverResult.FirstNameorDriverResult['FirstName']Driver.familyname-->DriverResult.LastNameorDriverResult['LastName']Driver.team-->DriverResult.TeamNameorDriverResult['TeamName']Driver.grid-->DriverResult.GridPositionorDriverResult['GridPosition']Driver.position-->DriverResult.PositionorDriverResult['Position']
Changelog V2.2.1 (`docs/changelog/v2.2.1.rst`)
v2.2.1
Changes:
- Log ergast error tracebacks on level DEBUG instead of WARNING to avoid
confusion when a failure was to be expected.
Bug Fixes:
- Fixed: no session results for Verstappen (driver number 1 vs 33)
(by @vlesierse) - Fixed: slicing telemetry by using multiple laps as a reference returns no
data if some laps have NaT values for 'Time' or 'LapStartTime' - Fixed regression: Loading of livetiming no longer possible since v2.2.0 if
recording does not contain a driver list
Changelog V2.2.2 (`docs/changelog/v2.2.2.rst`)
v2.2.2
Changes:
- Implement support for reading information about a drivers personal best
lap from the api. :func:~fastf1.core.Laps.pick_fastestwill now by
default return the quickest lap that is also marked as personal best lap
of any driver. This fixes the long standing problem that the fastest lap
returned by this function may actually be a deleted lap.
Bug Fixes:
- Fixed: data for the 2022 Saudi Arabian Grand Prix can not be loaded (#135)
- Fixed: incorrect python version check in live timing client, that
prevented running on actually supported versions of python (#132)
Changelog V2.2.3 (`docs/changelog/v2.2.3.rst`)
v2.2.3
Bug Fixes:
- Fixed crash in :func:
fastf1.Telemetry.calculate_driver_aheadin case
of missing car data (#146)
Changelog V2.2.4 (`docs/changelog/v2.2.4.rst`)
v2.2.4
Bug Fixes:
- compatibility fixes for supporting 'Sprint' sessions for the 2022 season
(see also #160)
Changelog V2.2.5 (`docs/changelog/v2.2.5.rst`)
v2.2.5
Bug Fixes:
- Fixed grid position, position and points missing from Sprint sessions
result in 2022 (#166)
New Features:
Added :func:
fastf1.plotting.driver_colorto get driver colors which are
similar to the team color but slightly different between both drivers of
one team. This ways the drivers can be differentiated better.
(by @dialtone in #159)Added support for loading race control messages, see
:attr:fastf1.core.Session.race_control_messages
(by @bruzie in #163)
Changelog V2.2.6 (`docs/changelog/v2.2.6.rst`)
v2.2.6
Bug Fixes:
Fixed incorrect lap start times for first lap after a red flag restart
Fixed first lap missing if a driver crashed during the first lap of a
sprint race (#175)Fixed headshot url missing from result of :func:
fastf1.api.driver_info
(by @bruzie in #173)
New Features:
- Added a check detect and to remove incorrect lap times in the api parser
(#167)
Changelog V2.2.7 (`docs/changelog/v2.2.7.rst`)
v2.2.7
Bug Fixes:
- Fixed an issue that prevented merging of car data and position data
in some cases (see #180)Changelog V2.2.8 (`docs/changelog/v2.2.8.rst`)
v2.2.8
Bug Fixes:
- Ensure that :attr:
fastf1.core.Session.driversreturns a list of
unique values. This prevents problems that result from drivers being
incorrectly listed multiple times in the session result information.
(see #182 for example)
Changelog V2.2.9 (`docs/changelog/v2.2.9.rst`)
v2.2.9
Bug Fixes:
- Fix a typo in :attr:`fastf1.plotting.DRIVER_TRANSLATE` (#207)Changelog V2.3.0 (`docs/changelog/v2.3.0.rst`)
v2.3.0
Bug Fixes:
The matplotlib dependency version is now required to be >= 3.3.3 to prevent
incompatibility. (#210)Fixed: NaT values for 'Time' or 'LapStartTime' may cause a crash
in :func:fastf1.core.Telemetry.calculate_driver_ahead(#151)Fixed: Data for speed trap 'SpeedST' is added to the wrong lap.
This additionally caused empty laps to exist for some drivers at the
beginning of some sessions.Fixed: :func:
fastf1.core.Telemetry.add_driver_aheadcould not
be called on previously resampled telemetry data. (#178)Added: Better error handling for sessions that did not take place.
Fixed: Tyre compound shown for some laps was incorrect in some special
cases. (#204)Fixed: Incorrect first and last name for Hulkenberg in fallback driver list
(by @niallmcevoy)Fixed: metadata for :class:
~fastf1.core.Telemetrywas not propagated
correctly in :func:fastf1.core.Telemetry.merge_channelsand
:func:fastf1.core.Telemetry.resample_channels.Fixed: incorrect call of scipy method in
:func:fastf1.legacy.inject_driver_aheadFixed: Error handling regression in :func:
fastf1.core.Session.loadFixed: :exc:
~fastf1.core.DataNotLoadedErrornot raised forcar_dataandpos_data.
New Features:
Added: Function :func:
fastf1.get_events_remaining(by @oscr)Added: Support for shorthand paths (e.g. '~/cache') in
:func:fastf1.Cache.enable_cache(by @oscr)
Changes:
- The default base url scheme for Ergast is changed from http to https.
Deprecations and Notices for Upcoming Changes:
Deprecation: Undocumented function :func:
fastf1.ergast.fetch_weekend
will be removed without a direct replacement in a future version
(target: v3.0.0).Change: :func:
fastf1.utils.to_timedeltaand
:func:fastf1.utils.to_datetimewill returnNaTinstead of raising and
exception if a valued cannot be parsed in a future version
(target: v3.0.0).
Changelog V2.3.1 (`docs/changelog/v2.3.1.rst`)
v2.3.1
Maintenance release for updating driver names and colors for the 2023 season
(#326 by @Casper-Guo).
Changelog V2.3.2 (`docs/changelog/v2.3.2.rst`)
v2.3.2
Maintenance release to limit the version of pandas to <2.0.0.
Changelog V3.0.X (`docs/changelog/v3.0.x.rst`)
What's new in v3.0.7
(released 17/07/2023)
Bug Fixes and Improvements
^^^^^^^^^^^^^^^^^^^^^^^^^^
Fixed an issue that prevented telemetry data from being loaded when position
data is missing (and vice versa) (#412)Fixed loading of Sprint Shootout results
(#413, regression introduced in v3.0.3)Added driver color for Ricciardo at AlphaTauri (by @pesaventofilippo in #418)
What's new in v3.0.6
(released 21/06/2023)
Release forces a cache update after updating from v3.0.4 and lower. Else, the
changes from v3.0.5 are not applied if the data is cached already.
What's new in v3.0.5
(released 21/06/2023)
Bug Fixes and Improvements
^^^^^^^^^^^^^^^^^^^^^^^^^^
Fixed an error when loading historic sessions (#400).
Fixed an error where lap times are incorrectly not marked as 'Personal Best'.
This also caused :meth:~fastf1.core.Laps.pick_fastestto return incorrect
laps. (#403)
What's new in v3.0.4
(released 03/06/2023)
Bug Fixes and Improvements
^^^^^^^^^^^^^^^^^^^^^^^^^^
Added missing color for compound "TEST-UNKNOWN" (by @Casper-Guo)
Bumped minimum version requirement for dependency 'timple'
What's new in v3.0.3
(released 19/05/2023)
Bug Fixes and Improvements
^^^^^^^^^^^^^^^^^^^^^^^^^^
Fixed incorrectly formatted color codes for tyre compound colors.
(by @Casper-Guo)Fixed a bug that prevented the calculation of results for Qualifying-like
sessions (for example Sprint Shootout) that only occurred on Pandas v1.5.3
and older.
What's new in v3.0.2
(released 09/05/2023)
Bug Fixes and Improvements
^^^^^^^^^^^^^^^^^^^^^^^^^^
Improved support for Sprint Shootout sessions and added session results for
these. (by @mdsakalu)Improved exception handling on various internal functions
What's new in v3.0.1
(released 07/05/2023)
Bug Fixes
^^^^^^^^^
- fixed a bug that prevented the use of the livetiming client from the
commandline
What's new in v3.0.0
(released 02/05/2023)
New Features
^^^^^^^^^^^^
Caching is now enabled by default and does not need to be manually configured
anymore. The cache defaults to using operating system specific default
locations that are intended for storing temporary files.
The cache directory can either be changed from within a script or by setting
and environment variable to define an alternative cache location.
See: :class:fastf1.Cache
(by @oscr)Full support for the Ergast F1 API has now been added, replacing the very
limited functionality that was previously available. Features of the new
implementation:- all endpoints supported
- all query filters supported
- can return data as Pandas DataFrames or raw
- can do automatic type casting to the best suited data type
- uses caching
- supports result limits and pagination
- enforces rate limits defined by Ergast (with cached requests not counting
towards the rate limits)
See: :ref:
jolpicaThe livetiming client now supports all current versions of Python. The limit
to version 3.9 and lower no longer exists for this feature. A big thank you
to @oscr for integrating the problematic python-signalr-client dependency
into FastF1 and fixing the problems that existed with Python 3.10 and higher.The log level for all parts of FastF1 can now be easily configured using
:func:fastf1.set_log_level. The logging system in FastF1 has been
reimplemented to make debugging easier. See :ref:loggingA partial last lap will now be added to :class:
fastf1.core.Lapswhen a
driver retires on track. This especially will make it easier to plot
telemetry data of such a lap as there is now a corresponding
:class:fastf1.core.Lap.When loaded, race control messages will now be parsed to find which laps
were deleted. The :class:fastf1.core.Lapsobject gets two new columns
'Deleted' and 'DeletedReason' that indicate that a lap was deleted and why
it was deleted.The intended total lap count of a race or sprint session is now available
through :attr:fastf1.core.Session.total_laps.
(by @Toskosz)Added method :func:
fastf1.core.Laps.split_qualifying_sessionsto split
laps for a qualifying session into Q1, Q2 and Q3.The F1 timing data API has been added as an additional fallback backend for
retrieving event schedule data (#260).In the event schedule,
Session*Datewill now be a timezone-aware local
timestamp (previously: local, but not timezone-aware). Additionally, for each
session there now exists a non-timezone aware UTC timestamp inSession*DateUtc(#253). Timezone information and UTC timestamps are only
available when using one of'fastf1'or'f1timing'as backend.Added
strict_searchparameter to :func:fastf1.get_eventthat disables
fuzzy matching for exact matching of session names. (by @Neron-png)Added track status data as :attr:
fastf1.core.Session.track_status.
(by @SpyrosKoun)Added function :func:
fastf1.core.Telemetry.add_track_statusfor adding
track status information to telemetry data. (by @SpyrosKoun))Added function :func:
fastf1.core.Laps.pick_lapfor conveniently selecting
specific laps by their lap number. (by @TracingInsights)Added a custom
__repr__to :class:fastf1.core.Sessionfor a more
meaningful string representation of the object. Now, information about the
year, round, event name and session name will be shown. (by @Casper-Guo)FastF1 can now be installed using conda-forge. (by @daylinmorgan)
Added
HeadshotURLandCountryCodeto
:class:fastf1.core.SessionResultsand :class:fastf1.core.DriverResult.
(by @lmontrieux)Tyre compound colors are now available through
:attr:fastf1.plotting.COMPOUND_COLORS. (by @Caspar-Guo)The cache now supports "offline mode" where only cached responses are
returned and no actual requests are sent even if an internet connection
is available. Offline mode can be enabled using
:func:fastf1.Cache.offline_mode.For race sessions, the previously missing first lap time is now automatically
added from Ergast (#293).For race sessions, lap start and end times are now correctly aligned between
drivers. Previously, there was a small difference in the order of a few tens
of milliseconds.Add current
Positionat the end of each lap to :class:fastf1.core.Laps
and :class:fastf1.core.Lap(#295).Add official classification as
ClassifiedPositionfor Races and Sprints
to :class:fastf1.core.SessionResultsand :class:fastf1.core.DriverResult.
TheClassifiedPositionlists the finishing position for drivers who are
officially classified or a reason for not being classified, for example if
a driver retired, was disqualified or similar. (#294)
Other Changes
^^^^^^^^^^^^^
- All columns in :class:
fastf1.core.Lapsthat were previously of typeint
are nowfloatto supportNaNvalues.
Bug Fixes
^^^^^^^^^
The API parser will now correctly detect when lap times were deleted and
will not mark these lap times as personal best time anymore if the deleted
lap was a drivers fastest lap. (#165)Enforce creation of :class:
fastf1.core.Lapswith default columns and
default dtypes (when created through :func:fastf1.core.Session.load)
(#310).Fixed a bug where FastF1 Series-like objects where returned instead of a
native pandasSerieswhen getting a single column of a FastF1
DataFrame-like object by slicing vertically.Improve loading of session results when F1 data is partially incomplete.
Improved type hints throughout FastF1 (by @transorsmth)
Enforce default column dtypes when creating a new :class:
fastf1.core.Laps
object. (#310)Fixed an issues were dtypes were always enforced when a new
:class:fastf1.core.SessionResultsobject was created, even ifforce_default_cols=False.Fixed incorrectly set
_internal_namesfor objects inheriting from
DataFrame or Series. This potentially caused incorrect warnings about
incorrectly creating new columns.Added missing
__finalize__calls for subclasses of DataFrames and Series
that resulted in metadata being lost.Fixed incorrectly spelled driver name for Hulkenberg. (by @lmontrieux)
Documentation improvements. (by @lmontrieux)
Fixed a bug where specific temporary error responses from Ergast where
cached. This then required the cache to be cleared so that the specific
API request would work again.Fixed a bug where lap times and sector times were missing if the previous
value was exactly equalFixed a bug in the API parser that created ghost laps with no real data and
no driver
Backwards Incompatible API Changes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:func:
fastf1.utils.to_datetimeand :func:fastf1.utils.to_timedeltawill
now returnNoneinstead of raising an exception when a string cannot
be parsed.The name of a Sprint session will now always be 'Sprint'. Previously, it was
'Sprint Qualifying' for the 2021 seasons and 'Sprint' for all subsequent
seasons.
Removals
^^^^^^^^
The following deprecated API elements have been removed:
Properties :attr:
fastf1.events.Event.name,
:attr:fastf1.events.Event.dateand :attr:fastf1.events.Event.gpCreating an :class:
fastf1.events.Eventobject by not specifying a theidentifierargument for :func:fastf1.get_sessionand
:func:fastf1.events.get_sessionis no longer supported.The argument
eventis no longer supported by
:func:fastf1.get_sessionand :func:fastf1.events.get_sessionand
replaced byidentifier.Functions :func:
fastf1.core.get_session(use
:func:fastf1.get_session) and :func:fastf1.core.get_round
(no replacement) have been removed.Methods :func:
fastf1.core.Session.load_lapsand
:func:fastf1.core.Session.load_telemetryhave been removed,Property :attr:
fastf1.core.Session.weekendhas been removedProperties :attr:
fastf1.core.DriverResult.name,
:attr:fastf1.core.DriverResult.familyname,
:attr:fastf1.core.DriverResult.grid,
:attr:fastf1.core.DriverResult.position,
:attr:fastf1.core.DriverResult.teamhave been removed:class:
fastf1.core.Driverhas been removed:class:
fastf1.core.Weekendhas been removed:func:
fastf1.ergast.fetch_weekendhas been removed
Performance Improvements
^^^^^^^^^^^^^^^^^^^^^^^^
- performance improvement in :func:
fastf1.api.car_data
and :func:fastf1.api.pos_data
Deprecations
^^^^^^^^^^^^
:mod:
fastf1.apiwill be considered private in future releases and may be
removed or changed. Please do not use functionality from :mod:fastf1.api.
If you currently require functionality from there, please open an issue
on Github with details about what you require and why.:mod:
fastf1.utils.delta_timeis considered deprecated and will be modified or
removed in a future release because it has a tendency to give inaccurate
results.
Changelog V3.1.X (`docs/changelog/v3.1.x.rst`)
What's new in v3.1.5
(released 24/11/2023)
New Features
^^^^^^^^^^^^
- Added driver colors for OWA, DEN, OSU
What's new in v3.1.5
(released 17/11/2023)
Bug Fixes
^^^^^^^^^
Fixed a bug that caused inconsistent behaviour in
:func:~fastf1.core.Laps.pick_fastestin some cases were there was no lap
that met the criteria for a fastest lap. Now, an empty
:class:~fastf1.core.Lapobject will always be returned when there is no
fastest lap. (Note that this will change in the future, see 'Deprecations'
below (#476) (by @Casper-Guo)Fixed a bug that prevented some sessions of the Las Vegas Grand Prix from
being loaded (#481)
Deprecations
^^^^^^^^^^^^
- In cases were no lap meets the criteria for a fastest lap,
:func:~fastf1.core.Laps.pick_fastestcurrently returns an empty
:class:~fastf1.core.Lapobject. Starting from version 3.3, this will
returnNoneinstead
What's new in v3.1.4
(released 26/10/2023)
Bug Fixes
^^^^^^^^^
Fixed a bug that caused :func:
~fastf1.core.Telemetry.add_driver_aheadto
only work with telemetry data that matches the sampling timebase of the
car data (#430)Improved robustness of the Ergast API parser to prevent crashes caused by some
empty values in the API response (#433) (by @harningle)Fixed: some laps that were generated by FastF1 had incorrect lap numbers
Fixed: pit out times from the lap onto the grid are no longer shown for the
first lap of a race-like session. The first lap will only have a pit out time
if a driver started from the pit lane or pitted on the formation lap.
(#467) (by @Casper-Guo)Improved robustness of the 'f1timing' schedule backend to prevent a crash
caused by partially incorrect data for the schedule of the Qatar GPFixed: laps for all drivers were marked as inaccurate if the lap accuracy
check could not be performed for one driver
New Features
^^^^^^^^^^^^
- Added driver colors for VES, POU, HAD, DOO and BEA
(#471) (by @pesaventofilippo)
What's new in v3.1.3
(released 07/10/2023)
Bug Fixes
^^^^^^^^^
- fixed a bug in the driver list parser that caused Piastri to be missing from
the results in the 2023 Qatar Sprint Shootout (#460)
What's new in v3.1.2
(released 31/08/2023)
Bug Fixes
^^^^^^^^^
- temporarily restrict Pandas<2.1.0 due to unexpected API changes
What's new in v3.1.1
(released 29/08/2023)
Hotfix to correct incorrect package definition that prevented import of FastF1.
What's new in v3.1.0
(released 29/08/2023)
New Features
^^^^^^^^^^^^
Added additional circuit information that includes the location of corners,
marshal lights, marshal sectors and the rotation of the track map. This
data is available through :func:fastf1.core.Session.get_circuit_info. Also
check out the new examples that show how to annotate your plots using this
data.
A huge thank you to @multiviewer (https://multiviewer.app/) for providing
this information through MultiViewer's API."SessionInfo" data from the F1 livetiming API is now available through
:attr:fastf1.core.Session.session_infoAdded driver colors for Shwartzman and Lawson (by @pesaventofilippo) (#441)
Various improvement to the
Laps.pick_*methods to make it easier to select
specific laps from :class:~fastf1.core.Laps(by @Casper-Guo) (#376).New (no equivalent has existed before)
- :func:
~fastf1.core.Laps.pick_not_deletedfor selecting all laps that
haven't been deleted
New (these methods replace methods that only accepted single values; the
new functions accept single values or lists of values):func:
~fastf1.core.Laps.pick_lapsfor selecting one or multiple laps
by their lap number; replaces :func:~fastf1.core.Laps.pick_lap:func:
~fastf1.core.Laps.pick_driversfor selecting laps from one or
multiple drivers; replaces :func:~fastf1.core.Laps.pick_driver:func:
~fastf1.core.Laps.pick_compoundsfor selecting laps driven on one or
multiple compounds; replaces :func:~fastf1.core.Laps.pick_tyre
Improved
- :func:
~fastf1.core.Laps.pick_track_statusnow has additional options for
thehowargument to exclude laps with a specific track status or match
or exclude laps with one of multiple track status values.
- :func:
Performance
^^^^^^^^^^^
- greatly improved speed when parsing car data and position data
Bug Fixes
^^^^^^^^^
Fixed :func:
~fastf1.core.Laps.split_qualifying_sessionsreturns
incorrect resultFixed incorrect calculation of results for Qualifying-like sessions (#429)
Fixed incorrect alignment of lap start/end times that causes shifted telemetry
data when comparing laps and incorrect results for calculated grid positions
(#440)Fixed an unhandled exception in the lap timing parser that made it impossible
to load data for the 2020 Miami Qualifying (#431)Fixed incorrectly set lap start times after some red flag restarts
Fixed a bug that could prevent data loading in case of partially missing data
Deprecations
^^^^^^^^^^^^
Deprecated :func:
fastf1.core.Laps.pick_lapDeprecated :func:
fastf1.core.Laps.pick_driverDeprecated :func:
fastf1.core.Laps.pick_tyre
Other Changes
^^^^^^^^^^^^^
Fixed some errors in the documentation (by @dawiddzhafarov, @RyanHaniff)
(#439, #402)Fixed some examples to no longer use deprecated arguments (by @wakamex) (#423)
Fixed an error in the SignalRClient example (by @erdieee) (#421)
Added a new team pace ranking example (by @Casper-Guo) (#420)
Changelog V3.2.X (`docs/changelog/v3.2.x.rst`)
What's new in v3.2.2
(released 09/02/2024)
Bug Fixes
^^^^^^^^^
- Fixed another bug that caused :meth:
fastf1.core.Session.get_circuit_info
to fail only in some cases if the default resampling frequency for
telemetry data is changed (#455)
What's new in v3.2.1
(released 05/02/2024)
Bug Fixes
^^^^^^^^^
- Fixed a bug that caused timestamps of telemetry data to have (apparent)
microseconds precision (even though this is not the case). As a result,
merging position data and car data did not have a well matching timestamp
index resulting in additional interpolated values. This problem only occurred
in combination with recent versions of Pandas.
Other
^^^^^
- Various changes to address deprecations in Pandas.
What's new in v3.2.0
(released 07/01/2024)
New Features
^^^^^^^^^^^^
Added support for Pandas version v2.1.0 and higher.
Methods :meth:
fastf1.core.Lap.get_telemetryand
:meth:fastf1.core.Laps.get_telemetrynow take an optional additionalfrequencykeyword argument to override the default frequency that is
used for resampling.Added :meth:
fastf1.core.Laps.pick_box_lapsto select inlaps and outlaps
(#454) (by @pesaventofilippo)Added the lap number to race control messages, see
:attr:fastf1.core.Session.race_control_messages(#475) (by @manpean)Improved lap data integrity checks (#449) (by @d-tomasino)
Added a string representation for the Cache class that gives information
about the cache path and the cache sizeAdded the function :func:
fastf1.Cache.get_cache_infothat returns
information about the cache path and the cache size
Bug Fixes
^^^^^^^^^
Fixed incorrect lap number (zero instead of one) for generated laps that are
added when a driver crashes on the very first lapFixed :meth:
fastf1.core.Session.get_circuit_infofails if the default
resampling frequency for telemetry data is changed (#455)Fixed multiple issues with the Ergast API interface that resulted in
invalid request being made and consequently no data being returned
(#489, #494) (by @Lombardoc4)Fixed missing driver information for drivers that did not start in a race
(classified as DNS - did not start) (#447)Fixed a regression introduced in v3.1.3 that caused the
CountryCode
to be missing from :class:fastf1.core.SessionResultsFixed a compatibility issued with Pandas v1.3.5
Changelog V3.3.X (`docs/changelog/v3.3.x.rst`)
What's new in v3.3.9
(released 05/07/2024)
New Features
^^^^^^^^^^^^
- Added support for driver Franco Colapinto (COL) (by @grahamjwhite) (#609)
What's new in v3.3.8
(released 10/06/2024)
Bug Fixes
^^^^^^^^^
- Resolved an issue where the majority of data was missing from the 2024
Sprint Qualifying session results (fixes #597).
What's new in v3.3.7
(released 28/05/2024)
Bug Fixes
^^^^^^^^^
- Fixed a bug that caused the timing data for the first lap of the Monaco GP
2024 to be missing entirely (fixes #579)
What's new in v3.3.6
(released 16/05/2024)
Bug Fixes
^^^^^^^^^
Laps where a driver crashes and retires on track now contain a correct
track status (fixes #575)Fixed previously incorrect circuit info for Mugello 2020 (fixes #563)
Others
^^^^^^
- Improved a warning message that informs about missing data when calculating
qualification results
What's new in v3.3.5
(released 19/04/2024)
Bug Fixes
^^^^^^^^^
Fixed an issue that causes no result data to be available for
'Sprint Qualifying' sessionsCorrectly handle reinstated lap times after they were previously deleted
What's new in v3.3.4
(released 17/04/2024)
Bug Fixes
^^^^^^^^^
- Correctly support the new "Sprint Qualifying"
What's new in v3.3.3
(released 05/04/2024)
New Features
^^^^^^^^^^^^
- Added support for driver Ayumu Iwasa (IWA)
What's new in v3.3.2
(released 26/03/2024)
Bug Fixes
^^^^^^^^^
- Fixed a bug that caused the track status values for each lap to be sometimes
incorrect in the 'TrackStatus' column of the :class:~fastf1.core.Laps
DataFrame (fixes #557 and more).
What's new in v3.3.1
(released 10/03/2024)
Bug Fixes
^^^^^^^^^
Fix: correctly handle empty strings when parsing them in
:func:fastf1.utils.to_datetime(by @erdieee) (#531)Fix: gracefully handle empty strings when parsing datetime values in
Ergast responses (by @mdsakalu) (#546). This fixes partially missing data
in the results Qualifying and Race results for the 2024 Saudi Arabia GP.
What's new in v3.3.0
(released 19/02/2024)
New Features
^^^^^^^^^^^^
Updated team names and team colors for the 2024 season. (As usual, this means
that this information is no longer valid for the previous season!)Improved the accuracy of :func:
fastf1.utils.delta_time(by @grahamjwhite)
(#512)
Changelog V3.4.X (`docs/changelog/v3.4.x.rst`)
What's new in v3.4.5
(released 26/02/2025)
Bug Fixes
^^^^^^^^^
- Add workaround to support 2025 pre-season testing sessions
What's new in v3.4.4
(released 17/11/2024)
Bug Fixes
^^^^^^^^^
- Use a custom user agent when requesting event schedule data from Github to
prevent the request from being blocked in some environments. (see #656)
What's new in v3.4.3
(released 03/11/2024)
Bug Fixes
^^^^^^^^^
- Added a workaround to fix an issue that made it impossible to load any data
for the Qualifying of the 2024 Sao Paulo Grand Prix (closes #652).
What's new in v3.4.2
(released 27/10/2024)
Bug Fixes
^^^^^^^^^
Fixed a bug that prevented getting the team color for "RB" in some
situations. (by @Casper-Guo) (#645)Improved some warning messages related to team name matching in the plotting
submodule. (by @Casper-Guo) (#645)
What's new in v3.4.1
(released 16/10/2024)
Bug Fixes
^^^^^^^^^
Fixed a bug that caused qualifying laps to be split incorrectly into Q1, Q2
and Q3 laps. Mainly outlaps were incorrectly assigned to the previous
session. (closes #605)Fixed errors in tyre data (compound, tyre age, ...). (Massive thanks to
user "TheBobba" on the MultiViewer Discord for noticing and helping me with
this!)Added error handling for a rare error caused by downgrading the
requests-cachedependency or by reusing the cache with various versions
of the dependency.
Other Changes
^^^^^^^^^^^^^
- Bumped some DeprecationWarnings to FutureWarnings to make them more visible
to users.
What's new in v3.4.0
(released 26/07/2024)
New Features
^^^^^^^^^^^^
Completely reimplemented the :mod:
fastf1.plottingmodule. The new module
provides a more flexible and powerful API for creating custom plots. This
is an overview of the relevant new features and changes:Driver and team names, abbreviations and colors are now supported for
all seasons since 2018 instead of only for the most recent season.Driver changes and test drivers running in free practice session are now
supported automatically and do no longer require an update of FastF1.Users can now choose between the "official" F1 color map and the color map
that was already used previously by FastF1.Driver specific colors are deprecated. Users are encouraged to use more
visually distinct plot styling options instead to differentiate between
drivers of the same team. The new
:func:~fastf1.plotting.get_driver_stylefunction can be used to easily
get driver specific styling options.Users can override team colors and short name constants on a per-session
basis.The API has been improved to be more consistent and easier to use.
Added support for a fallback mirror for the F1 livetiming API. If the primary
API is unavailable, FastF1 will automatically switch to the fallback mirror
and continue to work without any user intervention.
This feature is experimental and for now provided without any guarantees.Added a warning that informs users when event, driver or team names are
fuzzy matched. (by @Casper-Guo) (#574)Improved fuzzy matching of event names to give better matching results. (by
@Casper-Guo) (#579)Added support for Numpy v2.0.
The SignalRClient can now be started when an async event loop is already
running by awaiting the new
:func:fastf1.livetiming.client.SignalRClient.async_startcoroutine. This
enables usage in newer versions of Juypter Notebooks, for example.Set a default connection timeout of five seconds for all requests to the
Ergast API. This should prevent long data loading times when the API is
unresponsive.
Bug Fixes
^^^^^^^^^
Drivers that crashed on the very first lap are now assigned
NaNas their
position, ensuring correct positions throughout the field at then end of the
first lap. (by @AND2797) (#595)Fixed a bug that prevented loading of any data when driver information was
unavailable from the F1 livetiming API.Fixed a bug in the client side rate limiting that allowed higher rates than
intended. This may have caused the client to be temporarily blocked by the
server.
Deprecations
^^^^^^^^^^^^
The following module level properties of :mod:
fastf1.plottinghave been
deprecated:
:attr:~fastf1.plotting.COMPOUND_COLORS,
:attr:~fastf1.plotting.DRIVER_COLORS,
:attr:~fastf1.plotting.DRIVER_TRANSLATE,
:attr:~fastf1.plotting.TEAM_COLORS,
:attr:~fastf1.plotting.TEAM_TRANSLATE,
:attr:~fastf1.plotting.COLOR_PALETTEThe following functions in :mod:
fastf1.plottinghave been deprecated:
:func:~fastf1.plotting.driver_color,
:func:~fastf1.plotting.team_color,
:func:~fastf1.plotting.lapnumber_axisThe argument
misc_mpl_modsof function :func:~fastf1.plotting.setup_mpl
is deprecated and will be removed in the future without replacement for its
functionality.The argument
color_schemeof function :func:~fastf1.plotting.setup_mpl
will default toNonein the future, meaning that FastF1's default color
scheme will need to be enabled explicitly.
Increased minimum versions for dependencies
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The new minimum version of Python is 3.9. Support for Python 3.8 is dropped.
The minimum versions for the following dependencies have been increased:
- numpy to >=1.23.1
- scipy to >=1.8.1
Changelog V3.5.X (`docs/changelog/v3.5.x.rst`)
What's new in v3.5.3
(released 16/03/2025)
Bug Fixes
^^^^^^^^^
Fixed incorrect number of total laps (
Session.total_laps) for the
2025 Grand Prix of Australia.Fixed incorrectly added 58th lap for Norris in the 2025 Grand Prix of
Australia.
What's new in v3.5.2
(released 14/03/2025)
Bug Fixes
^^^^^^^^^
Use yellow instead of red as team color for Racing Bulls in the 2025 season
to better distinguish the color from others. (by @pesaventofilippo) (#707)Switch to a linear interpolation that considers sample timestamps correctly
when merging/resampling telemetry data.
What's new in v3.5.1
(released 13/03/2025)
New Features
^^^^^^^^^^^^
- :func:
~fastf1.plotting.get_driver_stylenow replaces the magic'auto'
color keyword recursively. This allows for more complex plotting styles, for
example when using the Plotly library. (by @Casper-Guo) (#701)
Bug Fixes
^^^^^^^^^
- Missing drivers are now only added to session results based on data from
Jolpica-F1 (formerly Ergast), when the session type is fully supported by
the API. This fixes cases where drivers were incorrectly added in practice
sessions, for example. (by @Casper-Guo) (#699)
What's new in v3.5.0
(released 01/03/2025)
New Features
^^^^^^^^^^^^
The backend for the Ergast API is now changed to its successor Jolpica-F1
(see https://github.com/jolpica/jolpica-f1 ) to ensure continued support for
the 2025 season and later seasons.Added team colors for the 2025 season. (by @Casper-Guo) (#690)
Bug Fixes
^^^^^^^^^
Incorrect and inconsistent data types in various places have been fixed. The
dtypes of all DataFrames after data loading now always match the dtypes that
are defined in the documentation. Some dtypes may have changed as a result
of this fix.Fixed lap time alignment failures in some edge cases.
Backwards Incompatible Changes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Laps.pick_fastest()will now returnNoneif no fastest lap exists, as
announced previously.
Previously, an emptyLapobject was returned.
Maintenance
^^^^^^^^^^^
Addressed upcoming changes in pandas and fixed a related deprecation warning
caused by implicit type coercion. (by @Casper-Guo) (#676, #682)Temporarily pinned
websocketsto version 14 or older to prevent issues
with live timing recording.
Changelog V3.6.X (`docs/changelog/v3.6.x.rst`)
What's new in v3.6.1
(released 05/09/2025)
Bug Fixes
^^^^^^^^^
- Fix an error when generating the driver-team mapping for plotting constants
(caused by incorrect source data in the 2025 Monza FP1).
What's new in v3.6.0
(released 08/07/2025)
New Features
^^^^^^^^^^^^
The number of laps that each driver completed in a race or sprint session is
now available in :class:~fastf1.core.SessionResults, accessible through
:attr:~fastf1.core.Session.results, in a newLapscolumn. (#766):func:
fastf1.get_events_remainingnow correctly considers the current time
of day and the starting time of the last session of an event to determine
the remaining events. (#750) (by @VLADOZXD)Preliminary Race and Sprint results are now calculated from timing data when
no official results data is available from Jolpica-F1.
(#737) (by @Casper-Guo)
Bug Fixes
^^^^^^^^^
Fixed a bug where incorrect positions were calculated for all drivers at the
end of the first lap in the 2025 British GP (#765)Added additional logic to detect and correct incorrect tyre information in
the source data of the 2025 Australian GP Race and the 2025 Miami GP
Sprint (#746)The API parser will now calculate missing lap times from existing sector
times if possible when the source data explicitly indicates a missing lap
time by providing an empty lap time object. This fixes data errors caused by
transponder issues with RUS car at the 2025 Bahrain GP. (#740)The team name matching used with the plotting functionality now additionally
considers the team short names to fix problems with the short "RB F1 Team"
name. (#726) (by @Casper-Guo)
Removals
^^^^^^^^
According to the deprecation timeline, the following functionality has been
removed after it was marked as deprecated in v3.4.0.
The following module level properties of :mod:
fastf1.plottinghave been
removed:COMPOUND_COLORSDRIVER_COLORSDRIVER_TRANSLATETEAM_COLORSTEAM_TRANSLATECOLOR_PALETTEThe following functions in :mod:
fastf1.plottinghave been removed:driver_color()team_color()lapnumber_axis()The argument
misc_mpl_modsof function :func:~fastf1.plotting.setup_mpl
has been removed without replacement for its functionality.The argument
color_schemeof function :func:~fastf1.plotting.setup_mpl
now defaults toNone.
Maintenance
^^^^^^^^^^^
- Addressed upcoming changes in pandas and fixed a related deprecation warning
caused by implicit type coercion. (by @Casper-Guo) (#727)
Miscellaneous
^^^^^^^^^^^^^
Updated the "Who can still win the drivers WDC" example to use the 2025
season. (#763) (by @faustocalvinio)Added a new "Season Summary Visualization" example to the gallery. (#661)
(by @eatwhatyoukill and @Casper-Guo)Documentation improvements (by @Casper-Guo)
Changelog V3.7.X (`docs/changelog/v3.7.x.rst`)
What's new in v3.7.0
(released 28/11/2025)
New Features
^^^^^^^^^^^^
Python 3.14 is now officially supported.
Major overhaul of the documentation with changes to the overall structure and design. Support for switching between
multiple documentation versions is available going forward from now.The livetiming client now uses a new endpoint and protocol. This follows changes by Formula 1, who have
gradually phased out the old endpoints.Support for authentication with an F1TV Access/Pro/Premium subscription has been added. Authentication is only
required when using the new live timing client, since the new endpoints no longer allow unauthenticated access. This
change has no effect on the majority of users who only load data after a session has ended.
Bug Fixes
^^^^^^^^^
Improved handling of unexpected data types in the Jolpica/Ergast API client to prevent crashes caused by
incorrect or unexpected external data. (#814)Fixed a bug that caused the "auto-cast" feature of the Ergast API client to not cast values of any objects
that were contained inside a JSON array. This bug was only encountered when using raw responses instead of
DataFrames. (#797)Various bugs related to usage of the live timing client and loading of created recordings have been fixed.
Contributing Ai Policy (`docs/contributing/ai_policy.rst`)
.. _ai-policy:
AI Policy
AI-based tools can help to make developers more productive. But current tools
are still unable to make meaningful changes in a complex code base without
significant human oversight. Human judgement and contextual understanding
are very important for a good contribution.
When making any contributions to FastF1, adhere to the guidelines that are
detailed below.
Pull requests and issues that appear to violate these guidelines may be
closed without review or comment by the maintainers. Accounts that repeatedly
violated these guidelines may be blocked.
Responsibility
You must be able to understand your own code and you must be able to
understand related parts of the existing source code. Ensure that your
code meets the code quality standards for FastF1. You are fully responsible
for the contributions that you submit to FastF1.
Communication
Communicate in your own words. Do not use AI to write comments, pull
request descriptions or issue descriptions. Using AI for this makes
it much more difficult to judge your contribution.
If you use AI for translation or grammar correction, please keep the
wording as close as possible to the original wording.
Disclosure
Disclose your usage of AI. Specify what tool(s) you used, how you used them
and what code or text is AI generated.
Copyright
Code generated by AI may infringe on copyright of a third party. It is your
responsibility to not infringe. When in doubt, remember that code that you
write yourself, without AI tools, is your work and does not infringe.
AI Agents
Do not submit fully AI generated pull requests! Don't just act as a proxy for
an AI tool. Maintainers can interact with these tools directly, if they wish
to do so. Submitting fully AI generated pull requests is a waste of reviewers
time.
Acknowledgement and Other Resources
Thank you to the developers of NumPy, SciPy, Matplotlib and various other libraries
for providing significant inspiration for these guidelines.
If you are interested in reading more about the pitfalls that can be associated with
using AI to create contributions on open source projects, here are some additional
resources:
- https://blog.scientific-python.org/scientific-python/community-considerations-around-ai/
- https://github.com/melissawm/open-source-ai-contribution-policies
Contributing Coding Guide (`docs/contributing/coding_guide.rst`)
.. _pr-guidelines:
Pull request guidelines
Pull requests (PRs) are the mechanism for contributing to FastF1s code and
documentation.
Summary for PR authors
.. note::
- We value contributions from people with all levels of experience. In
particular if this is your first PR not everything has to be perfect.
We'll guide you through the PR process. - Nevertheless, try to follow the guidelines below as well as you can to
help make the PR process quick and smooth. - Be patient with reviewers. We try our best to respond quickly, but we
have limited bandwidth. If there is no feedback within a couple of days,
please ping us by posting a comment to your PR. - Do not submit fully AI generated pull requests. Please read the :ref:
ai-policy.
When making a PR, pay attention to:
.. rst-class:: checklist
Adhere to the :ref:
coding_guidelines.Update the :ref:
documentationif necessary.Aim at making the PR as "ready-to-go" as you can. This helps to speed up
the review process.It is ok to open incomplete or work-in-progress PRs if you need help or
feedback from the developers. You may mark these asdraft pull requests <https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests#draft-pull-requests>_
on GitHub.When updating your PR, instead of adding new commits to fix something, please
consider amending your initial commit(s) to keep the history clean.
You can achieve this using.. code-block:: bash
git commit --amend --no-edit
git push [your-remote-repo] [your-branch] --force-with-lease
See also :ref:contributing for how to make a PR.
.. _pr-guidelines-details:
Detailed guidelines
.. _pr-documentation:
Documentation
Every new feature should be documented. If it's a new module, don't
forget to add a new rst file to the API docs.Each high-level function should have a small example in
theExamplessection of the docstring. This should be as simple as
possible to demonstrate the method. More complex examples should go into
a dedicated example file in the :file:examplesdirectory, which will be
rendered to the examples gallery in the documentation.Build the docs and make sure all formatting warnings are addressed.
See :ref:
documenting-fastf1for our documentation style guide.If your change is a major new feature, update
:file:docs/changelog.rst.
.. _pr-automated-tests:
Automated tests
Whenever a pull request is created or updated, various automated test tools
will run on all supported versions of Python.
Make sure that all test are passing. (All checks are listed at the bottom of
the GitHub page of your pull request)
Contributing Contributing (`docs/contributing/contributing.rst`)
.. _contributing:
============ Contributing
The community around FastF1 is slowly building and everyone is welcome to
contribute to the project.
.. note::
Before making contributions to FastF1, please read the :ref:ai-policy.
Submitting a bug report
If you find a bug in the code or documentation, do not hesitate to open a
new issue in the issue section <https://github.com/theOehrly/Fast-F1/issues>_
on Github. You are also welcome to post feature requests or pull requests.
If you have more general questions or problems that likely are not caused by
a bug in FastF1, you can open a newdiscussion <https://github.com/theOehrly/Fast-F1/discussions>_ instead.
If you are reporting a bug, please do your best to include the following:
A short, top-level summary of the bug. In most cases, this should be 1-2
sentences.A short, self-contained code snippet to reproduce the bug, ideally allowing
a simple copy and paste to reproduce. Please do your best to reduce the code
snippet to the minimum required.The actual outcome of the code snippet.
The expected outcome of the code snippet.
The FastF1 version and Python version that you are using.
You can grab the version with the following commands::text>>> import fastf1 >>> fastf1.__version__ # doctest: +SKIP '2.2.1' >>> import platform >>> platform.python_version() # doctest: +SKIP '3.9.2'
We have preloaded the issue creation page with a Markdown template that you
can use to organize this information.
Thank you for your help in keeping bug reports complete, targeted and
descriptive.
Requesting a new feature
Please post feature requests in theissue section <https://github.com/theOehrly/Fast-F1/issues>_ on Github.
Since FastF1 is an open source project with limited resources, you are
encouraged to also participate in the implementation as much as you can.
.. _contributing-code:
Contributing code
.. _how-to-contribute:
How to contribute
The preferred way to contribute to FastF1 is to fork the main repository <https://github.com/theOehrly/Fast-F1/>__ on GitHub,
then submit a "pull request" (PR).
A brief overview is:
Create an account <https://github.com/join>_ on GitHub if you do not
already have one.Fork the
project repository <https://github.com/theOehrly/Fast-F1>_:
click on the 'Fork' button near the top of the page. This creates a copy of
the code under your account on the GitHub server.Clone this copy to your local disk::
git clone https://github.com/
/Fast-F1.git Enter the directory and install the local version of FastF1.
See :ref:installing_for_devsfor instructionsCreate a branch to hold your changes::
git checkout -b my-feature origin/main
and start making changes. Never work in the
mainbranch!Work on this copy, on your computer, using Git to do the version control.
When you're done editing e.g.,fastf1/core.py, do::git add fastf1/core.py
git committo record your changes in Git, then push them to GitHub with::
git push -u origin my-feature
Finally, go to the web page of your fork of the FastF1 repo, and click
'Pull request' to send your changes to the maintainer for review.
.. seealso::
Git documentation <https://git-scm.com/doc>_Git-Contributing to a Project <https://git-scm.com/book/en/v2/GitHub-Contributing-to-a-Project>_Introduction to GitHub <https://lab.github.com/githubtraining/introduction-to-github>_
Contributing pull requests
It is recommended to check that your contribution complies with the following
rules before submitting a pull request:
If your pull request addresses an issue, please use the title to describe the
issue and mention the issue number in the pull request description to ensure
that a link is created to the original issue.All public methods should have informative docstrings with sample usage when
appropriate. Use thegoogle docstring standard <https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html>_.Formatting should follow the recommendations of PEP8_, as enforced by
ruff_. The maximum line length for all changed lines is 79 characters.
You can check code style compliance from the command line with ::python -m pip install ruff
ruff check .or your editor may provide integration with it. The above command will not
flag lines that are too long!Ruff will also be run before each commit if you have the pre-commit hooks
installed (see :ref:install_pre_commit)... _PEP8: https://www.python.org/dev/peps/pep-0008/
.. _ruff: https://docs.astral.sh/ruff/Changes (both new features and bugfixes) should have good test coverage. See
:ref:testingfor more details.Import the following modules using the standard scipy conventions::
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as pltIf your change is a major new feature, add an entry to the
Changelog
section by editingdocs/changelog.rst
.. note::
The current state of the FastF1 code base is not compliant with all
of those guidelines, but we expect that enforcing those constraints on all
new contributions will move the overall code base quality in the right
direction... seealso::
- :ref:
coding_guidelines - :ref:
testing - :ref:
documenting-fastf1
.. _contributing_documentation:
Contributing documentation
You as an end-user of FastF1 can make a valuable contribution because you
more clearly see the potential for improvement than a core developer.
For example, you can:
- Fix a typo
- Clarify a docstring
- Write or update an :ref:
example plot <contributing_gallery_examples>
The documentation source files live in the same GitHub repository as the code.
Contributions are proposed and accepted through the pull request process.
For details see :ref:how-to-contribute.
If you have trouble getting started, you may instead open an issue_
describing the intended improvement.
.. _issue: https://github.com/theOehrly/Fast-F1/issues
.. seealso::
- :ref:
documenting-fastf1
.. _contributing_gallery_examples:
Contributing examples to the gallery
FastF1 uses Sphinx-Gallery <https://sphinx-gallery.github.io/stable/index.html>_
to generate a gallery of examples. The examples gallery is generated from the
files located in the :file:examples folder. To add a new gallery example,
create a new python file in this directory. The file should contain all the
code required to plot the examples. Check out the documentation of
Sphinx-Gallery to find out how to format your example code to include headings,
sections and explanatory text for your example.
.. _coding_guidelines:
Coding guidelines
Supported versions of Python and dependencies
This project supports:
All minor versions of Python released 42 months prior to the project, and at
minimum the two latest minor versions.All minor versions of Numpy, Pandas and Matplotlib released in the 24 months
prior to the project, and at minimum the last three minor versions.For other dependencies: As a guideline, this project will try to support all
minor versions initially released in the 12 months prior to our planned
release date or the oldest that supports our minimum Python. We will only
bump these dependencies as we need new features or the old versions are no
longer compatible with other minimum version requirements of this project.
These guidelines are based on NEP 29__ .
__ https://numpy.org/neps/nep-0029-deprecation_policy.html
API changes
API consistency and stability are of great value. Therefore, API changes
(e.g. signature changes, behavior changes, removals) will only be conducted
if the added benefit is worth the user effort for adapting.
API changes in FastF1 have to be performed following the deprecation process
below, except in very rare circumstances as deemed necessary by the developers.
This ensures that users are notified before the change will take effect and thus
prevents unexpected breaking of code.
Note that FastF1 often needs to be adapted to changes in external APIs which
may come without prior warning. To be able to efficiently keep up with these
external changes, it can be necessary to make changes to FastF1 on shorter
notice than described below. In general, breaking changes and deprecations
should be avoided if possible and users should be given prior warnings and as
much time as possible to adapt.
Rules
- Deprecations are targeted at the next minor release (e.g. 3.x)
- Deprecated API is generally removed two minor releases
after introduction of the deprecation. Longer deprecations can be imposed by
core developers on a case-by-case basis to give more time for the transition
- The old API must remain fully functional during the deprecation period
- If alternatives to the deprecated API exist, they should be available
during the deprecation period
IntroducingAnnounce the deprecation in the changelog
:file:docs/changelog.rst(reference your pull request as well)If possible, issue a warning when the deprecated
API is used, using the pythonwarningsmodule. The correct warning levels
are:DeprecationWarningfor the first minor release where the deprecation is
announced. These warnings are mostly not shown to end users by default
(depending on how a function is called) but are shown to developers.FutureWarningstarting from the second minor release where the
deprecation is announced. These warnings are always shown to end users
and developers.
Expiring
1. Announce the deprecation in the changelog
:file:`docs/changelog.rst` (reference your pull request as well)
For the content, you can usually copy the deprecation notice
and adapt it slightly.
2. Change the code functionality and remove any related deprecation warnings.
Adding new API
--------------
Every new function, parameter and attribute that is not explicitly marked as
private (i.e., starts with an underscore) becomes part of FastF1's public
API. As discussed above, changing the existing API is cumbersome. Therefore,
take particular care when adding new API:
- Mark helper functions and internal attributes as private by prefixing them
with an underscore.
- Carefully think about good names for your functions and variables.
- Try to adopt patterns and naming conventions from existing parts of the
FastF1 API.
- Consider making as many arguments keyword-only as possible. See also
`API Evolution the Right Way -- Add Parameters Compatibly`__.
__ https://emptysqua.re/blog/api-evolution-the-right-way/#adding-parameters
New modules and files: installation
-----------------------------------
* If you have added new files or directories, or reorganized existing
ones, make sure the new files are included in the match patterns in
in *packages* in :file:`setup.cfg`.
.. _using_logging:
Using logging for debug messages
--------------------------------
FastF1 uses a logging system that is based on the standard Python `logging`
library to write verbose warnings, information, and debug messages.
Please use it! In all those places you write `print` calls to do your
debugging, try using `logger.debug` instead!
FastF1 creates one main logger and then uses child loggers for each module.
To include logging in your module, at the top of the module, you need to add
``from fastf1.logger import get_logger``. Then calls in your code like::
# set up the logger once (!)
logger = get_logger(__name__)
# code
logger.info('Here is some information')
logger.debug('Here is some more detailed information')
# more code
will log to a logger named ``fastf1.yourmodulename``.
Which logging level to use?There are five levels at which you can emit messages.
logger.criticalandlogger.errorare really only there for errors that
will end the use of the library but not kill the interpreter.logger.warningis used to warn the user, for example, if an operation has
failed gracefully, if some action is likely to have unintended side-effects
or similar.logger.infois for information that the user may want to know if the
program behaves oddly. For instance, if a driver did not participate in a
session, some data cannot be loaded for this specific driver. But FastF1 can
still be used normally with data of all other drivers in this session.logger.debugis the least likely to be displayed, and hence can be the
most verbose. Information that is usually only required for development
and debugging of FastF1 should be logged here.
By default, in FastF1, logging displays all log messages at levels higher thanlogging.INFO to sys.stderr.
.. _logging tutorial: https://docs.python.org/3/howto/logging.html#logging-basic-tutorial
Allowing optional functions to fail gracefully
FastF1 processes lots of data that may change unexpectedly, contain unknown
values or that is not always available. Of course, the best way to deal with
this is to write code that is as robust as possible. But of course, it is not
always possible to foresee what unexpected data your code might need to deal
with. In some cases, FastF1 cannot work without some specific data being
processed correctly. But in other cases, FastF1 can still be used with limited
functionality if we prevent it from crashing when such an error is encountered.
Examples for such cases are:
- loading optional data: weather data, telemetry, ...
- doing additional (cross) validation of data
- applying corrections to improve the accuracy of data
- ...
If such a task fails, we want FastF1 to show a warning to the user. But
especially if such an error is encountered during data loading, it should not
crash FastF1 and make the whole session unavailable to the user. Loading
incomplete data is always preferred over loading no data at all.
To deal with this, FastF1 provides a special function decorator called
:func:fastf1.logger.soft_exceptions that can be used as follows::
from fastf1.logger import soft_exceptions
@soft_exceptions(descr_name="optional data processing",
msg="Failed to do some optional data processing",
logger=logger)
def _optional_data_loading():
...
return
The basic functionality of this decorator is to wrap a one bigtry: ... except Exception: ... clause around the function call.
But additionally, if the function call fails, the msg is shown to the user,
using the logging level WARNING. The traceback is logged with the logging
level DEBUG and prefaced with the line "Traceback for failure in {descr_name}".
You need to pass the logger for the current module as a third argument to the
decorator.
This catch-all exception handling makes development more difficult, because for
example a debugger won't be able to stop on an unhandled exception. Therefore,
it is possible to easily disable the exception handling for all functions that
are decorated in this way. This is described in detail here:
:ref:logging.
Contributing Devenv Setup (`docs/contributing/devenv_setup.rst`)
.. _installing_for_devs:
===================================== Setting up FastF1 for development
.. _dev-environment:
Creating a dedicated environment
You should set up a dedicated environment to decouple your FastF1
development from other Python and FastF1 installations on your system.
Here we use python's virtual environment venv_, but you may also use others
such as conda.
.. _venv: https://docs.python.org/3/library/venv.html
A new environment can be set up with ::
python -m venv
and activated with one of the following::
source
Whenever you plan to work on FastF1, remember to activate the development
environment in your shell.
Retrieving the latest version of the code
FastF1 is hosted at https://github.com/theOehrly/Fast-F1.git.
git clone https://github.com/theOehrly/Fast-F1.gitThis will place the sources in a directory :file:Fast-F1 below your
current working directory.
If you have the proper privileges, you can use git@ instead ofhttps://, which works through the ssh protocol and might be easier to use
if you are using 2-factor authentication.
The data that the tests and the documentation build run against is provided by
two git submodules. Fetch them from within the :file:Fast-F1 directory, as
needed, using ::
git submodule update --init --depth 1 fastf1/testing/data # for the tests
git submodule update --init --depth 1 docs/data # for the docsEach of these downloads roughly 80 MB and uses a few hundred MB of disk space.
See :ref:testing_test_data and :ref:documenting_doc_data for details.
Installing FastF1 in editable mode
Install FastF1 in editable mode from the :file:Fast-F1 directory
using the command ::
python -m pip install -e .The 'editable/develop mode', builds everything and places links in your Python
environment so that Python will be able to import FastF1 from your
development source directory. This allows you to import your modified version
of FastF1 without re-installing after every change.
.. _install_pre_commit:
Installing additional dependencies for development
To install additional dependencies for development and testing run the
following command within the :file:Fast-F1 directory::
python -m pip install -r requirements/dev.txtIf you also want to build the documentation, you need to install further
additional dependencies::
python -m pip install -r requirements/doc-build.txt.. _pre_commit_hooks:
Installing pre-commit hooks
It is recommended to install pre-commit <https://pre-commit.com/>_ hooks.
These will automatically check and partially fix code style issues (using the
ruff linter and isort) when you run git commit. The hooks are defined in
the top level .pre-commit-config.yaml file. To install the hooks ::
pip install pre-commit
pre-commit installContributing Documenting Fastf1 (`docs/contributing/documenting_fastf1.rst`)
.. _documenting-fastf1:
===================== Writing documentation
Getting started
General file structure
All documentation is built from the :file:docs/. The :file:docs/
directory contains configuration files for Sphinx and reStructuredText
(ReST_; .rst) files that are rendered to documentation pages.
Setting up the doc build
The documentation for FastF1 is generated from reStructuredText (ReST_)
using the Sphinx_ documentation generation tool.
To build the documentation you will need to
:ref:set up FastF1 for development .
Building the docs
The documentation sources are found in the :file:docs/ directory in the trunk.
The configuration file for Sphinx is :file:docs/conf.py. It controls which
directories Sphinx parses, how the docs are built, and how the extensions are
used. The examples in the documentation are built against frozen API responses that
are provided by a git submodule. Fetch it before building the documentation
for the first time (see :ref:documenting_doc_data)::
git submodule update --init --depth 1 docs/data
To build the documentation in html format run the following command
from the :file:docs/ directory:
.. code:: sh
make html
The generated documentation can be found in :file:docs/_build/html and viewed
in an internet browser by opening the html files. Run the following command
to open the homepage of the documentation build:
.. code:: sh
make show
.. _documenting_doc_data:
Documentation data
The documentation build never makes requests to the live APIs. The examples
run against a frozen snapshot of previously recorded API responses instead, so
that the documentation is reproducible and independent of the availability of
the API servers.
This data lives in a separate repository,fastf1-doc-data <https://github.com/theOehrly/fastf1-doc-data>_, which is
included as a git submodule in :file:docs/data/. Fetch it before building the
documentation for the first time::
git submodule update --init --depth 1 docs/data
The commit of the submodule that is referenced by FastF1 is part of every
FastF1 commit. Checking out an older version of FastF1 and updating the
submodule therefore gives you exactly the data that this version of the
documentation was built against. The continuous integration build uses the
same referenced commit.
The directory :file:doc_cache/ that is created in the root of the repository
is used for FastF1's own parsed-data cache (stage 2 cache) while the
documentation is built. It only serves to improve performance, is not version
controlled and can be deleted at any time.
The tests use a separate dataset, see :ref:testing_test_data.
Adding documentation data
.........................
If an example requires data for which no response has been recorded, the build
fails at the very end and reports the affected URLs. This usually means that
the submodule is out of date, so try runninggit submodule update --init --depth 1 docs/data first.
If you write an example that requires data which has not been recorded yet,
you need to record it. Please first check whether you can write your example
based on a session that is already part of the data. Loading a single
additional race session adds roughly 30 MB of data that everybody who
contributes to FastF1 needs to download.
To record the missing data, run the following command from the :file:docs/
directory::
make record-data
This deletes the stage 2 cache and the previous build output, then builds the
documentation with recording enabled. Only the missing responses are requested
from the API; data that is already available is never re-downloaded. The new
responses are written to :file:docs/data/http_cache/, where they show up as
untracked files, and are listed at the end of the build.
.. note::
Recording requires an IP address that is not blocked by the F1 API. Data
centre IP addresses are usually blocked, so this cannot be done from a CI
runner.
Because :file:docs/data/ is a submodule, these files need to be contributed
to the fastf1-doc-data repository:
#. Fork fastf1-doc-data <https://github.com/theOehrly/fastf1-doc-data>_,
then commit the new files inside the submodule and push them to your fork::
cd docs/data
git status # you should be on a branch, not detached
git checkout -b add-data-<topic>
git remote add fork [email protected]:<you>/fastf1-doc-data.git
git status # this should list additions only
git add http_cache
git commit -m "add documentation data for <session>"
git push fork add-data-<topic> Recording only ever adds files. Any deletion or modification that shows up
here means that something went wrong, so investigate before committing.
If the push is rejected with shallow update not allowed, run
git fetch --unshallow origin first; the submodule was cloned with
--depth 1.
Then open a pull request against fastf1-doc-data.
#. Once it is merged, update the submodule reference in your FastF1 pull
request, so that the new data is actually used::
git submodule update --remote docs/data
git add docs/data Data that only exists in a fork or that is newer than the referenced commit
is never visible to the continuous integration build.
If you are unsure about any of this, just open your FastF1 pull request and
ask. Recording the data can also be done for you.
Writing documentation
In general, the style guidelines and formatting conventions described in
https://matplotlib.org/stable/devel/documenting_mpl.html should be applied to
FastF1 as well.
One notable exception is that FastF1 uses the google docstring standard <https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html>_
instead of the numpydoc format.
.. _ReST: https://docutils.sourceforge.io/rst.html
.. _Sphinx: http://www.sphinx-doc.org
Contributing Index (`docs/contributing/index.rst`)
.. _developers-guide-index:
############
Contributing
############
Thank you for your interest in helping to improve FastF1! There are various
ways to contribute to FastF1. All of them are super valuable but don't
necessarily require writing code at all. For example:
- contributing to the documentation
- opening new issues for bugs
- requesting new features
- asking for clarification on things you find unclear
- fixing bugs
- writing example scripts for the gallery
.. raw:: html
[Report a bug](contributing.html#submitting-a-bug-report)
[Request a feature](contributing.html#request-a-new-feature)
[Contribute code](contributing.html#contributing-code)
[Write documentation](contributing.html#contributing-documentation).. toctree::
:maxdepth: 2
contributing.rst
devenv_setup.rst
testing.rst
documenting_fastf1.rst
coding_guide.rst
ai_policy.rst
Acknowledgement: This contribution guide is heavily based on and in large
parts copied over and adapted from Matplotlibs documentation. There's no need
to reinvent the wheel if others have done a great job of explaining things
already.
Contributing Testing (`docs/contributing/testing.rst`)
.. _testing:
======= Testing
FastF1 uses the pytest_ framework.
The tests are in :file:fastf1/tests, and customizations to the pytest
testing infrastructure are in fastf1.testing.
.. _pytest: http://doc.pytest.org/en/latest/
.. _pytest-xdist: https://pypi.org/project/pytest-xdist/
.. _testing_requirements:
Requirements
To run the tests you will need to
:ref:set up FastF1 for development .
Running the tests
In the root directory of your development repository run::
python -m pytest
pytest can be configured via a lot of command-line parameters_. Some
particularly useful ones are:
============================= ===========-v or --verbose Be more verbose-n NUM Run tests in parallel over NUM
processes (requires pytest-xdist_)--capture=no or -s Do not capture stdout
============================= ===========
To run a single test from the command line, you can provide a file path,
optionally followed by the function separated by two colons, e.g., (tests do
not need to be installed, but FastF1 should be)::
pytest fastf1/tests/test_events.py::test_event_get_session_date
In addition, the following FastF1-specific options are available:
=========================== ===========--prj-doc Run only the tests for project structure and
documentation--create-http-cache Record missing test data from the live APIs,
see :ref:testing_test_data
=========================== ===========
.. _command-line parameters: http://doc.pytest.org/en/latest/usage.html
.. _testing_test_data:
Test data
The tests never make requests to the live APIs. They run against a frozen
snapshot of previously recorded API responses instead, so that test results are
reproducible and independent of the availability of the API servers.
This test data lives in a separate repository,fastf1-test-data <https://github.com/theOehrly/fastf1-test-data>_, which is
included as a git submodule in :file:fastf1/testing/data/. Fetch it before
running the tests for the first time::
git submodule update --init --depth 1 fastf1/testing/data
The submodule contains the recorded API responses in :file:http_cache/ as
well as the static test files that some tests read directly, namely the
live timing data in :file:livedata/ and the mocked API responses in
:file:cache_test/.
The commit of the submodule that is referenced by FastF1 is part of every
FastF1 commit. Checking out an older version of FastF1 and updating the
submodule therefore gives you exactly the test data that this version was
developed against. The continuous integration tests use the same referenced
commit, so that they test against the same data as a local test run.
The documentation build uses a separate dataset, see
:ref:documenting_doc_data.
The directory :file:test_cache/ that is created in the root of the repository
is used for FastF1's own parsed-data cache (stage 2 cache) while the tests run.
It stores data after parsing in FastF1 and only serves to improve performance.
This directory is not version controlled and can be deleted at any time.
Adding test data
................
If a test fails because no test data is available for a request, pytest will
report the affected URLs at the end of the test run. This usually means that
the submodule is out of date, so try runninggit submodule update --init --depth 1 fastf1/testing/data first.
If you write a test that requires data which has not been recorded yet, you
need to record it. Please first check whether you can write your test based
on a session that is already part of the test data. Loading a single
additional race session adds roughly 30 MB of data that everybody who
contributes to FastF1 needs to download.
To record the missing data, run the affected tests with::
python -m pytest --create-http-cache fastf1/tests/test_my_new_test.py
Only the missing responses are requested from the API; data that is already
available is never re-downloaded. The new responses are written to
:file:fastf1/testing/data/http_cache/, where they show up as untracked
files.
Because :file:fastf1/testing/data/ is a submodule, these files need to be
contributed to the fastf1-test-data repository:
#. Fork fastf1-test-data <https://github.com/theOehrly/fastf1-test-data>_,
then commit the new files inside the submodule and push them to your fork::
cd fastf1/testing/data
git status # you should be on a branch, not detached
git checkout -b add-data-<topic>
git remote add fork [email protected]:<you>/fastf1-test-data.git
git status # this should list additions only
git add http_cache
git commit -m "add test data for <session>"
git push fork add-data-<topic> Recording only ever adds files. Any deletion or modification that shows up
here means that something went wrong, so investigate before committing.
If the push is rejected with shallow update not allowed, run
git fetch --unshallow origin first; the submodule was cloned with
--depth 1.
Then open a pull request against fastf1-test-data.
#. Once it is merged, update the submodule reference in your FastF1 pull
request, so that the new data is actually used::
git submodule update --remote fastf1/testing/data
git add fastf1/testing/data Data that only exists in a fork or that is newer than the referenced commit
is never visible to the continuous integration tests.
If you are unsure about any of this, just open your FastF1 pull request and
ask. Recording the data can also be done for you.
Linting - Code style tests
FastF1 uses Ruff_ and isort_ to ensure that the code has a consistent style and
is easily readable. All code should conform to the guidelines that are defined
by PEP8_.
To check whether your code is formatted correctly, run::
ruff check .
To check and correct the import order, run::
python -m isort .
If you have installed the :ref:pre-commit hooks ,
these commands will also be run automatically before each commit.
.. _Ruff: https://docs.astral.sh/ruff/
.. _isort: https://pycqa.github.io/isort/
.. _PEP8: https://pep8.org/
Github Actions CI Tests
FastF1 uses Github Actions to run the tests on every push to the repository and
when updating a pull request. Usually, you should just let all tests run and
make sure that they are passing.
In rare cases, it may be useful to skip some tests. You can do this by adding
a specific comment to the commit message. The following comments are supported:
[skip-pytest]: Skip pytest runs on all Python versions[skip-ruff]: Skip Ruff code style checks[skip-isort]: Skip isort import order checks[skip-doc-build]: Skip building the documentation[skip-readme-test]: Skip the README render test for PyPI
Data Reference Howto Accurate Calculations (`docs/data_reference/howto_accurate_calculations.rst`)
.. _howto_accurate_calculations:
====================================== How to perform calculations accurately
This is intended to be a writeup of my experiences. I discovered all of this when trying to implement new functionality
or when trying to improve existing calculations. The data that can be received from the F1 API has a very limited
sample rate of about 4-5 Hz. Furthermore, the data is somewhat jittery. That said, one can still perform accurate
calculations based on this data. But doing validation and accuracy checks is a must.
Validating results
It is extremely important to never assume that something is correct just because it looks right on the first glance.
Often it is possible to validate the data "against itself" or just validate it logically. This may not always give
absolute certainty that the results are accurate. But it can show when there are errors in the calculations. Or maybe
the data is simply not accurate enough for what one is trying to do.
Here are two examples for (partially) validating calculated data:
- Use a known accurate value as a comparison. Let's assume we calculate the start time of each lap. As a result of
the calculations we get a timestamp per lap which marks the beginning of this lap. We can now subtract the
beginnings of two subsequent laps which will give us a measure for how long the first lap was, i.e. the lap
time. Lap timing is of course also measured separately and known to be accurate to one millisecond. And it
should be the same as our calculated values. This way we can validate the integrity of the calculated
timestamps, excluding any random errors or general inaccuracy. Of course, a fixed offset which is equal for all
timestamps would not show up as an error when using this validation.
- Check that the data makes sense. Again, assume we are trying to find the start of a lap. If have calculated the
timestamps for that, we can also calculated the position of the car at this time. Every time a lap starts, the
car should be crossing over the finish line. And the finish line cannot physically move. So the position of the
car should be the same every time a new lap starts. If it isn't there has to be an error somewhere.Working with the available data
A few straight forward guidelines can be set.
- Do not work with interpolated values. Interpolation does always introduce some inaccuracy and in my experience
this is rarely offset by more data points or by the fact that a timestamp matches better.
The API provides car data and position data separately and with two different time bases. If somehow possible,
you should use the data with the existing time base. That means, you cannot merge the datasets for use in
calculations as this requires interpolation. If you need a combined end result and/or a different time base,
do only merge and resample the result of your calculations. Do not resample the input data.
- Do not perform calculations based on values that have been calculated by means of integration. The low sample rate
of the source data and the existing inaccuracies mean that integration will always be error prone. Errors can
stack up and single outliers will influence all further results of the integration.Clearly, this rules can not always be followed. They sometimes need to be broken as there may be no other way around it.
But, by keeping these rules in mind, potential error sources can be reduced.
Slicing data by lap for use in further calculations
If you simply wish to visualize existing data, slicing laps is rather straight forward.
.. code-block:: python
session = fastf1.get_session(2020, 4, 'Q')
session.load()
fastest_lap = session.laps.pick_fastest()
tel = fastest_lap.telemetryThis will give you the merged telemetry with a first and last value being interpolated additionally so as to exactly
match the start and end of the lap.
This data is not suitable for further calculations though.
If you want to perform your own calculations with the data, you should use the raw data.
To stay away from interpolation before doing any calculations, the following could be done:
.. code-block:: python
session = fastf1.get_session(2020, 4, 'Q')
session.load()
fastest_lap = session.laps.pick_fastest()
# use padding so that there are values outside of the desired range for accurate interpolation later
car_data = fastest_lap.get_car_data(pad=1, pad_side='both')
pos_data = fastest_lap.get_pos_data(pad=1, pad_side='both')
# do calculations here
# ...
# ...
merged_data = car_data.merge_channels(pos_data)
# slice again to remove the padding and interpolate the exact first and last value
merged_data = merged_data.slice_by_lap(fastest_lap, interpolate_edges=True)Disclaimer
The information here is what I have discovered to be most effective. This is probably not perfect. There are just too
many (time consuming) things that can be tried out. If you have some better ideas or want to discuss accuracy and
possibilities, feel free to open an issue about it.
Data Reference Index (`docs/data_reference/index.rst`)
Data Reference
.. warning::
The data reference is still under construction and currently only provides limited
information.
The data reference provides an overview of all the data that is available via FastF1.
.. toctree::
:maxdepth: 1
:caption: Additional Information
howto_accurate_calculations
time_explanation
============== Available Data
The following is a short overview over the available data with some references
to functions and objects used to work with this data.
In most cases, the default workflow with FastF1 is to create a
:class:~fastf1.core.Session object using :func:~fastf1.get_session. You,
will then access all data through the session object. One notable exception to
this pattern is the wrapper for Ergast.
.. table:: Overview over the available data
:widths: auto
===================== ============================================================================================================================== ==================================================================================================
Topic Data References
===================== ============================================================================================================================== ==================================================================================================
Event Schedule event names, countries, locations, dates, scheduled starting times,... (previous and current season including upcoming events) :ref:event-schedule :func:~fastf1.get_event_schedule :func:~fastf1.get_event
Results driver names, team names, finishing and grid positions, points, finishing status,... :class:~fastf1.core.SessionResults, :class:~fastf1.core.DriverResult
Timing Data sector times, lap times, pit stops, tyre data and much more :attr:~fastf1.core.Session.laps :class:~fastf1.core.Laps
Track Status flags, safety car :attr:~fastf1.core.Session.track_status
Session Status started, finished, finalized :attr:~fastf1.core.Session.session_status
Race Control Messages investigations, penalties, restart announcements,... :attr:~fastf1.core.Session.race_control_messages
Telemetry speed, rpm, gear, normalized track position, ... :class:~fastf1.core.Telemetry :func:~fastf1.core.Lap.get_car_data
Track Markers corner numbers, marshall sectors, marshall lights :func:~fastf1.core.Session.get_circuit_info, :ref:circuit_info
Jolpica-F1 API all endpoints that are provided by Jolpica-F1 (previously Ergast) :ref:jolpica
===================== ============================================================================================================================== ==================================================================================================
Compatibility and Availability
Timing data, session information, car telemetry and position data are available
from 2018 onwards. (This data is usually available within 30-120 minutes after
the end of a session.)
It is also possible to obtain this data by recording the data live stream,
using the live timing recorder that is built into FastF1. Usually this is not
necessary but there have been server issues in the past which caused the
data to be not available for download. Recording of the data live stream is
therefore mostly a solution for redundancy.
Schedule information and session results are available for older seasons as
well, going back as far as 1950 (limited to data that is available throughErgast <https://ergast.com/mrd/>_).
Data Reference Time Explanation (`docs/data_reference/time_explanation.rst`)
.. _time-explanation:
=================================== Time, Date and Timing - Explanation
Working with Formula 1 data (or any motorsport data for that matter) requires working working with lots of different
values of time. These values can denote a point in time or a duration. The following is an explanation of the different
values of time which are used in this module.
Points in Time
Three different values of time can denote a point in time in this module. These are:
- Time
- SessionTime
- Date
SessionTime is a time which has a more or less arbitrary zero point multiple minutes before a session officially starts.
It is directly provided by the F1 live timing api. SessionTime zero marks the beginning of all data streams. The
SessionTime references events within the boundaries of one session.
--> SessionTime is relative to the beginning of a session
Date is a UTC timestamp containing date and time. It is therefore an absolute reference to tell when something
happened in the context of the time of day.
--> Date is an absolute point in time
Time references data relative in the current data set. The first sample of a given set of data will always mark the
zero point for this set of data.
--> Time is relative to the first sample of data in a set of data
For a sample of telemetry data this means, that the sample will always have the same value for its Date andSessionTime. But its value for Time will change when the dataset is modified.
Take the following set of example telemetry. Lets assume the variable tel holds previously loaded telemetry data
for one driver an for a full session (only time data is shown for simplification).
.. doctest::
:hide:
import fastf1
import pandas
session = fastf1.get_session(2020, 8, 'R')
session.load()
.. doctest::
tel = session.car_data['33'].loc[:, ['Time', 'SessionTime', 'Date']]
tel
Time SessionTime Date
0 0 days 00:00:02.984000 0 days 00:00:02.984000 2020-09-06 12:40:03.180
1 0 days 00:00:03.224000 0 days 00:00:03.224000 2020-09-06 12:40:03.420
2 0 days 00:00:03.464000 0 days 00:00:03.464000 2020-09-06 12:40:03.660
3 0 days 00:00:03.704000 0 days 00:00:03.704000 2020-09-06 12:40:03.900
4 0 days 00:00:03.944000 0 days 00:00:03.944000 2020-09-06 12:40:04.140
... ... ... ...
35533 0 days 02:23:27.764000 0 days 02:23:27.764000 2020-09-06 15:03:27.960
35534 0 days 02:23:28.004000 0 days 02:23:28.004000 2020-09-06 15:03:28.200
35535 0 days 02:23:28.244000 0 days 02:23:28.244000 2020-09-06 15:03:28.440
35536 0 days 02:23:28.484000 0 days 02:23:28.484000 2020-09-06 15:03:28.680
35537 0 days 02:23:28.724000 0 days 02:23:28.724000 2020-09-06 15:03:28.920
[35538 rows x 3 columns]
The telemetry comprises approximately 2 hours and 23 minutes of data.
The session (a race in this case) did not last this long, but the data starts
before the beginning of the session and ends after the end.SessionTime and Time are exactly the same for this set of data.
This is how the data looks as it is created by the api functions.
Next, the data is sliced to only include a subset of the full session.
.. doctest::
t1 = pandas.Timedelta(hours=1, minutes=20)
t2 = pandas.Timedelta(hours=1, minutes=30)
tel.slice_by_time(t1, t2)
Time SessionTime Date
19811 0 days 00:00:00.195000 0 days 01:20:00.195000 2020-09-06 14:00:00.391
19812 0 days 00:00:00.435000 0 days 01:20:00.435000 2020-09-06 14:00:00.631
19813 0 days 00:00:00.676000 0 days 01:20:00.676000 2020-09-06 14:00:00.872
19814 0 days 00:00:00.916000 0 days 01:20:00.916000 2020-09-06 14:00:01.112
19815 0 days 00:00:01.156000 0 days 01:20:01.156000 2020-09-06 14:00:01.352
... ... ... ...
22288 0 days 00:09:59.076000 0 days 01:29:59.076000 2020-09-06 14:09:59.272
22289 0 days 00:09:59.277000 0 days 01:29:59.277000 2020-09-06 14:09:59.473
22290 0 days 00:09:59.517000 0 days 01:29:59.517000 2020-09-06 14:09:59.713
22291 0 days 00:09:59.757000 0 days 01:29:59.757000 2020-09-06 14:09:59.953
22292 0 days 00:09:59.997000 0 days 01:29:59.997000 2020-09-06 14:10:00.193
[2482 rows x 3 columns]
SessionTime and Date have kept there reference point. But the reference point for Time has changed and its new
zero is now the first sample of this set of data.
If this subset of data was sliced again, Time would change again so as to start at zero on the first sample.
All three of these values have a use for different reasons. Here are some examples.
To check which other cars are on track while one driver is on a fast lap SessionTime is useful.
When overlapping multiple laps for comparison the data can be plotted over Time so that different laps have
a common zero point.
Date is useful when checking out something in reference to commonly used human time.
The relation between SessionTime and Date is a constant offset. This value is available through the session class.
.. doctest::
session.t0_date
Timestamp('2020-09-06 12:40:00.196000')
As already mentioned above, the zero point of the session time is before the actual start of a session. The session
itself officially starts at some later point in time. This value is also available through the session class.
.. doctest::
session.session_start_time
datetime.timedelta(seconds=2008, microseconds=79000)
str(session.session_start_time)
'0:33:28.079000'
Lap timing
.. currentmodule:: fastf1.core
Lap timing data is available in an instance of :class:Laps in :attr:Session.laps.
For each lap, the usual official timing information is available. It consists of the lap time and the sector times.
The columns for this data in :class:Laps are called 'LapTime', 'Sector1Time', 'Sector2Time' and 'Sector3Time'.
These four values are highly accurate and are considered the absolute truth.
For each lap, additional data is available. Amongst others the following time related data:
- 'Time': This marks the point in time when a lap was set, i.e. finished, as a SessionTime. The name 'Time' is
confusing here as it should be 'SessionTime'. It is kept mainly for backwards compatibility. - 'Sector*SessionTime': For each sector a session time is available. This marks the point in time when a sector time
was set. The 'Sector3Session' time is mathematically the same as the end of the lap ('Time'). In most cases this is
true, but there can be minor deviations in some edge cases. (In some cases the api function can not calculate the
timestamps correctly.) - 'LapStartTime': This marks the point in time (SessionTime) when a lap was started and is equivalent to the 'Time'
and 'Sector3Time' of the previous lap. - 'LapStartDate': This is the same as 'LapStartTime' just expressed as 'Date' instead of 'SessionTime'
- 'PitInTime'/'PitOutTime': This marks the point in time (SessionTime) when a car entered or left the pits.
These additional timestamps are not provided by the api. They are calculated as accurate as possible from the available
data but the accuracy can not be verified to millisecond precision.
Getting Started Basics (`docs/getting_started/basics.rst`)
Getting Started with the Basics
FastF1 is built mainly around Pandas DataFrame and Series objects.
If you are familiar with Pandas you'll immediately recognize this and working
with the data will be fairly straightforward. (If you're
not familiar with Pandas at all, it might be helpful to check out a short
tutorial.)
Loading a session or an event
The :class:fastf1.core.Session object is an important starting point for
everything you do with FastF1. Usually, the first thing you want to do
is load a session. For this, you should use
:func:fastf1.get_session.
For example, let's load the Qualifying of the 7th race of the 2021 season:
.. doctest::
import fastf1
session = fastf1.get_session(2021, 7, 'Q')
session.name
'Qualifying'
session.date
Timestamp('2021-06-19 13:00:00')
Now, which race weekend are we actually looking at here?
For this we have the :class:~fastf1.events.Event object which holds
information about each event. An event can be a race weekend or a testing
event and usually consists of multiple sessions. It is accessible through the
session object.
.. doctest::
session.event
RoundNumber 7
Country France
Location Le Castellet
OfficialEventName FORMULA 1 EMIRATES GRAND PRIX DE FRANCE 2021
EventDate 2021-06-20 00:00:00
EventName French Grand Prix
EventFormat conventional
Session1 Practice 1
Session1Date 2021-06-18 11:30:00+02:00
Session1DateUtc 2021-06-18 09:30:00
Session2 Practice 2
Session2Date 2021-06-18 15:00:00+02:00
Session2DateUtc 2021-06-18 13:00:00
Session3 Practice 3
Session3Date 2021-06-19 12:00:00+02:00
Session3DateUtc 2021-06-19 10:00:00
Session4 Qualifying
Session4Date 2021-06-19 15:00:00+02:00
Session4DateUtc 2021-06-19 13:00:00
Session5 Race
Session5Date 2021-06-20 15:00:00+02:00
Session5DateUtc 2021-06-20 13:00:00
F1ApiSupport True
Name: 7, dtype: object
The :class:~fastf1.events.Event object is a subclass of a
:class:pandas.Series. The individual values can therefore be accessed as it
is common for pandas objects:
.. doctest::
session.event['EventName']
'French Grand Prix'
session.event['EventDate'] # this is the date of the race day
Timestamp('2021-06-20 00:00:00')
You can also load an event directly, by using the function
:func:fastf1.get_event. The :class:~fastf1.events.Event object in turn
provides methods for accessing the individual associated sessions.
.. doctest::
event = fastf1.get_event(2021, 7)
event
RoundNumber 7
Country France
Location Le Castellet
OfficialEventName FORMULA 1 EMIRATES GRAND PRIX DE FRANCE 2021
EventDate 2021-06-20 00:00:00
EventName French Grand Prix
EventFormat conventional
Session1 Practice 1
Session1Date 2021-06-18 11:30:00+02:00
Session1DateUtc 2021-06-18 09:30:00
Session2 Practice 2
Session2Date 2021-06-18 15:00:00+02:00
Session2DateUtc 2021-06-18 13:00:00
Session3 Practice 3
Session3Date 2021-06-19 12:00:00+02:00
Session3DateUtc 2021-06-19 10:00:00
Session4 Qualifying
Session4Date 2021-06-19 15:00:00+02:00
Session4DateUtc 2021-06-19 13:00:00
Session5 Race
Session5Date 2021-06-20 15:00:00+02:00
Session5DateUtc 2021-06-20 13:00:00
F1ApiSupport True
Name: 7, dtype: object
session = event.get_race()
session.name
'Race'
Loading a session or an event by name
As an alternative to specifying an event number you can also load
events by using a clearly identifying name.
.. doctest::
event = fastf1.get_event(2021, 'French Grand Prix')
event['EventName']
'French Grand Prix'
You do not need to provide the exact event name. FastF1 will return the
event (or session) that matches your provided name best. Even if you don't
specify the correct name chances are high that FastF1 will find the event
you are looking for.
event = fastf1.get_event(2021, 'Spain')
event['EventName']
'Spanish Grand Prix'
But be aware that this does not always work. Sometimes another name just
matches the provided string better. For example, what we actually want is the
'Emilia Romagna Grand Prix' but we get the 'Belgian Grand Prix' if we don't
specify the name fully and/or correct enough. Why? Because FastF1 is not a
proper intelligent search engine. So check your results.
event = fastf1.get_event(2021, 'Emilian')
event['EventName']
'Belgian Grand Prix'
We need to be a bit more precise here.
event = fastf1.get_event(2021, 'Emilia Romagna')
event['EventName']
'Emilia Romagna Grand Prix'
Events and sessions can also be loaded by their country or location.
session = fastf1.get_session(2021, 'Silverstone', 'Q')
session.event['EventName']
'British Grand Prix'
Working with the event schedule
Instead of loading a specific session or event, it is possible to load the
full event schedule for a season. The :class:~fastf1.events.EventSchedule
is a subclass of a :class:pandas.DataFrame. Detailed information about
the data that is available in the event schedule can be found in
:ref:event-schedule.
schedule = fastf1.get_event_schedule(2021)
schedule
RoundNumber Country ... Session5DateUtc F1ApiSupport
0 0 Bahrain ... NaT False
1 1 Bahrain ... 2021-03-28 15:00:00 True
2 2 Italy ... 2021-04-18 13:00:00 True
3 3 Portugal ... 2021-05-02 14:00:00 True
4 4 Spain ... 2021-05-09 13:00:00 True
5 5 Monaco ... 2021-05-23 13:00:00 True
6 6 Azerbaijan ... 2021-06-06 12:00:00 True
7 7 France ... 2021-06-20 13:00:00 True
8 8 Austria ... 2021-06-27 13:00:00 True
9 9 Austria ... 2021-07-04 13:00:00 True
10 10 Great Britain ... 2021-07-18 14:00:00 True
11 11 Hungary ... 2021-08-01 13:00:00 True
12 12 Belgium ... 2021-08-29 13:00:00 True
13 13 Netherlands ... 2021-09-05 13:00:00 True
14 14 Italy ... 2021-09-12 13:00:00 True
15 15 Russia ... 2021-09-26 12:00:00 True
16 16 Turkey ... 2021-10-10 12:00:00 True
17 17 United States ... 2021-10-24 19:00:00 True
18 18 Mexico ... 2021-11-07 19:00:00 True
19 19 Brazil ... 2021-11-14 17:00:00 True
20 20 Qatar ... 2021-11-21 14:00:00 True
21 21 Saudi Arabia ... 2021-12-05 17:30:00 True
22 22 Abu Dhabi ... 2021-12-12 13:00:00 True
[23 rows x 23 columns]
schedule.columns # doctest: +NORMALIZE_WHITESPACE
Index(['RoundNumber', 'Country', 'Location', 'OfficialEventName', 'EventDate',
'EventName', 'EventFormat', 'Session1', 'Session1Date',
'Session1DateUtc', 'Session2', 'Session2Date', 'Session2DateUtc',
'Session3', 'Session3Date', 'Session3DateUtc', 'Session4',
'Session4Date', 'Session4DateUtc', 'Session5', 'Session5Date',
'Session5DateUtc', 'F1ApiSupport'],
dtype='object')
The event schedule provides methods for selecting specific events:
gp_12 = schedule.get_event_by_round(12)
gp_12['Country']
'Belgium'
gp_austin = schedule.get_event_by_name('Austin')
gp_austin['Country']
'United States'
Displaying driver info and session results
We have created a session now but everything has been rather boring so far.
So let's make it a bit more interesting by taking a look at the results of
this session. For this, it is first necessary to call
:func:Session.load <fastf1.core.Session.load>. This will load all available data for the
session from various APIs. Downloading and processing of the data may take a
few seconds. It is highly recommended to utilize FastF1's built-in caching
functionality to speed up data loading and prevent excessive API requests.
session = fastf1.get_session(2021, 'French Grand Prix', 'Q')
session.load()
session.results
DriverNumber BroadcastName Abbreviation ... Status Points Laps
33 33 M VERSTAPPEN VER ... NaN NaN
44 44 L HAMILTON HAM ... NaN NaN
77 77 V BOTTAS BOT ... NaN NaN
11 11 S PEREZ PER ... NaN NaN
55 55 C SAINZ SAI ... NaN NaN
10 10 P GASLY GAS ... NaN NaN
16 16 C LECLERC LEC ... NaN NaN
4 4 L NORRIS NOR ... NaN NaN
14 14 F ALONSO ALO ... NaN NaN
3 3 D RICCIARDO RIC ... NaN NaN
31 31 E OCON OCO ... NaN NaN
5 5 S VETTEL VET ... NaN NaN
99 99 A GIOVINAZZI GIO ... NaN NaN
63 63 G RUSSELL RUS ... NaN NaN
47 47 M SCHUMACHER MSC ... NaN NaN
6 6 N LATIFI LAT ... NaN NaN
7 7 K RAIKKONEN RAI ... NaN NaN
9 9 N MAZEPIN MAZ ... NaN NaN
18 18 L STROLL STR ... NaN NaN
22 22 Y TSUNODA TSU ... NaN NaN
[20 rows x 22 columns]
The results object (:class:fastf1.core.SessionResults) is a subclass of a
:class:pandas.DataFrame. Therefore, we can take a look at what data columns
there are:
session.results.columns # doctest: +NORMALIZE_WHITESPACE
Index(['DriverNumber', 'BroadcastName', 'Abbreviation', 'DriverId', 'TeamName',
'TeamColor', 'TeamId', 'FirstName', 'LastName', 'FullName',
'HeadshotUrl', 'CountryCode', 'Position', 'ClassifiedPosition',
'GridPosition', 'Q1', 'Q2', 'Q3', 'Time', 'Status', 'Points', 'Laps'],
dtype='object')
As an example, let's display the top ten drivers and their
respective Q3 times. The results are sorted by finishing position, therefore,
this is easy.
session.results.iloc[0:10].loc[:, ['Abbreviation', 'Q3']]
Abbreviation Q3
33 VER 0 days 00:01:29.990000
44 HAM 0 days 00:01:30.248000
77 BOT 0 days 00:01:30.376000
11 PER 0 days 00:01:30.445000
55 SAI 0 days 00:01:30.840000
10 GAS 0 days 00:01:30.868000
16 LEC 0 days 00:01:30.987000
4 NOR 0 days 00:01:31.252000
14 ALO 0 days 00:01:31.340000
3 RIC 0 days 00:01:31.382000
Working with laps and lap times
All individual laps of a session can be accessed through the property
:attr:Session.laps <fastf1.core.Session.laps>. The laps are represented
as :class:~fastf1.core.Laps object which again is a subclass of a
:class:pandas.DataFrame.
session = fastf1.get_session(2021, 'French Grand Prix', 'Q')
session.load()
session.laps
Time Driver ... FastF1Generated IsAccurate
0 0 days 00:17:35.479000 GAS ... False False
1 0 days 00:27:42.702000 GAS ... False False
2 0 days 00:30:15.038000 GAS ... False False
3 0 days 00:31:46.936000 GAS ... False True
4 0 days 00:34:20.695000 GAS ... False False
.. ... ... ... ... ...
265 0 days 00:54:22.881000 GIO ... False True
266 0 days 01:00:32.369000 GIO ... False False
267 0 days 01:03:24.940000 GIO ... False False
268 0 days 01:04:56.753000 GIO ... False True
269 0 days 01:06:42.885000 GIO ... False False
[270 rows x 31 columns]
That's more than 250 laps right there and 26 columns of information.
The following data columns are available:
session.laps.columns # doctest: +NORMALIZE_WHITESPACE
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', 'Deleted', 'DeletedReason',
'FastF1Generated', 'IsAccurate'],
dtype='object')
A detailed explanation for all these columns can be found in the
documentation of the :class:~fastf1.core.Laps class.
The :class:~fastf1.core.Laps object is not a simple DataFrame though.
Like FastF1's other data objects, it provides some more features specifically
for working with Formula 1 data.
One of these additional features are methods for selecting specific laps.
So let's see what the fastest lap time was and who is on pole.
fastest_lap = session.laps.pick_fastest()
fastest_lap['LapTime']
Timedelta('0 days 00:01:29.990000')
fastest_lap['Driver']
'VER'
Check out this example that shows how you can plot lap times:
:ref:sphx_glr_gen_modules_examples_gallery_results_strategy_plot_qualifying_results.py
Getting Started Index (`docs/getting_started/index.rst`)
Getting Started
This section provides information on how to install FastF1 and quickly introduces its basic usage.
.. toctree::
:maxdepth: 1
installation
basicsGetting Started Installation (`docs/getting_started/installation.rst`)
Installation
FastF1 requires Python |min_python_version| or higher.
It is recommended to install FastF1 using pip:
.. code-block:: bash
pip install fastf1
You can also install using conda:
.. code-block:: bash
conda install -c conda-forge fastf1
Alternatively, a wheel or a source distribution can be downloaded from PyPI <https://pypi.org/project/fastf1/>_.
Installation in Pyodide, JupyterLite and other WASM-based environments
FastF1 should be mostly compatible with Pyodide and other WASM-based
environments, although this is not extensively tested. Currently, the
installation and usage require some additional steps. You can find more
information and a guide inthis external repository <https://github.com/f1datajunkie/jupyterlite-fastf1>_
and the discussion in this issue <https://github.com/theOehrly/Fast-F1/issues/667>_.
Api Reference Legacy F1 Api (`docs/api_reference/legacy/f1_api.rst`)
F1 API - :mod:`fastf1.api`
Functions
^^^^^^^^^
.. automodule:: fastf1.api
:members: pages, make_path, timing_data, timing_app_data, car_data, position_data, track_status_data, session_status_data, race_control_messages, lap_count, driver_info, weather_data, season_schedule, fetch_page, parse
Api Reference Legacy Legacy (`docs/api_reference/legacy/legacy.rst`)
Legacy Functionality - :mod:`fastf1.legacy`
.. automodule:: fastf1.legacy
:members:
:undoc-members:
:show-inheritance:
--- METRICS ---
- Files Extracted: 79
- Estimated Token Budget: ~49336 tokens
- Canonical Reference: https://codewiki.google/github.com/theOehrly/Fast-F1