Skip to main content

Python client for the Steam network — CM protocol, PICS / CDN, WebAuth, Web API, Steam Guard, SteamIDs, master-server queries.

This is a fork of ValvePython/steam maintained under H47R15/steam. The upstream project is largely inactive; this fork exists to keep the library working against modern Python and current Steam wire protocols.

What changed vs. upstream

  • Python 3.13+ only. Dropped the py2 / py<3.4 compat shims (six, six.moves, raw_input, xrange, long, win_inet_pton, backports.lzma, enum34, …).

  • Modern protobuf runtime + regenerated ``_pb2`` files. Bumped from protobuf==3.20.3 to >=5.26,<7 and re-ran protoc (v33.2) against fresh SteamDB proto sources. The old per-message _reflection.GeneratedProtocolMessageType codegen shrunk ~20× to the modern _descriptor_pool.AddSerializedFile + _builder pattern (steammessages_base_pb2.py: 2 200 → 96 lines).

  • Full ``.pyi`` type stubs for every _pb2 file via mypy-protobufmsg.field accesses now type-check under Pylance / pyright.

  • Poetry-first workflow. pip + Makefile + setup.py replaced by a single pyproject.toml; regeneration steps registered as poetry run pb-* console scripts (details below).

  • ~50 new proto files picked up from upstream since the fork was last synced (family groups, game recording, remote client, SteamOS webui messages, HTML messages, virtual controller, community messages, and more). steam/enums/proto.py grew from 90 → 247 enums.

  • Real latent bug fixes surfaced while porting — e.g. a list + map(...) TypeError in struct.py, a tuple-vs-int mismatch in MarketingMessage.flags, hexlify(None) in avatar-URL fallback, broken CookieJar iteration in WebAuth.

Requirements

  • Python 3.13.11 (pinned via pyproject.toml). Any newer 3.13.x is fine. Older Pythons are not supported.

  • Poetry for dependency management.

  • protoc on PATH — required only when regenerating the _pb2 files (poetry run pb-compile). Install via brew install protobuf on macOS or the equivalent from your distro.

Install

Clone the repo and install with poetry:

git clone https://github.com/H47R15/steam.git
cd steam
poetry install --with dev --extras client

The client extra pulls in gevent + protobuf + gevent-eventemitter — required by SteamClient and CDN. Without it, only the requests-based subset (WebAPI / WebAuth / SteamID / master-server query) is functional.

Features

  • SteamClient — CM protocol client on top of gevent. Login flows (password / QR / refresh token), PICS product info, friends list, chat, game coordinator hooks.

  • AsyncSteamClient (new in 1.6+)asyncio facade around SteamClient for FastAPI / Starlette / TaskIQ / any asyncio app. Runs the sync client on a dedicated daemon thread with an isolated gevent hub, so the asyncio process is never monkey-patched. Auto- reconnect, typed exceptions, event bridge, cancellation. See steam/aio/ and the Async wiki page.

  • AsyncSteamPool — multi-account pool for workloads that need concurrent connections to multiple Steam accounts. Concurrent bringup, round-robin, per-member failure isolation.

  • FastAPI + TaskIQ integrationssteam.aio.integrations provides lifespan context managers and Depends providers for both frameworks. Lazy imports — installing steam.aio doesn’t force FastAPI or TaskIQ into your dependency graph.

  • MCP toolssteam.mcp exposes AsyncSteamClient as Model-Context-Protocol tools an LLM agent can call. Framework- agnostic definitions + a FastMCP adapter (works with the official mcp SDK and the standalone fastmcp package).

  • CDNClient — content depot downloads with manifest parsing.

  • WebAuth / MobileWebAuth — obtain authenticated requests.Session cookies for store.steampowered.com / steamcommunity.com.

  • WebAPI — thin wrapper around Steam’s api.steampowered.com that introspects the interface catalogue at construction time.

  • SteamAuthenticator — enable / disable / verify Steam Guard 2FA.

  • SteamID — parse and convert between the 32-bit / 64-bit / STEAM_X:Y:Z / community-URL representations.

  • Master server query protocol — query masters directly or through SteamClient.

Async quick-start (FastAPI)

from contextlib import asynccontextmanager
from fastapi import Depends, FastAPI
from steam.aio import AsyncSteamClient
from steam.aio.integrations.fastapi import (
    get_steam_client, steam_client_lifespan,
)

client = AsyncSteamClient()

async def _login(c):
    await c.anonymous_login()

@asynccontextmanager
async def lifespan(app):
    async with steam_client_lifespan(app, client, on_start=_login):
        yield

app = FastAPI(lifespan=lifespan)

@app.get("/product/{app_id}")
async def product(
    app_id: int,
    steam: AsyncSteamClient = Depends(get_steam_client),
):
    return await steam.get_product_info(apps=[app_id])

@app.get("/health")
async def health(
    steam: AsyncSteamClient = Depends(get_steam_client),
):
    return steam.status.__dict__

MCP quick-start

from mcp.server.fastmcp import FastMCP
from steam.aio import AsyncSteamClient
from steam.mcp import register_steam_tools

server = FastMCP("Steam")
client = AsyncSteamClient()
# ... start + login the client at app boot ...
register_steam_tools(server, client)
# server.run() as usual — LLM agents can now call
#   steam.status / steam.get_product_info / steam.send_um

Dev workflow (poetry)

All commands run from the repo root.

poetry install --with dev --extras client   # install everything
poetry run pytest                           # run the test suite (~83 tests, ~1s)
poetry run pytest -k test_webauth           # filter to a subset
poetry run pytest --tb=short -q             # concise output

poetry run pylint steam                     # optional lint pass

Regenerating protobufs

The _pb2.py and _pb2.pyi files under steam/protobufs are generated from .proto sources under protobufs/. Console scripts:

poetry run pb-fetch       # download + normalize .proto files from SteamDB
poetry run pb-compile     # protoc --python_out --mypy_out + post-process
poetry run pb-services    # regenerate steam/core/msg/unified.py service map
poetry run pb-gen-enums   # regenerate steam/enums/proto.py from *_pb2

poetry run pb-update      # all four in sequence — the usual entry point

pb-fetch reads URLs from protobuf_list.txt (comments and blank lines skipped) and downloads them into protobufs/. Locally-maintained .proto files (gc.proto, test_messages.proto) are set aside via .notouch rename before the fetch and restored after.

pb-compile wipes steam/protobufs/*_pb2.{py,pyi} first, then runs a single protoc invocation over every .proto. Post-processing:

  • .py — sibling protobuf imports get the steam.protobufs. prefix so runtime import works without steam/protobufs/ on sys.path.

  • .pyiDESCRIPTOR: _descriptor.Descriptor overrides inside each message class are stripped (they trip reportIncompatibleVariableOverride under types-protobuf 7.34+; the parent Message class’s union type is inherited instead).

VCR fixtures

Web-facing tests (test_webapi.py, test_webauth.py, test_steamid.py) replay recorded HTTP fixtures from vcr/*.yaml in RecordMode.NONE — no live network, no credentials needed for CI.

To regenerate the webapi.yaml cassette against a fresh Steam API response, copy .env.example to .env and fill in STEAM_API_KEY (see the template for instructions on where to get one), then follow the regen recipe at the top of tests/test_webapi.py.

The webauth_*.yaml cassettes are regenerated by tests/generete_webauth_vcr.py — needs real Steam credentials at run time; run interactively when the anonymized replay drifts from live.

Live smoke test

Beyond the unit suite, the CM handshake / anonymous-login / PICS-fetch end-to-end flow can be smoke-tested against live Steam:

from steam.client import SteamClient

client = SteamClient()
assert client.anonymous_login()
resp = client.get_product_info(apps=[553850], timeout=15)  # Helldivers 2
print(resp['apps'][553850]['common']['name'])
client.logout()
client.disconnect()

Layout

steam/
├── steam/              # library source
│   ├── client/         # SteamClient, CDN, builtins/*
│   ├── core/           # CM protocol, message framing
│   ├── aio/            # AsyncSteamClient facade for asyncio apps
│   │   ├── client.py       # AsyncSteamClient + ReconnectPolicy
│   │   ├── runner.py       # cross-thread gevent → asyncio bridge
│   │   ├── errors.py       # typed exception hierarchy
│   │   ├── pool.py         # AsyncSteamPool (multi-account)
│   │   ├── status.py       # ClientStatus + MetricsHook
│   │   └── integrations/   # fastapi.py + taskiq.py helpers
│   ├── mcp/            # Model-Context-Protocol tool wrappers
│   │   ├── tools.py        # Pydantic schemas + async handlers
│   │   └── server.py       # FastMCP adapter
│   ├── enums/          # SteamIntEnum wrappers (common.py hand-written,
│   │                   #   proto.py auto-generated by pb-gen-enums)
│   ├── protobufs/      # generated *_pb2.py + *_pb2.pyi
│   └── utils/
├── scripts/            # poetry console-script entry points (pb-*)
├── protobufs/          # .proto sources (fetched by pb-fetch)
├── typings/            # local pyright stubs (see typings/…/builder.pyi
│                       #   for the BuildServices typeshed override)
├── tests/              # pytest suite
├── vcr/                # recorded HTTP fixtures for offline test replay
├── docs/               # Sphinx source (rendered at steam.readthedocs.io
│                       #   — kept in-tree but not currently deployed
│                       #   from this fork)
└── pyproject.toml      # poetry config + [tool.pyright]

Upstream links (reference only — refer to this fork for maintained code):

License

MIT (unchanged from upstream). See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pysteam_client-1.7.0.tar.gz (937.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pysteam_client-1.7.0-py3-none-any.whl (1.1 MB view details)

Uploaded Python 3

File details

Details for the file pysteam_client-1.7.0.tar.gz.

File metadata

  • Download URL: pysteam_client-1.7.0.tar.gz
  • Upload date:
  • Size: 937.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for pysteam_client-1.7.0.tar.gz
Algorithm Hash digest
SHA256 77744d423a0d14d115661aed2fc426c8512632131b99ff4742c56e2464d7d4c6
MD5 552ae452adaa25948fc3b11995b582bd
BLAKE2b-256 0279f0fdfbf9045fc24f47ef87d34d37e84da943d2d0538aaaa0d996ca96c9de

See more details on using hashes here.

Provenance

The following attestation bundles were made for pysteam_client-1.7.0.tar.gz:

Publisher: publish.yml on H47R15/steam

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pysteam_client-1.7.0-py3-none-any.whl.

File metadata

  • Download URL: pysteam_client-1.7.0-py3-none-any.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for pysteam_client-1.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8dddc058c36e0fdf108290611727f47f2ac3bf03c426b90d335f01ebfa152c74
MD5 6b65188d8ae4dee1012b74cdf645c457
BLAKE2b-256 65160046b23e1b2014f977535b19027a36800cca1c0f545c77b913781fa6f2f2

See more details on using hashes here.

Provenance

The following attestation bundles were made for pysteam_client-1.7.0-py3-none-any.whl:

Publisher: publish.yml on H47R15/steam

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.8.2

2 files

1.8.0

2 files

1.7.10

2 files

1.7.6

2 files

This release

1.7.0 This release

2 files

1.6.0

2 files

1.5.1

2 files

1.5.0

2 files

1.4.7

2 files

1.4.6

2 files

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