skinapi-sdk 0.1.0__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.
- skinapi_sdk-0.1.0/.gitignore +10 -0
- skinapi_sdk-0.1.0/LICENSE +21 -0
- skinapi_sdk-0.1.0/PKG-INFO +99 -0
- skinapi_sdk-0.1.0/README.md +79 -0
- skinapi_sdk-0.1.0/examples/price.py +14 -0
- skinapi_sdk-0.1.0/pyproject.toml +29 -0
- skinapi_sdk-0.1.0/skinapi/__init__.py +175 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SkinVaults
|
|
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.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: skinapi-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python client for SkinAPI - CS2/Steam skin prices, float values, inventories and marketplace data.
|
|
5
|
+
Project-URL: Homepage, https://skinapi.skinvaults.online
|
|
6
|
+
Project-URL: Documentation, https://skinapi.skinvaults.online/docs
|
|
7
|
+
Project-URL: Repository, https://github.com/soccervortex/skinapi-py
|
|
8
|
+
Author: SkinVaults
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: api,cs2,csgo,float,inventory,marketplace,skin-prices,skinapi,skins,steam
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
+
Requires-Python: >=3.8
|
|
18
|
+
Requires-Dist: requests>=2.20
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# skinapi (Python)
|
|
22
|
+
|
|
23
|
+
Python client for [SkinAPI](https://skinapi.skinvaults.online) - real-time **CS2 / Dota 2 / Rust / TF2** skin prices, **float values**, Steam **inventories & profiles**, and multi-marketplace data through one REST API.
|
|
24
|
+
|
|
25
|
+
- Real-time prices aggregated across marketplaces
|
|
26
|
+
- CS2 float values, paint seed and wear
|
|
27
|
+
- Steam inventories, profiles and price history
|
|
28
|
+
- Automatic retries, timeouts and rate-limit tracking
|
|
29
|
+
- Free tier - get a key in ~2 minutes
|
|
30
|
+
|
|
31
|
+
## Install
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install skinapi
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Get a key
|
|
38
|
+
|
|
39
|
+
1. Sign in with Steam: https://skinapi.skinvaults.online/api/auth/steam
|
|
40
|
+
2. Create a key in your [dashboard](https://skinapi.skinvaults.online/dashboard)
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from skinapi import SkinAPI
|
|
46
|
+
|
|
47
|
+
api = SkinAPI("sk_live_your_key")
|
|
48
|
+
|
|
49
|
+
# Aggregated price for one item
|
|
50
|
+
price = api.item_price("AK-47 | Redline (Field-Tested)", game="cs2", currency="USD")
|
|
51
|
+
|
|
52
|
+
# Compare across marketplaces
|
|
53
|
+
markets = api.markets("AK-47 | Redline (Field-Tested)", game="cs2")
|
|
54
|
+
|
|
55
|
+
# Float value, paint seed and wear from a Steam inspect link
|
|
56
|
+
fl = api.float("STEAM_INSPECT_LINK")
|
|
57
|
+
|
|
58
|
+
# Steam profile and bans
|
|
59
|
+
profile = api.profile("STEAM_ID_OR_VANITY")
|
|
60
|
+
|
|
61
|
+
# Priced Steam inventory
|
|
62
|
+
inv = api.inventory("STEAM_ID", game="cs2", prices=True)
|
|
63
|
+
|
|
64
|
+
# Many items at once
|
|
65
|
+
batch = api.markets_batch(["AK-47 | Redline (Field-Tested)", "AWP | Asiimov (Field-Tested)"])
|
|
66
|
+
|
|
67
|
+
# Remaining quota after any call
|
|
68
|
+
print(api.rate_limit) # {'remaining_minute': ..., 'remaining_day': ..., 'reset': ...}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Errors raise `SkinAPIError` with `.status` and `.code`:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from skinapi import SkinAPIError
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
api.item_price("Nonexistent Item")
|
|
78
|
+
except SkinAPIError as e:
|
|
79
|
+
print(e.status, e.code, e)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Methods
|
|
83
|
+
|
|
84
|
+
`item_price`, `item_meta`, `search`, `catalog`, `history`, `markets`, `markets_batch`,
|
|
85
|
+
`deals`, `float`, `float_leaderboard`, `profile`, `friendlist`, `inventory`,
|
|
86
|
+
`inventory_history`, `inventory_batch`, `tradeup`, `status`.
|
|
87
|
+
|
|
88
|
+
Authentication uses the `x-api-key` header. Games: `cs2`, `dota2`, `rust`, `tf2`.
|
|
89
|
+
|
|
90
|
+
## Links
|
|
91
|
+
|
|
92
|
+
- Docs: https://skinapi.skinvaults.online/docs
|
|
93
|
+
- OpenAPI spec: https://skinapi.skinvaults.online/api/v1/openapi.json
|
|
94
|
+
- JavaScript client: https://www.npmjs.com/package/skinapi-js
|
|
95
|
+
- Discord: https://discord.gg/CqVnGdGc4Q
|
|
96
|
+
|
|
97
|
+
## License
|
|
98
|
+
|
|
99
|
+
MIT
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# skinapi (Python)
|
|
2
|
+
|
|
3
|
+
Python client for [SkinAPI](https://skinapi.skinvaults.online) - real-time **CS2 / Dota 2 / Rust / TF2** skin prices, **float values**, Steam **inventories & profiles**, and multi-marketplace data through one REST API.
|
|
4
|
+
|
|
5
|
+
- Real-time prices aggregated across marketplaces
|
|
6
|
+
- CS2 float values, paint seed and wear
|
|
7
|
+
- Steam inventories, profiles and price history
|
|
8
|
+
- Automatic retries, timeouts and rate-limit tracking
|
|
9
|
+
- Free tier - get a key in ~2 minutes
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install skinapi
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Get a key
|
|
18
|
+
|
|
19
|
+
1. Sign in with Steam: https://skinapi.skinvaults.online/api/auth/steam
|
|
20
|
+
2. Create a key in your [dashboard](https://skinapi.skinvaults.online/dashboard)
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
from skinapi import SkinAPI
|
|
26
|
+
|
|
27
|
+
api = SkinAPI("sk_live_your_key")
|
|
28
|
+
|
|
29
|
+
# Aggregated price for one item
|
|
30
|
+
price = api.item_price("AK-47 | Redline (Field-Tested)", game="cs2", currency="USD")
|
|
31
|
+
|
|
32
|
+
# Compare across marketplaces
|
|
33
|
+
markets = api.markets("AK-47 | Redline (Field-Tested)", game="cs2")
|
|
34
|
+
|
|
35
|
+
# Float value, paint seed and wear from a Steam inspect link
|
|
36
|
+
fl = api.float("STEAM_INSPECT_LINK")
|
|
37
|
+
|
|
38
|
+
# Steam profile and bans
|
|
39
|
+
profile = api.profile("STEAM_ID_OR_VANITY")
|
|
40
|
+
|
|
41
|
+
# Priced Steam inventory
|
|
42
|
+
inv = api.inventory("STEAM_ID", game="cs2", prices=True)
|
|
43
|
+
|
|
44
|
+
# Many items at once
|
|
45
|
+
batch = api.markets_batch(["AK-47 | Redline (Field-Tested)", "AWP | Asiimov (Field-Tested)"])
|
|
46
|
+
|
|
47
|
+
# Remaining quota after any call
|
|
48
|
+
print(api.rate_limit) # {'remaining_minute': ..., 'remaining_day': ..., 'reset': ...}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Errors raise `SkinAPIError` with `.status` and `.code`:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from skinapi import SkinAPIError
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
api.item_price("Nonexistent Item")
|
|
58
|
+
except SkinAPIError as e:
|
|
59
|
+
print(e.status, e.code, e)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Methods
|
|
63
|
+
|
|
64
|
+
`item_price`, `item_meta`, `search`, `catalog`, `history`, `markets`, `markets_batch`,
|
|
65
|
+
`deals`, `float`, `float_leaderboard`, `profile`, `friendlist`, `inventory`,
|
|
66
|
+
`inventory_history`, `inventory_batch`, `tradeup`, `status`.
|
|
67
|
+
|
|
68
|
+
Authentication uses the `x-api-key` header. Games: `cs2`, `dota2`, `rust`, `tf2`.
|
|
69
|
+
|
|
70
|
+
## Links
|
|
71
|
+
|
|
72
|
+
- Docs: https://skinapi.skinvaults.online/docs
|
|
73
|
+
- OpenAPI spec: https://skinapi.skinvaults.online/api/v1/openapi.json
|
|
74
|
+
- JavaScript client: https://www.npmjs.com/package/skinapi-js
|
|
75
|
+
- Discord: https://discord.gg/CqVnGdGc4Q
|
|
76
|
+
|
|
77
|
+
## License
|
|
78
|
+
|
|
79
|
+
MIT
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Run: SKINAPI_KEY=sk_live_... python examples/price.py
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
from skinapi import SkinAPI
|
|
5
|
+
|
|
6
|
+
api = SkinAPI(os.environ["SKINAPI_KEY"])
|
|
7
|
+
|
|
8
|
+
price = api.item_price("AK-47 | Redline (Field-Tested)", game="cs2", currency="USD")
|
|
9
|
+
print("Price:", price)
|
|
10
|
+
|
|
11
|
+
markets = api.markets("AK-47 | Redline (Field-Tested)", game="cs2")
|
|
12
|
+
print("Lowest:", markets.get("lowest"), "from", markets.get("lowestSource"))
|
|
13
|
+
|
|
14
|
+
print("Rate limit:", api.rate_limit)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "skinapi-sdk"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Python client for SkinAPI - CS2/Steam skin prices, float values, inventories and marketplace data."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "SkinVaults" }]
|
|
13
|
+
keywords = ["cs2", "csgo", "steam", "skins", "skin-prices", "float", "inventory", "marketplace", "api", "skinapi"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
20
|
+
]
|
|
21
|
+
dependencies = ["requests>=2.20"]
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Homepage = "https://skinapi.skinvaults.online"
|
|
25
|
+
Documentation = "https://skinapi.skinvaults.online/docs"
|
|
26
|
+
Repository = "https://github.com/soccervortex/skinapi-py"
|
|
27
|
+
|
|
28
|
+
[tool.hatch.build.targets.wheel]
|
|
29
|
+
packages = ["skinapi"]
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"""
|
|
2
|
+
skinapi - Python client for SkinAPI.
|
|
3
|
+
|
|
4
|
+
Real-time CS2/Dota2/Rust/TF2 skin prices, float values, inventories,
|
|
5
|
+
profiles and marketplace data.
|
|
6
|
+
|
|
7
|
+
Docs: https://skinapi.skinvaults.online/docs
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import random
|
|
13
|
+
import time
|
|
14
|
+
from typing import Any, Optional
|
|
15
|
+
|
|
16
|
+
import requests
|
|
17
|
+
|
|
18
|
+
__version__ = "0.1.0"
|
|
19
|
+
__all__ = ["SkinAPI", "SkinAPIError"]
|
|
20
|
+
|
|
21
|
+
DEFAULT_BASE = "https://skinapi.skinvaults.online/api/v1"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _int(v: Optional[str]) -> Optional[int]:
|
|
25
|
+
try:
|
|
26
|
+
return int(v) if v not in (None, "") else None
|
|
27
|
+
except (TypeError, ValueError):
|
|
28
|
+
return None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class SkinAPIError(Exception):
|
|
32
|
+
"""Raised on a non-2xx response or network failure."""
|
|
33
|
+
|
|
34
|
+
def __init__(self, status: int, code: Optional[str] = None,
|
|
35
|
+
message: Optional[str] = None, retryable: bool = False):
|
|
36
|
+
super().__init__(message or f"SkinAPI error {status}")
|
|
37
|
+
self.status = status
|
|
38
|
+
self.code = code
|
|
39
|
+
self.retryable = retryable
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class SkinAPI:
|
|
43
|
+
"""SkinAPI client. Pass your key (sk_live_...), created in the dashboard."""
|
|
44
|
+
|
|
45
|
+
def __init__(self, api_key: str, *, base_url: str = DEFAULT_BASE,
|
|
46
|
+
timeout: float = 15.0, max_retries: int = 2,
|
|
47
|
+
session: Optional[requests.Session] = None):
|
|
48
|
+
if not api_key:
|
|
49
|
+
raise ValueError("api_key is required")
|
|
50
|
+
self.api_key = api_key
|
|
51
|
+
self.base_url = base_url.rstrip("/")
|
|
52
|
+
self.timeout = timeout
|
|
53
|
+
self.max_retries = max_retries
|
|
54
|
+
self.session = session or requests.Session()
|
|
55
|
+
self.session.headers.update({"x-api-key": api_key})
|
|
56
|
+
#: Rate-limit info from the most recent response, or None.
|
|
57
|
+
self.rate_limit: Optional[dict] = None
|
|
58
|
+
|
|
59
|
+
# -- internals --
|
|
60
|
+
def _backoff(self, attempt: int) -> float:
|
|
61
|
+
return (2 ** attempt) * 0.5 * (0.8 + random.random() * 0.4)
|
|
62
|
+
|
|
63
|
+
def _retry_after(self, resp: requests.Response) -> Optional[float]:
|
|
64
|
+
ra = resp.headers.get("retry-after")
|
|
65
|
+
if ra and ra.isdigit():
|
|
66
|
+
return float(ra)
|
|
67
|
+
reset = _int(resp.headers.get("X-RateLimit-Reset"))
|
|
68
|
+
if reset:
|
|
69
|
+
ms = (reset - time.time() * 1000) if reset > 1e12 else (reset - time.time())
|
|
70
|
+
if 0 < ms < 60:
|
|
71
|
+
return ms
|
|
72
|
+
return None
|
|
73
|
+
|
|
74
|
+
def _request(self, method: str, path: str, *, params: Optional[dict] = None,
|
|
75
|
+
json: Optional[dict] = None) -> Any:
|
|
76
|
+
url = self.base_url + path
|
|
77
|
+
if params:
|
|
78
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
79
|
+
attempt = 0
|
|
80
|
+
while True:
|
|
81
|
+
try:
|
|
82
|
+
resp = self.session.request(method, url, params=params, json=json,
|
|
83
|
+
timeout=self.timeout)
|
|
84
|
+
except requests.RequestException as e:
|
|
85
|
+
if attempt < self.max_retries:
|
|
86
|
+
time.sleep(self._backoff(attempt)); attempt += 1; continue
|
|
87
|
+
raise SkinAPIError(0, "network_error", str(e), retryable=True)
|
|
88
|
+
|
|
89
|
+
self.rate_limit = {
|
|
90
|
+
"remaining_minute": _int(resp.headers.get("X-RateLimit-Remaining-Minute")),
|
|
91
|
+
"remaining_day": _int(resp.headers.get("X-RateLimit-Remaining-Day")),
|
|
92
|
+
"reset": _int(resp.headers.get("X-RateLimit-Reset")),
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (resp.status_code == 429 or resp.status_code >= 500) and attempt < self.max_retries:
|
|
96
|
+
time.sleep(self._retry_after(resp) or self._backoff(attempt))
|
|
97
|
+
attempt += 1
|
|
98
|
+
continue
|
|
99
|
+
|
|
100
|
+
try:
|
|
101
|
+
data = resp.json()
|
|
102
|
+
except ValueError:
|
|
103
|
+
data = {}
|
|
104
|
+
if not resp.ok:
|
|
105
|
+
err = (data or {}).get("error", {}) or {}
|
|
106
|
+
raise SkinAPIError(resp.status_code, err.get("code"), err.get("message"),
|
|
107
|
+
retryable=resp.status_code == 429 or resp.status_code >= 500)
|
|
108
|
+
return data.get("data", data)
|
|
109
|
+
|
|
110
|
+
def get(self, path: str, **params) -> Any:
|
|
111
|
+
return self._request("GET", path, params=params)
|
|
112
|
+
|
|
113
|
+
def post(self, path: str, body: dict) -> Any:
|
|
114
|
+
return self._request("POST", path, json=body)
|
|
115
|
+
|
|
116
|
+
# -- prices --
|
|
117
|
+
def item_price(self, name: str, *, game: str = "cs2", currency: str = "USD") -> Any:
|
|
118
|
+
return self.get("/items", name=name, game=game, currency=currency)
|
|
119
|
+
|
|
120
|
+
def item_meta(self, name: str) -> Any:
|
|
121
|
+
return self.get("/items/meta", name=name)
|
|
122
|
+
|
|
123
|
+
def search(self, q: str, *, limit: int = 20) -> Any:
|
|
124
|
+
return self.get("/items/search", q=q, limit=limit)
|
|
125
|
+
|
|
126
|
+
def catalog(self, *, game: str = "cs2", limit: Optional[int] = None,
|
|
127
|
+
offset: Optional[int] = None, q: Optional[str] = None,
|
|
128
|
+
type: Optional[str] = None, rarity: Optional[str] = None,
|
|
129
|
+
prices: Optional[bool] = None, sort: Optional[str] = None,
|
|
130
|
+
currency: str = "USD") -> Any:
|
|
131
|
+
return self.get("/catalog", game=game, limit=limit, offset=offset, q=q,
|
|
132
|
+
type=type, rarity=rarity, prices=prices, sort=sort, currency=currency)
|
|
133
|
+
|
|
134
|
+
def history(self, name: str, *, game: str = "cs2", days: int = 30, currency: str = "USD") -> Any:
|
|
135
|
+
return self.get("/history", name=name, game=game, days=days, currency=currency)
|
|
136
|
+
|
|
137
|
+
# -- marketplaces --
|
|
138
|
+
def markets(self, name: str, *, game: str = "cs2", currency: str = "USD") -> Any:
|
|
139
|
+
return self.get("/markets", name=name, game=game, currency=currency)
|
|
140
|
+
|
|
141
|
+
def markets_batch(self, names: list[str], *, game: str = "cs2", currency: str = "USD") -> Any:
|
|
142
|
+
return self.post("/markets/batch", {"names": names, "game": game, "currency": currency})
|
|
143
|
+
|
|
144
|
+
def deals(self, *, game: str = "cs2", min_discount: Optional[int] = None, currency: str = "USD") -> Any:
|
|
145
|
+
return self.get("/deals", game=game, min_discount=min_discount, currency=currency)
|
|
146
|
+
|
|
147
|
+
# -- floats --
|
|
148
|
+
def float(self, inspect_url: str) -> Any:
|
|
149
|
+
return self.get("/float", url=inspect_url)
|
|
150
|
+
|
|
151
|
+
def float_leaderboard(self, name: str, *, order: str = "asc", limit: int = 10) -> Any:
|
|
152
|
+
return self.get("/float/leaderboard", name=name, order=order, limit=limit)
|
|
153
|
+
|
|
154
|
+
# -- steam --
|
|
155
|
+
def profile(self, id_or_vanity: str) -> Any:
|
|
156
|
+
return self.get("/profile", id=id_or_vanity)
|
|
157
|
+
|
|
158
|
+
def friendlist(self, steam_id: str) -> Any:
|
|
159
|
+
return self.get("/friendlist", steam_id=steam_id)
|
|
160
|
+
|
|
161
|
+
def inventory(self, steam_id: str, *, game: str = "cs2", prices: bool = True, currency: str = "USD") -> Any:
|
|
162
|
+
return self.get("/inventory", steam_id=steam_id, game=game, prices=prices, currency=currency)
|
|
163
|
+
|
|
164
|
+
def inventory_history(self, steam_id: str, *, game: str = "cs2", days: int = 30, currency: str = "USD") -> Any:
|
|
165
|
+
return self.get("/inventory/history", steam_id=steam_id, game=game, days=days, currency=currency)
|
|
166
|
+
|
|
167
|
+
def inventory_batch(self, steam_ids: list[str], *, game: str = "cs2") -> Any:
|
|
168
|
+
return self.post("/inventory/batch", {"steam_ids": steam_ids, "game": game})
|
|
169
|
+
|
|
170
|
+
# -- tools --
|
|
171
|
+
def tradeup(self, items: list[dict]) -> Any:
|
|
172
|
+
return self.post("/tradeup", {"items": items})
|
|
173
|
+
|
|
174
|
+
def status(self) -> Any:
|
|
175
|
+
return self.get("/status")
|