pmxt 1.3.2__py3-none-any.whl → 1.3.4__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.
pmxt/__init__.py CHANGED
@@ -33,7 +33,7 @@ from .models import (
33
33
  CreateOrderParams,
34
34
  )
35
35
 
36
- __version__ = "1.3.2"
36
+ __version__ = "1.3.4"
37
37
  __all__ = [
38
38
  # Exchanges
39
39
  "Polymarket",
pmxt/client.py CHANGED
@@ -23,6 +23,7 @@ from pmxt_internal import models as internal_models
23
23
 
24
24
  from .models import (
25
25
  UnifiedMarket,
26
+ UnifiedEvent,
26
27
  MarketOutcome,
27
28
  PriceCandle,
28
29
  OrderBook,
@@ -74,6 +75,23 @@ def _convert_market(raw: Dict[str, Any]) -> UnifiedMarket:
74
75
  )
75
76
 
76
77
 
78
+ def _convert_event(raw: Dict[str, Any]) -> UnifiedEvent:
79
+ """Convert raw API response to UnifiedEvent."""
80
+ markets = [_convert_market(m) for m in raw.get("markets", [])]
81
+
82
+ return UnifiedEvent(
83
+ id=raw.get("id"),
84
+ title=raw.get("title"),
85
+ description=raw.get("description"),
86
+ slug=raw.get("slug"),
87
+ markets=markets,
88
+ url=raw.get("url"),
89
+ image=raw.get("image"),
90
+ category=raw.get("category"),
91
+ tags=raw.get("tags"),
92
+ )
93
+
94
+
77
95
  def _convert_candle(raw: Dict[str, Any]) -> PriceCandle:
78
96
  """Convert raw API response to PriceCandle."""
79
97
  return PriceCandle(
@@ -220,6 +238,8 @@ class Exchange(ABC):
220
238
  """Handle API response and extract data."""
221
239
  if not response.get("success"):
222
240
  error = response.get("error", {})
241
+ if isinstance(error, str):
242
+ raise Exception(error)
223
243
  raise Exception(error.get("message", "Unknown error"))
224
244
  return response.get("data")
225
245
 
@@ -307,6 +327,61 @@ class Exchange(ABC):
307
327
  return [_convert_market(m) for m in data]
308
328
  except ApiException as e:
309
329
  raise Exception(f"Failed to search markets: {e}")
330
+
331
+ def search_events(
332
+ self,
333
+ query: str,
334
+ params: Optional[MarketFilterParams] = None,
335
+ ) -> List[UnifiedEvent]:
336
+ """
337
+ Search events (groups of related markets) by keyword.
338
+
339
+ Args:
340
+ query: Search query
341
+ params: Optional filter parameters
342
+
343
+ Returns:
344
+ List of matching events
345
+
346
+ Example:
347
+ >>> events = exchange.search_events("Trump")
348
+ """
349
+ try:
350
+ # Manual implementation since generated client is missing this
351
+ params_dict = params.__dict__ if params else None
352
+
353
+ args = [query]
354
+ if params_dict:
355
+ args.append(params_dict)
356
+
357
+ body = {"args": args}
358
+
359
+ # Add credentials if available
360
+ creds = self._get_credentials_dict()
361
+ if creds:
362
+ body["credentials"] = creds
363
+
364
+ # Use raw api_client since generated method is missing
365
+ url = f"{self._api_client.configuration.host}/api/{self.exchange_name}/searchEvents"
366
+
367
+ headers = {"Content-Type": "application/json", "Accept": "application/json"}
368
+ headers.update(self._api_client.default_headers)
369
+
370
+ response = self._api_client.call_api(
371
+ method="POST",
372
+ url=url,
373
+ body=body,
374
+ header_params=headers
375
+ )
376
+
377
+ response.read()
378
+ import json
379
+ data_json = json.loads(response.data)
380
+
381
+ data = self._handle_response(data_json)
382
+ return [_convert_event(e) for e in data]
383
+ except Exception as e:
384
+ raise Exception(f"Failed to search events: {e}")
310
385
 
311
386
  def get_markets_by_slug(self, slug: str) -> List[UnifiedMarket]:
312
387
  """
pmxt/models.py CHANGED
@@ -9,6 +9,14 @@ from datetime import datetime
9
9
  from dataclasses import dataclass
10
10
 
11
11
 
12
+ # Parameter types
13
+ CandleInterval = Literal["1m", "5m", "15m", "1h", "6h", "1d"]
14
+ SortOption = Literal["volume", "liquidity", "newest"]
15
+ SearchIn = Literal["title", "description", "both"]
16
+ OrderSide = Literal["buy", "sell"]
17
+ OrderType = Literal["market", "limit"]
18
+
19
+
12
20
  @dataclass
13
21
  class MarketOutcome:
14
22
  """A single tradeable outcome within a market."""
@@ -87,6 +95,11 @@ class UnifiedMarket:
87
95
  down: Optional[MarketOutcome] = None
88
96
  """Convenience access to the Down outcome for binary markets."""
89
97
 
98
+ @property
99
+ def question(self) -> str:
100
+ """Alias for title."""
101
+ return self.title
102
+
90
103
 
91
104
  @dataclass
92
105
  class PriceCandle:
@@ -111,6 +124,74 @@ class PriceCandle:
111
124
  """Trading volume"""
112
125
 
113
126
 
127
+ @dataclass
128
+ class UnifiedEvent:
129
+ """A grouped collection of related markets."""
130
+
131
+ id: str
132
+ """Event ID"""
133
+
134
+ title: str
135
+ """Event title"""
136
+
137
+ description: str
138
+ """Event description"""
139
+
140
+ slug: str
141
+ """Event slug"""
142
+
143
+ markets: List[UnifiedMarket]
144
+ """Related markets in this event"""
145
+
146
+ url: str
147
+ """Event URL"""
148
+
149
+ image: Optional[str] = None
150
+ """Event image URL"""
151
+
152
+ category: Optional[str] = None
153
+ """Event category"""
154
+
155
+ tags: Optional[List[str]] = None
156
+ """Event tags"""
157
+
158
+ def search_markets(self, query: str, search_in: SearchIn = "both") -> List[UnifiedMarket]:
159
+ """
160
+ Search for markets within this event by keyword.
161
+
162
+ Args:
163
+ query: Search query (case-insensitive)
164
+ search_in: Where to search - "title", "description", or "both"
165
+
166
+ Returns:
167
+ List of matching markets
168
+
169
+ Example:
170
+ >>> events = api.search_events('Fed Chair')
171
+ >>> event = events[0]
172
+ >>> warsh_markets = event.search_markets('Kevin Warsh')
173
+ """
174
+ query_lower = query.lower()
175
+ results = []
176
+
177
+ for market in self.markets:
178
+ match = False
179
+
180
+ if search_in in ("title", "both"):
181
+ if query_lower in market.title.lower():
182
+ match = True
183
+
184
+ if search_in in ("description", "both") and market.description:
185
+ if query_lower in market.description.lower():
186
+ match = True
187
+
188
+ if match:
189
+ results.append(market)
190
+
191
+ return results
192
+
193
+
194
+
114
195
  @dataclass
115
196
  class OrderLevel:
116
197
  """A single price level in the order book."""
@@ -243,12 +324,6 @@ class Balance:
243
324
  """Locked in open orders"""
244
325
 
245
326
 
246
- # Parameter types
247
- CandleInterval = Literal["1m", "5m", "15m", "1h", "6h", "1d"]
248
- SortOption = Literal["volume", "liquidity", "newest"]
249
- SearchIn = Literal["title", "description", "both"]
250
- OrderSide = Literal["buy", "sell"]
251
- OrderType = Literal["market", "limit"]
252
327
 
253
328
 
254
329
  @dataclass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pmxt
3
- Version: 1.3.2
3
+ Version: 1.3.4
4
4
  Summary: Unified prediction market data API - The ccxt for prediction markets
5
5
  Author: PMXT Contributors
6
6
  License: MIT
@@ -1,14 +1,14 @@
1
- pmxt/__init__.py,sha256=60Edb9QkU4g2o9-42-vm3Rw3Md1QocdXIultWAK8jfs,1150
2
- pmxt/client.py,sha256=pTU7MYP_k0lj-0eJifbHVcpGQVn5U7MTTDisKbv3fVI,27755
3
- pmxt/models.py,sha256=ZqRu__L8jnhZOYjE_Zy20dpft177Jb4lOZIkvBwuorg,6438
1
+ pmxt/__init__.py,sha256=QUyTYIHTeamwGXyGf7_d-7UM91n-trP78TgmiooWQjA,1150
2
+ pmxt/client.py,sha256=YytS9Y1CD8A2NihUxedpmojH830eWE32v4-hbMsA4a8,30175
3
+ pmxt/models.py,sha256=6ku911tJoT1ItglYWHmg_OfvDmCPEvFXWDL562wCBIs,8259
4
4
  pmxt/server_manager.py,sha256=-G97dYEdKl7F3HK9bAOKYl-SGWP6HsvzZIx2QxiZm24,11494
5
5
  pmxt/_server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  pmxt/_server/bin/pmxt-ensure-server,sha256=kXIond0UbxS52FAVQD7kHmSBaL_s6cbIyapLRr4KZJw,4544
7
7
  pmxt/_server/server/bundled.js,sha256=KxMsOJdiw5D2ynSJGFUCeojDlA-w7Eu6ldlgDoeApp4,4196247
8
- pmxt_internal/__init__.py,sha256=TWRGUrnPnE5eJ05s9XyoeK6NaRsuv-KgfXAIRLSH438,6762
9
- pmxt_internal/api_client.py,sha256=hMQILzoVpEZAYaD01o0bVxE3pIcb0thRCW4ZWS-hLI8,27889
8
+ pmxt_internal/__init__.py,sha256=rTbculzYsP3ZAsVNJckX_iFXMNdLU3eETpPLcR-Y6Is,6762
9
+ pmxt_internal/api_client.py,sha256=7tnxPGfTzVx9xEneYQMVhZFCix6NMoR2NKHa1gkbeQk,27889
10
10
  pmxt_internal/api_response.py,sha256=eMxw1mpmJcoGZ3gs9z6jM4oYoZ10Gjk333s9sKxGv7s,652
11
- pmxt_internal/configuration.py,sha256=4oqyzwcK-xUvZo4SJx59CadQLQcgs8-jgAFiPG7IGlI,18320
11
+ pmxt_internal/configuration.py,sha256=sqCSSQUykt5E1s7EEI1gr-NYzCzKBtiei3cJXUVqnDs,18320
12
12
  pmxt_internal/exceptions.py,sha256=txF8A7vlan57JS69kFPs-IZF-Qhp7IZobBTJVa4fOaM,6644
13
13
  pmxt_internal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  pmxt_internal/rest.py,sha256=FMj4yaV6XLr842u_ScWHSzQsTFdk0jaUeuWLJoRbogQ,9760
@@ -59,7 +59,7 @@ pmxt_internal/models/unified_market.py,sha256=DoYhiH4HycYGlq858PEeB-CIA7haT6rxmJ
59
59
  pmxt_internal/models/watch_order_book_request.py,sha256=kavGUI-SLz2-Kam_jcJ_h0GDe0-9UkxqCmVsAi6Uios,3726
60
60
  pmxt_internal/models/watch_order_book_request_args_inner.py,sha256=ZHrjmFDGxRG5MXbuz4mUp9KFfo3XS7zuXWTyMNgi4xI,5464
61
61
  pmxt_internal/models/watch_trades_request.py,sha256=brrg8JbEe-aeg7mIe_Y2HzRPogp-IfRhkXChrxzqoLU,3722
62
- pmxt-1.3.2.dist-info/METADATA,sha256=6PvfHTMQafjJLsKC8v3ykslGwgJ6432t6_FVwV84O9w,6288
63
- pmxt-1.3.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
64
- pmxt-1.3.2.dist-info/top_level.txt,sha256=J_jrcouJ-x-5lpcXMxeW0GOSi1HsBVR5_PdSfvigVrw,19
65
- pmxt-1.3.2.dist-info/RECORD,,
62
+ pmxt-1.3.4.dist-info/METADATA,sha256=Xp9QzK2hMi2HUFkBrflPTR88Do9Q_GLNd4QPLwHaNxE,6288
63
+ pmxt-1.3.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
64
+ pmxt-1.3.4.dist-info/top_level.txt,sha256=J_jrcouJ-x-5lpcXMxeW0GOSi1HsBVR5_PdSfvigVrw,19
65
+ pmxt-1.3.4.dist-info/RECORD,,
pmxt_internal/__init__.py CHANGED
@@ -14,7 +14,7 @@
14
14
  """ # noqa: E501
15
15
 
16
16
 
17
- __version__ = "1.3.2"
17
+ __version__ = "1.3.4"
18
18
 
19
19
  # Define package exports
20
20
  __all__ = [
@@ -91,7 +91,7 @@ class ApiClient:
91
91
  self.default_headers[header_name] = header_value
92
92
  self.cookie = cookie
93
93
  # Set default User-Agent.
94
- self.user_agent = 'OpenAPI-Generator/1.3.2/python'
94
+ self.user_agent = 'OpenAPI-Generator/1.3.4/python'
95
95
  self.client_side_validation = configuration.client_side_validation
96
96
 
97
97
  def __enter__(self):
@@ -506,7 +506,7 @@ class Configuration:
506
506
  "OS: {env}\n"\
507
507
  "Python Version: {pyversion}\n"\
508
508
  "Version of the API: 0.4.4\n"\
509
- "SDK Package Version: 1.3.2".\
509
+ "SDK Package Version: 1.3.4".\
510
510
  format(env=sys.platform, pyversion=sys.version)
511
511
 
512
512
  def get_host_settings(self) -> List[HostSetting]:
File without changes