Python-обёртка для Steam Web API
Project description
steampy
Писал это для себя — хотел сделать бота который показывает статистику друзей в CS2, полез в официальную документацию Steam и чуть не сошёл с ума. Там надо руками собирать URL, разбираться в каком interface/method/version, парсить вложенный JSON... В общем написал обёртку, чтобы больше к этому не возвращаться.
from steampy import SteamClient
steam = SteamClient(api_key="...")
user = steam.user.get_profile("76561198000000000")
print(user.nickname)
games = steam.games.get_owned("76561198000000000")
print(f"игр в библиотеке: {len(games)}")
print(games[0].name, games[0].playtime_hours, "ч") # топ по времени уже отсортирован
Установка
pip install steampy-api
Для async-версии нужен ещё aiohttp:
pip install "steampy-api[async]"
API-ключ
Идёшь на steamcommunity.com/dev/apikey, вводишь любой домен (хоть localhost), получаешь ключ. Бесплатно.
Что умеет
Профили
user = steam.user.get_profile("76561198000000000")
user.nickname # имя
user.country # "RU", "UA", "DE"...
user.is_public # False если профиль закрыт
user.avatar_full # ссылка на аватарку
# если знаешь только ник из url типа steamcommunity.com/id/gaben
steam_id = steam.user.resolve_vanity_url("gaben")
# несколько профилей за один запрос, до 100
profiles = steam.user.get_profiles(["id1", "id2", "id3"])
# VAC-баны
bans = steam.user.get_bans("76561198000000000")
print(bans["VACBanned"]) # True/False
print(bans["NumberOfVACBans"]) # сколько раз
Игры
# библиотека, отсортирована по времени в игре
games = steam.games.get_owned("76561198000000000")
for g in games[:5]:
print(g.name, "—", g.playtime_hours, "ч")
# только то, во что играл последние 2 недели
recent = steam.games.get_recent("76561198000000000")
# достижения. app_id 730 — это CS2
achievements = steam.games.get_achievements("76561198000000000", app_id=730)
done = [a for a in achievements if a.achieved]
print(f"{len(done)} из {len(achievements)}")
# статистика — убийства, смерти, матчи и т.д.
stats = steam.games.get_stats("76561198000000000", app_id=730)
print(stats["total_kills"])
print(stats["total_deaths"])
Друзья
friends = steam.friends.get_list("76561198000000000")
# get_list возвращает только id, профили грузи отдельно
ids = [f.steam_id for f in friends[:100]]
profiles = steam.user.get_profiles(ids)
Маркет
# для маркета ключ не нужен
item = steam.market.get_price(730, "AK-47 | Redline (Field-Tested)")
print(item.lowest_price) # "1 234 ₽"
print(item.median_price) # "1 300 ₽"
print(item.volume) # сколько продали за сутки
# app_id игр которые чаще всего нужны:
# 730 CS2
# 570 Dota 2
# 440 TF2
# 252490 Rust
# 578080 PUBG
Инвентарь
# инвентарь CS2. для других игр меняй app_id
items = steam.inventory.get("76561198000000000", app_id=730)
print(f"предметов: {len(items)}")
for item in items[:5]:
print(item.name, item.rarity)
print(item.get_icon_url()) # ссылка на картинку
print(item.tradable, item.marketable)
# только tradable
tradable = [i for i in items if i.tradable]
# app_id других игр:
# 570 Dota 2
# 440 TF2
# 252490 Rust
# 753 Steam (карточки, фоны, смайлики — context_id=6)
Steam Store
# подробная инфа об игре
game = steam.store.get_game(730)
print(game.name) # Counter-Strike 2
print(game.genres) # ["Экшены", "Бесплатно"]
print(game.metacritic_score) # 83
print(game.platforms) # {"windows": True, "mac": False, "linux": True}
# цена и скидка
game = steam.store.get_game(1091500) # Cyberpunk
print(game.price_original) # 1999.0
print(game.price_final) # 999.5
print(game.discount_percent) # 50
print(game.on_sale) # True
# текущие акции (топ скидок)
sales = steam.store.get_sales()
for s in sales:
print(f"{s.name} -{s.discount_percent}% ({s.price_final}₽)")
# поиск игры по названию
results = steam.store.search("half-life")
for r in results:
print(r["name"], r["id"])
Async (для ботов)
import asyncio
from steampy import AsyncSteamClient
async def main():
async with AsyncSteamClient(api_key="...") as steam:
user = await steam.get_profile("76561198000000000")
print(user.nickname)
games = await steam.get_owned_games("76561198000000000")
print(games[0].name, games[0].playtime_hours, "ч")
asyncio.run(main())
С aiogram:
from steampy import AsyncSteamClient
steam = AsyncSteamClient(api_key="...")
@router.message(Command("profile"))
async def profile_cmd(message: Message):
steam_id = message.text.split()[-1]
user = await steam.get_profile(steam_id)
await message.answer(f"{user.nickname} | {user.country}")
# при остановке бота
async def on_shutdown():
await steam.close()
Несколько запросов параллельно через asyncio.gather:
profile, friends, bans = await asyncio.gather(
steam.get_profile(steam_id),
steam.get_friends(steam_id),
steam.get_bans(steam_id),
)
Кэш
По умолчанию включён с TTL 5 минут — Steam не банит за повторные запросы и не тратишь лимиты на одни и те же данные.
steam = SteamClient(api_key="...", cache_ttl=60) # 1 минута
steam = SteamClient(api_key="...", cache_ttl=0) # выключить кэш
# сбросить вручную
steam.clear_cache()
Работает одинаково для SteamClient и AsyncSteamClient.
Ошибки
from steampy.exceptions import SteamAPIError, SteamRateLimitError, SteamPrivateProfile
try:
user = steam.user.get_profile("76561198000000000")
except SteamPrivateProfile:
print("профиль закрыт")
except SteamRateLimitError:
print("слишком много запросов, подожди")
except SteamAPIError as e:
print(e) # неверный ключ и прочее
except ValueError as e:
print(e) # пользователь не найден
| Исключение | Когда |
|---|---|
SteamAPIError |
базовый класс, неверный ключ, неожиданный ответ сервера |
SteamRateLimitError |
превышен лимит запросов (HTTP 429) |
SteamPrivateProfile |
профиль или инвентарь скрыт (HTTP 403) |
SteamUserNotFound |
пользователь не найден |
ValueError |
неверные входные данные |
Что планирую добавить
- Пагинация для инвентаря (сейчас максимум 5000 предметов)
- Кэш для маркета и инвентаря (сейчас работает только для основного API)
Если нашёл баг
Открывай issue, постараюсь ответить. PR тоже принимаю.
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file steampy_api-0.2.0.tar.gz.
File metadata
- Download URL: steampy_api-0.2.0.tar.gz
- Upload date:
- Size: 15.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
420fbc8fedbb9379e82798c8ceb9d350e8e601da76930e8f39281a6ab31d665a
|
|
| MD5 |
cdcf9b3f386c703758eb6b2a74f0239d
|
|
| BLAKE2b-256 |
8b2e42191a66d940514b6a34f3ebf619e4783b84dd39813b2f939d7c617a76c1
|
File details
Details for the file steampy_api-0.2.0-py3-none-any.whl.
File metadata
- Download URL: steampy_api-0.2.0-py3-none-any.whl
- Upload date:
- Size: 18.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d84859c9dbe9be4658618d2e05063d1ca83d2750ec54a28a31fd50e56787d78c
|
|
| MD5 |
cb37e0cf24afdf7ece0d87b004c7eaa3
|
|
| BLAKE2b-256 |
299906c2a9c2a3a2e05a02208146dfaa058e0c290f86f9068f2a9675142319de
|