Предисловие.
В этом уроке вы научитесь работать с библиотекой steampy, на которой можно создать steam бота.
Подготовка
Первым делом, получите steam_api ключ, он нам понадобится для получения информации о трейдах. Получить его можно на сайте steam: https://steamcommunity.com/dev/apikey
Далее, понадобятся shared_secret и identity_secret, дающие полный доступ к вашему аккаунту.
Получить его можно в SDA в папке maFiles, при условии что вы не шифровали этот файл. Или на телефоне под управлением android с рут правами, к которому привязан steam.
Создайте текстовый файл steam_guard.json, и поместите туда следующий текст.
{
"steamid": "YOUR_STEAM_ID_64",
"shared_secret": "YOUR_SHARED_SECRET",
"identity_secret": "YOUR_IDENTITY_SECRET"
}
Steamid берем тут. В поле сайта, введите ссылку на аккаунт.
И установите библиотеку steampy, введя данную комманду в консоли.
pip install steampy
Что делать если steampy не работает?
Из-за изменения api стима, через steampy невозможно залогиниться, и как следствие, написать бота. Пока автор не обновил библиотеку, используйте форк steampy_rework. Он, почти, полная копия steampy, за исключением некоторых комманд:
Инициализируем steam_client так:
steam_client = SteamClient(steam_guard="guard.json")
А логинимся так:
steam_client.login(steam_login, steam_password)
Также, в этом форке удобней сохранять ссессию. Не забудьте поставить звезду автору библиотеки, ему это будет очень приятно.
Подтверждаем обмен.
Напишем основу стим бота.
from steampy.client import SteamClient #импортируем библиотеку
steam_client = SteamClient('MY_API_KEY')
steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'steam_guard.json') #авторизируемся в аккаунте
Данный код отвечает за авторизацию на аккаунте.
Далее, попросите друга или бота кинуть трейд, чтобы на аккаунте висел не принятый обмен.
И пройдите по данной ссылке.
https://api.steampowered.com/IEconService/GetTradeOffers/v1/?key=STEAM_API_KEY&get_received_offers=1
STEAM_API_KEY — замените на свой.
Данная ссылка, это api запрос, который выводит информацию о входящих трейдах в json формате, подробнее здесь.
Нас, во всем этом месиве, интересует только tradeofferid. Он понадобится для подтверждения обмена. Теперь, скопируйте следующие строки в свой скрипт.
trade_id = ваш_trade_id
steam_client.accept_trade_offer(trade_id)
trade_id — замените на собственный.
И запустите скрипт.
В итоге, обмен принят без нашего участия, что круто.
Кидаем обмен.
Кидать обмен можно только друзьям.
Создайте новый скрипт, и поместите туда следующий код:
from steampy.client import SteamClient, Asset
from steampy.utils import GameOptions, get_key_value_from_url, account_id_to_steam_id
def find_item_in_inventory(item_hash_name, items):
for item in items.values():
market_hash_name = item['market_hash_name']
if market_hash_name != item_hash_name:
continue
return {
'market_hash_name': market_hash_name,
'id': item['id']
}
def make_trade_1_item(give_item, get_item, trade_link):
game = GameOptions.TF2
my_items = steam_client.get_my_inventory(game)
my_item_give = find_item_in_inventory(give_item, my_items)
my_asset = [Asset(my_item_give['id'], game)]
partner_account_id = get_key_value_from_url(trade_link, 'partner', True)
partner_steam_id = account_id_to_steam_id(partner_account_id)
partner_items = steam_client.get_partner_inventory(partner_steam_id, game)
partner_item_give = find_item_in_inventory(get_item, partner_items)
partner_asset = [Asset(partner_item_give['id'], game)]
steam_client.make_offer_with_url(my_asset, partner_asset, trade_link)
steam_client = SteamClient('secret')
steam_client.login('secret', 'secret', "steam_guard.json")
trade_link = 'https://randomSteamTradeOfferLink1234_under_prog_ru'
make_trade_1_item('Refined Metal', 'Refined Metal', trade_link)
За отправку трейда отвечает функция make_trade_1_item, разберем её.
game = GameOptions.TF2
В качестве инвентаря выбрали инвентарь TF2
my_items = steam_client.get_my_inventory(game)
my_item_give = find_item_in_inventory(my_items, give_item)
Получаем информацию о предметах инвентаря. И отсеиваем ненужное, с помощью функции find_item_in_inventory. На выходе, получаем словарь такого формата:
{
'market_hash_name': напзвание_предмета,
'id': id_предмета
}
Далее, запаковываем предмет в Asset.
my_asset = [Asset(my_item_give['id'], game)]
Asset принимает 2 аргумента:
- id предмета
- код игры (для TF2, это 440)
Наши предметы готовы, осталось подготовить предметы партнера. Сперва, получим инвентарь партнера.
partner_account_id = get_key_value_from_url(trade_link, 'partner', True) #получаем id аккаунта из трейд ссылки
partner_steam_id = account_id_to_steam_id(partner_account_id) # id аккаунта преводим в steam_id
partner_items = steam_client.get_partner_inventory(partner_steam_id, game) #получаем инвентарь партнера
Отсеем все ненужное, и закинем в Asset.
partner_item_give = find_item_in_inventory(get_item, partner_items)
partner_asset = [Asset(partner_item_give['id'], game)]
Ассеты собраны, время посылать трейд.
steam_client.make_offer_with_url(my_asset, partner_asset, trade_link)
Пишем бота для торговой площадки Steam (SCM).
Чтобы получить цену предмета предмета с тп (торговой площадки).
from steampy.client import SteamClient
from steampy.models import GameOptions, Currency
itemName = "Winter 2021 Cosmetic Case"
resp = steam_client.market.fetch_price(itemName,game=GameOptions.TF2)
print(resp)
Необходимо воспользоваться методом fetch_price, который имеет следующий синтаксис
steam_client.market.fetch_price(имя_предмета, game=тип_игры)
Данный код не будет работать, если вы в объекте steam_client не залогинились.
Таким образом, код выше, ищет на тп цену Winter 2021 Cosmetic Case, и выводит её на экран (print).
Похожим образом, методом fetch_price_history, вы можете получить историю цен предмета.
steam_client.market.fetch_price_history(имя_предмета, game=тип_игры)
В данном примере мы установим заявку на покупку Winter 2021 Cosmetic Case, за 0.06 р.
Перепишите данный код:
from steampy.client import SteamClient
from steampy.models import GameOptions, Currency
itemName = "Winter 2021 Cosmetic Case"
response = steam_client.market.create_buy_order(itemName, "6", 1, GameOptions.TF2, Currency.RUB)
buy_order_id = response["buy_orderid"]
У метода create_buy_order, следующий синтаксис:
steam_client.market.create_buy_order(имя_предмета, цена_предмета*100, количество_заявок_на_покупку, тип_игры, тип_валюты)
- имя_предмета — имя предмета для покупки
- цена_предмета*100 — цена предмета помноженная на 100 (в примере цена = 6, валюта рубль, значит ордер создастся на цену 0.06 р)
- количество_заявок_на_покупку — количество предметов на покупку
Таким образом, вы можете автоматизировать покупку предметов на тп.
Продаем предмет на тп.
Перепишите данный код:
from steampy.models import GameOptions, Currency
from steampy.client import SteamClient, Asset
from steampy.utils import GameOptions, get_key_value_from_url, account_id_to_steam_id
def find_item_in_inventory(item_hash_name, items):
for item in items.values():
market_hash_name = item['market_hash_name']
if market_hash_name != item_hash_name:
continue
return {
'market_hash_name': market_hash_name,
'id': item['id']
}
steam_client = None
def initSteam():
global steam_client
print("Signing in steam account")
steam_client = SteamClient(ваш_апи_ключ_стим)
steam_client.login(ваш_логин_стим, ваш_пароль_стим, "steam_secret.json") #авторизируемся в аккаунте
itemName = "Winter 2021 Cosmetic Case"
my_items = steam_client.get_my_inventory(GameOptions.TF2) #Получаем свой инвентарь
my_item_sell = find_item_in_inventory(itemName, my_items) #Из него извлекаем нужный предмет на имени
sell_response = steam_client.market.create_sell_order(my_item_sell["id"], GameOptions.TF2, "4") #Выставляем на продажу за 4 копейки
print(sell_response)
initSteam()
За выставления лота на продажу отвечает метод steam_client.market.create_sell_order:
steam_client.market.create_sell_order(id_предмета, тип_игры, цена_продажи*100)
- id_предемета — id предмета в твоем инвентаре.
- тип_игры — переменная типа GameOptions
- цена_продажи*100 — цена, за которую продается предмет, без учета комиссии стим.
Чтобы получить id_предмета, сперва, я получил свой инвентарь (массив предметов), и, с помощью метода find_item_in_inventory, получил предмет с именем Winter 2021 Cosmetic Case
itemName = "Winter 2021 Cosmetic Case"
my_items = steam_client.get_my_inventory(GameOptions.TF2) #Получаем свой инвентарь
my_item_sell = find_item_in_inventory(itemName, my_items) #Из него извлекаем нужный предмет на имени
И передал id этого предмета в метод steam_client.market.create_sell_order
sell_response = steam_client.market.create_sell_order(my_item_sell["id"], GameOptions.TF2, "4") #Выставляем на продажу за 4 копейки
В итоге, Winter 2021 Cosmetic Case выставился на продажу за 0.06р (4 копейки + комиссия стима).
Сохранение сессии.
Каждый раз запуская бота, вы заново логинитесь в стиме. И все бы ничего, только вот, у стима есть ограничение на количество авторизаций. Решить проблему, можно с помощью сохранения сессии, и последующей её загрузки.
steam_client.login(api_keys.steam_login, api_keys.steam_password, "steam_secret.json")
Используя метод steam_client.login мы получаем сессию (набор куки, заголовков). По ключам которые находятся в куки, сайт стима понимает что мы авторизованны. Следовательно, сохранив сессию в файл, а позже загрузив, мы можем получить доступ к аккаунту, минуя авторизацию.
Для сохранения, будем использовать библиотеку pickle, позволяющую сохранять объекты языка Python, в файл. В своем примере, я сохранил весь обьект steam_client в файл.
import os
from steampy.models import GameOptions, Currency
from steampy.client import SteamClient, Asset
from steampy.utils import GameOptions, get_key_value_from_url, account_id_to_steam_id
import pickle
steam_client = None
def initSteam():
global steam_client
if(os.path.isfile("steamClient.pkl")):
print("Using previous session")
with open('steamClient.pkl', 'rb') as f:
steam_client = pickle.load(f)
else:
print("You not authorized, trying to login into Steam")
print("Signing in steam account")
steam_client = SteamClient(api_keys.steam_api_key)
steam_client.login(ваш_стим_логин, ваш_стим_пароль, "steam_secret.json") #авторизируемся в аккаунте
print("Saving session")
with open('steamClient.pkl', 'wb') as f:
pickle.dump(steam_client, f)
- Если файл steamClient.pkl существует, то подгружаем его pickle.load(f) в переменную steam_client.
- Если отсутствует, то логинимся в стиме steam_client.login, и объект steam_client сохраняем в файл steamClient.pkl.
Таким образом, бот авторизируется в стиме 1 раз, а дальше, будет подгружать сессию из файла.
Заключение.
Данная библиотека, мне очень помогла в написании tf2.tm бота, который я упоминал здесь. Применив знания с данной статьи отсюда и отсюда, вы сможете написать похожего бота.
Итоговый результат.
Steam Trade Offers Client for Python
Donate bitcoin: 3KrB6B5YRQuSEEZ5EVMAQeGa3SLCFZ76T7
steampy
is a library for Python, inspired by node-steam-tradeoffers, node-steam and other libraries for Node.js.
It was designed as a simple lightweight library, combining features of many steam libraries from Node.js into a single python module.
steampy
is capable of logging into steam, fetching trade offers and handling them in simple manner, using steam user credentials
and SteamGuard file(no need to extract and pass sessionID and webCookie).
steampy
is developed with Python 3 using type hints and many other features its supported for Windows, Linux and MacOs.
Table of Content
-
Installation
-
Usage
-
Examples
-
SteamClient methods
-
Market methods
-
Guard module functions
-
SteamChat methods
-
Test
-
License
Installation
Usage
Obtaining API Key
Obtaining SteamGuard from mobile device
Obtaining SteamGuard using Android emulation
from steampy.client import SteamClient steam_client = SteamClient('MY_API_KEY') steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE')
If you have steamid
, shared_secret
and identity_secret
you can place it in file Steamguard.txt
instead of fetching SteamGuard file from device.
{ "steamid": "YOUR_STEAM_ID_64", "shared_secret": "YOUR_SHARED_SECRET", "identity_secret": "YOUR_IDENTITY_SECRET" }
Examples
You’ll need to obtain your API key and SteamGuard file in order to run the examples,
and then fill login and password in storehose.py
file.
The storehouse.py
file contains an example of handling incoming trade offers.
If you want to generate authentication codes and use steampy as steam desktop authenticator
then fill required secrets in desktop_authenticator.py
file.
The desktop_authenticator.py
file contains examples of generating such one time codes/
python desktop_authenticator.py
SteamClient methods
Unless specified in documentation, the method does not require login to work(it uses API Key from constructor instead)
login(username: str, password: str, steam_guard: str) -> requests.Response
Log into the steam account. Allows to accept trade offers and some other methods.
from steampy.client import SteamClient steam_client = SteamClient('MY_API_KEY') steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE')
You can also use with
statement to automatically login and logout.
with SteamClient(api_key, login, password, steam_guard_file) as client: client.some_method1(...) client.some_method2(...) ...
logout() -> None
Using SteamClient.login
method is required before usage
Logout from steam.
from steampy.client import SteamClient steam_client = SteamClient('MY_API_KEY') steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE') steam_client.logout()
You can also use with
statement to automatically login and logout.
with SteamClient(api_key, login, password, steam_guard_file) as client: client.some_method1(...) client.some_method2(...) ...
is_session_alive() -> None
Using SteamClient.login
method is required before usage
Check if session is alive. This method fetches main page and check
if user name is there. Thanks for vasia123 for this solution.
from steampy.client import SteamClient steam_client = SteamClient('MY_API_KEY') steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE') is_session_alive = steam_client.is_session_alive()
api_call(request_method: str, interface: str, api_method: str, version: str, params: dict = None) -> requests.Response
Directly call api method from the steam api services.
Official steam api site
Unofficial but more elegant
from steampy.client import SteamClient steam_client = SteamClient('MY_API_KEY') params = {'key': 'MY_API_KEY'} summaries = steam_client.api_call('GET', 'IEconService', 'GetTradeOffersSummary', 'v1', params).json()
get_trade_offers_summary() -> dict
get_trade_offers(merge: bool = True) -> dict
Fetching trade offers from steam using an API call.
Method is fetching offers with descriptions that satisfy conditions:
* Are sent by us or others
* Are active (means they have `trade_offer_state` set to 2 (Active))
* Are not historical
* No time limitation
If merge
is set True
then offer items are merged from items data and items description into dict where items id
is key
and descriptions merged with data are value.
get_trade_offer(trade_offer_id: str, merge: bool = True) -> dict
get_trade_receipt(trade_id: str) -> list
Using SteamClient.login
method is required before usage
Getting the receipt for a trade with all item information after the items has been traded.
Do NOT store any item ids before you got the receipt since the ids may change.
«trade_id» can be found in trade offers: offer['response']['offer']['tradeid']
. Do not use ´tradeofferid´.
make_offer(items_from_me: List[Asset], items_from_them: List[Asset], partner_steam_id: str, message:str =») -> dict
Using SteamClient.login
method is required before usage
Asset
is class defined in client.py
, you can obtain asset_id
from SteamClient.get_my_inventory
method.
This method also uses identity secret from SteamGuard file to confirm the trade offer.
No need to manually confirm it on mobile app or email.
This method works when partner is your friend or steam.
In returned dict there will be trade offer id by the key tradeofferid
.
from steampy.client import SteamClient, Asset from steampy.utils import GameOptions steam_client = SteamClient('MY_API_KEY') steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE') partner_id = 'PARTNER_ID' game = GameOptions.CS my_items = steam_client.get_my_inventory(game) partner_items = steam_client.get_partner_inventory(partner_id, game) my_first_item = next(iter(my_items.values())) partner_first_item = next(iter(partner_items.values())) my_asset = Asset(my_first_item['id'], game) partner_asset = Asset(partner_first_item['id'], game) steam_client.make_offer([my_asset], [partner_asset], partner_id, 'Test offer')
make_offer_with_url(items_from_me: List[Asset], items_from_them: List[Asset], trade_offer_url: str, message: str = », case_sensitive: bool = True) -> dict
Using SteamClient.login
method is required before usage
This method is similar to SteamClient.make_offer
, but it takes trade url instead of friend account id.
It works even when partner isn’t your steam friend
In returned dict there will be trade offer id by the key tradeofferid
.
If case_sensitive
is False, then url params with be parsed with case insensitive params keys.
get_escrow_duration(trade_offer_url: str) -> int
Using SteamClient.login
method is required before usage
Check the escrow duration for trade between you and partner(given partner trade offer url)
accept_trade_offer(trade_offer_id: str) -> dict
Using SteamClient.login
method is required before usage
This method also uses identity secret from SteamGuard file to confirm the trade offer.
No need to manually confirm it on mobile app or email.
decline_trade_offer(trade_offer_id: str) -> dict
Decline trade offer that other user sent to us.
cancel_trade_offer(trade_offer_id: str) -> dict
Cancel trade offer that we sent to other user.
get_my_inventory(game: GameOptions, merge: bool = True, count: int = 5000) -> dict
Using SteamClient.login
method is required before usage
If merge
is set True
then inventory items are merged from items data and items description into dict where items id
is key
and descriptions merged with data are value.
Count
parameter is default max number of items, that can be fetched.
Inventory entries looks like this:
{'7146788981': {'actions': [{'link': 'steam://rungame/730/76561202255233023/+csgo_econ_action_preview%20S%owner_steamid%A%assetid%D316070896107169653', 'name': 'Inspect in Game...'}], 'amount': '1', 'appid': '730', 'background_color': '', 'classid': '1304827205', 'commodity': 0, 'contextid': '2', 'descriptions': [{'type': 'html', 'value': 'Exterior: Field-Tested'}, {'type': 'html', 'value': ' '}, {'type': 'html', 'value': 'Powerful and reliable, the AK-47 ' 'is one of the most popular assault ' 'rifles in the world. It is most ' 'deadly in short, controlled bursts ' 'of fire. It has been painted using ' 'a carbon fiber hydrographic and a ' 'dry-transfer decal of a red ' 'pinstripe.n' 'n' '<i>Never be afraid to push it to ' 'the limit</i>'}, {'type': 'html', 'value': ' '}, {'app_data': {'def_index': '65535', 'is_itemset_name': 1}, 'color': '9da1a9', 'type': 'html', 'value': 'The Phoenix Collection'}, {'type': 'html', 'value': ' '}, {'app_data': {'def_index': '65535'}, 'type': 'html', 'value': '<br><div id="sticker_info" ' 'name="sticker_info" title="Sticker ' 'Details" style="border: 2px solid ' 'rgb(102, 102, 102); border-radius: ' '6px; width=100; margin:4px; ' 'padding:8px;"><center><img ' 'width=64 height=48 ' 'src="https://steamcdn-a.akamaihd.net/apps/730/icons/econ/stickers/eslkatowice2015/pentasports.a6b0ddffefb5507453456c0d2c35b6a57821c171.png"><img ' 'width=64 height=48 ' 'src="https://steamcdn-a.akamaihd.net/apps/730/icons/econ/stickers/eslkatowice2015/pentasports.a6b0ddffefb5507453456c0d2c35b6a57821c171.png"><img ' 'width=64 height=48 ' 'src="https://steamcdn-a.akamaihd.net/apps/730/icons/econ/stickers/eslkatowice2015/pentasports.a6b0ddffefb5507453456c0d2c35b6a57821c171.png"><img ' 'width=64 height=48 ' 'src="https://steamcdn-a.akamaihd.net/apps/730/icons/econ/stickers/cologne2015/mousesports.3e75da497d9f75fa56f463c22db25f29992561ce.png"><br>Sticker: ' 'PENTA Sports | Katowice 2015, ' 'PENTA Sports | Katowice 2015, ' 'PENTA Sports | Katowice 2015, ' 'mousesports | Cologne ' '2015</center></div>'}], 'icon_drag_url': '', 'icon_url': '-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV09-5lpKKqPrxN7LEmyVQ7MEpiLuSrYmnjQO3-UdsZGHyd4_Bd1RvNQ7T_FDrw-_ng5Pu75iY1zI97bhLsvQz', 'icon_url_large': '-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV09-5lpKKqPrxN7LEm1Rd6dd2j6eQ9N2t2wK3-ENsZ23wcIKRdQE2NwyD_FK_kLq9gJDu7p_KyyRr7nNw-z-DyIFJbNUz', 'id': '7146788981', 'instanceid': '480085569', 'market_actions': [{'link': 'steam://rungame/730/76561202255233023/+csgo_econ_action_preview%20M%listingid%A%assetid%D316070896107169653', 'name': 'Inspect in Game...'}], 'market_hash_name': 'AK-47 | Redline (Field-Tested)', 'market_name': 'AK-47 | Redline (Field-Tested)', 'market_tradable_restriction': '7', 'marketable': 1, 'name': 'AK-47 | Redline', 'name_color': 'D2D2D2', 'owner_descriptions': '', 'tags': [{'category': 'Type', 'category_name': 'Type', 'internal_name': 'CSGO_Type_Rifle', 'name': 'Rifle'}, {'category': 'Weapon', 'category_name': 'Weapon', 'internal_name': 'weapon_ak47', 'name': 'AK-47'}, {'category': 'ItemSet', 'category_name': 'Collection', 'internal_name': 'set_community_2', 'name': 'The Phoenix Collection'}, {'category': 'Quality', 'category_name': 'Category', 'internal_name': 'normal', 'name': 'Normal'}, {'category': 'Rarity', 'category_name': 'Quality', 'color': 'd32ce6', 'internal_name': 'Rarity_Legendary_Weapon', 'name': 'Classified'}, {'category': 'Exterior', 'category_name': 'Exterior', 'internal_name': 'WearCategory2', 'name': 'Field-Tested'}, {'category': 'Tournament', 'category_name': 'Tournament', 'internal_name': 'Tournament6', 'name': '2015 ESL One Katowice'}, {'category': 'Tournament', 'category_name': 'Tournament', 'internal_name': 'Tournament7', 'name': '2015 ESL One Cologne'}, {'category': 'TournamentTeam', 'category_name': 'Team', 'internal_name': 'Team39', 'name': 'PENTA Sports'}, {'category': 'TournamentTeam', 'category_name': 'Team', 'internal_name': 'Team29', 'name': 'mousesports'}], 'tradable': 1, 'type': 'Classified Rifle'}}
get_partner_inventory(partner_steam_id: str, game: GameOptions, merge: bool = True, count: int = 5000) -> dict
Using SteamClient.login
method is required before usage
Inventory items can be merged like in SteamClient.get_my_inventory
method
Count
parameter is default max number of items, that can be fetched.
get_wallet_balance(convert_to_float: bool = True) -> Union[str, float]
Check account balance of steam acccount. It uses parse_price
method from utils
to covnert money string to Decimal if convert_to_decimal
is set to True
.
Example:
with SteamClient(api_key, login, password, steam_guard_file) as client: wallet_balance = client.get_wallet_balance() self.assertTrue(type(wallet_balance), decimal.Decimal)
market methods
fetch_price(item_hash_name: str, game: GameOptions, currency: str = Currency.USD) -> dict
Some games are predefined in GameOptions
class, such as GameOptions.DOTA2
, GameOptions.CS
and GameOptions.TF2, but
GameOptions` object can be constructed with custom parameters.
Currencies are defined in Currency class, currently
Default currency is USD
May rise TooManyRequests
exception if used more than 20 times in 60 seconds.
steam_client = SteamClient(self.credentials.api_key) item = 'M4A1-S | Cyrex (Factory New)' steam_client.market.fetch_price(item, game=GameOptions.CS) {'volume': '208', 'lowest_price': '$11.30 USD', 'median_price': '$11.33 USD', 'success': True}
fetch_price_history(item_hash_name: str, game: GameOptions) -> dict
Using SteamClient.login
method is required before usage
Returns list of price history of and item.
with SteamClient(self.credentials.api_key, self.credentials.login, self.credentials.password, self.steam_guard_file) as client: item = 'M4A1-S | Cyrex (Factory New)' response = client.market.fetch_price_history(item, GameOptions.CS) response['prices'][0] ['Jul 02 2014 01: +0', 417.777, '40']
Each entry in response['prices']
is a list, with first entry being date, second entry price, and third entry a volume.
get_my_market_listings() -> dict
Using SteamClient.login
method is required before usage
Returns market listings posted by user
steam_client = SteamClient(self.credentials.api_key) steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE') listings = steam_client.market.get_my_market_listings()
create_sell_order(assetid: str, game: GameOptions, money_to_receive: str) -> dict
Using SteamClient.login
method is required before usage
Create sell order of the asset on the steam market.
steam_client = SteamClient(self.credentials.api_key) steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE') asset_id_to_sell = 'some_asset_id' game = GameOptions.DOTA2 sell_response = steam_client.market.create_sell_order(asset_id_to_sell, game, "10000")
⚠️ money_to_receive
has to be in cents, so «100.00» should be passed has «10000»
create_buy_order(market_name: str, price_single_item: str, quantity: int, game: GameOptions, currency: Currency = Currency.USD) -> dict
Using SteamClient.login
method is required before usage
Create buy order of the assets on the steam market.
steam_client = SteamClient(self.credentials.api_key) steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE') response = steam_client.market.create_buy_order("AK-47 | Redline (Field-Tested)", "1034", 2, GameOptions.CS, Currency.EURO) buy_order_id = response["buy_orderid"]
⚠️ price_single_item
has to be in cents, so «10.34» should be passed has «1034»
buy_item(market_name: str, market_id: str, price: int, fee: int, game: GameOptions, currency: Currency = Currency.USD) -> dict
Using SteamClient.login
method is required before usage
Buy a certain item from market listing.
steam_client = SteamClient(self.credentials.api_key) steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE') response = steam_client.market.buy_item('AK-47 | Redline (Field-Tested)', '1942659007774983251', 81, 10, GameOptions.CS, Currency.RUB) wallet_balance = response["wallet_info"]["wallet_balance"]
cancel_sell_order(sell_listing_id: str) -> None
Using SteamClient.login
method is required before usage
Cancel previously requested sell order on steam market.
steam_client = SteamClient(self.credentials.api_key) steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE') sell_order_id = "some_sell_order_id" response = steam_client.market.cancel_sell_order(sell_order_id)
cancel_buy_order(buy_order_id) -> dict
Using SteamClient.login
method is required before usage
Cancel previously requested buy order on steam market.
steam_client = SteamClient(self.credentials.api_key) steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE') buy_order_id = "some_buy_order_id" response = steam_client.market.cancel_buy_order(buy_order_id)
Currencies
Currency class | Description |
---|---|
Currency.USD | United States Dollar |
Currency.GBP | United Kingdom Pound |
Currency.EURO | European Union Euro |
Currency.CHF | Swiss Francs |
Currency.RUB | Russian Rouble |
Currency.PLN | Polish Złoty |
Currency.BRL | Brazilian Reals |
Currency.JPY | Japanese Yen |
Currency.NOK | Norwegian Krone |
Currency.IDR | Indonesian Rupiah |
Currency.MYR | Malaysian Ringgit |
Currency.PHP | Philippine Peso |
Currency.SGD | Singapore Dollar |
Currency.THB | Thai Baht |
Currency.VND | Vietnamese Dong |
Currency.KRW | South Korean Won |
Currency.TRY | Turkish Lira |
Currency.UAH | Ukrainian Hryvnia |
Currency.MXN | Mexican Peso |
Currency.CAD | Canadian Dollars |
Currency.AUD | Australian Dollars |
Currency.NZD | New Zealand Dollar |
Currency.CNY | Chinese Renminbi (yuan) |
Currency.INR | Indian Rupee |
Currency.CLP | Chilean Peso |
Currency.PEN | Peruvian Sol |
Currency.COP | Colombian Peso |
Currency.ZAR | South African Rand |
Currency.HKD | Hong Kong Dollar |
Currency.TWD | New Taiwan Dollar |
Currency.SAR | Saudi Riyal |
Currency.AED | United Arab Emirates Dirham |
Currency.SEK | Swedish Krona |
Currency.ARS | Argentine Peso |
Currency.ILS | Israeli New Shekel |
Currency.BYN | Belarusian Ruble |
Currency.KZT | Kazakhstani Tenge |
Currency.KWD | Kuwaiti Dinar |
Currency.QAR | Qatari Riyal |
Currency.CRC | Costa Rican Colón |
Currency.UYU | Uruguayan Peso |
Currency.BGN | Bulgarian Lev |
Currency.HRK | Croatian Kuna |
Currency.CZK | Czech Koruna |
Currency.DKK | Danish Krone |
Currency.HUF | Hungarian Forint |
Currency.RON | Romanian Leu |
guard module functions
load_steam_guard(steam_guard: str) -> dict
If steam_guard
is file name then load and parse it, else just parse steam_guard
as json string.
generate_one_time_code(shared_secret: str, timestamp: int = None) -> str
Generate one time code for logging into Steam using shared_secret from SteamGuard file.
If none timestamp provided, timestamp will be set to current time.
generate_confirmation_key(identity_secret: str, tag: str, timestamp: int = int(time.time())) -> bytes
Generate mobile device confirmation key for accepting trade offer.
Default timestamp is current time.
SteamChat methods
send_message(steamid_64: str, text: str) -> requests.Response
Send the string contained in text
to the desired steamid_64
.
client.chat.send_message("[steamid]", "This is a message.")
fetch_messages() -> dict
Returns a dictionary with all new sent and received messages:
{
'sent': [
{'partner': "[steamid]", 'message': "This is a message."}
],
'received': []
}
client.chat.fetch_messages()
Test
All public methods are documented and tested.
guard
module has unit tests, client
uses an acceptance test.
For the acceptance test you have to put credentials.pwd
and Steamguard
file into test
directory
Example credentials.pwd
file:
account1 password1 api_key1
account2 password2 api_key2
In some tests you also have to obtain transaction_id
.
You can do it by SteamClient.get_trade_offers
or by logging manually into steam account in browser and get it from url
In some tests you also have to obtain partner steam id.
You can do it by by logging manually into steam account in browser and get it from url
License
MIT License
Copyright (c) 2016 Michał Bukowski
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the «Software»), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED «AS IS», WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
steam.py is a modern, easy to use, and async ready API wrapper for the Steam API and its CMs. Heavily inspired by
discord.py and borrowing functionality from
ValvePython/steam.
Key Features#
-
Modern Pythonic API using
async
/await
syntax -
Command extension to aid with bot creation
-
Easy to use with an object-oriented design
-
Fully typed hinted for faster development
Getting help#
-
These are good pages to start with if it’s your first time see Quickstart & F.A.Q
-
Ask us in our discord server.
-
If you’re looking for something specific, try the index or searching.
-
Report bugs in the issue tracker.
API references#
Pages detailing the API.
- steam API Reference
- steam.ext.commands API Reference
Extensions#
steam.py has extension modules to help with common tasks.
steam.ext.commands
— Bot commands framework
i am currently working on a project that involves TF2,python,and steam trading. I would like to know how i can send a steam trade offer from python. I do not need source code or anything, just point me in the right direction. I have searched for ~20 mins on google and cant find anything quite like what i want, they all want to log in to check steam trade offers or the community market prices.
asked Jul 13, 2015 at 3:57
I looked hard and couldn’t find a Python library unfortunately, but I did find this Node.js library that does what you want and looks robust at first glance:
Steam trading for Node.js
Allows you to automate Steam trading in Node.js.
https://github.com/seishun/node-steam-trade
You might consider writing your app in Javascript, because the library is there. Alternatively, call your Python functions from Node.js.
answered Jul 13, 2015 at 4:11
1
Jun 21, 2021
1 min read
steam.py
A modern, easy to use, and async ready package to interact with the Steam API. Heavily inspired by discord.py and borrowing functionality from ValvePython/steam.
Key Features
- Modern Pythonic API using
async
/await
syntax - Command extension to aid with bot creation
- Easy to use with an object-oriented design
- Fully typed hinted for faster development
Installation
Python 3.7 or higher is required
To install the library just run either of the following commands:
# Linux/macOS
python3 -m pip install -U steamio
# Windows
py -m pip install -U steamio
Or for the development version.
# Linux/macOS
python3 -m pip install -U "steamio @ git+https://github.com/Gobot1234/[email protected]"
# Windows
py -m pip install -U "steamio @ git+https://github.com/Gobot1234/[email protected]"
Quick Example
import steam
class MyClient(steam.Client):
async def on_ready(self) -> None:
print("Logged in as", self.user)
async def on_trade_receive(self, trade: steam.TradeOffer) -> None:
await trade.partner.send("Thank you for your trade")
print(f"Received trade: #{trade.id}")
print("Trade partner is:", trade.partner)
print("We would send:", len(trade.items_to_send), "items")
print("We would receive:", len(trade.items_to_receive), "items")
if trade.is_gift():
print("Accepting the trade as it is a gift")
await trade.accept()
client = MyClient()
client.run("username", "password")
Bot Example
from steam.ext import commands
bot = commands.Bot(command_prefix="!")
@bot.command
async def ping(ctx: commands.Context) -> None:
await ctx.send("Pong!")
bot.run("username", "password")
GitHub
https://github.com/Gobot1234/steam.py
John was the first writer to have joined pythonawesome.com. He has since then inculcated very effective writing and reviewing culture at pythonawesome which rivals have found impossible to imitate.
Previous Post
A multipurpose Telegram Bot made with Pyrogram and asynchronous programming
Next Post
A Python 3 package for Misty II development using Misty’s REST API
Я решился сделать «небольшой» парсер нужной мне информации по лотам торговой площадки стим для оперирование с ней в дальнейшем. Поскольку, я просмотрел множество информации, как это можно сделать, я не нашел ничего потного или нашел, но без должного объяснения.
Допусти пример https://question-it.com/questions/4398755/steam-ma… тут формируется запрос к ТП с понятным объяснения для данной ситуации. Мне нужна более подробное разъяснение некая документация.
Я не рассматриваю вариант с официальным api, так как там нет подробностей именно с ТП (steamworks).
Python я выбрал, так как мне этот язык намного ближе к сердцу и я в нем больше разбираюсь ( в любом случаем можно будет переписать на него ).
Порядок действий:
1. Это сделать полный парсинг всех лотов по игре условно возьмем pubg ( id 578080 ).
2. По нужному алгоритму я выбираю предметы ( ну допустим в массив)
3. По выбранным предметам я собираю полную инфу, то есть цена авто покупки, просто покупки, продажи, в бушующем возможно индивидуальный id предмета, float и т д.
И естественно эти запросы должны формироваться автоматически по заданной модели и сохранять все это в бд ( это самая легкая часть )
Это все мне нужно для создания бота стим. Да, я больной человек, который развлекается таким образом.
Я видел, что есть уже подобные решения, но там на столько огромные проекты ( в несколько тысяч строк ), что я буду разбираться в них до второго предшествии и мне будет гораздо проще и интереснее разобраться в этом самому.
Я рассматривал вариант «против лома нет приема» в виде bs4, но это прям крайний вариант к которому я приду, в случае не удачи с api или его подобием.
Я прощу вас дать мне механизм, как это сделать или стать, гайды и другую инфу.
A Steam lib for trade automation
Project description
The author of this package has not provided a project description
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
Built Distribution
Close
Hashes for steampy-0.75.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | df81d3feb4e0ee64ab14f407aff21eccb3572744e9ab5a044a704d10ab6326b2 |
|
MD5 | 6e9f359ce19e65e279f25020a50b139e |
|
BLAKE2b-256 | 47a1c90f07d14ce4b70cb3807c375c751ac31be78f1eda8bae35bea97896ee1d |
Close
Hashes for steampy-0.75-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | da6004e05ce303f0e6229f78ec97ea635c96bb10dee3867e6ab1f0abae98dc9a |
|
MD5 | e8863512979e4a782f1bf79ad35a873f |
|
BLAKE2b-256 | 595efea9e9da99da546fb86406c2e524c02f95df3c2783ac637d05a8475c358c |