Skip to content

Commit

Permalink
add CI mode for Cache: only request uncached data
Browse files Browse the repository at this point in the history
  • Loading branch information
theOehrly committed Apr 12, 2023
1 parent d745b93 commit 518f739
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
5 changes: 3 additions & 2 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,6 @@ def reference_laps_data():
def fastf1_setup():
import fastf1
from fastf1.logger import LoggingManager
fastf1.Cache.enable_cache('test_cache')
LoggingManager.debug = True
fastf1.Cache.enable_cache('test_cache') # use specific cache directory
fastf1.Cache.ci_mode(True) # only request uncached data
LoggingManager.debug = True # raise all exceptions
1 change: 1 addition & 0 deletions fastf1/ergast/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ def _get(cls, url: str, params: dict) -> Union[dict, list]:
try:
return json.loads(r.content.decode('utf-8'))
except Exception as exc:
Cache.delete_response(url) # don't keep a corrupted response
raise ErgastJsonError(
f"Failed to parse Ergast response ({url})"
) from exc
Expand Down
42 changes: 42 additions & 0 deletions fastf1/req.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ class Cache:
_requests_session: requests.Session = _SessionWithRateLimiting()
_default_cache_enabled = False # flag to ensure that warning about disabled cache is logged once only # noqa: E501
_tmp_disabled = False
_ci_mode = False

@classmethod
def enable_cache(
Expand Down Expand Up @@ -261,6 +262,15 @@ def requests_get(cls, *args, **kwargs):
cls._enable_default_cache()
if (cls._requests_session_cached is None) or cls._tmp_disabled:
return cls._requests_session.get(*args, **kwargs)

if cls._ci_mode:
# try to return a cached response first
resp = cls._requests_session_cached.get(
*args, only_if_cached=True, **kwargs)
# 504 indicates that no cached response was found
if resp.status_code != 504:
return resp

return cls._requests_session_cached.get(*args, **kwargs)

@classmethod
Expand All @@ -275,8 +285,24 @@ def requests_post(cls, *args, **kwargs):
cls._enable_default_cache()
if (cls._requests_session_cached is None) or cls._tmp_disabled:
return cls._requests_session.post(*args, **kwargs)

if cls._ci_mode:
# try to return a cached response first
resp = cls._requests_session_cached.post(
*args, only_if_cached=True, **kwargs)
# 504 indicates that no cached response was found
if resp.status_code != 504:
return resp

return cls._requests_session_cached.post(*args, **kwargs)

@classmethod
def delete_response(cls, url):
"""Deletes a single cached response from the cache, if caching is
enabled. If caching is not enabled, this call is ignored."""
if cls._requests_session_cached is not None:
cls._requests_session_cached.cache.delete(urls=[url])

@staticmethod
def _custom_cache_filter(response: requests.Response):
# this function provides custom filtering to decide which responses
Expand Down Expand Up @@ -554,6 +580,22 @@ def offline_mode(cls, enabled: bool):
cls._enable_default_cache()
cls._requests_session_cached.settings.only_if_cached = enabled

@classmethod
def ci_mode(cls, enabled: bool):
"""Enable or disable CI mode.
In this mode, cached requests will be reused even if they are expired.
Only uncached data will actually be requested and is then cached. This
means, as long as CI mode is enabled, every request is only ever made
once and reused indefinetly.
This serves two purposes. First, reduce the number of requests that is
sent on when a large number of tests is run in parallel, potentially
in multiple environments simultaneously. Second, make test runs more
predictable because data usually does not change between runs.
"""
cls._ci_mode = enabled

@classmethod
def _convert_size(cls, size_bytes): # https://stackoverflow.com/questions/5194057/better-way-to-convert-file-sizes-in-python # noqa: E501
if size_bytes == 0:
Expand Down

0 comments on commit 518f739

Please sign in to comment.