Vycka12 commited on
Commit
647e2d7
·
1 Parent(s): c6390ac

Update frontend to use Hugging Face Space as backend

Browse files
frontend/src/App.jsx CHANGED
@@ -1,7 +1,7 @@
1
  import { useState, useEffect } from 'react'
2
  import './App.css'
3
 
4
- const API_BASE = (import.meta.env.VITE_API_URL || 'https://6efb-85-206-120-41.ngrok-free.app') + '/api';
5
 
6
  function App() {
7
  const [symbols, setSymbols] = useState(['BTC/USDT']);
 
1
  import { useState, useEffect } from 'react'
2
  import './App.css'
3
 
4
+ const API_BASE = (import.meta.env.VITE_API_URL || 'https://vycka12-binance-data-backend.hf.space') + '/api';
5
 
6
  function App() {
7
  const [symbols, setSymbols] = useState(['BTC/USDT']);
hf_space/Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim
2
+
3
+ WORKDIR /app
4
+
5
+ COPY requirements.txt .
6
+ RUN pip install --no-cache-dir -r requirements.txt
7
+
8
+ COPY . .
9
+
10
+ # HF Spaces expects port 7860
11
+ EXPOSE 7860
12
+
13
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860", "--timeout-keep-alive", "600"]
hf_space/app.py ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+
4
+ sys.stdout.reconfigure(encoding='utf-8')
5
+
6
+ from fastapi import FastAPI, HTTPException
7
+ from fastapi.middleware.cors import CORSMiddleware
8
+ from pydantic import BaseModel
9
+ import ccxt
10
+ from typing import Optional
11
+ import modal
12
+
13
+ app = FastAPI(title="Binance Data Dashboard API")
14
+
15
+ # CORS - allow all origins for Vercel frontend
16
+ app.add_middleware(
17
+ CORSMiddleware,
18
+ allow_origins=["*"],
19
+ allow_credentials=True,
20
+ allow_methods=["*"],
21
+ allow_headers=["*"],
22
+ )
23
+
24
+ # Binance client for symbol list only
25
+ try:
26
+ binance = ccxt.binance()
27
+ except Exception as e:
28
+ print(f"Warning: Could not init Binance client: {e}")
29
+ binance = None
30
+
31
+ class DownloadRequest(BaseModel):
32
+ symbol: str
33
+ interval: str
34
+ data_type: str
35
+ start_date: str
36
+ end_date: str
37
+ threshold: Optional[float] = 1_000_000
38
+ agg_mode: Optional[str] = "Standard (Klines + Liq)"
39
+ datasetType: Optional[str] = None
40
+
41
+ @app.get("/")
42
+ def health():
43
+ return {"status": "ok", "message": "Binance Data Dashboard API on Hugging Face"}
44
+
45
+ @app.get("/api/symbols")
46
+ def get_symbols():
47
+ try:
48
+ if binance is None:
49
+ raise Exception("Binance client not initialized")
50
+ markets = binance.load_markets()
51
+ symbols = sorted(list(markets.keys()))
52
+ return {"symbols": symbols}
53
+ except Exception as e:
54
+ raise HTTPException(status_code=500, detail=str(e))
55
+
56
+ @app.post("/api/download")
57
+ def download_data(request: DownloadRequest):
58
+ print(f"\n{'='*60}")
59
+ print(f"[CLOUD] Download request:")
60
+ print(f" Symbol: {request.symbol}")
61
+ print(f" Interval: {request.interval}")
62
+ print(f" Data Type: {request.data_type}")
63
+ print(f" Start: {request.start_date}")
64
+ print(f" End: {request.end_date}")
65
+ print(f" Threshold: {request.threshold}")
66
+ print(f"{'='*60}")
67
+
68
+ try:
69
+ if request.data_type == 'Klines (OHLCV)':
70
+ print("[CLOUD] Calling fetch_klines_cloud...")
71
+ fn = modal.Function.from_name("binance-data-dashboard", "fetch_klines_cloud")
72
+ result = fn.remote(request.symbol, request.interval, request.start_date, request.end_date)
73
+
74
+ elif request.data_type == 'Liquidations':
75
+ print("[CLOUD] Calling fetch_liquidations_cloud...")
76
+ fn = modal.Function.from_name("binance-data-dashboard", "fetch_liquidations_cloud")
77
+ result = fn.remote(request.symbol, request.start_date, request.end_date)
78
+
79
+ elif request.data_type == 'AggTrades':
80
+ print("[CLOUD] Calling fetch_aggtrades_cloud...")
81
+ fn = modal.Function.from_name("binance-data-dashboard", "fetch_aggtrades_cloud")
82
+ result = fn.remote(request.symbol, request.start_date, request.end_date)
83
+
84
+ elif request.data_type == 'Dollar Bars (ML Ready)':
85
+ print(f"[CLOUD] Calling fetch_dollar_bars_cloud (threshold: {request.threshold})...")
86
+ fn = modal.Function.from_name("binance-data-dashboard", "fetch_dollar_bars_cloud")
87
+ result = fn.remote(request.symbol, request.start_date, request.end_date, request.threshold)
88
+
89
+ else:
90
+ raise HTTPException(status_code=400, detail="Unknown data type.")
91
+
92
+ print(f"[CLOUD] Result received: success={result.get('success')}, rows={result.get('row_count', 0)}")
93
+ return result
94
+
95
+ except Exception as e:
96
+ print(f"KLAIDA: {str(e)}")
97
+ raise HTTPException(status_code=500, detail=str(e))
hf_space/requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn[standard]
3
+ ccxt
4
+ modal
5
+ pydantic