The key `romm:twitch_token_expires_at` is not needed, as we already
set an expiration time for the token key itself. If the token is still
present in Redis, it is valid. If not, it means we either never fetched
it, or it was too close to expiration.
With this change, fetching the Twitch token makes a single Redis call
instead of two.
IGDB provides alternative names for games, which we are currently not
considering when checking for an exact match.
This change starts considering alternative names, in addition to the
game's name and slug, when checking for an exact match.
This change includes more categories when matching IGDB games. While
testing, some games were incorrectly matched to the wrong game, and the
reason was that the game was a Port (e.g. `Arkanoid`, `Contra`,
`Double Dragon`, `Metal Gear` for NES), a Remake (e.g.
`Adventure Island` for NES), or a Remaster.
The short-term goal is to completely typehint the IGDB API responses. This
first change adds the base structures and enums RomM currently uses.
The `ExpandableField` type will allow us to model the expansion
mechanism the IGDB API provides, where a field can include either an ID,
or the full nested structure.
Pytest v8.2 introduced the `PYTEST_VERSION` environment variable [1],
that can be used to check if code is running from within a pytest run.
This way, we can avoid checking the loaded `sys` modules.
[1] https://docs.pytest.org/en/stable/changelog.html#id57
This improvement avoids extra IGDB API requests when a received Rom is
an exact match. It avoids up to 2 requests per Rom, when an exact match
is found.
Convert `IGDBBaseHandler` methods to be asynchronous, and use an `httpx`
async client, instead of `requests` sync client.
This change also removes the direct dependency with `requests`, as the
project no longer uses it, preferring `httpx` instead.
Introduce an asynchronous Redis instance to be used in async functions.
Also, this change migrates most of the sync cache usage to the new async
cache.
This change avoids blocking requests when retrieving covers from
SteamGridDB, which is the main bottleneck as the current implementation
iterates over paginated results for multiple games.
Using an asynchronous client like `httpx` provides a good performance
improvement, and reduces the latency when calling this endpoint.
Also, the inclusion of FastAPI `lifespan` allows instantiating a single
client on startup.
When testing with "Final Fantasy V Advance", the endpoint goes from ~9s
to ~1.5s to retrieve all covers.
The SteamGridDB API has a bug, where the `total` field for the paginated
endpoint `/v2/grids/game/:gameId` sometimes double/triple counts results
(e.g. returning `total=172` when there are actually 86 results).
To avoid this issue, this change relies on each page's number of
results. If the received page has less than the requested amount of
grids, we know that is the last page.