EricSam commited on
Commit
b5e8aa6
Β·
verified Β·
1 Parent(s): ffbd55f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -23
app.py CHANGED
@@ -10,10 +10,12 @@ from datetime import datetime
10
  # Initialize hotdog classification pipeline
11
  hotdog_pipeline = pipeline(task="image-classification", model="julien-c/hotdog-not-hotdog")
12
 
 
 
 
 
13
  # Configuration
14
  API_BASE_URL = "https://open-api.bingx.com"
15
- API_KEY = os.getenv('BINGX_API_KEY', "")
16
- API_SECRET = os.getenv('BINGX_API_SECRET', "")
17
 
18
  # Generate Signature
19
  def generate_signature(api_secret, params_str):
@@ -27,32 +29,32 @@ def parse_params(params):
27
  return params_str + "&timestamp=" + str(int(time.time() * 1000)) if params_str else "timestamp=" + str(int(time.time() * 1000))
28
 
29
  # Fetch from BingX API
30
- def fetch_from_api(endpoint, params=None):
31
- if not API_KEY or not API_SECRET:
32
- raise ValueError("BingX API Key and Secret are not set. Please configure them in Hugging Face Space Secrets.")
33
  params = params or {}
34
  params['recvWindow'] = params.get('recvWindow', '5000')
35
  params_str = parse_params(params)
36
- signature = generate_signature(API_SECRET, params_str)
37
  url = f"{API_BASE_URL}{endpoint}?{params_str}&signature={signature}"
38
  try:
39
- response = requests.get(url, headers={'X-BX-APIKEY': API_KEY, 'Content-Type': 'application/json'})
40
  response.raise_for_status()
41
  return response.json()
42
  except requests.exceptions.RequestException as e:
43
  raise Exception(f"API Error: {str(e)}")
44
 
45
  # Fetch Specific Data
46
- def fetch_balance():
47
- data = fetch_from_api('/openApi/swap/v3/user/balance')
48
  return data['data'][0]['walletBalance'] if data['data'] and data['data'][0]['asset'] == 'USDT' else 0
49
 
50
- def fetch_open_positions():
51
- data = fetch_from_api('/openApi/swap/v2/user/positions', {'symbol': 'BTC-USDT'})
52
  return data['data'] or []
53
 
54
- def fetch_trade_history():
55
- data = fetch_from_api('/openApi/swap/v2/user/income', {'limit': 100})
56
  return data['data'] or []
57
 
58
  # Helper Functions
@@ -82,7 +84,7 @@ def calculate_portfolio_allocation(positions):
82
  data = [val / total_value * 100 if total_value else 0 for val in by_symbol.values()]
83
  return {'labels': labels, 'data': data}
84
 
85
- # Update UI Functions (as Gradio components)
86
  def update_trading_table(positions, trades):
87
  table_rows = []
88
  for pos in positions:
@@ -139,7 +141,7 @@ def update_performance_chart(trades):
139
  return gr.Chart(value=chart_data, type="line", options={
140
  'responsive': True,
141
  'plugins': {'legend': {'display': False}},
142
- 'scales': {'y': {'grid': {'color': 'rgba(0, 0, 0, 0.05)', 'borderDash': [5]}, 'ticks': {'callback': lambda value: f'${value}'}}, 'x': {'grid': {'display': False}}}
143
  })
144
 
145
  def update_allocation_chart(allocation):
@@ -166,7 +168,7 @@ def update_allocation_chart(allocation):
166
  }), gr.HTML(legend_html)
167
 
168
  # Main Data Fetch and Update Function
169
- def update_dashboard():
170
  try:
171
  balance = fetch_balance()
172
  positions = fetch_open_positions()
@@ -191,10 +193,16 @@ def update_dashboard():
191
  )
192
  except Exception as e:
193
  return (
194
- "$0.00", 0, "0 Long β€’ 0 Short", "$0.00", "Low", "0%", gr.HTML("<tr><td colspan='8' class='py-4 text-center'>Error: Failed to sync with BingX API</td></tr>"),
195
  gr.HTML("<div>Error loading stats</div>"), gr.Chart(), (gr.Chart(), gr.HTML("")), "Just now", "Just now"
196
  )
197
 
 
 
 
 
 
 
198
  # Gradio Interface
199
  with gr.Blocks(title="Nakhoda4X Pro") as demo:
200
  gr.Markdown("""
@@ -209,7 +217,6 @@ with gr.Blocks(title="Nakhoda4X Pro") as demo:
209
  gr.Markdown("Connected to BingX via API")
210
  with gr.Column():
211
  refresh_btn = gr.Button("Refresh", variant="secondary")
212
- new_trade_btn = gr.Button("New Trade", variant="primary")
213
 
214
  with gr.Row():
215
  with gr.Column(scale=1):
@@ -244,7 +251,12 @@ with gr.Blocks(title="Nakhoda4X Pro") as demo:
244
  with api_connection:
245
  gr.HTML("<div class='bg-gradient-to-r from-primary to-secondary rounded-2xl p-6'>")
246
  gr.HTML("<div class='flex items-center mb-4'><div class='mr-4'><div class='h-12 w-12 rounded-xl bg-white/30 flex items-center justify-center'><i class='fas fa-plug text-white text-xl'></i></div></div><div><h3 class='text-lg font-bold text-white'>BingX API Connected</h3><p id='last-sync' class='text-blue-100'>Last synced: Just now</p></div></div>")
 
 
 
 
247
  sync_now = gr.Button("Sync Now", elem_classes="w-full py-3 bg-white rounded-xl text-primary font-bold flex items-center justify-center")
 
248
  with gr.Column():
249
  portfolio_allocation = gr.Blocks()
250
  with portfolio_allocation:
@@ -254,19 +266,23 @@ with gr.Blocks(title="Nakhoda4X Pro") as demo:
254
  allocation_chart = gr.Chart()
255
  allocation_legend = gr.HTML()
256
 
257
- # Initial update
258
- stats_cards.update(value=gr.HTML("<div class='grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6'>"))
259
- demo.load(fn=update_dashboard, inputs=None, outputs=[
 
 
 
 
260
  total_balance, open_trades, trade_types, today_profit,
261
  risk_exposure, exposure_percent, trading_activity, advanced_stats,
262
  performance_chart, (allocation_chart, allocation_legend), gr.State(value=None), gr.State(value=None)
263
  ])
264
- refresh_btn.click(fn=update_dashboard, inputs=None, outputs=[
265
  total_balance, open_trades, trade_types, today_profit,
266
  risk_exposure, exposure_percent, trading_activity, advanced_stats,
267
  performance_chart, (allocation_chart, allocation_legend), gr.State(value=None), gr.State(value=None)
268
  ])
269
- sync_now.click(fn=update_dashboard, inputs=None, outputs=[
270
  total_balance, open_trades, trade_types, today_profit,
271
  risk_exposure, exposure_percent, trading_activity, advanced_stats,
272
  performance_chart, (allocation_chart, allocation_legend), gr.State(value=None), gr.State(value=None)
 
10
  # Initialize hotdog classification pipeline
11
  hotdog_pipeline = pipeline(task="image-classification", model="julien-c/hotdog-not-hotdog")
12
 
13
+ # Global state for API credentials (updated by user input)
14
+ api_key = gr.State(os.getenv('BINGX_API_KEY', ""))
15
+ api_secret = gr.State(os.getenv('BINGX_API_SECRET', ""))
16
+
17
  # Configuration
18
  API_BASE_URL = "https://open-api.bingx.com"
 
 
19
 
20
  # Generate Signature
21
  def generate_signature(api_secret, params_str):
 
29
  return params_str + "&timestamp=" + str(int(time.time() * 1000)) if params_str else "timestamp=" + str(int(time.time() * 1000))
30
 
31
  # Fetch from BingX API
32
+ def fetch_from_api(endpoint, params=None, api_key=api_key, api_secret=api_secret):
33
+ if not api_key.value or not api_secret.value:
34
+ raise ValueError("BingX API Key and Secret are not set. Please enter them in the Manage API Credentials section.")
35
  params = params or {}
36
  params['recvWindow'] = params.get('recvWindow', '5000')
37
  params_str = parse_params(params)
38
+ signature = generate_signature(api_secret.value, params_str)
39
  url = f"{API_BASE_URL}{endpoint}?{params_str}&signature={signature}"
40
  try:
41
+ response = requests.get(url, headers={'X-BX-APIKEY': api_key.value, 'Content-Type': 'application/json'})
42
  response.raise_for_status()
43
  return response.json()
44
  except requests.exceptions.RequestException as e:
45
  raise Exception(f"API Error: {str(e)}")
46
 
47
  # Fetch Specific Data
48
+ def fetch_balance(api_key=api_key, api_secret=api_secret):
49
+ data = fetch_from_api('/openApi/swap/v3/user/balance', api_key=api_key, api_secret=api_secret)
50
  return data['data'][0]['walletBalance'] if data['data'] and data['data'][0]['asset'] == 'USDT' else 0
51
 
52
+ def fetch_open_positions(api_key=api_key, api_secret=api_secret):
53
+ data = fetch_from_api('/openApi/swap/v2/user/positions', {'symbol': 'BTC-USDT'}, api_key=api_key, api_secret=api_secret)
54
  return data['data'] or []
55
 
56
+ def fetch_trade_history(api_key=api_key, api_secret=api_secret):
57
+ data = fetch_from_api('/openApi/swap/v2/user/income', {'limit': 100}, api_key=api_key, api_secret=api_secret)
58
  return data['data'] or []
59
 
60
  # Helper Functions
 
84
  data = [val / total_value * 100 if total_value else 0 for val in by_symbol.values()]
85
  return {'labels': labels, 'data': data}
86
 
87
+ # Update UI Functions
88
  def update_trading_table(positions, trades):
89
  table_rows = []
90
  for pos in positions:
 
141
  return gr.Chart(value=chart_data, type="line", options={
142
  'responsive': True,
143
  'plugins': {'legend': {'display': False}},
144
+ 'scales': {'y': {'grid': {'color': 'rgba(0, 0, 0, 0.05)', 'borderDash': [5]}, 'ticks': {'callback': lambda value: f'${value}'}}, 'x': {'grid': {'display': false}}}
145
  })
146
 
147
  def update_allocation_chart(allocation):
 
168
  }), gr.HTML(legend_html)
169
 
170
  # Main Data Fetch and Update Function
171
+ def update_dashboard(api_key, api_secret):
172
  try:
173
  balance = fetch_balance()
174
  positions = fetch_open_positions()
 
193
  )
194
  except Exception as e:
195
  return (
196
+ "$0.00", 0, "0 Long β€’ 0 Short", "$0.00", "Low", "0%", gr.HTML("<tr><td colspan='8' class='py-4 text-center'>Error: Failed to sync with BingX API - Check credentials</td></tr>"),
197
  gr.HTML("<div>Error loading stats</div>"), gr.Chart(), (gr.Chart(), gr.HTML("")), "Just now", "Just now"
198
  )
199
 
200
+ # Save Credentials Function
201
+ def save_credentials(new_api_key, new_api_secret, api_key, api_secret):
202
+ if not new_api_key or not new_api_secret:
203
+ return gr.Warning("Both API Key and Secret are required."), api_key, api_secret
204
+ return gr.Info("Credentials saved successfully! Syncing data..."), gr.State(value=new_api_key), gr.State(value=new_api_secret)
205
+
206
  # Gradio Interface
207
  with gr.Blocks(title="Nakhoda4X Pro") as demo:
208
  gr.Markdown("""
 
217
  gr.Markdown("Connected to BingX via API")
218
  with gr.Column():
219
  refresh_btn = gr.Button("Refresh", variant="secondary")
 
220
 
221
  with gr.Row():
222
  with gr.Column(scale=1):
 
251
  with api_connection:
252
  gr.HTML("<div class='bg-gradient-to-r from-primary to-secondary rounded-2xl p-6'>")
253
  gr.HTML("<div class='flex items-center mb-4'><div class='mr-4'><div class='h-12 w-12 rounded-xl bg-white/30 flex items-center justify-center'><i class='fas fa-plug text-white text-xl'></i></div></div><div><h3 class='text-lg font-bold text-white'>BingX API Connected</h3><p id='last-sync' class='text-blue-100'>Last synced: Just now</p></div></div>")
254
+ with gr.Row():
255
+ api_key_input = gr.Textbox(label="API Key", value=api_key.value, type="password")
256
+ api_secret_input = gr.Textbox(label="API Secret", value=api_secret.value, type="password")
257
+ save_btn = gr.Button("Save Credentials", variant="primary")
258
  sync_now = gr.Button("Sync Now", elem_classes="w-full py-3 bg-white rounded-xl text-primary font-bold flex items-center justify-center")
259
+ gr.Markdown("**Note:** Credentials are stored in memory for this session only.")
260
  with gr.Column():
261
  portfolio_allocation = gr.Blocks()
262
  with portfolio_allocation:
 
266
  allocation_chart = gr.Chart()
267
  allocation_legend = gr.HTML()
268
 
269
+ # Event Handlers
270
+ save_btn.click(
271
+ fn=save_credentials,
272
+ inputs=[api_key_input, api_secret_input, api_key, api_secret],
273
+ outputs=[gr.Markdown(), api_key, api_secret]
274
+ )
275
+ demo.load(fn=update_dashboard, inputs=[api_key, api_secret], outputs=[
276
  total_balance, open_trades, trade_types, today_profit,
277
  risk_exposure, exposure_percent, trading_activity, advanced_stats,
278
  performance_chart, (allocation_chart, allocation_legend), gr.State(value=None), gr.State(value=None)
279
  ])
280
+ refresh_btn.click(fn=update_dashboard, inputs=[api_key, api_secret], outputs=[
281
  total_balance, open_trades, trade_types, today_profit,
282
  risk_exposure, exposure_percent, trading_activity, advanced_stats,
283
  performance_chart, (allocation_chart, allocation_legend), gr.State(value=None), gr.State(value=None)
284
  ])
285
+ sync_now.click(fn=update_dashboard, inputs=[api_key, api_secret], outputs=[
286
  total_balance, open_trades, trade_types, today_profit,
287
  risk_exposure, exposure_percent, trading_activity, advanced_stats,
288
  performance_chart, (allocation_chart, allocation_legend), gr.State(value=None), gr.State(value=None)