Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
__pycache__/
*.pyc
.DS_Store
.idea
3 changes: 0 additions & 3 deletions .idea/.gitignore

This file was deleted.

8 changes: 0 additions & 8 deletions .idea/csfloat_api.iml

This file was deleted.

6 changes: 0 additions & 6 deletions .idea/inspectionProfiles/profiles_settings.xml

This file was deleted.

7 changes: 0 additions & 7 deletions .idea/misc.xml

This file was deleted.

8 changes: 0 additions & 8 deletions .idea/modules.xml

This file was deleted.

6 changes: 0 additions & 6 deletions .idea/vcs.xml

This file was deleted.

58 changes: 43 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,20 +73,48 @@ Failing to close the session may result in warnings about unclosed client sessio

## Core Methods

* `get_exchange_rates()` – Retrieve current exchange rates.
* `get_all_listings(...)` – List items with optional filters (prices in cents).
* `get_specific_listing(listing_id)` – Get detailed info for a specific listing.
* `get_buy_orders(listing_id)` – Retrieve buy orders for a listing.
* `get_my_buy_orders(...)` – List your own buy orders.
* `get_me()` – Fetch authenticated user profile.
* `get_stall(user_id)` – Get a user's stall (listed items).
* `create_listing(asset_id, price, ...)` – Create a new listing (price in cents).
* `create_buy_order(market_hash_name, max_price, quantity)` – Place a buy order.
* `make_offer(listing_id, price)` – Make an offer on a listing.
* `buy_now(total_price, listing_id)` – Instantly buy one or more listings.
* `delete_buy_order(id)` – Cancel an existing buy order.

For a full list of methods and parameters, refer to the library's source code.
### Meta
* `get_exchange_rates()` - Retrieve current exchange rates.
* `get_location()` - Get detected location metadata.

### Account
* `get_me(raw_response=False)` - Fetch authenticated user profile.
* `get_account_standing()` - Retrieve account standing details.
* `get_transactions(page=0, limit=10)` - Get your transaction history.

### Trades and Offers
* `get_pending_trades(limit=500, page=0)` - List pending trades.
* `get_trades(states, limit=500, page=0)` - List trades filtered by state.
* `get_trade_history(role="seller", limit=30, page=0)` - List completed, failed, or cancelled trades.
* `get_offers(limit=40)` - Fetch your offers timeline.
* `accept_sale(trade_ids)` - Accept one or more sales.

### Listings (Browse)
* `get_all_listings(...)` - List items with optional filters (prices in cents).
* `get_specific_listing(listing_id, raw_response=False)` - Get detailed info for a specific listing.
* `get_similar(listing_id, raw_response=False)` - Find listings similar to a given listing.
* `get_sales(market_hash_name, paint_index=None)` - Retrieve historical sales for an item.
* `get_stall(user_id, limit=40, raw_response=False)` - Get a user's stall (listed items).

### Inventory and Watchlist
* `get_inventory()` - Retrieve your inventory.
* `get_watchlist(limit=40)` - Retrieve your watchlist.
* `delete_watchlist(id)` - Remove a listing from your watchlist.

### Listing Management
* `create_listing(asset_id, price, ...)` - Create a new listing (price in cents).
* `update_listing_price(listing_id, price)` - Update a listing price.
* `delete_listing(listing_id)` - Remove an existing listing.
* `make_offer(listing_id, price)` - Make an offer on a listing.
* `buy_now(total_price, listing_id)` - Instantly buy one or more listings.

### Buy Orders
* `get_buy_orders(listing_id, limit=10, raw_response=False)` - Retrieve buy orders for a listing.
* `get_my_buy_orders(page=0, limit=10)` - List your own buy orders.
* `create_buy_order(market_hash_name, max_price, quantity)` - Place a buy order.
* `delete_buy_order(id)` - Cancel an existing buy order.

For detailed parameters and return types, refer to `csfloat_client.py`.

## Proxy Support

Expand Down Expand Up @@ -114,4 +142,4 @@ Contributions are welcome! Please submit issues and pull requests on the [GitHub

## License

This project is licensed under the [MIT License](https://opensource.org/licenses/MIT).
This project is licensed under the [MIT License](https://opensource.org/licenses/MIT).
39 changes: 34 additions & 5 deletions csfloat_client.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import aiohttp
import re
from aiohttp_socks.connector import ProxyConnector
from typing import Iterable, Union, Optional, Dict, List
from typing import Iterable, Union, Optional, Dict, List, Sequence
from .models.listing import Listing
from .models.buy_orders import BuyOrders
from .models.me import Me
Expand Down Expand Up @@ -97,11 +97,13 @@ async def _request(self, method: str, parameters: str, json_data=None) -> Option

return await response.json()

def _validate_category(self, category: int) -> None:
@staticmethod
def _validate_category(category: int) -> None:
if category not in (0, 1, 2, 3):
raise ValueError(f'Unknown category parameter "{category}"')

def _validate_sort_by(self, sort_by: str) -> None:
@staticmethod
def _validate_sort_by(sort_by: str) -> None:
valid_sort_by = (
'lowest_price', 'highest_price', 'most_recent', 'expires_soon',
'lowest_float', 'highest_float', 'best_deal', 'highest_discount',
Expand All @@ -110,15 +112,32 @@ def _validate_sort_by(self, sort_by: str) -> None:
if sort_by not in valid_sort_by:
raise ValueError(f'Unknown sort_by parameter "{sort_by}"')

def _validate_type(self, type_: str) -> None:
@staticmethod
def _validate_type(type_: str) -> None:
if type_ not in ('buy_now', 'auction'):
raise ValueError(f'Unknown type parameter "{type_}"')

def _validate_role(self, role: str) -> None:
@staticmethod
def _validate_role(role: str) -> None:
valid_roles = ("seller", "buyer")
if role not in valid_roles:
raise ValueError(f'Unknown role parameter: {role}')

@staticmethod
def _validate_trade_states(states: Sequence[str]) -> str:
allowed_states = {"queued", "pending", "verified", "failed", "cancelled"}
if isinstance(states, str) or not isinstance(states, Sequence):
raise ValueError("states must be a sequence of trade state strings.")
unique_states = []
for state in states:
if state not in allowed_states:
raise ValueError(f'Unknown trade state "{state}"')
if state not in unique_states:
unique_states.append(state)
if not unique_states:
raise ValueError("states must include at least one trade state.")
return ",".join(unique_states)

async def get_exchange_rates(self) -> Optional[dict]:
parameters = "/meta/exchange-rates"
method = "GET"
Expand Down Expand Up @@ -165,6 +184,16 @@ async def get_pending_trades(
response = await self._request(method=method, parameters=parameters)
return response

async def get_trades(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could potentially remove get_pending_trades(...). What's your take on this?

self, states: Sequence[str], limit: int = 500, page: int = 0
) -> Optional[dict]:
state_param = self._validate_trade_states(states)
parameters = f"/me/trades?state={state_param}&limit={limit}&page={page}"
method = "GET"

response = await self._request(method=method, parameters=parameters)
return response

async def get_similar(
self, *, listing_id: int, raw_response: bool = False
) -> Union[Iterable[Listing], dict]:
Expand Down
1 change: 1 addition & 0 deletions models/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ def low_rank(self) -> Optional[int]:
def stickers(self) -> Optional[List[Sticker]]:
if self._stickers is not None:
return [Sticker(data=sticker) for sticker in self._stickers]
return None

@property
def tradable(self) -> Optional[bool]:
Expand Down
2 changes: 1 addition & 1 deletion models/stall.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List, Dict, Any, Optional
from typing import List, Dict, Any
from .listing import Listing


Expand Down
13 changes: 10 additions & 3 deletions models/stickers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Dict, Any, Optional
from warnings import deprecated


class StickerReference:
Expand Down Expand Up @@ -28,7 +29,7 @@ def updated_at(self) -> Optional[str]:

class Sticker:
__slots__ = (
"_stickerId",
"_sticker_id",
"_slot",
"_wear",
"_offset_x",
Expand All @@ -39,7 +40,7 @@ class Sticker:
)

def __init__(self, *, data: Dict[str, Any]):
self._stickerId = data.get("stickerId")
self._sticker_id = data.get("stickerId")
self._slot = data.get("slot")
self._wear = data.get("wear")
self._offset_x = data.get("offset_x")
Expand All @@ -49,8 +50,13 @@ def __init__(self, *, data: Dict[str, Any]):
self._reference = data.get("reference")

@property
@deprecated("'stickerId' is deprecated; use 'sticker_id' instead.")
def stickerId(self) -> Optional[int]:
return self._stickerId
return self.sticker_id

@property
def sticker_id(self) -> Optional[int]:
return self._sticker_id

@property
def slot(self) -> Optional[int]:
Expand All @@ -72,3 +78,4 @@ def name(self) -> Optional[str]:
def reference(self) -> Optional[StickerReference]:
if self._reference is not None:
return StickerReference(data=self._reference)
return None