Skip to main content

Python wrapper for Steam Web API — profiles, games, inventory, market, store

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


Download files

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

Source Distribution

steampy_api-0.2.1.tar.gz (18.3 kB view details)

Uploaded Source

Built Distribution

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

steampy_api-0.2.1-py3-none-any.whl (19.3 kB view details)

Uploaded Python 3

File details

Details for the file steampy_api-0.2.1.tar.gz.

File metadata

  • Download URL: steampy_api-0.2.1.tar.gz
  • Upload date:
  • Size: 18.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for steampy_api-0.2.1.tar.gz
Algorithm Hash digest
SHA256 8d2698846ce2f3bd587df99fb165db4af5f5328365c30731694b5d6af77aabcc
MD5 12d2594fdd7cfb5c6d0e0de2a9e65e8c
BLAKE2b-256 1e802474c2804485e721fc14f6453b87783b6279d2dac365f1ad60b497dc3e10

See more details on using hashes here.

File details

Details for the file steampy_api-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: steampy_api-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 19.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for steampy_api-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 628f6857292fedac092558e92cd60509d894f2a42f887624f13d3e5d52da6a28
MD5 91399d32b5465c2ba7af43fe14b09f50
BLAKE2b-256 7992851efa459fd67935cc1055a9e90649c8d0f8a67bbe682cb1d36e9bf9a674

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page