Skip to content
cbyte edited this page Jul 19, 2026 · 1 revision

FAQ

Do I need a Steam API key?

Sometimes.

  • WebAPI — needs a key for authenticated endpoints (ISteamUser.*, most user-scoped calls, everything on the Partner host). A handful of endpoints like ISteamWebAPIUtil.GetServerInfo are anonymous. Get a key from steamcommunity.com/dev/apikey.
  • SteamClient PICS calls — never need a key. Anonymous login is enough for public product info via client.get_product_info(apps=[...]).
  • SteamClient licensed-content calls — need a real user login (cli_login / login), not a key.
  • WebAuth — never needs a key. Uses username + password + Steam Guard code.

Can I log in with my regular account?

Yes.

from steam.client import SteamClient

client = SteamClient()
client.cli_login()   # prompts for username, password, 2FA

Or programmatically with client.login(username, password, two_factor_code='...'). See SteamClient for the full flow, including how to handle the EVENT_AUTH_CODE_REQUIRED event.

Never commit credentials to source. Read them from .env or a secret store.

How do I download game files?

Use CDNClient. Requires a logged-in SteamClient with a license for the app:

import steam.monkey; steam.monkey.patch_minimal()

from steam.client import SteamClient
from steam.client.cdn import CDNClient

client = SteamClient()
client.cli_login()

cdn = CDNClient(client)

# Iterate all files in Dota 2's depots you have access to.
for f in cdn.iter_files(570, r'game\dota\gameinfo.gi'):
    print(f.read().decode('utf-8'))

Anonymous logins can't download most games — they only have a license for the "Steam free products" package. See the "Auth token gating" section of CDNClient.

Do the tests need internet?

No.

poetry run pytest

Runs all ~83 tests, ~1 second, no network. Web-facing tests replay recorded HTTP fixtures from vcr/*.yaml in RecordMode.NONE.

If you're regenerating cassettes (rare — only when Steam changes a response shape), you'll need a real API key + Steam credentials. See Contributing.

How do I regenerate the wire format after Valve changes it?

poetry run pb-update

Chains pb-fetchpb-compilepb-servicespb-gen-enums. See Regenerating Protobufs for the details of each step and how to add a new upstream proto.

Can I use this without gevent?

Yes — for the requests-based subset.

poetry install    # skip --extras client

WebAPI, WebAuth, SteamID, and Master Server Queries all work without the client extra. SteamClient and CDNClient need gevent.

What versions of Steam Guard 2FA are supported?

Steam's mobile authenticator (TOTP with a Steam-custom alphabet). See SteamAuthenticator.

Note: Steam's TOTP is not compatible with Google Authenticator / Authy directly — the alphabet is different. The secrets dict SteamAuthenticator.add() returns is compatible with Steam Desktop Authenticator (SDA) and WinAuth if you want a GUI client alongside the Python code.

Failed to fetch content servers when constructing CDNClient

Usually one of:

  • Your SteamClient isn't logged in. Anonymous is fine but client.cell_id must be set — anonymous_login() handles that automatically.
  • Cell ID mismatch. CDNClient copies client.cell_id on construction; if you construct before logging in, it stays 0. Log in first, then instantiate CDNClient(client).
  • Steam infrastructure hiccup. Retry.

ModuleNotFoundError: No module named 'gevent'

You skipped the client extra. Re-run:

poetry install --extras client

Can I use this with asyncio?

Not directly — the CM protocol client is built on gevent. You can drive it from an asyncio program by running SteamClient in a dedicated thread and shuttling messages over a queue, but that's out-of-scope for this library.

The requests-based subset (WebAPI, WebAuth, SteamID, Master Server Queries) is synchronous but doesn't touch gevent — wrap those calls in asyncio.to_thread(...) and they compose fine with async code.

Why does the fork exist? Why not just use ValvePython?

Upstream is largely inactive. This fork exists to:

  • Keep the library working on Python 3.13.
  • Modernise the protobuf runtime (5.x/6.x) so message classes are static-analyser-friendly.
  • Fix latent bugs surfaced while porting.
  • Ship full type stubs.

The public API is intentionally preserved — you can drop-in swap. See Fork Changes for the full list.

What happens when Steam kills the CM protocol?

Then this library breaks. Steam has been slowly migrating everything to the WebAPI + unified-messages path — WebAPI covers the modern REST-ish surface, and send_um / send_um_and_wait on SteamClient covers the service-method path over CM. Public-facing CM messages haven't been deprecated as of the fork's last regen, but if they are, WebAPI + service methods should cover most workflows.

Where do I report bugs?

Where's the docs site?

You're on it. There's also a Sphinx source tree at docs/ in the repo (kept in-tree but not currently deployed from this fork), and the old ReadTheDocs at steam.readthedocs.io that still applies to the mostly-unchanged public API.

Clone this wiki locally