diff --git a/AGENTS.md b/AGENTS.md index b15e5f5..d5c3e82 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,7 +1,7 @@ # 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. diff --git a/CHANGELOG.md b/CHANGELOG.md index 208f65a..1e53231 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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_` 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 diff --git a/CLAUDE.md b/CLAUDE.md index 17ba7e8..8127c4d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -144,7 +144,7 @@ Reference issues from PRs via `Closes #N` so the issue closes on merge. # 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. diff --git a/ROADMAP.md b/ROADMAP.md index 77eb609..7c667ee 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -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}.` sub-namespaces (`#348`); + `MarketsResource.list_trades_all` → `list_all_trades` to match the + `list_all_` 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 diff --git a/docs/migration.md b/docs/migration.md index 5856fb4..2652415 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -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: diff --git a/docs/migrations/v2-to-v3.md b/docs/migrations/v2-to-v3.md new file mode 100644 index 0000000..32a0bb9 --- /dev/null +++ b/docs/migrations/v2-to-v3.md @@ -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__all` suffix form. Renamed to `list_all_` (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. diff --git a/mkdocs.yml b/mkdocs.yml index a8d1d41..388ee7c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -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 diff --git a/pyproject.toml b/pyproject.toml index c6c2006..1855952 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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" }