Skip to content

Commit 0629bcd

Browse files
committed
Refactor liquidation API and enhance routing
- Renamed the existing `api/liquidation.py` API to `api/liquidation_curves_api.py` for improved clarity. - Updated the routing in `app.py` to include the new `liquidation_curves_api` under the `/api/liquidation-curves` path. - Adjusted imports in `__init__.py` and other relevant files to reflect the new API structure. - Renamed page/liquidation_curves.py to liquidation `liquidation_curves_page.py` to follow updated naming convention. - Added a loading animation and error handling in the Streamlit interface for better user experience during data fetching.
1 parent 108f8af commit 0629bcd

File tree

7 files changed

+52
-14
lines changed

7 files changed

+52
-14
lines changed

backend/api/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
deposits_api,
55
health,
66
high_leverage_api,
7-
liquidation,
7+
liquidation_curves_api,
88
market_recommender_api,
99
metadata,
1010
open_interest_api,

backend/api/liquidation.py renamed to backend/api/liquidation_curves_api.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,23 @@
77
router = APIRouter()
88

99

10-
@router.get("/liquidation-curve")
10+
@router.get("/liquidation-curves")
1111
def get_liquidation_curve(request: BackendRequest, market_index: int):
1212
vat: Vat = request.state.backend_state.vat
13+
last_oracle_slot = getattr(request.state.backend_state, "last_oracle_slot", 0)
14+
# Debug logging to understand the slot issue
15+
print(f"[DEBUG] Liquidation API - last_oracle_slot: {last_oracle_slot}, pickle_path: {request.state.backend_state.current_pickle_path}")
1316
liquidations_long: list[tuple[float, float, str]] = []
1417
liquidations_short: list[tuple[float, float, str]] = []
1518
market_price = vat.perp_oracles.get(market_index)
1619
if market_price is None:
1720
print("Market price is None")
18-
return {"liquidations_long": [], "liquidations_short": [], "market_price_ui": 0}
21+
return {
22+
"liquidations_long": [],
23+
"liquidations_short": [],
24+
"market_price_ui": 0,
25+
"slot": last_oracle_slot
26+
}
1927
market_price_ui = market_price.price / PRICE_PRECISION
2028
for pubkey, user in vat.users.user_map.items():
2129
perp_position = user.get_perp_position(market_index)
@@ -48,4 +56,5 @@ def get_liquidation_curve(request: BackendRequest, market_index: int):
4856
"liquidations_long": liquidations_long,
4957
"liquidations_short": liquidations_short,
5058
"market_price_ui": market_price_ui,
59+
"slot": last_oracle_slot,
5160
}

backend/app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
backend_health,
1414
deposits_api,
1515
health,
16-
liquidation,
16+
liquidation_curves_api,
1717
market_recommender_api,
1818
metadata,
1919
open_interest_api,
@@ -80,7 +80,7 @@ async def lifespan(app: FastAPI):
8080
app.include_router(health.router, prefix="/api/health", tags=["health"])
8181
app.include_router(backend_health.router, prefix="/api/backend-health", tags=["backend-health"])
8282
app.include_router(metadata.router, prefix="/api/metadata", tags=["metadata"])
83-
app.include_router(liquidation.router, prefix="/api/liquidation", tags=["liquidation"])
83+
app.include_router(liquidation_curves_api.router, prefix="/api/liquidation-curves", tags=["liquidation-curves"])
8484
app.include_router(price_shock.router, prefix="/api/price-shock", tags=["price-shock"])
8585
app.include_router(
8686
asset_liability.router, prefix="/api/asset-liability", tags=["asset-liability"]

images/pacman.gif

18.5 KB
Loading

src/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from page.backend import backend_page
1313
from page.deposits_page import deposits_page
1414
from page.health import health_page
15-
from page.liquidation_curves import liquidation_curves_page
15+
from page.liquidation_curves_page import liquidation_curves_page
1616
from page.market_inspector import market_inspector_page
1717
from page.orderbook import orderbook_page
1818
from page.pnl import pnl_page

src/page/liquidation_curves.py renamed to src/page/liquidation_curves_page.py

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,35 @@
11
from collections import defaultdict
22
from typing import List, Tuple, TypedDict
3+
import time
34

45
import numpy as np
56
import plotly.graph_objects as go
67
import streamlit as st
78
from driftpy.constants.perp_markets import mainnet_perp_market_configs
89

910
from lib.api import fetch_api_data
11+
from src.utils import get_current_slot
12+
13+
RETRY_DELAY_SECONDS = 5
1014

1115

1216
class PriceData(TypedDict):
1317
notional: float
1418
positions: List[Tuple[str, float]]
1519

1620

21+
def is_processing(result):
22+
"""Checks if the API result indicates backend processing."""
23+
return isinstance(result, dict) and result.get("result") == "processing"
24+
25+
26+
def has_error(result):
27+
"""Checks if the API result indicates an error or is missing essential data."""
28+
return result is None or (
29+
isinstance(result, dict) and "liquidations_long" not in result
30+
)
31+
32+
1733
def plot_liquidation_curves(liquidation_data):
1834
liquidations_long = liquidation_data["liquidations_long"]
1935
liquidations_short = liquidation_data["liquidations_short"]
@@ -133,23 +149,36 @@ def liquidation_curves_page():
133149
liquidation_data = None
134150
try:
135151
liquidation_data = fetch_api_data(
136-
"liquidation",
137-
"liquidation-curve",
152+
"liquidation-curves",
153+
"liquidation-curves",
138154
params=dict(st.query_params),
139-
retry=True,
155+
retry=False,
140156
)
141157
except Exception as e:
142158
st.write(e)
143159
st.stop()
144160

145-
if liquidation_data is None:
146-
st.write("Fetching data for the first time...")
147-
st.image(
148-
"https://i.gifer.com/origin/8a/8a47f769c400b0b7d81a8f6f8e09a44a_w200.gif"
161+
if is_processing(liquidation_data):
162+
st.info(
163+
f"Backend is processing liquidation data. Auto-refreshing in {RETRY_DELAY_SECONDS} seconds..."
149164
)
165+
with st.spinner("Please wait..."):
166+
time.sleep(RETRY_DELAY_SECONDS)
167+
st.rerun()
168+
return
169+
170+
if has_error(liquidation_data):
171+
st.write("Fetching data for the first time...")
172+
st.image("images/pacman.gif")
150173
st.write("Check again in one minute!")
151174
st.stop()
152175

176+
# Display slot age information
177+
slot = liquidation_data.get("slot", 0)
178+
current_slot = get_current_slot()
179+
slot_age = current_slot - slot
180+
st.info(f"Data from slot {slot}, which is {slot_age} slots old.")
181+
153182
(
154183
long_fig,
155184
short_fig,

src/page/welcome.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def welcome_page():
2727
)
2828

2929
st.page_link(
30-
StreamlitPage("page/liquidation_curves.py", url_path="liquidation-curves"),
30+
StreamlitPage("page/liquidation_curves_page.py", url_path="liquidation-curves"),
3131
label="💧 **Liquidations** - Explore liquidation curves and potential risks",
3232
)
3333
st.page_link(

0 commit comments

Comments
 (0)