Skip to main content

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


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.0.tar.gz (15.8 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.0-py3-none-any.whl (18.2 kB view details)

Uploaded Python 3

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

Hashes for steampy_api-0.2.0.tar.gz
Algorithm Hash digest
SHA256 420fbc8fedbb9379e82798c8ceb9d350e8e601da76930e8f39281a6ab31d665a
MD5 cdcf9b3f386c703758eb6b2a74f0239d
BLAKE2b-256 8b2e42191a66d940514b6a34f3ebf619e4783b84dd39813b2f939d7c617a76c1

See more details on using hashes here.

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

Hashes for steampy_api-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d84859c9dbe9be4658618d2e05063d1ca83d2750ec54a28a31fd50e56787d78c
MD5 cb37e0cf24afdf7ece0d87b004c7eaa3
BLAKE2b-256 299906c2a9c2a3a2e05a02208146dfaa058e0c290f86f9068f2a9675142319de

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