gfathertech commited on
Commit
bb015e0
Β·
verified Β·
1 Parent(s): 6f85e2d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -31
app.py CHANGED
@@ -5,15 +5,25 @@ Compatible with Gradio 6.0+
5
  """
6
  import os
7
  import gradio as gr
 
8
  from client import BackendClient
9
 
10
  # ── Environment Configurations ────────────────────────────────────────────
11
  BACKEND_URL = os.getenv("BACKEND_URL", "http://localhost:7860")
12
  HF_TOKEN = os.getenv("HF_TOKEN") or os.getenv("API_KEY", "")
13
- USER_KEY = os.getenv("USER_KEY", "samuel_super_secret_key_1234567890_key")
 
14
 
15
  client = BackendClient(backend_url=BACKEND_URL, token=HF_TOKEN)
16
 
 
 
 
 
 
 
 
 
17
  # ── Custom CSS for ChatGPT-style Layout ───────────────────────────────────
18
  custom_css = """
19
  .sidebar-container {
@@ -41,7 +51,11 @@ custom_css = """
41
  # ── Helper to Load & Parse Backend Schema ─────────────────────────────────
42
  def load_backend_modules(api_key: str):
43
  """Fetch live OpenAPI spec and parse available backend routes into modules."""
44
- ok, schema = client.fetch_openapi_schema(user_api_key=api_key)
 
 
 
 
45
  modules_map = {}
46
 
47
  if ok and isinstance(schema, dict) and "paths" in schema:
@@ -68,7 +82,7 @@ def load_backend_modules(api_key: str):
68
  return modules_map, module_names
69
 
70
 
71
- # Load initial schema at startup
72
  INITIAL_MAP, INITIAL_CHOICES = load_backend_modules(USER_KEY)
73
 
74
  # ── Gradio Blocks Interface (Clean Gradio 6.0 Constructor) ────────────────
@@ -84,9 +98,9 @@ with gr.Blocks(title="SOG-X Modular Workspace") as demo:
84
  with gr.Accordion("βš™οΈ Backend & Credentials", open=False):
85
  user_key_input = gr.Textbox(
86
  label="Active API Key",
87
- value=USER_KEY,
88
  type="password",
89
- placeholder="Enter your 32+ char key...",
90
  interactive=True,
91
  )
92
  sync_btn = gr.Button("πŸ”„ Sync Backend Modules", size="sm")
@@ -170,31 +184,37 @@ with gr.Blocks(title="SOG-X Modular Workspace") as demo:
170
  params = {}
171
  payload = {}
172
  files = {}
173
-
174
- # Parse uploaded files
175
- if file_obj is not None:
176
- file_path = file_obj.name if hasattr(file_obj, "name") else str(file_obj)
177
- files["file"] = open(file_path, "rb")
178
-
179
- # Parse text input
180
- if text_val and text_val.strip():
181
- cleaned_text = text_val.strip()
182
- if method == "GET":
183
- params["query"] = cleaned_text
184
- params["url"] = cleaned_text
185
- else:
186
- payload["input"] = cleaned_text
187
- payload["url"] = cleaned_text
188
- payload["prompt"] = cleaned_text
189
-
190
- success, response = client.execute_dynamic_request(
191
- path=path,
192
- method=method,
193
- params=params,
194
- payload=payload,
195
- files=files,
196
- user_api_key=active_key,
197
- )
 
 
 
 
 
 
198
 
199
  # Check for downloadable output path in JSON response
200
  if success and isinstance(response, dict) and "file_path" in response:
@@ -210,9 +230,11 @@ with gr.Blocks(title="SOG-X Modular Workspace") as demo:
210
 
211
  # ── Launch Application (Gradio 6.0 Compliant) ─────────────────────────────
212
  if __name__ == "__main__":
 
 
213
  demo.launch(
214
  server_name="0.0.0.0",
215
- server_port=7860,
216
  theme=gr.themes.Soft(),
217
  css=custom_css,
218
  share=False,
 
5
  """
6
  import os
7
  import gradio as gr
8
+ import spaces
9
  from client import BackendClient
10
 
11
  # ── Environment Configurations ────────────────────────────────────────────
12
  BACKEND_URL = os.getenv("BACKEND_URL", "http://localhost:7860")
13
  HF_TOKEN = os.getenv("HF_TOKEN") or os.getenv("API_KEY", "")
14
+ # No hardcoded fallback β€” if USER_KEY isn't set as a Space secret, start blank.
15
+ USER_KEY = os.getenv("USER_KEY", "")
16
 
17
  client = BackendClient(backend_url=BACKEND_URL, token=HF_TOKEN)
18
 
19
+
20
+ @spaces.GPU
21
+ def _warmup():
22
+ """Dummy function so HF's ZeroGPU startup check finds a @spaces.GPU function.
23
+ Not actually used for compute β€” all real work happens on the remote backend."""
24
+ return "ok"
25
+
26
+
27
  # ── Custom CSS for ChatGPT-style Layout ───────────────────────────────────
28
  custom_css = """
29
  .sidebar-container {
 
51
  # ── Helper to Load & Parse Backend Schema ─────────────────────────────────
52
  def load_backend_modules(api_key: str):
53
  """Fetch live OpenAPI spec and parse available backend routes into modules."""
54
+ try:
55
+ ok, schema = client.fetch_openapi_schema(user_api_key=api_key)
56
+ except Exception as e:
57
+ ok, schema = False, {"error": str(e)}
58
+
59
  modules_map = {}
60
 
61
  if ok and isinstance(schema, dict) and "paths" in schema:
 
82
  return modules_map, module_names
83
 
84
 
85
+ # Load initial schema at startup (safe even if backend is unreachable)
86
  INITIAL_MAP, INITIAL_CHOICES = load_backend_modules(USER_KEY)
87
 
88
  # ── Gradio Blocks Interface (Clean Gradio 6.0 Constructor) ────────────────
 
98
  with gr.Accordion("βš™οΈ Backend & Credentials", open=False):
99
  user_key_input = gr.Textbox(
100
  label="Active API Key",
101
+ value="", # never pre-fill a real secret into a client-visible field
102
  type="password",
103
+ placeholder="Enter your API key...",
104
  interactive=True,
105
  )
106
  sync_btn = gr.Button("πŸ”„ Sync Backend Modules", size="sm")
 
184
  params = {}
185
  payload = {}
186
  files = {}
187
+ file_handle = None
188
+
189
+ try:
190
+ # Parse uploaded files
191
+ if file_obj is not None:
192
+ file_path = file_obj.name if hasattr(file_obj, "name") else str(file_obj)
193
+ file_handle = open(file_path, "rb")
194
+ files["file"] = file_handle
195
+
196
+ # Parse text input
197
+ if text_val and text_val.strip():
198
+ cleaned_text = text_val.strip()
199
+ if method == "GET":
200
+ params["query"] = cleaned_text
201
+ params["url"] = cleaned_text
202
+ else:
203
+ payload["input"] = cleaned_text
204
+ payload["url"] = cleaned_text
205
+ payload["prompt"] = cleaned_text
206
+
207
+ success, response = client.execute_dynamic_request(
208
+ path=path,
209
+ method=method,
210
+ params=params,
211
+ payload=payload,
212
+ files=files,
213
+ user_api_key=active_key,
214
+ )
215
+ finally:
216
+ if file_handle:
217
+ file_handle.close()
218
 
219
  # Check for downloadable output path in JSON response
220
  if success and isinstance(response, dict) and "file_path" in response:
 
230
 
231
  # ── Launch Application (Gradio 6.0 Compliant) ─────────────────────────────
232
  if __name__ == "__main__":
233
+ _warmup() # satisfies HF ZeroGPU startup check; app itself does no local GPU work
234
+ port = int(os.getenv("PORT", 7860))
235
  demo.launch(
236
  server_name="0.0.0.0",
237
+ server_port=port,
238
  theme=gr.themes.Soft(),
239
  css=custom_css,
240
  share=False,