pykalshi 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.
- pykalshi-0.1.0/LICENSE +21 -0
- pykalshi-0.1.0/PKG-INFO +182 -0
- pykalshi-0.1.0/README.md +138 -0
- pykalshi-0.1.0/kalshi_api/__init__.py +144 -0
- pykalshi-0.1.0/kalshi_api/api_keys.py +59 -0
- pykalshi-0.1.0/kalshi_api/client.py +526 -0
- pykalshi-0.1.0/kalshi_api/enums.py +54 -0
- pykalshi-0.1.0/kalshi_api/events.py +87 -0
- pykalshi-0.1.0/kalshi_api/exceptions.py +115 -0
- pykalshi-0.1.0/kalshi_api/exchange.py +37 -0
- pykalshi-0.1.0/kalshi_api/feed.py +592 -0
- pykalshi-0.1.0/kalshi_api/markets.py +234 -0
- pykalshi-0.1.0/kalshi_api/models.py +552 -0
- pykalshi-0.1.0/kalshi_api/orderbook.py +146 -0
- pykalshi-0.1.0/kalshi_api/orders.py +144 -0
- pykalshi-0.1.0/kalshi_api/portfolio.py +542 -0
- pykalshi-0.1.0/kalshi_api/py.typed +0 -0
- pykalshi-0.1.0/kalshi_api/rate_limiter.py +171 -0
- pykalshi-0.1.0/pykalshi.egg-info/PKG-INFO +182 -0
- pykalshi-0.1.0/pykalshi.egg-info/SOURCES.txt +33 -0
- pykalshi-0.1.0/pykalshi.egg-info/dependency_links.txt +1 -0
- pykalshi-0.1.0/pykalshi.egg-info/requires.txt +18 -0
- pykalshi-0.1.0/pykalshi.egg-info/top_level.txt +1 -0
- pykalshi-0.1.0/pyproject.toml +80 -0
- pykalshi-0.1.0/setup.cfg +4 -0
- pykalshi-0.1.0/tests/test_api_keys.py +211 -0
- pykalshi-0.1.0/tests/test_client.py +153 -0
- pykalshi-0.1.0/tests/test_exchange.py +173 -0
- pykalshi-0.1.0/tests/test_feed.py +687 -0
- pykalshi-0.1.0/tests/test_integration.py +102 -0
- pykalshi-0.1.0/tests/test_markets.py +519 -0
- pykalshi-0.1.0/tests/test_models.py +285 -0
- pykalshi-0.1.0/tests/test_portfolio.py +364 -0
- pykalshi-0.1.0/tests/test_series.py +360 -0
- pykalshi-0.1.0/tests/test_workflow.py +102 -0
pykalshi-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024
|
|
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.
|
pykalshi-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pykalshi
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A typed Python client for the Kalshi prediction markets API with WebSocket streaming, automatic retries, and ergonomic interfaces
|
|
5
|
+
Author-email: Arsh Koneru <arshkon@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/ArshKA/kalshi-api
|
|
8
|
+
Project-URL: Repository, https://github.com/ArshKA/kalshi-api
|
|
9
|
+
Project-URL: Documentation, https://github.com/ArshKA/kalshi-api#readme
|
|
10
|
+
Project-URL: Issues, https://github.com/ArshKA/kalshi-api/issues
|
|
11
|
+
Keywords: kalshi,prediction-markets,trading,api-client,websocket,finance,betting,forecasting,elections,event-contracts,binary-options,real-time,async,pydantic,orderbook,market-data
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.9
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: requests>=2.31.0
|
|
28
|
+
Requires-Dist: pydantic>=2.0.0
|
|
29
|
+
Requires-Dist: cryptography>=41.0.0
|
|
30
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
31
|
+
Requires-Dist: websockets>=11.0
|
|
32
|
+
Provides-Extra: web
|
|
33
|
+
Requires-Dist: fastapi>=0.100.0; extra == "web"
|
|
34
|
+
Requires-Dist: uvicorn>=0.23.0; extra == "web"
|
|
35
|
+
Requires-Dist: aiofiles>=23.0.0; extra == "web"
|
|
36
|
+
Provides-Extra: dev
|
|
37
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
38
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
39
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
40
|
+
Requires-Dist: pytest-mock>=3.0.0; extra == "dev"
|
|
41
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
42
|
+
Requires-Dist: types-requests>=2.31.0; extra == "dev"
|
|
43
|
+
Dynamic: license-file
|
|
44
|
+
|
|
45
|
+
# kalshi-api
|
|
46
|
+
|
|
47
|
+
A typed Python client for the [Kalshi](https://kalshi.com) prediction markets API with WebSocket streaming, automatic retries, and ergonomic interfaces.
|
|
48
|
+
|
|
49
|
+
## Installation
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install kalshi-api
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Create a `.env` file with your credentials from [kalshi.com](https://kalshi.com) → Account & Security → API Keys:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
KALSHI_API_KEY_ID=your-key-id
|
|
59
|
+
KALSHI_PRIVATE_KEY_PATH=/path/to/private-key.key
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Quick Start
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from kalshi_api import KalshiClient, Action, Side
|
|
66
|
+
|
|
67
|
+
client = KalshiClient()
|
|
68
|
+
user = client.get_user()
|
|
69
|
+
|
|
70
|
+
# Browse markets
|
|
71
|
+
markets = client.get_markets(status="open", limit=5)
|
|
72
|
+
market = client.get_market("KXBTC-25JAN15-B100000")
|
|
73
|
+
|
|
74
|
+
# Place an order
|
|
75
|
+
order = user.place_order(
|
|
76
|
+
market,
|
|
77
|
+
action=Action.BUY,
|
|
78
|
+
side=Side.YES,
|
|
79
|
+
count=10,
|
|
80
|
+
price=45 # cents
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
order.cancel() # if needed
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Usage
|
|
87
|
+
|
|
88
|
+
### Portfolio
|
|
89
|
+
|
|
90
|
+
`KalshiClient` handles authentication. Call `get_user()` to access your portfolio:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
client = KalshiClient() # Uses .env credentials
|
|
94
|
+
client = KalshiClient(demo=True) # Use demo environment
|
|
95
|
+
|
|
96
|
+
user = client.get_user()
|
|
97
|
+
user.get_balance() # BalanceModel with balance, portfolio_value
|
|
98
|
+
user.get_positions() # Your current positions
|
|
99
|
+
user.get_fills() # Your trade history
|
|
100
|
+
user.get_orders(status="resting") # Your open orders
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Markets
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
# Search markets
|
|
107
|
+
markets = client.get_markets(series_ticker="KXBTC", status="open")
|
|
108
|
+
|
|
109
|
+
# Get a specific market
|
|
110
|
+
market = client.get_market("KXBTC-25JAN15-B100000")
|
|
111
|
+
print(market.title, market.yes_bid, market.yes_ask)
|
|
112
|
+
|
|
113
|
+
# Market data
|
|
114
|
+
orderbook = market.get_orderbook()
|
|
115
|
+
trades = market.get_trades()
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Orders
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
from kalshi_api import Action, Side, OrderType
|
|
122
|
+
|
|
123
|
+
# Limit order (default)
|
|
124
|
+
order = user.place_order(market, Action.BUY, Side.YES, count=10, price=50)
|
|
125
|
+
|
|
126
|
+
# Market order
|
|
127
|
+
order = user.place_order(market, Action.BUY, Side.YES, count=10, order_type=OrderType.MARKET)
|
|
128
|
+
|
|
129
|
+
order.cancel()
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Real-time Streaming
|
|
133
|
+
|
|
134
|
+
Subscribe to live market data via WebSocket:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
from kalshi_api import Feed
|
|
138
|
+
|
|
139
|
+
async def main():
|
|
140
|
+
async with Feed(client) as feed:
|
|
141
|
+
await feed.subscribe_ticker("KXBTC-25JAN15-B100000")
|
|
142
|
+
await feed.subscribe_orderbook("KXBTC-25JAN15-B100000")
|
|
143
|
+
|
|
144
|
+
async for msg in feed:
|
|
145
|
+
print(msg) # TickerMessage, OrderbookSnapshotMessage, etc.
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Error Handling
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
from kalshi_api import InsufficientFundsError, RateLimitError, KalshiAPIError
|
|
152
|
+
|
|
153
|
+
try:
|
|
154
|
+
user.place_order(...)
|
|
155
|
+
except InsufficientFundsError:
|
|
156
|
+
print("Not enough balance")
|
|
157
|
+
except RateLimitError:
|
|
158
|
+
pass # Client auto-retries with backoff
|
|
159
|
+
except KalshiAPIError as e:
|
|
160
|
+
print(f"{e.status_code}: {e.error_code}")
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Comparison with Official SDK
|
|
164
|
+
|
|
165
|
+
| Feature | kalshi-api | kalshi-python (official) |
|
|
166
|
+
|---------|------------|--------------------------|
|
|
167
|
+
| WebSocket streaming | ✓ | — |
|
|
168
|
+
| Automatic retry with backoff | ✓ | — |
|
|
169
|
+
| Rate limit handling | ✓ | — |
|
|
170
|
+
| Domain objects (`Market`, `Order`) | ✓ | — |
|
|
171
|
+
| Typed exceptions | ✓ | — |
|
|
172
|
+
| Local orderbook management | ✓ | — |
|
|
173
|
+
| Pydantic models | ✓ | — |
|
|
174
|
+
| Core trading API coverage | ✓ | ✓ |
|
|
175
|
+
| Full API coverage | — | ✓ |
|
|
176
|
+
|
|
177
|
+
The official SDK is auto-generated from the OpenAPI spec. This library adds the infrastructure needed for production trading: real-time data, error recovery, and ergonomic interfaces.
|
|
178
|
+
|
|
179
|
+
## Links
|
|
180
|
+
|
|
181
|
+
- [Kalshi API Reference](https://trading-api.readme.io/reference)
|
|
182
|
+
- [kalshi-python (official SDK)](https://github.com/Kalshi/kalshi-python)
|
pykalshi-0.1.0/README.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# kalshi-api
|
|
2
|
+
|
|
3
|
+
A typed Python client for the [Kalshi](https://kalshi.com) prediction markets API with WebSocket streaming, automatic retries, and ergonomic interfaces.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install kalshi-api
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Create a `.env` file with your credentials from [kalshi.com](https://kalshi.com) → Account & Security → API Keys:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
KALSHI_API_KEY_ID=your-key-id
|
|
15
|
+
KALSHI_PRIVATE_KEY_PATH=/path/to/private-key.key
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
from kalshi_api import KalshiClient, Action, Side
|
|
22
|
+
|
|
23
|
+
client = KalshiClient()
|
|
24
|
+
user = client.get_user()
|
|
25
|
+
|
|
26
|
+
# Browse markets
|
|
27
|
+
markets = client.get_markets(status="open", limit=5)
|
|
28
|
+
market = client.get_market("KXBTC-25JAN15-B100000")
|
|
29
|
+
|
|
30
|
+
# Place an order
|
|
31
|
+
order = user.place_order(
|
|
32
|
+
market,
|
|
33
|
+
action=Action.BUY,
|
|
34
|
+
side=Side.YES,
|
|
35
|
+
count=10,
|
|
36
|
+
price=45 # cents
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
order.cancel() # if needed
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
### Portfolio
|
|
45
|
+
|
|
46
|
+
`KalshiClient` handles authentication. Call `get_user()` to access your portfolio:
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
client = KalshiClient() # Uses .env credentials
|
|
50
|
+
client = KalshiClient(demo=True) # Use demo environment
|
|
51
|
+
|
|
52
|
+
user = client.get_user()
|
|
53
|
+
user.get_balance() # BalanceModel with balance, portfolio_value
|
|
54
|
+
user.get_positions() # Your current positions
|
|
55
|
+
user.get_fills() # Your trade history
|
|
56
|
+
user.get_orders(status="resting") # Your open orders
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Markets
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
# Search markets
|
|
63
|
+
markets = client.get_markets(series_ticker="KXBTC", status="open")
|
|
64
|
+
|
|
65
|
+
# Get a specific market
|
|
66
|
+
market = client.get_market("KXBTC-25JAN15-B100000")
|
|
67
|
+
print(market.title, market.yes_bid, market.yes_ask)
|
|
68
|
+
|
|
69
|
+
# Market data
|
|
70
|
+
orderbook = market.get_orderbook()
|
|
71
|
+
trades = market.get_trades()
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Orders
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from kalshi_api import Action, Side, OrderType
|
|
78
|
+
|
|
79
|
+
# Limit order (default)
|
|
80
|
+
order = user.place_order(market, Action.BUY, Side.YES, count=10, price=50)
|
|
81
|
+
|
|
82
|
+
# Market order
|
|
83
|
+
order = user.place_order(market, Action.BUY, Side.YES, count=10, order_type=OrderType.MARKET)
|
|
84
|
+
|
|
85
|
+
order.cancel()
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Real-time Streaming
|
|
89
|
+
|
|
90
|
+
Subscribe to live market data via WebSocket:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from kalshi_api import Feed
|
|
94
|
+
|
|
95
|
+
async def main():
|
|
96
|
+
async with Feed(client) as feed:
|
|
97
|
+
await feed.subscribe_ticker("KXBTC-25JAN15-B100000")
|
|
98
|
+
await feed.subscribe_orderbook("KXBTC-25JAN15-B100000")
|
|
99
|
+
|
|
100
|
+
async for msg in feed:
|
|
101
|
+
print(msg) # TickerMessage, OrderbookSnapshotMessage, etc.
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Error Handling
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from kalshi_api import InsufficientFundsError, RateLimitError, KalshiAPIError
|
|
108
|
+
|
|
109
|
+
try:
|
|
110
|
+
user.place_order(...)
|
|
111
|
+
except InsufficientFundsError:
|
|
112
|
+
print("Not enough balance")
|
|
113
|
+
except RateLimitError:
|
|
114
|
+
pass # Client auto-retries with backoff
|
|
115
|
+
except KalshiAPIError as e:
|
|
116
|
+
print(f"{e.status_code}: {e.error_code}")
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Comparison with Official SDK
|
|
120
|
+
|
|
121
|
+
| Feature | kalshi-api | kalshi-python (official) |
|
|
122
|
+
|---------|------------|--------------------------|
|
|
123
|
+
| WebSocket streaming | ✓ | — |
|
|
124
|
+
| Automatic retry with backoff | ✓ | — |
|
|
125
|
+
| Rate limit handling | ✓ | — |
|
|
126
|
+
| Domain objects (`Market`, `Order`) | ✓ | — |
|
|
127
|
+
| Typed exceptions | ✓ | — |
|
|
128
|
+
| Local orderbook management | ✓ | — |
|
|
129
|
+
| Pydantic models | ✓ | — |
|
|
130
|
+
| Core trading API coverage | ✓ | ✓ |
|
|
131
|
+
| Full API coverage | — | ✓ |
|
|
132
|
+
|
|
133
|
+
The official SDK is auto-generated from the OpenAPI spec. This library adds the infrastructure needed for production trading: real-time data, error recovery, and ergonomic interfaces.
|
|
134
|
+
|
|
135
|
+
## Links
|
|
136
|
+
|
|
137
|
+
- [Kalshi API Reference](https://trading-api.readme.io/reference)
|
|
138
|
+
- [kalshi-python (official SDK)](https://github.com/Kalshi/kalshi-python)
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Kalshi API Client Library
|
|
3
|
+
|
|
4
|
+
A clean, modular interface for the Kalshi trading API.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
|
|
9
|
+
from .client import KalshiClient
|
|
10
|
+
from .events import Event
|
|
11
|
+
from .markets import Market, Series
|
|
12
|
+
from .orders import Order
|
|
13
|
+
from .portfolio import Portfolio
|
|
14
|
+
from .exchange import Exchange
|
|
15
|
+
from .api_keys import APIKeys
|
|
16
|
+
from .feed import (
|
|
17
|
+
Feed,
|
|
18
|
+
TickerMessage,
|
|
19
|
+
OrderbookSnapshotMessage,
|
|
20
|
+
OrderbookDeltaMessage,
|
|
21
|
+
OrderbookMessage,
|
|
22
|
+
TradeMessage,
|
|
23
|
+
FillMessage,
|
|
24
|
+
PositionMessage,
|
|
25
|
+
MarketLifecycleMessage,
|
|
26
|
+
OrderGroupUpdateMessage,
|
|
27
|
+
)
|
|
28
|
+
from .enums import (
|
|
29
|
+
Side,
|
|
30
|
+
Action,
|
|
31
|
+
OrderType,
|
|
32
|
+
OrderStatus,
|
|
33
|
+
MarketStatus,
|
|
34
|
+
CandlestickPeriod,
|
|
35
|
+
TimeInForce,
|
|
36
|
+
SelfTradePrevention,
|
|
37
|
+
)
|
|
38
|
+
from .models import (
|
|
39
|
+
PositionModel,
|
|
40
|
+
FillModel,
|
|
41
|
+
OrderModel,
|
|
42
|
+
BalanceModel,
|
|
43
|
+
MarketModel,
|
|
44
|
+
EventModel,
|
|
45
|
+
OrderbookResponse,
|
|
46
|
+
CandlestickResponse,
|
|
47
|
+
ExchangeStatus,
|
|
48
|
+
Announcement,
|
|
49
|
+
APILimits,
|
|
50
|
+
APIKey,
|
|
51
|
+
GeneratedAPIKey,
|
|
52
|
+
SeriesModel,
|
|
53
|
+
TradeModel,
|
|
54
|
+
SettlementModel,
|
|
55
|
+
QueuePositionModel,
|
|
56
|
+
OrderGroupModel,
|
|
57
|
+
SubaccountModel,
|
|
58
|
+
SubaccountBalanceModel,
|
|
59
|
+
SubaccountTransferModel,
|
|
60
|
+
ForecastPercentileHistory,
|
|
61
|
+
)
|
|
62
|
+
from .orderbook import OrderbookManager
|
|
63
|
+
from .rate_limiter import RateLimiter, NoOpRateLimiter
|
|
64
|
+
from .exceptions import (
|
|
65
|
+
KalshiError,
|
|
66
|
+
KalshiAPIError,
|
|
67
|
+
AuthenticationError,
|
|
68
|
+
InsufficientFundsError,
|
|
69
|
+
ResourceNotFoundError,
|
|
70
|
+
RateLimitError,
|
|
71
|
+
OrderRejectedError,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Set up logging to NullHandler by default to avoid "No handler found" warnings.
|
|
75
|
+
logging.getLogger(__name__).addHandler(logging.NullHandler())
|
|
76
|
+
|
|
77
|
+
__all__ = [
|
|
78
|
+
# Client
|
|
79
|
+
"KalshiClient",
|
|
80
|
+
# Domain objects
|
|
81
|
+
"Event",
|
|
82
|
+
"Market",
|
|
83
|
+
"Series",
|
|
84
|
+
"Order",
|
|
85
|
+
"Portfolio",
|
|
86
|
+
"Exchange",
|
|
87
|
+
"APIKeys",
|
|
88
|
+
# Feed (WebSocket)
|
|
89
|
+
"Feed",
|
|
90
|
+
"TickerMessage",
|
|
91
|
+
"OrderbookSnapshotMessage",
|
|
92
|
+
"OrderbookDeltaMessage",
|
|
93
|
+
"OrderbookMessage",
|
|
94
|
+
"TradeMessage",
|
|
95
|
+
"FillMessage",
|
|
96
|
+
"PositionMessage",
|
|
97
|
+
"MarketLifecycleMessage",
|
|
98
|
+
"OrderGroupUpdateMessage",
|
|
99
|
+
# Enums
|
|
100
|
+
"Side",
|
|
101
|
+
"Action",
|
|
102
|
+
"OrderType",
|
|
103
|
+
"OrderStatus",
|
|
104
|
+
"MarketStatus",
|
|
105
|
+
"CandlestickPeriod",
|
|
106
|
+
"TimeInForce",
|
|
107
|
+
"SelfTradePrevention",
|
|
108
|
+
# Models
|
|
109
|
+
"PositionModel",
|
|
110
|
+
"FillModel",
|
|
111
|
+
"OrderModel",
|
|
112
|
+
"BalanceModel",
|
|
113
|
+
"MarketModel",
|
|
114
|
+
"EventModel",
|
|
115
|
+
"OrderbookResponse",
|
|
116
|
+
"CandlestickResponse",
|
|
117
|
+
"ExchangeStatus",
|
|
118
|
+
"Announcement",
|
|
119
|
+
"APILimits",
|
|
120
|
+
"APIKey",
|
|
121
|
+
"GeneratedAPIKey",
|
|
122
|
+
"SeriesModel",
|
|
123
|
+
"TradeModel",
|
|
124
|
+
"SettlementModel",
|
|
125
|
+
"QueuePositionModel",
|
|
126
|
+
"OrderGroupModel",
|
|
127
|
+
"ForecastPercentileHistory",
|
|
128
|
+
# Utilities
|
|
129
|
+
"OrderbookManager",
|
|
130
|
+
"RateLimiter",
|
|
131
|
+
"NoOpRateLimiter",
|
|
132
|
+
# Subaccount Models
|
|
133
|
+
"SubaccountModel",
|
|
134
|
+
"SubaccountBalanceModel",
|
|
135
|
+
"SubaccountTransferModel",
|
|
136
|
+
# Exceptions
|
|
137
|
+
"KalshiError",
|
|
138
|
+
"KalshiAPIError",
|
|
139
|
+
"AuthenticationError",
|
|
140
|
+
"InsufficientFundsError",
|
|
141
|
+
"ResourceNotFoundError",
|
|
142
|
+
"RateLimitError",
|
|
143
|
+
"OrderRejectedError",
|
|
144
|
+
]
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
from .models import APIKey, GeneratedAPIKey, APILimits
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from .client import KalshiClient
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class APIKeys:
|
|
10
|
+
"""API key management and account limits."""
|
|
11
|
+
|
|
12
|
+
def __init__(self, client: KalshiClient) -> None:
|
|
13
|
+
self._client = client
|
|
14
|
+
|
|
15
|
+
def list(self) -> list[APIKey]:
|
|
16
|
+
"""List all API keys for this account."""
|
|
17
|
+
data = self._client.get("/api_keys")
|
|
18
|
+
return [APIKey.model_validate(k) for k in data.get("api_keys", [])]
|
|
19
|
+
|
|
20
|
+
def create(self, public_key: str, name: str | None = None) -> APIKey:
|
|
21
|
+
"""Create an API key with a provided RSA public key.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
public_key: PEM-encoded RSA public key.
|
|
25
|
+
name: Optional name for the key.
|
|
26
|
+
"""
|
|
27
|
+
body: dict = {"public_key": public_key}
|
|
28
|
+
if name:
|
|
29
|
+
body["name"] = name
|
|
30
|
+
data = self._client.post("/api_keys", body)
|
|
31
|
+
return APIKey.model_validate(data["api_key"])
|
|
32
|
+
|
|
33
|
+
def generate(self, name: str | None = None) -> GeneratedAPIKey:
|
|
34
|
+
"""Generate a new API key pair (Kalshi creates both keys).
|
|
35
|
+
|
|
36
|
+
Returns a GeneratedAPIKey with the private_key field populated.
|
|
37
|
+
The private key is only returned ONCE - store it securely.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
name: Optional name for the key.
|
|
41
|
+
"""
|
|
42
|
+
body: dict = {}
|
|
43
|
+
if name:
|
|
44
|
+
body["name"] = name
|
|
45
|
+
data = self._client.post("/api_keys/generate", body)
|
|
46
|
+
return GeneratedAPIKey.model_validate(data)
|
|
47
|
+
|
|
48
|
+
def delete(self, key_id: str) -> None:
|
|
49
|
+
"""Delete an API key.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
key_id: The API key ID to delete.
|
|
53
|
+
"""
|
|
54
|
+
self._client.delete(f"/api_keys/{key_id}")
|
|
55
|
+
|
|
56
|
+
def get_limits(self) -> APILimits:
|
|
57
|
+
"""Get API rate limits for this account."""
|
|
58
|
+
data = self._client.get("/account/limits")
|
|
59
|
+
return APILimits.model_validate(data)
|