Skip to content

Commit 2d58508

Browse files
tdobrowolski1claude
andcommitted
Tighten client method return annotations to TypedDicts
Imports under TYPE_CHECKING (zero runtime cost; from __future__ annotations already present). Methods retyped: stock_summary, narrative, exposure_levels, greeks, max_pain, vrp, exposure_summary, zero_dte. Method bodies untouched — TypedDicts ARE dicts at runtime so existing callers keep working. Bump to 0.4.0rc8. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 61829bd commit 2d58508

2 files changed

Lines changed: 19 additions & 10 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "flashalpha"
7-
version = "0.4.0rc7"
7+
version = "0.4.0rc8"
88
description = "Python SDK for the FlashAlpha options analytics API — live options screener, gamma exposure (GEX), VRP, delta, vanna, charm, greeks, 0DTE analytics, volatility surfaces, and more."
99
readme = "README.md"
1010
license = "MIT"

src/flashalpha/client.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,16 @@
1717
)
1818

1919
if TYPE_CHECKING:
20-
from .types import ZeroDteResponse
20+
from .types import (
21+
ExposureLevelsResponse,
22+
ExposureSummaryResponse,
23+
MaxPainResponse,
24+
NarrativeResponse,
25+
PricingGreeksResponse,
26+
StockSummaryResponse,
27+
VrpResponse,
28+
ZeroDteResponse,
29+
)
2130

2231
BASE_URL = "https://lab.flashalpha.com"
2332

@@ -122,7 +131,7 @@ def surface(self, symbol: str) -> dict:
122131
"""Volatility surface grid (public, no auth required)."""
123132
return self._get(f"/v1/surface/{_seg(symbol)}")
124133

125-
def stock_summary(self, symbol: str) -> dict:
134+
def stock_summary(self, symbol: str) -> StockSummaryResponse:
126135
"""Comprehensive stock summary (price, vol, exposure, macro)."""
127136
return self._get(f"/v1/stock/{_seg(symbol)}/summary")
128137

@@ -189,19 +198,19 @@ def chex(self, symbol: str, *, expiration: str | None = None) -> dict:
189198
params["expiration"] = expiration
190199
return self._get(f"/v1/exposure/chex/{_seg(symbol)}", params or None)
191200

192-
def exposure_summary(self, symbol: str) -> dict:
201+
def exposure_summary(self, symbol: str) -> ExposureSummaryResponse:
193202
"""Full exposure summary (GEX/DEX/VEX/CHEX + hedging). Requires Growth+."""
194203
return self._get(f"/v1/exposure/summary/{_seg(symbol)}")
195204

196-
def exposure_levels(self, symbol: str) -> dict:
205+
def exposure_levels(self, symbol: str) -> ExposureLevelsResponse:
197206
"""Key support/resistance levels from options exposure."""
198207
return self._get(f"/v1/exposure/levels/{_seg(symbol)}")
199208

200-
def narrative(self, symbol: str) -> dict:
209+
def narrative(self, symbol: str) -> NarrativeResponse:
201210
"""Verbal narrative analysis of exposure. Requires Growth+."""
202211
return self._get(f"/v1/exposure/narrative/{_seg(symbol)}")
203212

204-
def zero_dte(self, symbol: str, *, strike_range: float | None = None) -> "ZeroDteResponse":
213+
def zero_dte(self, symbol: str, *, strike_range: float | None = None) -> ZeroDteResponse:
205214
"""Real-time 0DTE analytics: regime, expected move, pin risk, hedging, decay. Requires Growth+.
206215
207216
Returns a ``ZeroDteResponse`` (a ``TypedDict`` — runtime-equivalent to
@@ -232,7 +241,7 @@ def greeks(
232241
type: str = "call",
233242
r: float | None = None,
234243
q: float | None = None,
235-
) -> dict:
244+
) -> PricingGreeksResponse:
236245
"""Full BSM greeks (first, second, third order)."""
237246
params: dict[str, Any] = {"spot": spot, "strike": strike, "dte": dte, "sigma": sigma, "type": type}
238247
if r is not None:
@@ -315,7 +324,7 @@ def symbols(self) -> dict:
315324

316325
# ── VRP (Variance Risk Premium) ─────────────────────────────────
317326

318-
def vrp(self, symbol: str) -> dict:
327+
def vrp(self, symbol: str) -> VrpResponse:
319328
"""Variance risk premium analytics — the implied-vs-realized vol
320329
spread, conditioned on dealer gamma and vanna regime, with
321330
strategy scores for harvesting.
@@ -342,7 +351,7 @@ def vrp(self, symbol: str) -> dict:
342351

343352
# ── Max Pain ────────────────────────────────────────────────────
344353

345-
def max_pain(self, symbol: str, *, expiration: str | None = None) -> dict:
354+
def max_pain(self, symbol: str, *, expiration: str | None = None) -> MaxPainResponse:
346355
"""Max pain analysis with dealer alignment overlay, pain curve, OI
347356
breakdown, expected move context, pin probability, and multi-expiry
348357
calendar. Requires Growth+.

0 commit comments

Comments
 (0)