problee 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.
problee-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Problee
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.
problee-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,209 @@
1
+ Metadata-Version: 2.1
2
+ Name: problee
3
+ Version: 0.1.0
4
+ Summary: Official Python SDK for the Problee prediction market API
5
+ Author-email: Problee <dev@problee.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://problee.com
8
+ Project-URL: Documentation, https://docs.problee.com
9
+ Project-URL: Repository, https://github.com/problee/problee-python
10
+ Project-URL: Changelog, https://github.com/problee/problee-python/blob/main/CHANGELOG.md
11
+ Keywords: problee,prediction-market,api,sdk,trading,world-chain
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.8
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.8
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: requests>=2.28.0
27
+ Provides-Extra: websocket
28
+ Requires-Dist: websockets>=10.0; extra == "websocket"
29
+ Provides-Extra: all
30
+ Requires-Dist: websockets>=10.0; extra == "all"
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=7.0; extra == "dev"
33
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
34
+ Requires-Dist: mypy>=1.0; extra == "dev"
35
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
36
+ Requires-Dist: responses>=0.23.0; extra == "dev"
37
+
38
+ # Problee Python SDK
39
+
40
+ Official Python SDK for the Problee prediction market API.
41
+
42
+ ## Installation
43
+
44
+ ```bash
45
+ pip install problee
46
+ ```
47
+
48
+ For WebSocket support:
49
+
50
+ ```bash
51
+ pip install problee[websocket]
52
+ ```
53
+
54
+ ## Quick Start
55
+
56
+ ```python
57
+ from problee import ProbClient
58
+
59
+ # Initialize client with your API key
60
+ client = ProbClient(api_key="pk_live_...")
61
+
62
+ # List open markets
63
+ markets = client.markets.list(status="open")
64
+ for market in markets.markets:
65
+ print(f"{market.question}")
66
+ print(f" YES: {market.prices.yes:.2%}")
67
+ print(f" NO: {market.prices.no:.2%}")
68
+ ```
69
+
70
+ ## Features
71
+
72
+ - **Markets API**: List, filter, and get market details
73
+ - **Positions API**: Check wallet positions
74
+ - **Quotes API**: Get trade quotes and build transactions
75
+ - **SSE Streaming**: Real-time price updates via Server-Sent Events
76
+ - **WebSocket**: Real-time market updates via WebSocket
77
+
78
+ ## Usage Examples
79
+
80
+ ### List Markets
81
+
82
+ ```python
83
+ # List all open markets
84
+ markets = client.markets.list(status="open")
85
+
86
+ # Filter by category
87
+ crypto_markets = client.markets.list(category="crypto")
88
+
89
+ # Sort by volume
90
+ trending = client.markets.list(sort="volume_24h")
91
+ ```
92
+
93
+ ### Get Market Details
94
+
95
+ ```python
96
+ # Get single market
97
+ market = client.markets.get("0x1234...")
98
+ print(f"Question: {market.question}")
99
+ print(f"Status: {market.status}")
100
+ print(f"YES Price: {market.prices.yes}")
101
+
102
+ # Get price history
103
+ history = client.markets.get_history("0x1234...", interval="1h")
104
+
105
+ # Get recent trades
106
+ trades = client.markets.get_trades("0x1234...", limit=50)
107
+ ```
108
+
109
+ ### Get Quote
110
+
111
+ ```python
112
+ # Get quote to buy YES shares
113
+ quote = client.quotes.get(
114
+ market_id="0x1234...",
115
+ side="buy",
116
+ outcome="yes",
117
+ amount="1000000000000000000", # 1 USDC in wei
118
+ )
119
+
120
+ print(f"Price: {quote.price:.4f}")
121
+ print(f"Shares: {quote.shares_out}")
122
+ print(f"Price Impact: {quote.price_impact:.2%}")
123
+ print(f"Quote ID: {quote.quote_id}")
124
+ ```
125
+
126
+ ### Check Positions
127
+
128
+ ```python
129
+ # Get all positions for a wallet
130
+ positions = client.positions.list("0xYourWallet...")
131
+ for pos in positions.positions:
132
+ print(f"Market: {pos.market_address}")
133
+ print(f"YES Shares: {pos.yes_shares}")
134
+ print(f"NO Shares: {pos.no_shares}")
135
+ ```
136
+
137
+ ### Stream Prices (SSE)
138
+
139
+ ```python
140
+ # Stream real-time price updates
141
+ for update in client.stream.prices():
142
+ if update.event_type == "price":
143
+ print(f"Price: YES={update.data['yes']}, NO={update.data['no']}")
144
+ elif update.event_type == "tokenPrice":
145
+ print(f"Token: {update.data['symbol']} = ${update.data['price']}")
146
+ ```
147
+
148
+ ### WebSocket Streaming
149
+
150
+ ```python
151
+ import asyncio
152
+
153
+ async def stream_updates():
154
+ async with client.ws.connect() as ws:
155
+ # Subscribe to market updates
156
+ await ws.subscribe("market", "0x1234...")
157
+
158
+ async for msg in ws:
159
+ if msg.type == "price_update":
160
+ print(f"Price: {msg.data['prices']}")
161
+ elif msg.type == "trade":
162
+ print(f"Trade: {msg.data}")
163
+
164
+ asyncio.run(stream_updates())
165
+ ```
166
+
167
+ ## Error Handling
168
+
169
+ ```python
170
+ from problee import ProbClient
171
+ from problee.exceptions import (
172
+ AuthenticationError,
173
+ RateLimitError,
174
+ NotFoundError,
175
+ ValidationError,
176
+ )
177
+
178
+ client = ProbClient(api_key="pk_live_...")
179
+
180
+ try:
181
+ market = client.markets.get("0xinvalid")
182
+ except NotFoundError:
183
+ print("Market not found")
184
+ except AuthenticationError:
185
+ print("Invalid API key")
186
+ except RateLimitError as e:
187
+ print(f"Rate limited. Retry after {e.retry_after} seconds")
188
+ except ValidationError as e:
189
+ print(f"Invalid request: {e.errors}")
190
+ ```
191
+
192
+ ## Builder Attribution
193
+
194
+ If you're building an app on Problee, you can include your builder ID:
195
+
196
+ ```python
197
+ client = ProbClient(
198
+ api_key="pk_live_...",
199
+ builder_id="your-builder-id",
200
+ )
201
+ ```
202
+
203
+ ## API Documentation
204
+
205
+ For full API documentation, visit: https://docs.problee.com
206
+
207
+ ## License
208
+
209
+ MIT License - see LICENSE file for details.
@@ -0,0 +1,172 @@
1
+ # Problee Python SDK
2
+
3
+ Official Python SDK for the Problee prediction market API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install problee
9
+ ```
10
+
11
+ For WebSocket support:
12
+
13
+ ```bash
14
+ pip install problee[websocket]
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```python
20
+ from problee import ProbClient
21
+
22
+ # Initialize client with your API key
23
+ client = ProbClient(api_key="pk_live_...")
24
+
25
+ # List open markets
26
+ markets = client.markets.list(status="open")
27
+ for market in markets.markets:
28
+ print(f"{market.question}")
29
+ print(f" YES: {market.prices.yes:.2%}")
30
+ print(f" NO: {market.prices.no:.2%}")
31
+ ```
32
+
33
+ ## Features
34
+
35
+ - **Markets API**: List, filter, and get market details
36
+ - **Positions API**: Check wallet positions
37
+ - **Quotes API**: Get trade quotes and build transactions
38
+ - **SSE Streaming**: Real-time price updates via Server-Sent Events
39
+ - **WebSocket**: Real-time market updates via WebSocket
40
+
41
+ ## Usage Examples
42
+
43
+ ### List Markets
44
+
45
+ ```python
46
+ # List all open markets
47
+ markets = client.markets.list(status="open")
48
+
49
+ # Filter by category
50
+ crypto_markets = client.markets.list(category="crypto")
51
+
52
+ # Sort by volume
53
+ trending = client.markets.list(sort="volume_24h")
54
+ ```
55
+
56
+ ### Get Market Details
57
+
58
+ ```python
59
+ # Get single market
60
+ market = client.markets.get("0x1234...")
61
+ print(f"Question: {market.question}")
62
+ print(f"Status: {market.status}")
63
+ print(f"YES Price: {market.prices.yes}")
64
+
65
+ # Get price history
66
+ history = client.markets.get_history("0x1234...", interval="1h")
67
+
68
+ # Get recent trades
69
+ trades = client.markets.get_trades("0x1234...", limit=50)
70
+ ```
71
+
72
+ ### Get Quote
73
+
74
+ ```python
75
+ # Get quote to buy YES shares
76
+ quote = client.quotes.get(
77
+ market_id="0x1234...",
78
+ side="buy",
79
+ outcome="yes",
80
+ amount="1000000000000000000", # 1 USDC in wei
81
+ )
82
+
83
+ print(f"Price: {quote.price:.4f}")
84
+ print(f"Shares: {quote.shares_out}")
85
+ print(f"Price Impact: {quote.price_impact:.2%}")
86
+ print(f"Quote ID: {quote.quote_id}")
87
+ ```
88
+
89
+ ### Check Positions
90
+
91
+ ```python
92
+ # Get all positions for a wallet
93
+ positions = client.positions.list("0xYourWallet...")
94
+ for pos in positions.positions:
95
+ print(f"Market: {pos.market_address}")
96
+ print(f"YES Shares: {pos.yes_shares}")
97
+ print(f"NO Shares: {pos.no_shares}")
98
+ ```
99
+
100
+ ### Stream Prices (SSE)
101
+
102
+ ```python
103
+ # Stream real-time price updates
104
+ for update in client.stream.prices():
105
+ if update.event_type == "price":
106
+ print(f"Price: YES={update.data['yes']}, NO={update.data['no']}")
107
+ elif update.event_type == "tokenPrice":
108
+ print(f"Token: {update.data['symbol']} = ${update.data['price']}")
109
+ ```
110
+
111
+ ### WebSocket Streaming
112
+
113
+ ```python
114
+ import asyncio
115
+
116
+ async def stream_updates():
117
+ async with client.ws.connect() as ws:
118
+ # Subscribe to market updates
119
+ await ws.subscribe("market", "0x1234...")
120
+
121
+ async for msg in ws:
122
+ if msg.type == "price_update":
123
+ print(f"Price: {msg.data['prices']}")
124
+ elif msg.type == "trade":
125
+ print(f"Trade: {msg.data}")
126
+
127
+ asyncio.run(stream_updates())
128
+ ```
129
+
130
+ ## Error Handling
131
+
132
+ ```python
133
+ from problee import ProbClient
134
+ from problee.exceptions import (
135
+ AuthenticationError,
136
+ RateLimitError,
137
+ NotFoundError,
138
+ ValidationError,
139
+ )
140
+
141
+ client = ProbClient(api_key="pk_live_...")
142
+
143
+ try:
144
+ market = client.markets.get("0xinvalid")
145
+ except NotFoundError:
146
+ print("Market not found")
147
+ except AuthenticationError:
148
+ print("Invalid API key")
149
+ except RateLimitError as e:
150
+ print(f"Rate limited. Retry after {e.retry_after} seconds")
151
+ except ValidationError as e:
152
+ print(f"Invalid request: {e.errors}")
153
+ ```
154
+
155
+ ## Builder Attribution
156
+
157
+ If you're building an app on Problee, you can include your builder ID:
158
+
159
+ ```python
160
+ client = ProbClient(
161
+ api_key="pk_live_...",
162
+ builder_id="your-builder-id",
163
+ )
164
+ ```
165
+
166
+ ## API Documentation
167
+
168
+ For full API documentation, visit: https://docs.problee.com
169
+
170
+ ## License
171
+
172
+ MIT License - see LICENSE file for details.
@@ -0,0 +1,35 @@
1
+ """
2
+ Problee Python SDK
3
+
4
+ Official Python client for the Problee prediction market API.
5
+ """
6
+
7
+ __version__ = "0.1.0"
8
+
9
+ from .client import ProbClient
10
+ from .models.market import Market, MarketStatus, MarketCategory
11
+ from .models.position import Position
12
+ from .models.quote import Quote
13
+ from .exceptions import (
14
+ ProbError,
15
+ AuthenticationError,
16
+ RateLimitError,
17
+ NotFoundError,
18
+ ValidationError,
19
+ APIError,
20
+ )
21
+
22
+ __all__ = [
23
+ "ProbClient",
24
+ "Market",
25
+ "MarketStatus",
26
+ "MarketCategory",
27
+ "Position",
28
+ "Quote",
29
+ "ProbError",
30
+ "AuthenticationError",
31
+ "RateLimitError",
32
+ "NotFoundError",
33
+ "ValidationError",
34
+ "APIError",
35
+ ]
@@ -0,0 +1,13 @@
1
+ """
2
+ Problee API Modules
3
+ """
4
+
5
+ from .markets import MarketsAPI
6
+ from .positions import PositionsAPI
7
+ from .quotes import QuotesAPI
8
+
9
+ __all__ = [
10
+ "MarketsAPI",
11
+ "PositionsAPI",
12
+ "QuotesAPI",
13
+ ]
@@ -0,0 +1,119 @@
1
+ """
2
+ Markets API
3
+ """
4
+
5
+ from typing import Optional, List, TYPE_CHECKING
6
+ from ..models.market import Market, MarketListResponse, MarketStatus, MarketCategory
7
+
8
+ if TYPE_CHECKING:
9
+ from ..client import ProbClient
10
+
11
+
12
+ class MarketsAPI:
13
+ """Markets API methods."""
14
+
15
+ def __init__(self, client: "ProbClient"):
16
+ self._client = client
17
+
18
+ def list(
19
+ self,
20
+ status: Optional[str] = None,
21
+ category: Optional[str] = None,
22
+ sort: Optional[str] = None,
23
+ limit: int = 20,
24
+ cursor: Optional[str] = None,
25
+ ) -> MarketListResponse:
26
+ """
27
+ List markets with optional filters.
28
+
29
+ Args:
30
+ status: Filter by status (open, closed, resolved)
31
+ category: Filter by category (sports, politics, crypto, entertainment, other)
32
+ sort: Sort order (new, trending, volume_24h, closing_soon)
33
+ limit: Max results per page (default 20, max 100)
34
+ cursor: Pagination cursor
35
+
36
+ Returns:
37
+ MarketListResponse with list of markets and pagination info
38
+ """
39
+ params = {"limit": limit}
40
+ if status:
41
+ params["status"] = status
42
+ if category:
43
+ params["category"] = category
44
+ if sort:
45
+ params["sort"] = sort
46
+ if cursor:
47
+ params["cursor"] = cursor
48
+
49
+ response = self._client._request("GET", "/api/v1/markets", params=params)
50
+ return MarketListResponse.from_dict(response)
51
+
52
+ def get(self, market_id: str) -> Market:
53
+ """
54
+ Get a single market by ID (address).
55
+
56
+ Args:
57
+ market_id: Market address
58
+
59
+ Returns:
60
+ Market object
61
+ """
62
+ response = self._client._request("GET", f"/api/v1/markets/{market_id}")
63
+ return Market.from_dict(response)
64
+
65
+ def get_history(
66
+ self,
67
+ market_id: str,
68
+ interval: str = "1h",
69
+ limit: int = 100,
70
+ ) -> List[dict]:
71
+ """
72
+ Get price history for a market.
73
+
74
+ Args:
75
+ market_id: Market address
76
+ interval: Time bucket (1m, 5m, 1h, 1d)
77
+ limit: Max data points
78
+
79
+ Returns:
80
+ List of price history points
81
+ """
82
+ params = {"interval": interval, "limit": limit}
83
+ response = self._client._request(
84
+ "GET", f"/api/v1/markets/{market_id}/history", params=params
85
+ )
86
+ return response.get("history", [])
87
+
88
+ def get_trades(
89
+ self,
90
+ market_id: str,
91
+ limit: int = 50,
92
+ ) -> List[dict]:
93
+ """
94
+ Get recent trades for a market.
95
+
96
+ Args:
97
+ market_id: Market address
98
+ limit: Max trades to return
99
+
100
+ Returns:
101
+ List of trade objects
102
+ """
103
+ params = {"limit": limit}
104
+ response = self._client._request(
105
+ "GET", f"/api/v1/markets/{market_id}/trades", params=params
106
+ )
107
+ return response.get("trades", [])
108
+
109
+ def list_open(self, **kwargs) -> MarketListResponse:
110
+ """List open markets."""
111
+ return self.list(status="open", **kwargs)
112
+
113
+ def list_resolved(self, **kwargs) -> MarketListResponse:
114
+ """List resolved markets."""
115
+ return self.list(status="resolved", **kwargs)
116
+
117
+ def list_by_category(self, category: str, **kwargs) -> MarketListResponse:
118
+ """List markets by category."""
119
+ return self.list(category=category, **kwargs)
@@ -0,0 +1,49 @@
1
+ """
2
+ Positions API
3
+ """
4
+
5
+ from typing import Optional, TYPE_CHECKING
6
+ from ..models.position import Position, PositionListResponse
7
+
8
+ if TYPE_CHECKING:
9
+ from ..client import ProbClient
10
+
11
+
12
+ class PositionsAPI:
13
+ """Positions API methods."""
14
+
15
+ def __init__(self, client: "ProbClient"):
16
+ self._client = client
17
+
18
+ def list(self, address: str) -> PositionListResponse:
19
+ """
20
+ Get all positions for a wallet address.
21
+
22
+ Args:
23
+ address: Wallet address (0x...)
24
+
25
+ Returns:
26
+ PositionListResponse with list of positions
27
+ """
28
+ response = self._client._request("GET", f"/api/v1/positions/{address}")
29
+ return PositionListResponse.from_dict(response)
30
+
31
+ def get(self, address: str, market_id: str) -> Optional[Position]:
32
+ """
33
+ Get position for a specific market.
34
+
35
+ Args:
36
+ address: Wallet address
37
+ market_id: Market address
38
+
39
+ Returns:
40
+ Position or None if no position
41
+ """
42
+ params = {"market_id": market_id}
43
+ response = self._client._request(
44
+ "GET", f"/api/v1/positions/{address}", params=params
45
+ )
46
+ positions = response.get("positions", [])
47
+ if positions:
48
+ return Position.from_dict(positions[0])
49
+ return None
@@ -0,0 +1,85 @@
1
+ """
2
+ Quotes API
3
+ """
4
+
5
+ from typing import Optional, TYPE_CHECKING
6
+ from ..models.quote import Quote, TransactionData
7
+
8
+ if TYPE_CHECKING:
9
+ from ..client import ProbClient
10
+
11
+
12
+ class QuotesAPI:
13
+ """Quotes API methods."""
14
+
15
+ def __init__(self, client: "ProbClient"):
16
+ self._client = client
17
+
18
+ def get(
19
+ self,
20
+ market_id: str,
21
+ side: str,
22
+ outcome: str,
23
+ amount: str,
24
+ slippage_bps: int = 50,
25
+ ) -> Quote:
26
+ """
27
+ Get a quote for a trade.
28
+
29
+ Args:
30
+ market_id: Market address
31
+ side: "buy" or "sell"
32
+ outcome: "yes", "no", or "draw"
33
+ amount: Amount in wei (as string)
34
+ slippage_bps: Slippage tolerance in basis points (default 50 = 0.5%)
35
+
36
+ Returns:
37
+ Quote object with price and execution details
38
+ """
39
+ payload = {
40
+ "market_id": market_id,
41
+ "side": side,
42
+ "outcome": outcome,
43
+ "amount": amount,
44
+ "slippage_bps": slippage_bps,
45
+ }
46
+ response = self._client._request("POST", "/api/v1/quote", json=payload)
47
+ return Quote.from_dict(response)
48
+
49
+ def get_buy_yes(self, market_id: str, amount: str, **kwargs) -> Quote:
50
+ """Get quote to buy YES shares."""
51
+ return self.get(market_id, "buy", "yes", amount, **kwargs)
52
+
53
+ def get_buy_no(self, market_id: str, amount: str, **kwargs) -> Quote:
54
+ """Get quote to buy NO shares."""
55
+ return self.get(market_id, "buy", "no", amount, **kwargs)
56
+
57
+ def get_sell_yes(self, market_id: str, amount: str, **kwargs) -> Quote:
58
+ """Get quote to sell YES shares."""
59
+ return self.get(market_id, "sell", "yes", amount, **kwargs)
60
+
61
+ def get_sell_no(self, market_id: str, amount: str, **kwargs) -> Quote:
62
+ """Get quote to sell NO shares."""
63
+ return self.get(market_id, "sell", "no", amount, **kwargs)
64
+
65
+ def build_transaction(
66
+ self,
67
+ quote_id: str,
68
+ rpc_url: str,
69
+ ) -> TransactionData:
70
+ """
71
+ Build transaction data from a quote.
72
+
73
+ Args:
74
+ quote_id: Quote ID from get() response
75
+ rpc_url: RPC URL for the chain
76
+
77
+ Returns:
78
+ TransactionData with calldata for execution
79
+ """
80
+ payload = {"quote_id": quote_id}
81
+ headers = {"X-RPC-URL": rpc_url}
82
+ response = self._client._request(
83
+ "POST", "/api/v1/tx/build", json=payload, headers=headers
84
+ )
85
+ return TransactionData.from_dict(response)