polymarket-apis 0.3.0__py3-none-any.whl → 0.3.2__py3-none-any.whl

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 polymarket-apis might be problematic. Click here for more details.

@@ -7,7 +7,9 @@ import httpx
7
7
  from ..types.common import EthAddress, TimeseriesPoint
8
8
  from ..types.data_types import (
9
9
  Activity,
10
+ EventLiveVolume,
10
11
  HolderResponse,
12
+ MarketValue,
11
13
  Position,
12
14
  Trade,
13
15
  UserMetric,
@@ -24,29 +26,40 @@ class PolymarketDataClient:
24
26
  def _build_url(self, endpoint: str) -> str:
25
27
  return urljoin(self.base_url, endpoint)
26
28
 
29
+ def get_ok(self) -> str:
30
+ response = self.client.get(self.base_url)
31
+ response.raise_for_status()
32
+ return response.json()["data"]
33
+
27
34
  def get_positions(
28
- self,
29
- user: str,
30
- condition_id: Optional[Union[str, list[str]]] = None,
31
- size_threshold: float = 1.0,
32
- redeemable: Optional[bool] = None,
33
- mergeable: Optional[bool] = None,
34
- title: Optional[str] = None,
35
- limit: int = 100,
36
- offset: int = 0,
37
- sort_by: Literal[
38
- "TOKENS",
39
- "CURRENT",
40
- "INITIAL",
41
- "CASHPNL",
42
- "PERCENTPNL",
43
- "TITLE",
44
- "RESOLVING",
45
- "PRICE",
46
- ] = "TOKENS",
47
- sort_direction: Literal["ASC", "DESC"] = "DESC",
35
+ self,
36
+ user: EthAddress,
37
+ condition_id: Optional[
38
+ Union[str, list[str]]
39
+ ] = None, # mutually exclusive with event_id
40
+ event_id: Optional[
41
+ Union[int, list[int]]
42
+ ] = None, # mutually exclusive with condition_id
43
+ size_threshold: float = 1.0,
44
+ redeemable: bool = False,
45
+ mergeable: bool = False,
46
+ title: Optional[str] = None,
47
+ limit: int = 100,
48
+ offset: int = 0,
49
+ sort_by: Literal[
50
+ "TOKENS",
51
+ "CURRENT",
52
+ "INITIAL",
53
+ "CASHPNL",
54
+ "PERCENTPNL",
55
+ "TITLE",
56
+ "RESOLVING",
57
+ "PRICE",
58
+ "AVGPRICE",
59
+ ] = "TOKENS",
60
+ sort_direction: Literal["ASC", "DESC"] = "DESC",
48
61
  ) -> list[Position]:
49
- params = {
62
+ params: dict[str, str | list[str] | int | float] = {
50
63
  "user": user,
51
64
  "sizeThreshold": size_threshold,
52
65
  "limit": min(limit, 500),
@@ -56,6 +69,10 @@ class PolymarketDataClient:
56
69
  params["market"] = condition_id
57
70
  if isinstance(condition_id, list):
58
71
  params["market"] = ",".join(condition_id)
72
+ if isinstance(event_id, str):
73
+ params["eventId"] = event_id
74
+ if isinstance(event_id, list):
75
+ params["eventId"] = [str(i) for i in event_id]
59
76
  if redeemable is not None:
60
77
  params["redeemable"] = redeemable
61
78
  if mergeable is not None:
@@ -72,17 +89,20 @@ class PolymarketDataClient:
72
89
  return [Position(**pos) for pos in response.json()]
73
90
 
74
91
  def get_trades(
75
- self,
76
- limit: int = 100,
77
- offset: int = 0,
78
- taker_only: bool = True,
79
- filter_type: Optional[Literal["CASH", "TOKENS"]] = None,
80
- filter_amount: Optional[float] = None,
81
- condition_id: Optional[str] = None,
82
- user: Optional[str] = None,
83
- side: Optional[Literal["BUY", "SELL"]] = None,
92
+ self,
93
+ limit: int = 100,
94
+ offset: int = 0,
95
+ taker_only: bool = True,
96
+ filter_type: Optional[Literal["CASH", "TOKENS"]] = None,
97
+ filter_amount: Optional[
98
+ float
99
+ ] = None, # must be provided together with filter_type
100
+ condition_id: Optional[str | list[str]] = None,
101
+ event_id: Optional[int | list[int]] = None,
102
+ user: Optional[str] = None,
103
+ side: Optional[Literal["BUY", "SELL"]] = None,
84
104
  ) -> list[Trade]:
85
- params = {
105
+ params: dict[str, int | bool | float | str | list[str]] = {
86
106
  "limit": min(limit, 500),
87
107
  "offset": offset,
88
108
  "takerOnly": taker_only,
@@ -91,8 +111,14 @@ class PolymarketDataClient:
91
111
  params["filterType"] = filter_type
92
112
  if filter_amount:
93
113
  params["filterAmount"] = filter_amount
94
- if condition_id:
114
+ if isinstance(condition_id, str):
95
115
  params["market"] = condition_id
116
+ if isinstance(condition_id, list):
117
+ params["market"] = ",".join(condition_id)
118
+ if isinstance(event_id, str):
119
+ params["eventId"] = event_id
120
+ if isinstance(event_id, list):
121
+ params["eventId"] = [str(i) for i in event_id]
96
122
  if user:
97
123
  params["user"] = user
98
124
  if side:
@@ -103,23 +129,39 @@ class PolymarketDataClient:
103
129
  return [Trade(**trade) for trade in response.json()]
104
130
 
105
131
  def get_activity(
106
- self,
107
- user: str,
108
- limit: int = 100,
109
- offset: int = 0,
110
- condition_id: Optional[Union[str, list[str]]] = None,
111
- type: Optional[Union[Literal["TRADE", "SPLIT", "MERGE", "REDEEM", "REWARD", "CONVERSION"], list[Literal["TRADE", "SPLIT", "MERGE", "REDEEM", "REWARD", "CONVERSION"]]]] = None,
112
- start: Optional[datetime] = None,
113
- end: Optional[datetime] = None,
114
- side: Optional[Literal["BUY", "SELL"]] = None,
115
- sort_by: Literal["TIMESTAMP", "TOKENS", "CASH"] = "TIMESTAMP",
116
- sort_direction: Literal["ASC", "DESC"] = "DESC",
132
+ self,
133
+ user: EthAddress,
134
+ limit: int = 100,
135
+ offset: int = 0,
136
+ condition_id: Optional[Union[str, list[str]]] = None,
137
+ event_id: Optional[Union[int, list[int]]] = None,
138
+ type: Optional[
139
+ Union[
140
+ Literal["TRADE", "SPLIT", "MERGE", "REDEEM", "REWARD", "CONVERSION"],
141
+ list[
142
+ Literal["TRADE", "SPLIT", "MERGE", "REDEEM", "REWARD", "CONVERSION"]
143
+ ],
144
+ ]
145
+ ] = None,
146
+ start: Optional[datetime] = None,
147
+ end: Optional[datetime] = None,
148
+ side: Optional[Literal["BUY", "SELL"]] = None,
149
+ sort_by: Literal["TIMESTAMP", "TOKENS", "CASH"] = "TIMESTAMP",
150
+ sort_direction: Literal["ASC", "DESC"] = "DESC",
117
151
  ) -> list[Activity]:
118
- params = {"user": user, "limit": min(limit, 500), "offset": offset}
152
+ params: dict[str, str | list[str] | int] = {
153
+ "user": user,
154
+ "limit": min(limit, 500),
155
+ "offset": offset,
156
+ }
119
157
  if isinstance(condition_id, str):
120
158
  params["market"] = condition_id
121
159
  if isinstance(condition_id, list):
122
160
  params["market"] = ",".join(condition_id)
161
+ if isinstance(event_id, str):
162
+ params["eventId"] = event_id
163
+ if isinstance(event_id, list):
164
+ params["eventId"] = [str(i) for i in event_id]
123
165
  if isinstance(type, str):
124
166
  params["type"] = type
125
167
  if isinstance(type, list):
@@ -140,22 +182,21 @@ class PolymarketDataClient:
140
182
  return [Activity(**activity) for activity in response.json()]
141
183
 
142
184
  def get_holders(
143
- self,
144
- condition_id: str,
145
- limit: int = 20,
185
+ self,
186
+ condition_id: str,
187
+ limit: int = 500,
188
+ min_balance: int = 1,
146
189
  ) -> list[HolderResponse]:
147
- """Takes in a condition_id and returns a list of at most 20 top holders for each corresponding token_id."""
148
- params = {"market": condition_id, "limit": limit}
190
+ """Takes in a condition_id and returns top holders for each corresponding token_id."""
191
+ params = {"market": condition_id, "limit": limit, "min_balance": min_balance}
149
192
  response = self.client.get(self._build_url("/holders"), params=params)
150
193
  response.raise_for_status()
151
- return [
152
- HolderResponse(**holder_data) for holder_data in response.json()
153
- ]
194
+ return [HolderResponse(**holder_data) for holder_data in response.json()]
154
195
 
155
196
  def get_value(
156
- self,
157
- user: str,
158
- condition_ids: Optional[Union[str, list[str]]] = None,
197
+ self,
198
+ user: EthAddress,
199
+ condition_ids: Optional[Union[str, list[str]]] = None,
159
200
  ) -> ValueResponse:
160
201
  """
161
202
  Get the current value of a user's position in a set of markets.
@@ -175,13 +216,67 @@ class PolymarketDataClient:
175
216
  response.raise_for_status()
176
217
  return ValueResponse(**response.json()[0])
177
218
 
219
+ def get_closed_positions(
220
+ self,
221
+ user: EthAddress,
222
+ condition_ids: Optional[Union[str, list[str]]] = None,
223
+ ) -> list[Position]:
224
+ """Get all closed positions."""
225
+ params = {"user": user}
226
+ if isinstance(condition_ids, str):
227
+ params["market"] = condition_ids
228
+ if isinstance(condition_ids, list):
229
+ params["market"] = ",".join(condition_ids)
230
+
231
+ response = self.client.get(self._build_url("/closed-positions"), params=params)
232
+ response.raise_for_status()
233
+ return [Position(**pos) for pos in response.json()]
234
+
235
+ def get_total_markets_traded(
236
+ self,
237
+ user: EthAddress,
238
+ ) -> int:
239
+ """Get the total number of markets a user has traded in."""
240
+ params = {"user": user}
241
+
242
+ response = self.client.get(self._build_url("/traded"), params=params)
243
+ response.raise_for_status()
244
+ return response.json()["traded"]
245
+
246
+ def get_open_interest(
247
+ self,
248
+ condition_ids: Optional[Union[str, list[str]]] = None,
249
+ ) -> list[MarketValue]:
250
+ """Get open interest."""
251
+ params = {}
252
+
253
+ if isinstance(condition_ids, str):
254
+ params["market"] = condition_ids
255
+ if isinstance(condition_ids, list):
256
+ params["market"] = ",".join(condition_ids)
257
+
258
+ response = self.client.get(self._build_url("/oi"), params=params)
259
+ response.raise_for_status()
260
+ return [MarketValue(**oi) for oi in response.json()]
261
+
262
+ def get_live_volume(
263
+ self,
264
+ event_id: int,
265
+ ) -> EventLiveVolume:
266
+ """Get live volume for a given event."""
267
+ params = {"id": str(event_id)}
268
+
269
+ response = self.client.get(self._build_url("/live-volume"), params=params)
270
+ response.raise_for_status()
271
+ return EventLiveVolume(**response.json()[0])
272
+
178
273
  # website endpoints
179
274
 
180
275
  def get_pnl(
181
- self,
182
- user: EthAddress,
183
- period: Literal["all", "1m", "1w", "1d"] = "all",
184
- frequency: Literal["1h", "3h", "12h", "1d"] = "1h",
276
+ self,
277
+ user: EthAddress,
278
+ period: Literal["all", "1m", "1w", "1d"] = "all",
279
+ frequency: Literal["1h", "3h", "12h", "1d"] = "1h",
185
280
  ) -> list[TimeseriesPoint]:
186
281
  """Get a user's PnL timeseries in the last day, week, month or all with a given frequency."""
187
282
  params = {
@@ -190,22 +285,36 @@ class PolymarketDataClient:
190
285
  "fidelity": frequency,
191
286
  }
192
287
 
193
- response = self.client.get("https://user-pnl-api.polymarket.com/user-pnl", params=params)
288
+ response = self.client.get(
289
+ "https://user-pnl-api.polymarket.com/user-pnl", params=params
290
+ )
194
291
  response.raise_for_status()
195
292
  return [TimeseriesPoint(**point) for point in response.json()]
196
293
 
197
- def get_user_metric(self, user: EthAddress, metric: Literal["profit", "volume"] = "profit", window: Literal["1d", "7d", "30d", "all"] = "all"):
294
+ def get_user_metric(
295
+ self,
296
+ user: EthAddress,
297
+ metric: Literal["profit", "volume"] = "profit",
298
+ window: Literal["1d", "7d", "30d", "all"] = "all",
299
+ ):
198
300
  """Get a user's overall profit or volume in the last day, week, month or all."""
199
301
  params = {
200
302
  "address": user,
201
303
  "window": window,
202
304
  "limit": 1,
203
305
  }
204
- response = self.client.get("https://lb-api.polymarket.com/" + metric, params=params)
306
+ response = self.client.get(
307
+ "https://lb-api.polymarket.com/" + metric, params=params
308
+ )
205
309
  response.raise_for_status()
206
310
  return UserMetric(**response.json()[0])
207
311
 
208
- def get_leaderboard_user_rank(self, user: EthAddress, metric: Literal["profit", "volume"] = "profit", window: Literal["1d", "7d", "30d", "all"] = "all"):
312
+ def get_leaderboard_user_rank(
313
+ self,
314
+ user: EthAddress,
315
+ metric: Literal["profit", "volume"] = "profit",
316
+ window: Literal["1d", "7d", "30d", "all"] = "all",
317
+ ):
209
318
  """Get a user's rank on the leaderboard by profit or volume."""
210
319
  params = {
211
320
  "address": user,
@@ -216,17 +325,23 @@ class PolymarketDataClient:
216
325
  response.raise_for_status()
217
326
  return UserRank(**response.json()[0])
218
327
 
219
- def get_leaderboard_top_users(self, metric: Literal["profit", "volume"] = "profit", window: Literal["1d", "7d", "30d", "all"] = "all", limit: int = 100):
328
+ def get_leaderboard_top_users(
329
+ self,
330
+ metric: Literal["profit", "volume"] = "profit",
331
+ window: Literal["1d", "7d", "30d", "all"] = "all",
332
+ limit: int = 100,
333
+ ):
220
334
  """Get the leaderboard of the top at most 100 users by profit or volume."""
221
335
  params = {
222
336
  "window": window,
223
337
  "limit": limit,
224
338
  }
225
- response = self.client.get("https://lb-api.polymarket.com/" + metric, params=params)
339
+ response = self.client.get(
340
+ "https://lb-api.polymarket.com/" + metric, params=params
341
+ )
226
342
  response.raise_for_status()
227
343
  return [UserMetric(**user) for user in response.json()]
228
344
 
229
-
230
345
  def __enter__(self):
231
346
  return self
232
347