-
Notifications
You must be signed in to change notification settings - Fork 0
WebAPI
steam.webapi.WebAPI is a thin wrapper around Steam's Web API. It hits api.steampowered.com (or partner.steam-api.com), introspects the full interface catalogue at construction time, and lets you call any endpoint as api.Interface.Method(**params).
The wrapper is self-contained — it only needs requests. No gevent, no protobuf, no client extra required.
-
Yes — for authenticated endpoints (
ISteamUser.*, most user-scoped calls, everything on the Partner host). -
No — for a handful of read-only endpoints like
ISteamWebAPIUtil.GetServerInfo, and for interface discovery on the Public host.
Get a key from steamcommunity.com/dev/apikey. The account needs a purchase history + Steam Guard + verified phone number to be eligible.
from steam.webapi import WebAPI
api = WebAPI(key='YOUR_KEY_HERE')
resp = api.ISteamUser.ResolveVanityURL(vanityurl='valve', url_type=2)
# {'response': {'steamid': '103582791429521412', 'success': 1}}
# Or pin a specific version explicitly:
resp = api.ISteamUser.ResolveVanityURL_v1(vanityurl='valve', url_type=2)
# Or fall through to the .call() helper:
resp = api.call('ISteamUser.ResolveVanityURL', vanityurl='valve', url_type=2)Attribute access is populated at construction time from GetSupportedAPIList — everything Steam exposes to your key becomes a real method with docstring-rendered parameter info:
help(api.ISteamUser.ResolveVanityURL)WebAPI(
key,
format='json',
raw=False,
https=True,
http_timeout=30,
apihost=APIHost.Public,
auto_load_interfaces=True,
)
-
key— Steam API key.Noneis accepted for endpoints that don't need one, but interface discovery on the Partner host will fail without a key. -
format—'json','vdf', or'xml'. Default'json'. -
raw=True— return the raw response body as a string, skip parsing. -
https=True— use HTTPS. Required on the Partner host. -
http_timeout=30— seconds. -
apihost—APIHost.Public(api.steampowered.com) orAPIHost.Partner(partner.steam-api.com). -
auto_load_interfaces=True— hitGetSupportedAPIListon construction. Turn off for a bare wrapper you'll populate manually via.load_interfaces(dict).
Every constructor parameter can also be passed per-call to override the default — e.g. api.ISteamUser.ResolveVanityURL(format='vdf', ...).
For one-off calls without instantiating a WebAPI:
from steam.webapi import get, post
# GET
resp = get('ISteamWebAPIUtil', 'GetServerInfo', 1)
# POST (all params in the request body)
resp = post('ISteamRemoteStorage', 'GetPublishedFileDetails', 1,
params={
'key': 'YOUR_KEY_HERE',
'itemcount': 5,
'publishedfileids': [1, 1, 1, 1, 1],
})Signatures:
get(interface, method, version=1, apihost='api.steampowered.com', https=True, caller=None, session=None, params=None) -> Any
post(interface, method, version=1, apihost='api.steampowered.com', https=True, caller=None, session=None, params=None) -> Any
Under the hood both delegate to webapi_request(url, method, ...) — see steam/webapi.py if you need to hit a URL neither wrapper covers.
resp = api.ISteamWebAPIUtil.GetServerInfo(format='vdf')format='json' (default) — response is parsed with json.loads. Returns dict.
format='vdf' — Valve's KeyValues text format. Parsed with the vdf package. Returns dict.
format='xml' — parsed with stdlib xml.etree.ElementTree. Returns an Element. Note: the fork swapped lxml → stdlib xml.etree here. If you need XPath 1.0 or other lxml features, pass raw=True and parse the text yourself.
raw=True — return the raw response text, no parsing.
Steam's schema uses param[0] naming for list-shaped inputs. WebAPIMethod handles that transparently:
resp = api.ISteamRemoteStorage.GetPublishedFileDetails(
itemcount=5,
publishedfileids=[1, 2, 3, 4, 5], # serialised as publishedfileids[0]=1, [1]=2, ...
)Pass a Python list for any parameter Steam declares as an array — the wrapper enforces list at the call site (ValueError on anything else).
Many Web API endpoints take a delimited list of IDs in a single parameter — ISteamUser.GetPlayerSummaries accepts up to 100 comma-separated steamids, ISteamUser.GetPlayerBans the same, and so on. Steam enforces per-endpoint caps; the wrapper chunks the input list so you don't have to loop by hand.
batch_call(method_path, id_param, ids, chunk_size=100, join_char=',', **extra_params)-
method_path—Interface.Method(e.g.'ISteamUser.GetPlayerSummaries'), same shape.call()takes. -
id_param— the parameter name on that method that accepts the delimited list (e.g.'steamids'). -
ids— the full list to batch across. -
chunk_size=100— matchesGetPlayerSummaries. Consult Steam's docs per endpoint;GetPlayerBansalso 100. -
join_char=','— most classicI*interfaces want comma-separated. Newer*Servicemethods often want a JSON array — for those, build the JSON yourself and loop over.call()directly. -
extra_params— passed verbatim to every chunked call.
Example — 250 steamids across 3 round-trips:
api = WebAPI(key='ABC...')
steamids = [76561198010623137, 76561198010623138, ...] # 250 items
chunks = api.batch_call(
'ISteamUser.GetPlayerSummaries',
id_param='steamids',
ids=steamids,
chunk_size=100,
)
# 250 items → chunks of 100 / 100 / 50 = 3 HTTP calls
all_players = [p for chunk in chunks for p in chunk['response']['players']]Returns a list of per-chunk responses in call order — flatten it as your endpoint's response shape dictates.
Endpoints like IStoreBrowseService.GetItems want a JSON-serialised input, not a delimited list. batch_call isn't the right shape for those — build the JSON payload yourself:
import json
CHUNK = 50
for start in range(0, len(app_ids), CHUNK):
chunk = app_ids[start:start + CHUNK]
input_json = json.dumps({
'ids': [{'appid': aid} for aid in chunk],
'context': {'language': 'english'},
})
resp = api.call('IStoreBrowseService.GetItems', input_json=input_json)
# ...print(api.doc()) # all interfaces + methods
print(api.ISteamUser.doc()) # single interface
print(api.ISteamUser.ResolveVanityURL.doc()) # single method + paramsOr with help():
help(api.ISteamUser.ResolveVanityURL)Fully populated from Steam's own interface catalog — the docs list every parameter, its type, whether it's required / optional, and any Valve-provided description.
Every WebAPI instance has .session — a requests.Session. Swap it out to share cookies with a WebAuth session:
from steam.webapi import WebAPI
import steam.webauth as wa
user = wa.WebAuth('username')
user.cli_login('password')
api = WebAPI(key='...')
api.session = user.session # webapi now carries login cookiesfrom steam.webapi import WebAPI, APIHost
api = WebAPI(key='...', apihost=APIHost.Partner)-
APIHost.Public=api.steampowered.com. HTTP or HTTPS. Some endpoints anonymous, most need a key. -
APIHost.Partner=partner.steam-api.com. HTTPS only. Every request needs a valid partner key (HTTP 403 otherwise).
-
ValueError— unknown parameter, missing required parameter, wrong-type list, badformatvalue. -
requests.HTTPError— 4xx / 5xx from Steam.webapi_requestcalls.raise_for_status()before returning. -
KeyError— malformed response missing an expected key (rare — usually indicates a schema drift).
H47R15/steam — maintained fork of ValvePython/steam. MIT licensed.