Skip to content

Commit fd984e8

Browse files
tdobrowolski1claude
andcommitted
v0.3.1: rename screener endpoint path /v1/screener/live -> /v1/screener
SDK method (fa.screener()) unchanged — this is a transparent path update to track the renamed backend endpoint. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent bde6d52 commit fd984e8

4 files changed

Lines changed: 25 additions & 25 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.3.0"
7+
version = "0.3.1"
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/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
TierRestrictedError,
1111
)
1212

13-
__version__ = "0.3.0"
13+
__version__ = "0.3.1"
1414
__all__ = [
1515
"FlashAlpha",
1616
"FlashAlphaError",

src/flashalpha/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ def screener(
375375
body["limit"] = limit
376376
if offset is not None:
377377
body["offset"] = offset
378-
return self._post("/v1/screener/live", body)
378+
return self._post("/v1/screener", body)
379379

380380
# ── Account & System ────────────────────────────────────────────
381381

tests/test_client.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ def test_screener_empty(fa):
336336
"meta": {"total_count": 10, "returned_count": 10, "tier": "growth"},
337337
"data": [{"symbol": "SPY", "price": 656.01}],
338338
}
339-
responses.post(f"{BASE}/v1/screener/live", json=payload)
339+
responses.post(f"{BASE}/v1/screener", json=payload)
340340
result = fa.screener()
341341
assert result["meta"]["tier"] == "growth"
342342
assert result["data"][0]["symbol"] == "SPY"
@@ -346,18 +346,18 @@ def test_screener_empty(fa):
346346

347347
@responses.activate
348348
def test_screener_sends_post_with_json_content_type(fa):
349-
responses.post(f"{BASE}/v1/screener/live", json={"meta": {}, "data": []})
349+
responses.post(f"{BASE}/v1/screener", json={"meta": {}, "data": []})
350350
fa.screener(limit=5)
351351
req = responses.calls[0].request
352352
assert req.method == "POST"
353-
assert req.url == f"{BASE}/v1/screener/live"
353+
assert req.url == f"{BASE}/v1/screener"
354354
assert req.headers.get("Content-Type") == "application/json"
355355
assert req.headers.get("X-Api-Key") == "test-key"
356356

357357

358358
@responses.activate
359359
def test_screener_leaf_filter(fa):
360-
responses.post(f"{BASE}/v1/screener/live", json={"meta": {}, "data": []})
360+
responses.post(f"{BASE}/v1/screener", json={"meta": {}, "data": []})
361361
fa.screener(filters={"field": "regime", "operator": "eq", "value": "positive_gamma"})
362362
body = _screener_body(responses.calls[0])
363363
assert body["filters"]["field"] == "regime"
@@ -367,7 +367,7 @@ def test_screener_leaf_filter(fa):
367367

368368
@responses.activate
369369
def test_screener_and_group(fa):
370-
responses.post(f"{BASE}/v1/screener/live", json={"meta": {}, "data": []})
370+
responses.post(f"{BASE}/v1/screener", json={"meta": {}, "data": []})
371371
fa.screener(
372372
filters={
373373
"op": "and",
@@ -390,7 +390,7 @@ def test_screener_and_group(fa):
390390

391391
@responses.activate
392392
def test_screener_or_group(fa):
393-
responses.post(f"{BASE}/v1/screener/live", json={"meta": {}, "data": []})
393+
responses.post(f"{BASE}/v1/screener", json={"meta": {}, "data": []})
394394
fa.screener(
395395
filters={
396396
"op": "or",
@@ -406,7 +406,7 @@ def test_screener_or_group(fa):
406406

407407
@responses.activate
408408
def test_screener_nested_and_inside_or(fa):
409-
responses.post(f"{BASE}/v1/screener/live", json={"meta": {}, "data": []})
409+
responses.post(f"{BASE}/v1/screener", json={"meta": {}, "data": []})
410410
fa.screener(
411411
filters={
412412
"op": "or",
@@ -436,7 +436,7 @@ def test_screener_nested_and_inside_or(fa):
436436

437437
@responses.activate
438438
def test_screener_between_operator(fa):
439-
responses.post(f"{BASE}/v1/screener/live", json={"meta": {}, "data": []})
439+
responses.post(f"{BASE}/v1/screener", json={"meta": {}, "data": []})
440440
fa.screener(filters={"field": "atm_iv", "operator": "between", "value": [15, 25]})
441441
body = _screener_body(responses.calls[0])
442442
assert body["filters"]["operator"] == "between"
@@ -445,7 +445,7 @@ def test_screener_between_operator(fa):
445445

446446
@responses.activate
447447
def test_screener_in_operator(fa):
448-
responses.post(f"{BASE}/v1/screener/live", json={"meta": {}, "data": []})
448+
responses.post(f"{BASE}/v1/screener", json={"meta": {}, "data": []})
449449
fa.screener(filters={"field": "term_state", "operator": "in", "value": ["contango", "mixed"]})
450450
body = _screener_body(responses.calls[0])
451451
assert body["filters"]["operator"] == "in"
@@ -454,7 +454,7 @@ def test_screener_in_operator(fa):
454454

455455
@responses.activate
456456
def test_screener_null_operators(fa):
457-
responses.post(f"{BASE}/v1/screener/live", json={"meta": {}, "data": []})
457+
responses.post(f"{BASE}/v1/screener", json={"meta": {}, "data": []})
458458
fa.screener(filters={"field": "vrp_regime", "operator": "is_not_null"})
459459
body = _screener_body(responses.calls[0])
460460
assert body["filters"]["operator"] == "is_not_null"
@@ -464,7 +464,7 @@ def test_screener_null_operators(fa):
464464
@responses.activate
465465
def test_screener_cascading_filters(fa):
466466
"""Cascading filters on expiries/strikes/contracts levels."""
467-
responses.post(f"{BASE}/v1/screener/live", json={"meta": {}, "data": []})
467+
responses.post(f"{BASE}/v1/screener", json={"meta": {}, "data": []})
468468
fa.screener(
469469
filters={
470470
"op": "and",
@@ -489,7 +489,7 @@ def test_screener_cascading_filters(fa):
489489

490490
@responses.activate
491491
def test_screener_with_formulas(fa):
492-
responses.post(f"{BASE}/v1/screener/live", json={"meta": {}, "data": []})
492+
responses.post(f"{BASE}/v1/screener", json={"meta": {}, "data": []})
493493
fa.screener(
494494
formulas=[{"alias": "vrp_ratio", "expression": "atm_iv / rv_20d"}],
495495
filters={"formula": "vrp_ratio", "operator": "gte", "value": 1.2},
@@ -504,7 +504,7 @@ def test_screener_with_formulas(fa):
504504

505505
@responses.activate
506506
def test_screener_inline_formula(fa):
507-
responses.post(f"{BASE}/v1/screener/live", json={"meta": {}, "data": []})
507+
responses.post(f"{BASE}/v1/screener", json={"meta": {}, "data": []})
508508
fa.screener(
509509
filters={"formula": "atm_iv - rv_20d", "operator": "gt", "value": 6},
510510
)
@@ -514,7 +514,7 @@ def test_screener_inline_formula(fa):
514514

515515
@responses.activate
516516
def test_screener_multi_sort(fa):
517-
responses.post(f"{BASE}/v1/screener/live", json={"meta": {}, "data": []})
517+
responses.post(f"{BASE}/v1/screener", json={"meta": {}, "data": []})
518518
fa.screener(
519519
sort=[
520520
{"field": "dealer_flow_risk", "direction": "asc"},
@@ -530,7 +530,7 @@ def test_screener_multi_sort(fa):
530530

531531
@responses.activate
532532
def test_screener_pagination(fa):
533-
responses.post(f"{BASE}/v1/screener/live", json={"meta": {}, "data": []})
533+
responses.post(f"{BASE}/v1/screener", json={"meta": {}, "data": []})
534534
fa.screener(limit=10, offset=10)
535535
body = _screener_body(responses.calls[0])
536536
assert body["limit"] == 10
@@ -539,23 +539,23 @@ def test_screener_pagination(fa):
539539

540540
@responses.activate
541541
def test_screener_negative_number(fa):
542-
responses.post(f"{BASE}/v1/screener/live", json={"meta": {}, "data": []})
542+
responses.post(f"{BASE}/v1/screener", json={"meta": {}, "data": []})
543543
fa.screener(filters={"field": "net_gex", "operator": "lt", "value": -500000})
544544
body = _screener_body(responses.calls[0])
545545
assert body["filters"]["value"] == -500000
546546

547547

548548
@responses.activate
549549
def test_screener_select_star(fa):
550-
responses.post(f"{BASE}/v1/screener/live", json={"meta": {}, "data": []})
550+
responses.post(f"{BASE}/v1/screener", json={"meta": {}, "data": []})
551551
fa.screener(select=["*"])
552552
body = _screener_body(responses.calls[0])
553553
assert body["select"] == ["*"]
554554

555555

556556
@responses.activate
557557
def test_screener_select_star_with_formula(fa):
558-
responses.post(f"{BASE}/v1/screener/live", json={"meta": {}, "data": []})
558+
responses.post(f"{BASE}/v1/screener", json={"meta": {}, "data": []})
559559
fa.screener(
560560
formulas=[{"alias": "ratio", "expression": "call_wall / (put_wall + 30)"}],
561561
select=["*", "ratio"],
@@ -580,7 +580,7 @@ def test_screener_returns_response_structure(fa):
580580
{"symbol": "SPY", "price": 656.01, "regime": "positive_gamma", "atm_iv": 20.7}
581581
],
582582
}
583-
responses.post(f"{BASE}/v1/screener/live", json=payload)
583+
responses.post(f"{BASE}/v1/screener", json=payload)
584584
result = fa.screener()
585585
assert result["meta"]["tier"] == "alpha"
586586
assert result["meta"]["universe_size"] == 250
@@ -594,7 +594,7 @@ def test_screener_tier_restricted_alpha_field(fa):
594594
"error": "validation_error",
595595
"message": "Field 'harvest_score' requires the Alpha plan or higher.",
596596
}
597-
responses.post(f"{BASE}/v1/screener/live", json=err_body, status=400)
597+
responses.post(f"{BASE}/v1/screener", json=err_body, status=400)
598598
with pytest.raises(FlashAlphaError) as exc:
599599
fa.screener(filters={"field": "harvest_score", "operator": "gte", "value": 65})
600600
assert exc.value.status_code == 400
@@ -608,7 +608,7 @@ def test_screener_formula_error(fa):
608608
"error": "formula_error",
609609
"message": "Unexpected token '+' at position 5",
610610
}
611-
responses.post(f"{BASE}/v1/screener/live", json=err_body, status=400)
611+
responses.post(f"{BASE}/v1/screener", json=err_body, status=400)
612612
with pytest.raises(FlashAlphaError):
613613
fa.screener(formulas=[{"alias": "bad", "expression": "+ atm_iv"}])
614614

@@ -622,7 +622,7 @@ def test_screener_tier_restricted_403(fa):
622622
"current_plan": "Free",
623623
"required_plan": "Growth",
624624
}
625-
responses.post(f"{BASE}/v1/screener/live", json=err_body, status=403)
625+
responses.post(f"{BASE}/v1/screener", json=err_body, status=403)
626626
with pytest.raises(TierRestrictedError) as exc:
627627
fa.screener()
628628
assert exc.value.current_plan == "Free"

0 commit comments

Comments
 (0)