-
Notifications
You must be signed in to change notification settings - Fork 0
Fork Changes
This page summarises what's different in H47R15/steam vs. the upstream ValvePython/steam. For the definitive current diff, see the README.rst at the repo root.
Upstream is largely inactive. This fork exists to keep the library working against modern Python and current Steam wire protocols. The shape of the public API is intentionally preserved — the same SteamClient, WebAPI, WebAuth, SteamID, etc. call sites work.
-
Python 3.13+ only. Dropped every py2 / py<3.4 compat shim:
-
six,six.moves -
raw_inputpolyfills xrangelong-
win_inet_pton(py2.7 Windows-only IPv4 helper) backports.lzmaenum34
-
The stdlib on Python 3.13 provides all of these natively.
Older Pythons are not supported — the runtime pyproject.toml pin is ^3.13.11.
-
Runtime
protobufdependency bumped from==3.20.3to>=5.26,<7. -
Regenerated every
_pb2.pywithprotoc33.2 against fresh SteamDB proto sources. The old per-message_reflection.GeneratedProtocolMessageTypecodegen shrunk ~20× to the modern_descriptor_pool.AddSerializedFile+_builderpattern.Example:
steammessages_base_pb2.pywent from ~2 200 lines to ~96 lines. The runtime does oneAddSerializedFilecall at import time and lets_builderconstruct message classes lazily — no more dynamic attribute mutation of a top-level dict, which pyright / Pylance could never introspect. -
Upper bound
<7reserves the next major bump for a deliberate migration, not an accidental one.
-
Full
.pyitype stubs for every_pb2file viamypy-protobuf.msg.fieldaccesses now type-check under Pylance / pyright. -
py.typedmarker atsteam/py.typed(PEP 561) — signals that this package ships inline types. -
types-protobuf >= 4.24dev dep — provides the baseMessagetypeshed stubs the domain.pyifiles inherit from. - Local stub override at
typings/google/protobuf/internal/builder.pyi— patches a typeshed bug inBuildServices. See Type Checking for details.
- Removed
setup.py,Makefile,dev_requirements.txt. - Single
pyproject.tomlfor the runtime deps, dev deps, extras (client), and metadata. - Regeneration steps registered as
poetry run pb-*console scripts:-
poetry run pb-fetch— download proto sources. -
poetry run pb-compile— protoc + post-process. -
poetry run pb-services— regeneratesteam/core/msg/unified.pyservice map. -
poetry run pb-gen-enums— regeneratesteam/enums/proto.pyfrom*_pb2. -
poetry run pb-update— all four in sequence (the usual entry point).
-
- Removed
Vagrantfile(the old Vagrant-based dev setup is no longer needed).
Full workflow on Regenerating Protobufs.
Additive — no change to the sync surface. Upstream stops at the gevent-based SteamClient; this fork adds an asyncio-facing layer on top.
-
steam.aio.AsyncSteamClient— asyncio facade aroundSteamClient. Runs the sync client on a dedicated daemon thread with its own isolated gevent hub. The asyncio process is never monkey-patched, sohttpx/uvicorn/motorkeep working. See AsyncSteamClient for the design and full API. -
Auto-reconnect + relogin on CM disconnect, with
ReconnectPolicyfor backoff / retry tuning. -
Typed exception hierarchy (
steam.aio.errors) —AsyncSteamErrorbase +SteamNotStartedError,SteamClosedError,SteamLoginError(carriesEResult),SteamReconnectError,SteamRPCTimeoutError. Multi-inherits fromRuntimeError/TimeoutErrorfor backwards-compat with callers catching stdlib types. -
Event bridge —
await client.wait_event(name, timeout=...)for single-shot,async for evt in client.events(*names)for streaming subscription with a bounded internal queue. - Cancellation — cancelling the awaiting coroutine kills the underlying gevent greenlet (no zombie greenlets on the runner thread).
-
AsyncSteamPool— multi-account pool with concurrent bringup, round-robin selection, per-member failure isolation. -
Status + metrics hook —
client.statusreturns a JSON-serialisableClientStatusdataclass suitable for a FastAPI/healthendpoint.metrics_hook=callback fires on every lifecycle transition and RPC boundary;prometheus_hook()factory included. -
Framework integrations at
steam.aio.integrations.fastapi/steam.aio.integrations.taskiq—lifespan+Dependsfor FastAPI, broker startup hook +TaskiqDependsfor TaskIQ. Framework SDKs imported lazily so users don't pay for what they don't use.
-
steam.mcp— exposesAsyncSteamClientas MCP tools an LLM agent can call.- Framework-agnostic tool definitions (Pydantic schemas + async handlers) at
steam.mcp.tools. - Thin FastMCP adapter at
steam.mcp.server— works with the officialmcpSDK (mcp.server.fastmcp.FastMCP) and the standalonefastmcppackage. - Three built-in tools:
steam.status,steam.get_product_info,steam.send_um. - Extend or filter via the
bindings=parameter toregister_steam_tools.
- Framework-agnostic tool definitions (Pydantic schemas + async handlers) at
See MCP for the full walkthrough.
Picked up from upstream Steam since the fork was last synced. Includes:
- Family groups.
- Game recording.
- Remote client.
- SteamOS webui messages.
- HTML messages.
- Virtual controller.
- Community messages.
steam/enums/proto.py grew from ~90 enums to ~247 enums as a consequence.
Real latent bugs surfaced while porting. A few notable ones:
-
struct.pyTypeError: unsupported operand type(s) for +: 'list' and 'map'— py2 semantics returned alistfrommap(...); py3 returns an iterator. Thelist + map(...)expression only ever worked on py2. Fixed. -
MarketingMessage.flagstuple-vs-int mismatch — the flags field was being unpacked as a tuple in one code path and indexed as an int in another. Fixed. -
hexlify(None)in avatar-URL fallback — accounts without an avatar returnedNonefrom the source field;hexlifydoesn't acceptNone. Guarded. -
Broken
CookieJariteration inWebAuth—RequestsCookieJarmixesCookieJar(yieldsCookie) withMutableMapping[str, str](yieldsstr). Direct iteration was type-ambiguous and misbehaved under py3. Fixed by wrapping inlist(iter(...)).
- Same public API.
SteamClient,WebAPI,WebAuth,SteamID,SteamAuthenticator,CDNClient,game_servers.query_master,game_servers.a2s_*— all live at their old import paths with their old signatures. - Same MIT license.
- Same class-level docstrings.
- Same event names (
EVENT_LOGGED_ON,EVENT_DISCONNECTED, etc.).
Upstream ReadTheDocs steam.readthedocs.io is mostly still applicable — the library shape has not diverged, only its Python runtime and protobuf vintage baseline.
-
Vagrantfile— no more Vagrant. - Py2 shims —
six,xrange,raw_input,long,win_inet_pton,backports.lzma,enum34. -
setup.py/Makefile/dev_requirements.txt— replaced bypyproject.toml. -
lxmldependency inWebAPI— replaced with stdlibxml.etree.ElementTree. Zero runtime dep. If you need XPath 1.0 or other lxml features, passraw=Trueand parse the text yourself.
Versioning is managed by python-semantic-release. Conventional-commit messages drive the version bumps automatically in CI. See Contributing for commit style.
- Upstream: github.com/ValvePython/steam
- Old docs: steam.readthedocs.io — mostly applicable, but this wiki is authoritative for the fork.
- CLI companion (unmaintained upstream): github.com/ValvePython/steamctl
H47R15/steam — maintained fork of ValvePython/steam. MIT licensed.