steampie 0.80__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of steampie might be problematic. Click here for more details.
- steampie-0.80/LICENSE.txt +21 -0
- steampie-0.80/PKG-INFO +11 -0
- steampie-0.80/README.md +643 -0
- steampie-0.80/examples/__init__.py +0 -0
- steampie-0.80/examples/chat_bot.py +38 -0
- steampie-0.80/examples/desktop_authenticator.py +14 -0
- steampie-0.80/examples/inventory.py +54 -0
- steampie-0.80/examples/storehouse.py +53 -0
- steampie-0.80/setup.cfg +7 -0
- steampie-0.80/setup.py +29 -0
- steampie-0.80/steampie/__init__.py +0 -0
- steampie-0.80/steampie/chat.py +103 -0
- steampie-0.80/steampie/client.py +450 -0
- steampie-0.80/steampie/confirmation.py +151 -0
- steampie-0.80/steampie/exceptions.py +26 -0
- steampie-0.80/steampie/guard.py +60 -0
- steampie-0.80/steampie/login.py +127 -0
- steampie-0.80/steampie/market.py +282 -0
- steampie-0.80/steampie/models.py +109 -0
- steampie-0.80/steampie/utils.py +211 -0
- steampie-0.80/steampie.egg-info/PKG-INFO +11 -0
- steampie-0.80/steampie.egg-info/SOURCES.txt +29 -0
- steampie-0.80/steampie.egg-info/dependency_links.txt +1 -0
- steampie-0.80/steampie.egg-info/requires.txt +3 -0
- steampie-0.80/steampie.egg-info/top_level.txt +3 -0
- steampie-0.80/test/__init__.py +0 -0
- steampie-0.80/test/test_client.py +209 -0
- steampie-0.80/test/test_guard.py +29 -0
- steampie-0.80/test/test_market.py +100 -0
- steampie-0.80/test/test_utils.py +62 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2016 Michał Bukowski gigibukson@gmail.com
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
steampie-0.80/PKG-INFO
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: steampie
|
|
3
|
+
Version: 0.80
|
|
4
|
+
Summary: A Steam lib for trade automation
|
|
5
|
+
Home-page: https://github.com/venoia/steampie
|
|
6
|
+
Download-URL: https://github.com/venoia/steampie/tarball/0.80
|
|
7
|
+
Author: venoia
|
|
8
|
+
Author-email: overutilization@gmail.com
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: steam,trade
|
|
11
|
+
License-File: LICENSE.txt
|
steampie-0.80/README.md
ADDED
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
Steam Trade Offers Client for Python
|
|
2
|
+
=======
|
|
3
|
+
|
|
4
|
+
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=XC8BMJ8QRD9ZY "Donate to this project via PayPal")
|
|
5
|
+
|
|
6
|
+
Donate bitcoin: 3PRzESHsTVkCFK7osjwFGQLZjSf7qXP1Ta
|
|
7
|
+
|
|
8
|
+
`steampy` is a library for Python, inspired by node-steam-tradeoffers, node-steam and other libraries for Node.js.
|
|
9
|
+
It was designed as a simple lightweight library, combining features of many steam libraries from Node.js into a single python module.
|
|
10
|
+
`steampy` is capable of logging into steam, fetching trade offers and handling them in simple manner, using steam user credentials
|
|
11
|
+
and SteamGuard file(no need to extract and pass sessionID and webCookie).
|
|
12
|
+
`steampy` is developed with Python 3 using type hints and many other features its supported for Windows, Linux and MacOs.
|
|
13
|
+
|
|
14
|
+
Table of Content
|
|
15
|
+
================
|
|
16
|
+
|
|
17
|
+
* [Installation](https://github.com/bukson/steampy#installation)
|
|
18
|
+
|
|
19
|
+
* [Usage](https://github.com/bukson/steampy#usage)
|
|
20
|
+
|
|
21
|
+
* [Examples](https://github.com/bukson/steampy#examples)
|
|
22
|
+
|
|
23
|
+
* [SteamClient methods](https://github.com/bukson/steampy#steamclient-methods)
|
|
24
|
+
|
|
25
|
+
* [Market methods](https://github.com/bukson/steampy#market-methods)
|
|
26
|
+
|
|
27
|
+
* [Guard module functions](https://github.com/bukson/steampy#guard-module-functions)
|
|
28
|
+
|
|
29
|
+
* [SteamChat methods](https://github.com/bukson/steampy#steamchat-methods)
|
|
30
|
+
|
|
31
|
+
* [Test](https://github.com/bukson/steampy#test)
|
|
32
|
+
|
|
33
|
+
* [License](https://github.com/bukson/steampy#license)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
Installation
|
|
37
|
+
============
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
pip install steampy
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Usage
|
|
44
|
+
=======
|
|
45
|
+
[Obtaining API Key](http://steamcommunity.com/dev/apikey)
|
|
46
|
+
|
|
47
|
+
[Obtaining SteamGuard from mobile device]( https://github.com/SteamTimeIdler/stidler/wiki/Getting-your-%27shared_secret%27-code-for-use-with-Auto-Restarter-on-Mobile-Authentication )
|
|
48
|
+
|
|
49
|
+
[Obtaining SteamGuard using Android emulation]( https://github.com/codepath/android_guides/wiki/Genymotion-2.0-Emulators-with-Google-Play-support)
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from steampy.client import SteamClient
|
|
53
|
+
|
|
54
|
+
steam_client = SteamClient('MY_API_KEY')
|
|
55
|
+
steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE')
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
If you have `steamid`, `shared_secret` and `identity_secret` you can place it in file `Steamguard.txt` instead of fetching SteamGuard file from device.
|
|
59
|
+
```python
|
|
60
|
+
{
|
|
61
|
+
"steamid": "YOUR_STEAM_ID_64",
|
|
62
|
+
"shared_secret": "YOUR_SHARED_SECRET",
|
|
63
|
+
"identity_secret": "YOUR_IDENTITY_SECRET"
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Examples
|
|
68
|
+
========
|
|
69
|
+
|
|
70
|
+
You'll need to obtain your API key and SteamGuard file in order to run the examples,
|
|
71
|
+
and then fill login and password in `storehose.py` file.
|
|
72
|
+
The `storehouse.py` file contains an example of handling incoming trade offers.
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
python storehouse.py
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
If you want to generate authentication codes and use steampy as steam desktop authenticator
|
|
79
|
+
then fill required secrets in `desktop_authenticator.py` file.
|
|
80
|
+
The `desktop_authenticator.py` file contains examples of generating such one time codes/
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
python desktop_authenticator.py
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
SteamClient methods
|
|
88
|
+
===================
|
|
89
|
+
|
|
90
|
+
Unless specified in documentation, the method does not require login to work(it uses API Key from constructor instead)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
**login(username: str, password: str, steam_guard: str) -> requests.Response**
|
|
94
|
+
|
|
95
|
+
Log into the steam account. Allows to accept trade offers and some other methods.
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from steampy.client import SteamClient
|
|
99
|
+
|
|
100
|
+
steam_client = SteamClient('MY_API_KEY')
|
|
101
|
+
steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE')
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
You can also use `with` statement to automatically login and logout.
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
with SteamClient(api_key, login, password, steam_guard_file) as client:
|
|
108
|
+
client.some_method1(...)
|
|
109
|
+
client.some_method2(...)
|
|
110
|
+
...
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**logout() -> None**
|
|
114
|
+
|
|
115
|
+
Using `SteamClient.login` method is required before usage
|
|
116
|
+
Logout from steam.
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from steampy.client import SteamClient
|
|
120
|
+
|
|
121
|
+
steam_client = SteamClient('MY_API_KEY')
|
|
122
|
+
steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE')
|
|
123
|
+
steam_client.logout()
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
You can also use `with` statement to automatically login and logout.
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
with SteamClient(api_key, login, password, steam_guard_file) as client:
|
|
130
|
+
client.some_method1(...)
|
|
131
|
+
client.some_method2(...)
|
|
132
|
+
...
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**is_session_alive() -> None**
|
|
136
|
+
|
|
137
|
+
Using `SteamClient.login` method is required before usage
|
|
138
|
+
Check if session is alive. This method fetches main page and check
|
|
139
|
+
if user name is there. Thanks for vasia123 for this solution.
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from steampy.client import SteamClient
|
|
143
|
+
|
|
144
|
+
steam_client = SteamClient('MY_API_KEY')
|
|
145
|
+
steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE')
|
|
146
|
+
is_session_alive = steam_client.is_session_alive()
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**api_call(request_method: str, interface: str, api_method: str, version: str, params: dict = None) -> requests.Response**
|
|
150
|
+
|
|
151
|
+
Directly call api method from the steam api services.
|
|
152
|
+
|
|
153
|
+
[Official steam api site](https://developer.valvesoftware.com/wiki/Steam_Web_API)
|
|
154
|
+
|
|
155
|
+
[Unofficial but more elegant](https://lab.xpaw.me/steam_api_documentation.html)
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
from steampy.client import SteamClient
|
|
159
|
+
|
|
160
|
+
steam_client = SteamClient('MY_API_KEY')
|
|
161
|
+
params = {'key': 'MY_API_KEY'}
|
|
162
|
+
summaries = steam_client.api_call('GET', 'IEconService', 'GetTradeOffersSummary', 'v1', params).json()
|
|
163
|
+
```
|
|
164
|
+
**get_trade_offers_summary() -> dict**
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
**get_trade_offers(merge: bool = True) -> dict**
|
|
168
|
+
|
|
169
|
+
Fetching trade offers from steam using an API call.
|
|
170
|
+
Method is fetching offers with descriptions that satisfy conditions:
|
|
171
|
+
|
|
172
|
+
* Are sent by us or others
|
|
173
|
+
* Are active (means they have `trade_offer_state` set to 2 (Active))
|
|
174
|
+
* Are not historical
|
|
175
|
+
* No time limitation
|
|
176
|
+
|
|
177
|
+
If `merge` is set `True` then offer items are merged from items data and items description into dict where items `id` is key
|
|
178
|
+
and descriptions merged with data are value.
|
|
179
|
+
|
|
180
|
+
**get_trade_offer(trade_offer_id: str, merge: bool = True) -> dict**
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
**get_trade_receipt(trade_id: str) -> list**
|
|
184
|
+
|
|
185
|
+
Using `SteamClient.login` method is required before usage
|
|
186
|
+
Getting the receipt for a trade with all item information after the items has been traded.
|
|
187
|
+
Do NOT store any item ids before you got the receipt since the ids may change.
|
|
188
|
+
"trade_id" can be found in trade offers: `offer['response']['offer']['tradeid']`. Do not use ´tradeofferid´.
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
**make_offer(items_from_me: List[Asset], items_from_them: List[Asset], partner_steam_id: str, message:str ='') -> dict**
|
|
192
|
+
|
|
193
|
+
Using `SteamClient.login` method is required before usage
|
|
194
|
+
`Asset` is class defined in `client.py`, you can obtain `asset_id` from `SteamClient.get_my_inventory` method.
|
|
195
|
+
This method also uses identity secret from SteamGuard file to confirm the trade offer.
|
|
196
|
+
No need to manually confirm it on mobile app or email.
|
|
197
|
+
This method works when partner is your friend or steam.
|
|
198
|
+
In returned dict there will be trade offer id by the key `tradeofferid`.
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
from steampy.client import SteamClient, Asset
|
|
202
|
+
from steampy.utils import GameOptions
|
|
203
|
+
|
|
204
|
+
steam_client = SteamClient('MY_API_KEY')
|
|
205
|
+
steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE')
|
|
206
|
+
partner_id = 'PARTNER_ID'
|
|
207
|
+
game = GameOptions.CS
|
|
208
|
+
my_items = steam_client.get_my_inventory(game)
|
|
209
|
+
partner_items = steam_client.get_partner_inventory(partner_id, game)
|
|
210
|
+
my_first_item = next(iter(my_items.values()))
|
|
211
|
+
partner_first_item = next(iter(partner_items.values()))
|
|
212
|
+
my_asset = Asset(my_first_item['id'], game)
|
|
213
|
+
partner_asset = Asset(partner_first_item['id'], game)
|
|
214
|
+
steam_client.make_offer([my_asset], [partner_asset], partner_id, 'Test offer')
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**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**
|
|
218
|
+
|
|
219
|
+
Using `SteamClient.login` method is required before usage
|
|
220
|
+
This method is similar to `SteamClient.make_offer`, but it takes trade url instead of friend account id.
|
|
221
|
+
It works even when partner isn't your steam friend
|
|
222
|
+
In returned dict there will be trade offer id by the key `tradeofferid`.
|
|
223
|
+
If `case_sensitive` is False, then url params with be parsed with case insensitive params keys.
|
|
224
|
+
|
|
225
|
+
**get_escrow_duration(trade_offer_url: str) -> int**
|
|
226
|
+
|
|
227
|
+
Using `SteamClient.login` method is required before usage
|
|
228
|
+
|
|
229
|
+
Check the escrow duration for trade between you and partner(given partner trade offer url)
|
|
230
|
+
|
|
231
|
+
**accept_trade_offer(trade_offer_id: str) -> dict**
|
|
232
|
+
|
|
233
|
+
Using `SteamClient.login` method is required before usage
|
|
234
|
+
This method also uses identity secret from SteamGuard file to confirm the trade offer.
|
|
235
|
+
No need to manually confirm it on mobile app or email.
|
|
236
|
+
|
|
237
|
+
**decline_trade_offer(trade_offer_id: str) -> dict**
|
|
238
|
+
|
|
239
|
+
Decline trade offer that **other** user sent to us.
|
|
240
|
+
|
|
241
|
+
**cancel_trade_offer(trade_offer_id: str) -> dict**
|
|
242
|
+
|
|
243
|
+
Cancel trade offer that **we** sent to other user.
|
|
244
|
+
|
|
245
|
+
**get_my_inventory(game: GameOptions, merge: bool = True, count: int = 5000) -> dict**
|
|
246
|
+
|
|
247
|
+
Using `SteamClient.login` method is required before usage
|
|
248
|
+
|
|
249
|
+
If `merge` is set `True` then inventory items are merged from items data and items description into dict where items `id` is key
|
|
250
|
+
and descriptions merged with data are value.
|
|
251
|
+
|
|
252
|
+
`Count` parameter is default max number of items, that can be fetched.
|
|
253
|
+
|
|
254
|
+
Inventory entries looks like this:
|
|
255
|
+
```python
|
|
256
|
+
{'7146788981': {'actions': [{'link': 'steam://rungame/730/76561202255233023/+csgo_econ_action_preview%20S%owner_steamid%A%assetid%D316070896107169653',
|
|
257
|
+
'name': 'Inspect in Game...'}],
|
|
258
|
+
'amount': '1',
|
|
259
|
+
'appid': '730',
|
|
260
|
+
'background_color': '',
|
|
261
|
+
'classid': '1304827205',
|
|
262
|
+
'commodity': 0,
|
|
263
|
+
'contextid': '2',
|
|
264
|
+
'descriptions': [{'type': 'html',
|
|
265
|
+
'value': 'Exterior: Field-Tested'},
|
|
266
|
+
{'type': 'html', 'value': ' '},
|
|
267
|
+
{'type': 'html',
|
|
268
|
+
'value': 'Powerful and reliable, the AK-47 '
|
|
269
|
+
'is one of the most popular assault '
|
|
270
|
+
'rifles in the world. It is most '
|
|
271
|
+
'deadly in short, controlled bursts '
|
|
272
|
+
'of fire. It has been painted using '
|
|
273
|
+
'a carbon fiber hydrographic and a '
|
|
274
|
+
'dry-transfer decal of a red '
|
|
275
|
+
'pinstripe.\n'
|
|
276
|
+
'\n'
|
|
277
|
+
'<i>Never be afraid to push it to '
|
|
278
|
+
'the limit</i>'},
|
|
279
|
+
{'type': 'html', 'value': ' '},
|
|
280
|
+
{'app_data': {'def_index': '65535',
|
|
281
|
+
'is_itemset_name': 1},
|
|
282
|
+
'color': '9da1a9',
|
|
283
|
+
'type': 'html',
|
|
284
|
+
'value': 'The Phoenix Collection'},
|
|
285
|
+
{'type': 'html', 'value': ' '},
|
|
286
|
+
{'app_data': {'def_index': '65535'},
|
|
287
|
+
'type': 'html',
|
|
288
|
+
'value': '<br><div id="sticker_info" '
|
|
289
|
+
'name="sticker_info" title="Sticker '
|
|
290
|
+
'Details" style="border: 2px solid '
|
|
291
|
+
'rgb(102, 102, 102); border-radius: '
|
|
292
|
+
'6px; width=100; margin:4px; '
|
|
293
|
+
'padding:8px;"><center><img '
|
|
294
|
+
'width=64 height=48 '
|
|
295
|
+
'src="https://steamcdn-a.akamaihd.net/apps/730/icons/econ/stickers/eslkatowice2015/pentasports.a6b0ddffefb5507453456c0d2c35b6a57821c171.png"><img '
|
|
296
|
+
'width=64 height=48 '
|
|
297
|
+
'src="https://steamcdn-a.akamaihd.net/apps/730/icons/econ/stickers/eslkatowice2015/pentasports.a6b0ddffefb5507453456c0d2c35b6a57821c171.png"><img '
|
|
298
|
+
'width=64 height=48 '
|
|
299
|
+
'src="https://steamcdn-a.akamaihd.net/apps/730/icons/econ/stickers/eslkatowice2015/pentasports.a6b0ddffefb5507453456c0d2c35b6a57821c171.png"><img '
|
|
300
|
+
'width=64 height=48 '
|
|
301
|
+
'src="https://steamcdn-a.akamaihd.net/apps/730/icons/econ/stickers/cologne2015/mousesports.3e75da497d9f75fa56f463c22db25f29992561ce.png"><br>Sticker: '
|
|
302
|
+
'PENTA Sports | Katowice 2015, '
|
|
303
|
+
'PENTA Sports | Katowice 2015, '
|
|
304
|
+
'PENTA Sports | Katowice 2015, '
|
|
305
|
+
'mousesports | Cologne '
|
|
306
|
+
'2015</center></div>'}],
|
|
307
|
+
'icon_drag_url': '',
|
|
308
|
+
'icon_url': '-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV09-5lpKKqPrxN7LEmyVQ7MEpiLuSrYmnjQO3-UdsZGHyd4_Bd1RvNQ7T_FDrw-_ng5Pu75iY1zI97bhLsvQz',
|
|
309
|
+
'icon_url_large': '-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV09-5lpKKqPrxN7LEm1Rd6dd2j6eQ9N2t2wK3-ENsZ23wcIKRdQE2NwyD_FK_kLq9gJDu7p_KyyRr7nNw-z-DyIFJbNUz',
|
|
310
|
+
'id': '7146788981',
|
|
311
|
+
'instanceid': '480085569',
|
|
312
|
+
'market_actions': [{'link': 'steam://rungame/730/76561202255233023/+csgo_econ_action_preview%20M%listingid%A%assetid%D316070896107169653',
|
|
313
|
+
'name': 'Inspect in Game...'}],
|
|
314
|
+
'market_hash_name': 'AK-47 | Redline (Field-Tested)',
|
|
315
|
+
'market_name': 'AK-47 | Redline (Field-Tested)',
|
|
316
|
+
'market_tradable_restriction': '7',
|
|
317
|
+
'marketable': 1,
|
|
318
|
+
'name': 'AK-47 | Redline',
|
|
319
|
+
'name_color': 'D2D2D2',
|
|
320
|
+
'owner_descriptions': '',
|
|
321
|
+
'tags': [{'category': 'Type',
|
|
322
|
+
'category_name': 'Type',
|
|
323
|
+
'internal_name': 'CSGO_Type_Rifle',
|
|
324
|
+
'name': 'Rifle'},
|
|
325
|
+
{'category': 'Weapon',
|
|
326
|
+
'category_name': 'Weapon',
|
|
327
|
+
'internal_name': 'weapon_ak47',
|
|
328
|
+
'name': 'AK-47'},
|
|
329
|
+
{'category': 'ItemSet',
|
|
330
|
+
'category_name': 'Collection',
|
|
331
|
+
'internal_name': 'set_community_2',
|
|
332
|
+
'name': 'The Phoenix Collection'},
|
|
333
|
+
{'category': 'Quality',
|
|
334
|
+
'category_name': 'Category',
|
|
335
|
+
'internal_name': 'normal',
|
|
336
|
+
'name': 'Normal'},
|
|
337
|
+
{'category': 'Rarity',
|
|
338
|
+
'category_name': 'Quality',
|
|
339
|
+
'color': 'd32ce6',
|
|
340
|
+
'internal_name': 'Rarity_Legendary_Weapon',
|
|
341
|
+
'name': 'Classified'},
|
|
342
|
+
{'category': 'Exterior',
|
|
343
|
+
'category_name': 'Exterior',
|
|
344
|
+
'internal_name': 'WearCategory2',
|
|
345
|
+
'name': 'Field-Tested'},
|
|
346
|
+
{'category': 'Tournament',
|
|
347
|
+
'category_name': 'Tournament',
|
|
348
|
+
'internal_name': 'Tournament6',
|
|
349
|
+
'name': '2015 ESL One Katowice'},
|
|
350
|
+
{'category': 'Tournament',
|
|
351
|
+
'category_name': 'Tournament',
|
|
352
|
+
'internal_name': 'Tournament7',
|
|
353
|
+
'name': '2015 ESL One Cologne'},
|
|
354
|
+
{'category': 'TournamentTeam',
|
|
355
|
+
'category_name': 'Team',
|
|
356
|
+
'internal_name': 'Team39',
|
|
357
|
+
'name': 'PENTA Sports'},
|
|
358
|
+
{'category': 'TournamentTeam',
|
|
359
|
+
'category_name': 'Team',
|
|
360
|
+
'internal_name': 'Team29',
|
|
361
|
+
'name': 'mousesports'}],
|
|
362
|
+
'tradable': 1,
|
|
363
|
+
'type': 'Classified Rifle'}}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
**get_partner_inventory(partner_steam_id: str, game: GameOptions, merge: bool = True, count: int = 5000) -> dict**
|
|
367
|
+
|
|
368
|
+
Using `SteamClient.login` method is required before usage
|
|
369
|
+
|
|
370
|
+
Inventory items can be merged like in `SteamClient.get_my_inventory` method
|
|
371
|
+
|
|
372
|
+
`Count` parameter is default max number of items, that can be fetched.
|
|
373
|
+
|
|
374
|
+
**get_wallet_balance(convert_to_float: bool = True) -> Union[str, float]**
|
|
375
|
+
|
|
376
|
+
Check account balance of steam acccount. It uses `parse_price` method from utils
|
|
377
|
+
to covnert money string to Decimal if `convert_to_decimal` is set to `True`.
|
|
378
|
+
|
|
379
|
+
Example:
|
|
380
|
+
```python
|
|
381
|
+
with SteamClient(api_key, login, password, steam_guard_file) as client:
|
|
382
|
+
wallet_balance = client.get_wallet_balance()
|
|
383
|
+
self.assertTrue(type(wallet_balance), decimal.Decimal)
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
market methods
|
|
387
|
+
==============
|
|
388
|
+
|
|
389
|
+
**fetch_price(item_hash_name: str, game: GameOptions, currency: str = Currency.USD) -> dict**
|
|
390
|
+
|
|
391
|
+
Some games are predefined in `GameOptions` class, such as `GameOptions.DOTA2`, `GameOptions.CS` and `GameOptions.TF2,
|
|
392
|
+
but `GameOptions` object can be constructed with custom parameters.
|
|
393
|
+
|
|
394
|
+
Currencies are defined in Currency class, [currently](https://github.com/bukson/steampy#currencies)
|
|
395
|
+
|
|
396
|
+
Default currency is USD
|
|
397
|
+
|
|
398
|
+
May rise `TooManyRequests` exception if used more than 20 times in 60 seconds.
|
|
399
|
+
|
|
400
|
+
```python
|
|
401
|
+
steam_client = SteamClient(self.credentials.api_key)
|
|
402
|
+
item = 'M4A1-S | Cyrex (Factory New)'
|
|
403
|
+
steam_client.market.fetch_price(item, game=GameOptions.CS)
|
|
404
|
+
{'volume': '208', 'lowest_price': '$11.30 USD', 'median_price': '$11.33 USD', 'success': True}
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
**fetch_price_history(item_hash_name: str, game: GameOptions) -> dict**
|
|
408
|
+
|
|
409
|
+
Using `SteamClient.login` method is required before usage
|
|
410
|
+
|
|
411
|
+
Returns list of price history of and item.
|
|
412
|
+
```python
|
|
413
|
+
with SteamClient(self.credentials.api_key, self.credentials.login,
|
|
414
|
+
self.credentials.password, self.steam_guard_file) as client:
|
|
415
|
+
item = 'M4A1-S | Cyrex (Factory New)'
|
|
416
|
+
response = client.market.fetch_price_history(item, GameOptions.CS)
|
|
417
|
+
response['prices'][0]
|
|
418
|
+
['Jul 02 2014 01: +0', 417.777, '40']
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
Each entry in `response['prices']` is a list, with first entry being date, second entry price, and third entry a volume.
|
|
422
|
+
|
|
423
|
+
**get_my_market_listings() -> dict**
|
|
424
|
+
|
|
425
|
+
Using `SteamClient.login` method is required before usage
|
|
426
|
+
|
|
427
|
+
Returns market listings posted by user
|
|
428
|
+
|
|
429
|
+
```python
|
|
430
|
+
steam_client = SteamClient(self.credentials.api_key)
|
|
431
|
+
steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE')
|
|
432
|
+
listings = steam_client.market.get_my_market_listings()
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
**create_sell_order(assetid: str, game: GameOptions, money_to_receive: str) -> dict**
|
|
437
|
+
|
|
438
|
+
Using `SteamClient.login` method is required before usage
|
|
439
|
+
|
|
440
|
+
Create sell order of the asset on the steam market.
|
|
441
|
+
|
|
442
|
+
```python
|
|
443
|
+
steam_client = SteamClient(self.credentials.api_key)
|
|
444
|
+
steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE')
|
|
445
|
+
asset_id_to_sell = 'some_asset_id'
|
|
446
|
+
game = GameOptions.DOTA2
|
|
447
|
+
sell_response = steam_client.market.create_sell_order(asset_id_to_sell, game, "10000")
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
⚠️ `money_to_receive` has to be in cents, so "100.00" should be passed has "10000"
|
|
451
|
+
|
|
452
|
+
**create_buy_order(market_name: str, price_single_item: str, quantity: int, game: GameOptions, currency: Currency = Currency.USD) -> dict**
|
|
453
|
+
|
|
454
|
+
Using `SteamClient.login` method is required before usage
|
|
455
|
+
|
|
456
|
+
Create buy order of the assets on the steam market.
|
|
457
|
+
|
|
458
|
+
```python
|
|
459
|
+
steam_client = SteamClient(self.credentials.api_key)
|
|
460
|
+
steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE')
|
|
461
|
+
response = steam_client.market.create_buy_order("AK-47 | Redline (Field-Tested)", "1034", 2, GameOptions.CS, Currency.EURO)
|
|
462
|
+
buy_order_id = response["buy_orderid"]
|
|
463
|
+
```
|
|
464
|
+
⚠️ `price_single_item` has to be in cents, so "10.34" should be passed has "1034"
|
|
465
|
+
|
|
466
|
+
**buy_item(market_name: str, market_id: str, price: int, fee: int, game: GameOptions, currency: Currency = Currency.USD) -> dict**
|
|
467
|
+
|
|
468
|
+
Using `SteamClient.login` method is required before usage
|
|
469
|
+
|
|
470
|
+
Buy a certain item from market listing.
|
|
471
|
+
|
|
472
|
+
```python
|
|
473
|
+
steam_client = SteamClient(self.credentials.api_key)
|
|
474
|
+
steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE')
|
|
475
|
+
response = steam_client.market.buy_item('AK-47 | Redline (Field-Tested)', '1942659007774983251', 81, 10,
|
|
476
|
+
GameOptions.CS, Currency.RUB)
|
|
477
|
+
wallet_balance = response["wallet_info"]["wallet_balance"]
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
**cancel_sell_order(sell_listing_id: str) -> None**
|
|
481
|
+
|
|
482
|
+
Using `SteamClient.login` method is required before usage
|
|
483
|
+
|
|
484
|
+
Cancel previously requested sell order on steam market.
|
|
485
|
+
|
|
486
|
+
```python
|
|
487
|
+
steam_client = SteamClient(self.credentials.api_key)
|
|
488
|
+
steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE')
|
|
489
|
+
sell_order_id = "some_sell_order_id"
|
|
490
|
+
response = steam_client.market.cancel_sell_order(sell_order_id)
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
**cancel_buy_order(buy_order_id) -> dict**
|
|
494
|
+
|
|
495
|
+
Using `SteamClient.login` method is required before usage
|
|
496
|
+
|
|
497
|
+
Cancel previously requested buy order on steam market.
|
|
498
|
+
|
|
499
|
+
```python
|
|
500
|
+
steam_client = SteamClient(self.credentials.api_key)
|
|
501
|
+
steam_client.login('MY_USERNAME', 'MY_PASSWORD', 'PATH_TO_STEAMGUARD_FILE')
|
|
502
|
+
buy_order_id = "some_buy_order_id"
|
|
503
|
+
response = steam_client.market.cancel_buy_order(buy_order_id)
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
Currencies
|
|
507
|
+
----------
|
|
508
|
+
|
|
509
|
+
| Currency class | Description |
|
|
510
|
+
| --- | --- |
|
|
511
|
+
| Currency.USD | United States Dollar |
|
|
512
|
+
| Currency.GBP | United Kingdom Pound |
|
|
513
|
+
| Currency.EURO | European Union Euro |
|
|
514
|
+
| Currency.CHF | Swiss Francs |
|
|
515
|
+
| Currency.RUB | Russian Rouble |
|
|
516
|
+
| Currency.PLN | Polish Złoty |
|
|
517
|
+
| Currency.BRL | Brazilian Reals |
|
|
518
|
+
| Currency.JPY | Japanese Yen |
|
|
519
|
+
| Currency.NOK | Norwegian Krone |
|
|
520
|
+
| Currency.IDR | Indonesian Rupiah |
|
|
521
|
+
| Currency.MYR | Malaysian Ringgit |
|
|
522
|
+
| Currency.PHP | Philippine Peso |
|
|
523
|
+
| Currency.SGD | Singapore Dollar |
|
|
524
|
+
| Currency.THB | Thai Baht |
|
|
525
|
+
| Currency.VND | Vietnamese Dong |
|
|
526
|
+
| Currency.KRW | South Korean Won |
|
|
527
|
+
| Currency.TRY | Turkish Lira |
|
|
528
|
+
| Currency.UAH | Ukrainian Hryvnia |
|
|
529
|
+
| Currency.MXN | Mexican Peso |
|
|
530
|
+
| Currency.CAD | Canadian Dollars |
|
|
531
|
+
| Currency.AUD | Australian Dollars |
|
|
532
|
+
| Currency.NZD | New Zealand Dollar |
|
|
533
|
+
| Currency.CNY | Chinese Renminbi (yuan) |
|
|
534
|
+
| Currency.INR | Indian Rupee |
|
|
535
|
+
| Currency.CLP | Chilean Peso |
|
|
536
|
+
| Currency.PEN | Peruvian Sol |
|
|
537
|
+
| Currency.COP | Colombian Peso |
|
|
538
|
+
| Currency.ZAR | South African Rand |
|
|
539
|
+
| Currency.HKD | Hong Kong Dollar |
|
|
540
|
+
| Currency.TWD | New Taiwan Dollar |
|
|
541
|
+
| Currency.SAR | Saudi Riyal |
|
|
542
|
+
| Currency.AED | United Arab Emirates Dirham |
|
|
543
|
+
| Currency.SEK | Swedish Krona |
|
|
544
|
+
| Currency.ARS | Argentine Peso |
|
|
545
|
+
| Currency.ILS | Israeli New Shekel |
|
|
546
|
+
| Currency.BYN | Belarusian Ruble |
|
|
547
|
+
| Currency.KZT | Kazakhstani Tenge |
|
|
548
|
+
| Currency.KWD | Kuwaiti Dinar |
|
|
549
|
+
| Currency.QAR | Qatari Riyal |
|
|
550
|
+
| Currency.CRC | Costa Rican Colón |
|
|
551
|
+
| Currency.UYU | Uruguayan Peso |
|
|
552
|
+
| Currency.BGN | Bulgarian Lev |
|
|
553
|
+
| Currency.HRK | Croatian Kuna |
|
|
554
|
+
| Currency.CZK | Czech Koruna |
|
|
555
|
+
| Currency.DKK | Danish Krone |
|
|
556
|
+
| Currency.HUF | Hungarian Forint |
|
|
557
|
+
| Currency.RON | Romanian Leu |
|
|
558
|
+
|
|
559
|
+
guard module functions
|
|
560
|
+
======================
|
|
561
|
+
|
|
562
|
+
**load_steam_guard(steam_guard: str) -> dict**
|
|
563
|
+
|
|
564
|
+
If `steam_guard` is file name then load and parse it, else just parse `steam_guard` as json string.
|
|
565
|
+
|
|
566
|
+
**generate_one_time_code(shared_secret: str, timestamp: int = None) -> str**
|
|
567
|
+
|
|
568
|
+
Generate one time code for logging into Steam using shared_secret from SteamGuard file.
|
|
569
|
+
If none timestamp provided, timestamp will be set to current time.
|
|
570
|
+
|
|
571
|
+
**generate_confirmation_key(identity_secret: str, tag: str, timestamp: int = int(time.time())) -> bytes**
|
|
572
|
+
|
|
573
|
+
Generate mobile device confirmation key for accepting trade offer.
|
|
574
|
+
Default timestamp is current time.
|
|
575
|
+
|
|
576
|
+
SteamChat methods
|
|
577
|
+
==============
|
|
578
|
+
|
|
579
|
+
**send_message(steamid_64: str, text: str) -> requests.Response**
|
|
580
|
+
|
|
581
|
+
Send the string contained in `text` to the desired `steamid_64`.
|
|
582
|
+
|
|
583
|
+
`client.chat.send_message("[steamid]", "This is a message.")`
|
|
584
|
+
|
|
585
|
+
**fetch_messages() -> dict**
|
|
586
|
+
|
|
587
|
+
Returns a dictionary with all new sent and received messages:
|
|
588
|
+
|
|
589
|
+
```
|
|
590
|
+
{
|
|
591
|
+
'sent': [
|
|
592
|
+
{'partner': "[steamid]", 'message': "This is a message."}
|
|
593
|
+
],
|
|
594
|
+
'received': []
|
|
595
|
+
}
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
`client.chat.fetch_messages()`
|
|
599
|
+
|
|
600
|
+
Test
|
|
601
|
+
====
|
|
602
|
+
|
|
603
|
+
All public methods are documented and tested.
|
|
604
|
+
`guard` module has unit tests, `client` uses an acceptance test.
|
|
605
|
+
For the acceptance test you have to put `credentials.pwd` and `Steamguard` file into `test` directory
|
|
606
|
+
|
|
607
|
+
Example `credentials.pwd` file:
|
|
608
|
+
|
|
609
|
+
```
|
|
610
|
+
account1 password1 api_key1
|
|
611
|
+
account2 password2 api_key2
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
In some tests you also have to obtain `transaction_id`.
|
|
615
|
+
You can do it by `SteamClient.get_trade_offers` or by logging manually into steam account in browser and get it from url
|
|
616
|
+
|
|
617
|
+
In some tests you also have to obtain partner steam id.
|
|
618
|
+
You can do it by by logging manually into steam account in browser and get it from url
|
|
619
|
+
|
|
620
|
+
License
|
|
621
|
+
=======
|
|
622
|
+
|
|
623
|
+
MIT License
|
|
624
|
+
|
|
625
|
+
Copyright (c) 2016 [Michał Bukowski](gigibukson@gmail.com)
|
|
626
|
+
|
|
627
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
628
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
629
|
+
in the Software without restriction, including without limitation the rights
|
|
630
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
631
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
632
|
+
furnished to do so, subject to the following conditions:
|
|
633
|
+
|
|
634
|
+
The above copyright notice and this permission notice shall be included in all
|
|
635
|
+
copies or substantial portions of the Software.
|
|
636
|
+
|
|
637
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
638
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
639
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
640
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
641
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
642
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
643
|
+
SOFTWARE.
|
|
File without changes
|