Skip to main content

Speedrun.com API V2 wrapper

A WIP Python wrapper for Speedrun.com's new backend API.

WIP documentation for the API can be found in speedruncom-apiv2-docs

Why use APIv2?

Speedrun.com's official API (aka APIv1) is not actively maintained, and both misses a large number of modern features (including various social connections on user profiles) and several unaddressed issues hinder its usage;

  • pagination breaks at 10,000 items on all endpoints
  • some endpoints are completely broken (notably run verification)
  • some endpoints are in a degraded state (/leaderboards position)

APIv2 does struggle with some tasks APIv1 excels at; in particular grabbing all runs from a game at once is not currently possible with APIv2, instead requiring iterating through every leaderboard.

APIv2 also has no promise of stability; it can and will change without warning. This library attempts to stay up-to-date, but you may need to periodically check for updates or monkeypatch while the library is missing updated values.

Usage

pip install speedruncompy, then import speedruncompy.

Asynchronous

Speedruncompy is async-first, being built around aiohttp.

from speedruncompy import GetGameLeaderboard2
import asyncio

async def async_demo():
    get_game_leaderboard = GetGameLeaderboard2(gameId="a", categoryId="b")

    leaderboard = await get_game_leaderboard.perform() # Await a single request

    leaderboard_full = await get_game_leaderboard.perform_all() # Await all pages - this awaits page 1, then awaits all other pages simultaneously.

asyncio.run(async_demo())

Synchronous

If you just need some responses for a script, you can use the synchronous API:

from speedruncompy import GetGameLeaderboard2

leaderboard = GetGameLeaderboard2(gameId="a", categoryId="b").perform_sync() # Perform a single request

# Paginated endpoints also have helper methods to get & merge all pages available.
leaderboard_full = GetGameLeaderboard2(gameId="", categoryId="").perform_all_sync() # Perform a request for all pages available.

Helper dictionaries ("condensers")

Many endpoints return a set of lists of objects. Most of these objects contain an id parameter which is referred to by other objects; for example, Run.playerIds contains a list of the player IDs present in a run.

Speedruncompy provides convenience properties to access objects by these IDs;

from speedruncompy import GetGameLeaderboard2

leaderboard = GetGameLeaderboard2(gameId="a", categoryId="b").perform_all_sync()

runner_id = leaderboard.runList[0].playerList[0]
player_name = leaderboard._playerDict[runner_id].name

Client

Speedruncompy stores authorisation cookies on a SpeedrunClient object. This can be passed to any request as a keyword parameter _client.

Speedrun.com authorises APIv2 requests with the cookie PHPSESSID. PutAuthLogin sets this ID on a successful login, but you can also set it directly:

from speedruncompy import SpeedrunClient, GetSession
import asyncio

token = ""  # Should be stored as part of the environment variables, not directly in code!

async def client_demo():
    client = SpeedrunClient(PHPSESSID=token)
    # or:
    client.PHPSESSID = token

    response = await GetSession(_client=client).perform()
    assert response.session.signedIn

Default client

Requests with no client specified use a default global client - you can access this at speedruncompy.api._default.

import speedruncompy
from speedruncompy import GetSession

token = ""

speedruncompy.api._default.PHPSESSID = token

# No _client passed, uses _default
session_response = GetSession().perform_sync()
assert session_response.session.signedIn

Sessions

If you want to perform many requests in quick succession, it is often better to keep the HTTP session open until you have completed all your requests. SpeedrunClients offer an asynchronous context manager for this purpose:

from speedruncompy import SpeedrunClient, GetGameSummary
import asyncio

game_ids = ["a", "b", "c"]

async def session_demo():
    client = SpeedrunClient()

    async with client:
        requests = [GetGameSummary(gameId=g) for g in game_ids]
        all_summaries = asyncio.gather(*[r.perform() for r in requests])

Building

If you wish to build & test Speedruncompy, you will need to install uv for environment & package management.

We include .vscode/extensions.json for recommended extensions.

  1. Run uv sync --all-extras to install both the runtime & testing dependencies.
  2. Build using uv build.
    • Wheels are generated to dist; the package version is obtained from version control, so the version will contain a dev postfix unless you commit your changes and tag the commit with a vM.m.v version tag.

Testing

Testing requires additional environment constants, which can be provided via a .env file; a .env_example is provided with the necessary variables.

PHPSESSID is obtained from a logged-in session on the site; open dev tools > Storage > Cookies > Copy the PHPSESSID value. This is a secret that allows people to access your account with no restrictions, so keep it safe.

Omissions

Admin-only endpoints will not be added due to lack of testability and usability. These include:

  • GetUserList
  • GetChallengesList
  • GetAdminStatusSummary
  • GetTicketQueueCounts
  • GetTicketStatusCounts
  • PutGameDelete

Metadata

Release files for speedruncompy 1.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for speedruncompy 1.1.1
File Size Uploaded Provenance
speedruncompy-1.1.1.tar.gz 166.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for speedruncompy 1.1.1
File Interpreter ABI Platform
speedruncompy-1.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 211.6 kB

Release files / speedruncompy-1.1.1.tar.gz

Download URL speedruncompy-1.1.1.tar.gz
Size 166.8 kB
Tags Source
SHA-256 checksum
How to use checksums
d9d9fd7956ecb5e6648cec4a6875e5a7bd3ace8469717162ef9946a4c80e702f
BLAKE2b-256 checksum
How to use checksums
61bd2677bf5d7a377ce1efc3c6c301e116c61fd03385c49e4d7dd858fdb3cce6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / speedruncompy-1.1.1-py3-none-any.whl

Download URL speedruncompy-1.1.1-py3-none-any.whl
Size 44.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3e29278c863e8f71b9f8b091c5fbbfde2649bffd4e1cd1b9681f69399bed72c8
BLAKE2b-256 checksum
How to use checksums
d8abb82c89d72201dd4248fa3f9820660b9d2ae82874fd246b9372b3b78d0f3c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for speedruncompy 1.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page