Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- gitnexus:start -->
# GitNexus — Code Intelligence

This project is indexed by GitNexus as **kalshi-python-sdk** (8490 symbols, 17402 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.
This project is indexed by GitNexus as **kalshi-python-sdk** (8568 symbols, 17351 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.

> If any GitNexus tool warns the index is stale, run `npx gitnexus analyze` in terminal first.

Expand Down
92 changes: 92 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,98 @@

All notable changes to kalshi-sdk will be documented in this file.

## 3.0.0 — 2026-05-22

Public-API rename release. Three breaking-rename issues (`#348`, `#349`, `#351`)
that were deferred from the v2.7.0 audit closure now land with **one-release
deprecation aliases**: both old and new spellings work in v3.0.0; old names
emit `DeprecationWarning` and will be removed in a future release (v3.1+).

This is the first release in the v3 line. The wire protocol is unchanged from
v2.7.0; v3 is purely a public Python API ergonomics break.

### Migration

See `docs/migrations/v2-to-v3.md` for full BEFORE/AFTER snippets and a one-page
search-and-replace cheat sheet.

### Breaking changes

All three changes ship with `@typing_extensions.deprecated` aliases on the old
names — existing v2.x callers continue to work, but get a `DeprecationWarning`
on every call until they migrate.

- **`CommunicationsResource` sub-namespaces** (`#348`). Flat noun-prefixed
methods (`list_rfqs`, `get_rfq`, `create_rfq`, `delete_rfq`, `list_all_rfqs`,
`list_quotes`, `get_quote`, `create_quote`, `delete_quote`, `accept_quote`,
`confirm_quote`, `list_all_quotes`) are split into two sub-resources matching
the OpenAPI v3.18.0 tag structure:

```python
# v2.x (deprecated in v3.0.0)
client.communications.list_rfqs(...)
client.communications.create_rfq(...)
client.communications.accept_quote(quote_id, accepted_side="yes")

# v3.0.0+
client.communications.rfqs.list(...)
client.communications.rfqs.create(...)
client.communications.quotes.accept(quote_id, accepted_side="yes")
```

The misc `client.communications.get_id(...)` stays at the top level (no
sub-noun). The new sub-resource classes `RFQsResource`, `QuotesResource`,
`AsyncRFQsResource`, `AsyncQuotesResource` are exported from `kalshi/__init__.py`
for type annotations.

- **`MarketsResource.list_trades_all` → `list_all_trades`** (`#349`).
Standardizes on `list_all_<noun>` matching the other three resources
(`CommunicationsResource.list_all_rfqs`, `SubaccountsResource.list_all_transfers`,
etc.). `list_trades_all` remains as a deprecated alias.

```python
# v2.x (deprecated in v3.0.0)
for trade in client.markets.list_trades_all(ticker="..."):
...

# v3.0.0+
for trade in client.markets.list_all_trades(ticker="..."):
...
```

- **`OrdersResource.fills` / `fills_all` → `PortfolioResource.fills` /
`fills_all`** (`#351`). The endpoint URL is `/portfolio/fills`; this aligns
the SDK layout with the URL family (`portfolio.settlements`,
`portfolio.deposits`, `portfolio.withdrawals`). The old `OrdersResource.fills`
/ `fills_all` remain as deprecated aliases.

```python
# v2.x (deprecated in v3.0.0)
page = client.orders.fills(ticker="...")

# v3.0.0+
page = client.portfolio.fills(ticker="...")
```

### Polish

- **`_fills_params` deduped** to `kalshi/resources/_base.py` (was duplicated in
`orders.py` and `portfolio.py` during the relocation).

### Internal

- 78 new regression tests covering the deprecation-alias delegation and warning
emission across sync + async pairs for every renamed method (12 communications
forwarders × 2, plus markets + fills × 2 each).
- `tests/_contract_support.py` `METHOD_ENDPOINT_MAP` registers both old and new
spellings for the duration of the alias window.

### Deprecation removal schedule

The v3.0.0 aliases will be removed no sooner than **v3.1.0**. Callers should
migrate before then. Each deprecated method has a `@typing_extensions.deprecated`
decorator that surfaces in type checkers and IDEs per PEP 702.

## 2.7.0 — 2026-05-22

Post-v2.6 independent multi-LLM reviewer audit closure. **47 issues filed
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ Reference issues from PRs via `Closes #N` so the issue closes on merge.
<!-- gitnexus:start -->
# GitNexus — Code Intelligence

This project is indexed by GitNexus as **kalshi-python-sdk** (8490 symbols, 17402 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.
This project is indexed by GitNexus as **kalshi-python-sdk** (8568 symbols, 17351 relationships, 300 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely.

> If any GitNexus tool warns the index is stale, run `npx gitnexus analyze` in terminal first.

Expand Down
16 changes: 16 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

## Shipped

- **v3.0.0 (2026-05-22)** — first major release in the v3 line. Three
breaking-rename issues (`#348`, `#349`, `#351`) deferred from the v2.7.0
audit closure land with one-release deprecation aliases:
`CommunicationsResource` flat noun-prefixed methods split into
`client.communications.{rfqs,quotes}.<verb>` sub-namespaces (`#348`);
`MarketsResource.list_trades_all` → `list_all_trades` to match the
`list_all_<noun>` convention used by Communications/Subaccounts (`#349`);
`OrdersResource.fills` / `fills_all` relocate to `PortfolioResource`
alongside `settlements` / `deposits` / `withdrawals` since the endpoint URL
is `/portfolio/fills` (`#351`). Wire protocol unchanged. New
`RFQsResource`/`QuotesResource`/`AsyncRFQsResource`/`AsyncQuotesResource`
exported from `kalshi/__init__.py` for type annotations. 78 new regression
tests covering deprecation-alias delegation and warning emission. Migration
guide at `docs/migrations/v2-to-v3.md`. Aliases removed no sooner than
v3.1.0.

See `CHANGELOG.md` for full release history.

- **v2.7.0 (2026-05-22)** — post-v2.6 independent multi-LLM reviewer audit
Expand Down
22 changes: 22 additions & 0 deletions docs/migration.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# Migration

## v2.7 → v3.0

v3.0.0 is the first major release in the v3 line. It renames three groups of
public methods (issues `#348`, `#349`, `#351`). The wire protocol is
unchanged from v2.7.0; v3 is purely a Python-API ergonomics break.

**One-release deprecation window.** All old names continue to work in v3.0.0
as `@typing_extensions.deprecated` aliases. Each emits `DeprecationWarning`
on every call. Aliases will be removed no sooner than v3.1.0.

For full BEFORE/AFTER snippets and a one-page search-and-replace cheat sheet,
see [v2-to-v3.md](migrations/v2-to-v3.md). Quick summary:

| Rename | Old (deprecated v3.0.0) | New (v3.0.0+) |
|---|---|---|
| Communications sub-namespaces | `client.communications.list_rfqs(...)` | `client.communications.rfqs.list(...)` |
| | `client.communications.get_quote(id)` | `client.communications.quotes.get(id)` |
| | (12 forwarders total across rfqs/quotes) | (same; sub-resource methods) |
| `*_all` naming | `client.markets.list_trades_all(...)` | `client.markets.list_all_trades(...)` |
| `fills` relocation | `client.orders.fills(...)` | `client.portfolio.fills(...)` |
| | `client.orders.fills_all(...)` | `client.portfolio.fills_all(...)` |

## v2.5 → v2.6

v2.6 ships two behavioral fences, both surface bugs that were already wrong:
Expand Down
162 changes: 162 additions & 0 deletions docs/migrations/v2-to-v3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# Migrating from v2.x to v3.0.0

v3.0.0 renames three groups of public methods. All old names continue to work
in v3.0.0 as `@typing_extensions.deprecated` aliases that emit
`DeprecationWarning` on every call. The aliases will be removed no sooner than
**v3.1.0**, so migrate before then.

The wire protocol is unchanged. v3 is purely a Python-API ergonomics break.

## TL;DR — search and replace cheat sheet

| Find | Replace |
|---|---|
| `.communications.list_rfqs(` | `.communications.rfqs.list(` |
| `.communications.list_all_rfqs(` | `.communications.rfqs.list_all(` |
| `.communications.get_rfq(` | `.communications.rfqs.get(` |
| `.communications.create_rfq(` | `.communications.rfqs.create(` |
| `.communications.delete_rfq(` | `.communications.rfqs.delete(` |
| `.communications.list_quotes(` | `.communications.quotes.list(` |
| `.communications.list_all_quotes(` | `.communications.quotes.list_all(` |
| `.communications.get_quote(` | `.communications.quotes.get(` |
| `.communications.create_quote(` | `.communications.quotes.create(` |
| `.communications.delete_quote(` | `.communications.quotes.delete(` |
| `.communications.accept_quote(` | `.communications.quotes.accept(` |
| `.communications.confirm_quote(` | `.communications.quotes.confirm(` |
| `.markets.list_trades_all(` | `.markets.list_all_trades(` |
| `.orders.fills(` | `.portfolio.fills(` |
| `.orders.fills_all(` | `.portfolio.fills_all(` |

These map 1:1 — argument signatures and return types are identical. The only
behavioral difference is that the old names emit a `DeprecationWarning`.

## 1. CommunicationsResource sub-namespaces (#348)

The flat noun-prefixed methods on `CommunicationsResource` collapse into two
sub-resources matching the OpenAPI v3.18.0 tag structure.

### Before (v2.x)

```python
from kalshi import KalshiClient

client = KalshiClient.from_env()

rfqs = client.communications.list_rfqs(limit=50)
rfq = client.communications.get_rfq("rfq-123")
new = client.communications.create_rfq(market_ticker="MKT-1", rest_remainder=True)
client.communications.delete_rfq("rfq-123")

quotes = client.communications.list_quotes(quote_creator_user_id="u1")
client.communications.accept_quote("q-456", accepted_side="yes")
client.communications.confirm_quote("q-456")
```

### After (v3.0.0)

```python
from kalshi import KalshiClient

client = KalshiClient.from_env()

rfqs = client.communications.rfqs.list(limit=50)
rfq = client.communications.rfqs.get("rfq-123")
new = client.communications.rfqs.create(market_ticker="MKT-1", rest_remainder=True)
client.communications.rfqs.delete("rfq-123")

quotes = client.communications.quotes.list(quote_creator_user_id="u1")
client.communications.quotes.accept("q-456", accepted_side="yes")
client.communications.quotes.confirm("q-456")
```

### Notes

- `client.communications.get_id(...)` (the misc endpoint) **stays at the top
level** — no sub-noun.
- The async API mirrors the sync API: `async_client.communications.rfqs.list(...)`.
- If you type-annotate sub-resource attributes, import the new classes from the
top level:
```python
from kalshi import RFQsResource, QuotesResource, AsyncRFQsResource, AsyncQuotesResource
```

## 2. `*_all` naming standardization (#349)

`MarketsResource.list_trades_all` was the only outlier still using the
`list_<noun>_all` suffix form. Renamed to `list_all_<noun>` (prefix form) to
match the other three resources.

### Before (v2.x)

```python
for trade in client.markets.list_trades_all(ticker="MKT-1", limit=200):
process(trade)
```

### After (v3.0.0)

```python
for trade in client.markets.list_all_trades(ticker="MKT-1", limit=200):
process(trade)
```

Same iterator semantics, same filter kwargs.

## 3. `fills` relocation: orders → portfolio (#351)

The `/portfolio/fills` endpoint now sits on `PortfolioResource` alongside
`settlements`, `deposits`, and `withdrawals` — matching the URL family.

### Before (v2.x)

```python
page = client.orders.fills(ticker="MKT-1", min_ts=since)
for fill in client.orders.fills_all(order_id="ord-1"):
process(fill)
```

### After (v3.0.0)

```python
page = client.portfolio.fills(ticker="MKT-1", min_ts=since)
for fill in client.portfolio.fills_all(order_id="ord-1"):
process(fill)
```

Signatures and return types are identical (`Page[Fill]` with `cursor`,
`min_ts`, `max_ts`, `ticker`, `order_id`, etc.).

## Detecting deprecated calls during migration

The aliases use `@typing_extensions.deprecated` (PEP 702), which type checkers
recognize. Add a stricter pytest config for the duration of your migration:

```toml
# pyproject.toml
[tool.pytest.ini_options]
filterwarnings = [
"error::DeprecationWarning:kalshi.*",
]
```

This turns every deprecated kalshi call into a test failure until you update.

For a softer approach, log warnings instead of erroring:

```python
import warnings
warnings.filterwarnings("default", category=DeprecationWarning, module=r"kalshi(\..*)?")
```

## Why a major version for renames?

Per project policy (CHANGELOG §2.7.0), bug-surfacing behavioral fences ship in
minor releases; intentional public-API renames are reserved for major releases.
v3.0.0 is the first major version under this policy. v2.5–v2.7 each shipped
behavioral fences in minor versions because they surfaced silent bugs;
v3.0.0 renames previously-correct method names purely for API ergonomics.

## Removal schedule

The deprecated aliases will be removed no sooner than **v3.1.0**. Migration
done before then is forward-compatible across all v3.x.
4 changes: 3 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,7 @@ nav:
- Live data: resources/live-data.md
- WebSocket: websockets.md
- Testing: testing.md
- Migration: migration.md
- Migration:
- Overview: migration.md
- v2 → v3: migrations/v2-to-v3.md
- API Reference: reference.md
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "kalshi-sdk"
version = "2.7.0"
version = "3.0.0"
description = "A professional Python SDK for the Kalshi prediction markets API"
readme = "README.md"
license = { text = "MIT" }
Expand Down
Loading