Basementup commited on
Commit
8bed15c
·
verified ·
1 Parent(s): 32d5b84

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -73
app.py CHANGED
@@ -6,16 +6,7 @@ import asyncio
6
  import subprocess
7
  from pathlib import Path
8
  import gradio as gr
9
-
10
- try:
11
- import spaces
12
- SPACES_ENABLED = True
13
- except ImportError:
14
- SPACES_ENABLED = False
15
- class spaces:
16
- @staticmethod
17
- def GPU(f):
18
- return f
19
 
20
  # All dependencies are installed via requirements.txt / apt.txt
21
  from pypdf import PdfReader
@@ -39,59 +30,43 @@ _MODELS = [
39
  def call_llama(prompt: str, max_tokens: int = 2000) -> str:
40
  token = os.environ.get("HF_TOKEN", "")
41
  headers = {"Authorization": f"Bearer {token}"} if token else {}
42
-
43
- # Add default header to prevent gating issues
44
- headers["User-Agent"] = "Phoenix-Framework/1.0"
45
-
46
  for model in _MODELS:
47
- for attempt in range(5):
48
  try:
 
49
  resp = _req.post(
50
  _FREE_API.format(model=model),
51
  headers=headers,
52
  json={
53
- "inputs": prompt,
54
  "parameters": {
55
  "max_new_tokens": max_tokens,
56
  "temperature": 0.7,
57
  "return_full_text": False,
58
  "do_sample": True,
59
  },
60
- "options": {"wait_for_model": True, "use_cache": False}
61
  },
62
  timeout=180
63
  )
64
-
65
  if resp.status_code == 200:
66
  result = resp.json()
67
  if isinstance(result, list) and result:
68
  text = result[0].get("generated_text", "").strip()
69
  if text:
70
  return text
71
- elif isinstance(result, dict) and "generated_text" in result:
72
- text = result.get("generated_text", "").strip()
73
- if text:
74
- return text
75
-
76
- # 503 = model loading, retry with backoff
77
- if resp.status_code == 503:
78
- wait_time = min(60 * (attempt + 1), 300) # cap at 5 min
79
- time.sleep(wait_time)
80
  continue
81
-
82
- # 429/402 = rate limit or payment issue, skip model
83
- if resp.status_code in [429, 402]:
84
  break
85
-
86
- # Other errors, retry after delay
87
- time.sleep(5 * (attempt + 1))
88
- continue
89
-
90
- except Exception as e:
91
- time.sleep(5 * (attempt + 1))
92
  continue
93
-
94
- return "Could not reach AI models. Please check: 1) HF_TOKEN env var is set, 2) Network connection, 3) Hugging Face API status (try again in 60 seconds)."
95
 
96
  # =============================================================================
97
  # FILE EXTRACTION
@@ -116,7 +91,6 @@ def extract_image_text(path):
116
  except Exception as e:
117
  return f"[Image OCR error: {e}]"
118
 
119
- @spaces.GPU
120
  def transcribe_audio(path):
121
  try:
122
  model = whisper.load_model("base")
@@ -130,7 +104,6 @@ def extract_content(file):
130
  return ""
131
  path = file.name if hasattr(file, "name") else str(file)
132
  ext = Path(path).suffix.lower()
133
-
134
  if ext == ".pdf":
135
  return extract_pdf_text(path)
136
  elif ext in [".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".tiff"]:
@@ -223,8 +196,9 @@ def analyse(files):
223
  r4 = call_llama(
224
  f"You are Layoutbot — part of the Metabolic Phoenix Framework "
225
  f"by Dwayne Anthony Brian Galloway.\n\n"
226
- f"Fact Ledger:\n{r1[:1500]}\n\nBreach Analysis:\n{r2[:1500]}\n\n"
227
- f"Loop Output:\n{r3[:1000]}\n\nCase Summary Context Complete\n\n"
 
228
  f"{'='*60}\n\n"
229
  "Produce a complete litigation-ready case summary. "
230
  "Breaches have occurred and are on the record. Write accordingly.\n\n"
@@ -233,8 +207,7 @@ def analyse(files):
233
  "TOP 5 ARGUMENTS — strongest first, each grounded in confirmed fact and statute\n"
234
  "REQUIRED NEXT STEPS — mandatory actions in priority order\n"
235
  "ESCALATION MAP — which body receives what, by what deadline\n\n"
236
- "Ms. Nala | Injectiv8 | Dwayne Anthony Brian Galloway" + PLAIN_ENGLISH,
237
- max_tokens=2500
238
  )
239
  return r1, r2, r3, r4
240
 
@@ -316,7 +289,6 @@ def text_to_speech_full(text, speed=1.0, pitch=1.0):
316
  return result
317
  except Exception:
318
  pass
319
-
320
  # fallback to gTTS
321
  try:
322
  from gtts import gTTS
@@ -341,17 +313,17 @@ def make_audio(text, speed=1.0, pitch=1.0):
341
  return text_to_speech_full(text, speed, pitch)
342
 
343
  # =============================================================================
344
- # DOCUMENT GENERATION
345
  # =============================================================================
346
  def generate_dummy(r1, r2, r3, r4, typ: str):
347
  if not r1:
348
  return "Run analysis first."
349
  prompt_map = {
350
- "letter": "Draft a formal Letter Before Action to the relevant institution naming the breach, citing statute, and demanding remedy within 14 days.",
351
- "complaint": "Draft a formal regulatory complaint to the appropriate ombudsman or regulator, stating facts, breaches, and requested remedy.",
352
- "witness": "Draft a Witness Statement in first person, confirming facts, dates, and personal knowledge of the breaches.",
353
- "skeleton": "Draft a Skeleton Argument for court proceedings: issues in dispute, legal principles, case law, and conclusions.",
354
- "referral": "Draft a Regulatory Referral setting out the systemic breaches and requesting investigation and enforcement action."
355
  }
356
  prompt = prompt_map.get(typ, "")
357
  return call_llama(
@@ -424,9 +396,6 @@ with gr.Blocks(css=CSS, title="Metabolic Phoenix Framework") as demo:
424
  <p class="own">Invented &amp; Owned by Dwayne Anthony Brian Galloway &nbsp;·&nbsp; 2026</p>
425
  </div>""")
426
 
427
- # Analysis state to persist across cycles
428
- analysis_state = gr.State([None, None, None, None])
429
-
430
  pdf_input = gr.File(
431
  label="Upload Documents — PDF · Image · Audio · Video · Text — drop multiple",
432
  file_types=[
@@ -464,15 +433,15 @@ with gr.Blocks(css=CSS, title="Metabolic Phoenix Framework") as demo:
464
  gen_referral = gr.Button("Regulatory Referral", variant="secondary")
465
  doc_output = gr.Textbox(label="Generated Document", lines=20)
466
 
467
- def analyse_and_update_state(files):
468
- r1, r2, r3, r4 = analyse(files)
469
- return r1, r2, r3, r4, [r1, r2, r3, r4]
470
 
471
- # Analyse button: run analysis and update state
472
  analyse_btn.click(
473
- fn=analyse_and_update_state,
474
  inputs=pdf_input,
475
- outputs=[out1, out2, out3, out4, analysis_state]
476
  )
477
 
478
  # TTS for each cycle
@@ -483,15 +452,20 @@ with gr.Blocks(css=CSS, title="Metabolic Phoenix Framework") as demo:
483
 
484
  # Document reading without analysis
485
  read_doc_btn.click(
486
- fn=lambda files: text_to_speech_full(
487
- "\n\n".join([extract_content(f) for f in (files if isinstance(files, list) else [files] if files else [])]),
488
- 1.0, 1.0
489
  ),
490
- inputs=pdf_input,
 
491
  outputs=read_doc_audio
492
  )
493
 
494
- # Document generation (use analysis_state)
 
 
 
 
495
  gen_letter.click(fn=lambda s: generate_letter(*s), inputs=analysis_state, outputs=doc_output)
496
  gen_complaint.click(fn=lambda s: generate_complaint(*s), inputs=analysis_state, outputs=doc_output)
497
  gen_witness.click(fn=lambda s: generate_witness(*s), inputs=analysis_state, outputs=doc_output)
@@ -499,13 +473,8 @@ with gr.Blocks(css=CSS, title="Metabolic Phoenix Framework") as demo:
499
  gen_referral.click(fn=lambda s: generate_referral(*s), inputs=analysis_state, outputs=doc_output)
500
 
501
  gr.HTML("""<div class="foot">
502
- Metabolic Phoenix Framework · Dwayne Anthony Brian Galloway · 2026
503
  </div>""")
504
 
505
  if __name__ == "__main__":
506
- demo.launch(
507
- server_name="0.0.0.0",
508
- server_port=7860,
509
- show_error=True,
510
- share=False # Spaces handles sharing automatically
511
- )
 
6
  import subprocess
7
  from pathlib import Path
8
  import gradio as gr
9
+ import spaces
 
 
 
 
 
 
 
 
 
10
 
11
  # All dependencies are installed via requirements.txt / apt.txt
12
  from pypdf import PdfReader
 
30
  def call_llama(prompt: str, max_tokens: int = 2000) -> str:
31
  token = os.environ.get("HF_TOKEN", "")
32
  headers = {"Authorization": f"Bearer {token}"} if token else {}
 
 
 
 
33
  for model in _MODELS:
34
+ for attempt in range(4):
35
  try:
36
+ fmt = prompt
37
  resp = _req.post(
38
  _FREE_API.format(model=model),
39
  headers=headers,
40
  json={
41
+ "inputs": fmt,
42
  "parameters": {
43
  "max_new_tokens": max_tokens,
44
  "temperature": 0.7,
45
  "return_full_text": False,
46
  "do_sample": True,
47
  },
48
+ "options": {"wait_for_model": True}
49
  },
50
  timeout=180
51
  )
 
52
  if resp.status_code == 200:
53
  result = resp.json()
54
  if isinstance(result, list) and result:
55
  text = result[0].get("generated_text", "").strip()
56
  if text:
57
  return text
58
+ elif resp.status_code == 503:
59
+ time.sleep(30 * (attempt + 1))
 
 
 
 
 
 
 
60
  continue
61
+ elif resp.status_code in [429, 402]:
 
 
62
  break
63
+ else:
64
+ time.sleep(10)
65
+ continue
66
+ except Exception:
67
+ time.sleep(10)
 
 
68
  continue
69
+ return "Could not reach AI. Models may be loading — please try again in 30 seconds."
 
70
 
71
  # =============================================================================
72
  # FILE EXTRACTION
 
91
  except Exception as e:
92
  return f"[Image OCR error: {e}]"
93
 
 
94
  def transcribe_audio(path):
95
  try:
96
  model = whisper.load_model("base")
 
104
  return ""
105
  path = file.name if hasattr(file, "name") else str(file)
106
  ext = Path(path).suffix.lower()
 
107
  if ext == ".pdf":
108
  return extract_pdf_text(path)
109
  elif ext in [".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".tiff"]:
 
196
  r4 = call_llama(
197
  f"You are Layoutbot — part of the Metabolic Phoenix Framework "
198
  f"by Dwayne Anthony Brian Galloway.\n\n"
199
+ f"FACT LEDGER:\n{r1[:1500]}\n\n"
200
+ f"BREACH ANALYSIS:\n{r2[:1500]}\n\n"
201
+ f"LOOP OUTPUT:\n{r3[:1500]}\n\n"
202
  f"{'='*60}\n\n"
203
  "Produce a complete litigation-ready case summary. "
204
  "Breaches have occurred and are on the record. Write accordingly.\n\n"
 
207
  "TOP 5 ARGUMENTS — strongest first, each grounded in confirmed fact and statute\n"
208
  "REQUIRED NEXT STEPS — mandatory actions in priority order\n"
209
  "ESCALATION MAP — which body receives what, by what deadline\n\n"
210
+ "Ms. Nala | Injectiv8 | Dwayne Anthony Brian Galloway" + PLAIN_ENGLISH
 
211
  )
212
  return r1, r2, r3, r4
213
 
 
289
  return result
290
  except Exception:
291
  pass
 
292
  # fallback to gTTS
293
  try:
294
  from gtts import gTTS
 
313
  return text_to_speech_full(text, speed, pitch)
314
 
315
  # =============================================================================
316
+ # DOCUMENT GENERATION (short versions for demo)
317
  # =============================================================================
318
  def generate_dummy(r1, r2, r3, r4, typ: str):
319
  if not r1:
320
  return "Run analysis first."
321
  prompt_map = {
322
+ "letter": "Draft a formal Letter Before Action...",
323
+ "complaint": "Draft a formal regulatory complaint...",
324
+ "witness": "Draft a Witness Statement...",
325
+ "skeleton": "Draft a Skeleton Argument...",
326
+ "referral": "Draft a Regulatory Referral..."
327
  }
328
  prompt = prompt_map.get(typ, "")
329
  return call_llama(
 
396
  <p class="own">Invented &amp; Owned by Dwayne Anthony Brian Galloway &nbsp;·&nbsp; 2026</p>
397
  </div>""")
398
 
 
 
 
399
  pdf_input = gr.File(
400
  label="Upload Documents — PDF · Image · Audio · Video · Text — drop multiple",
401
  file_types=[
 
433
  gen_referral = gr.Button("Regulatory Referral", variant="secondary")
434
  doc_output = gr.Textbox(label="Generated Document", lines=20)
435
 
436
+ # Helper to bind analysis outputs for generation
437
+ def _get_outputs(r1, r2, r3, r4):
438
+ return r1, r2, r3, r4
439
 
440
+ # Analyse
441
  analyse_btn.click(
442
+ fn=analyse,
443
  inputs=pdf_input,
444
+ outputs=[out1, out2, out3, out4]
445
  )
446
 
447
  # TTS for each cycle
 
452
 
453
  # Document reading without analysis
454
  read_doc_btn.click(
455
+ fn=lambda files, speed, pitch: text_to_speech_full(
456
+ "\n\n".join([extract_content(f) for f in (files if isinstance(files, list) else [files])]),
457
+ speed, pitch
458
  ),
459
+ inputs=[pdf_input, gr.Slider(0.5, 2.0, value=1.0, label="Speed"),
460
+ gr.Slider(0.5, 2.0, value=1.0, label="Pitch")],
461
  outputs=read_doc_audio
462
  )
463
 
464
+ # Document generation (bind analysis outputs as state)
465
+ analysis_state = gr.State([None, None, None, None])
466
+ for out in [out1, out2, out3, out4]:
467
+ out.change(lambda *vals: vals, [out1, out2, out3, out4], analysis_state)
468
+
469
  gen_letter.click(fn=lambda s: generate_letter(*s), inputs=analysis_state, outputs=doc_output)
470
  gen_complaint.click(fn=lambda s: generate_complaint(*s), inputs=analysis_state, outputs=doc_output)
471
  gen_witness.click(fn=lambda s: generate_witness(*s), inputs=analysis_state, outputs=doc_output)
 
473
  gen_referral.click(fn=lambda s: generate_referral(*s), inputs=analysis_state, outputs=doc_output)
474
 
475
  gr.HTML("""<div class="foot">
476
+ Metabolic Phoenix Framework &nbsp;·&nbsp; Dwayne Anthony Brian Galloway &nbsp;·&nbsp; 2026
477
  </div>""")
478
 
479
  if __name__ == "__main__":
480
+ demo.launch()