cstr commited on
Commit
0536b51
Β·
verified Β·
1 Parent(s): 7136934

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +101 -133
app.py CHANGED
@@ -170,36 +170,43 @@ def send_to_model(*args, **kwargs):
170
 
171
  def send_to_model_impl(prompt, model_selection, hf_model_choice, hf_custom_model, hf_api_key,
172
  groq_model_choice, groq_api_key, openai_api_key):
173
- """Implementation of send to model functionality"""
174
- if model_selection == "HuggingFace Inference":
175
- if not hf_api_key:
176
- return "HuggingFace API key required.", []
177
-
178
- model_id = hf_custom_model if hf_model_choice == "Custom Model" else model_registry.hf_models[hf_model_choice]
179
- summary = send_to_hf_inference(prompt, model_id, hf_api_key)
180
-
181
- elif model_selection == "Groq API":
182
- if not groq_api_key:
183
- return "Groq API key required.", []
184
- summary = send_to_groq(prompt, groq_model_choice, groq_api_key)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
 
186
- elif model_selection == "OpenAI ChatGPT":
187
- if not openai_api_key:
188
- return "OpenAI API key required.", []
189
- summary = send_to_openai(prompt, openai_api_key)
 
 
 
 
 
190
 
191
- else:
192
- return "Invalid model selection.", []
193
-
194
- if summary.startswith("Error"):
195
- return summary, []
196
-
197
- # Save summary for download
198
- with tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.txt') as f:
199
- f.write(summary)
200
-
201
- return summary, [f.name]
202
-
203
  def send_to_hf_inference(prompt: str, model_name: str, api_key: str) -> str:
204
  """Send prompt to HuggingFace using Inference API"""
205
  try:
@@ -266,21 +273,17 @@ def send_to_openai(prompt: str, api_key: str) -> str:
266
  return f"Error with OpenAI API: {e}"
267
 
268
  def copy_text_js(element_id: str) -> str:
269
- return f"""
270
- () => {{
271
- try {{
272
- const elem = document.querySelector('#{element_id} textarea');
273
- if (!elem) throw new Error('Element not found');
274
- const text = elem.value;
275
- if (!text) throw new Error('No text to copy');
276
- navigator.clipboard.writeText(text);
277
- return "Copied to clipboard!";
278
- }} catch (e) {{
279
- console.error(e);
280
- return "Failed to copy: " + e.message;
281
- }}
282
  }}
283
- """
284
 
285
  def open_chatgpt() -> str:
286
  """Open ChatGPT in new browser tab"""
@@ -354,44 +357,16 @@ def generate_prompt(text, template, snippet_idx=None):
354
  logging.error(f"Error generating prompt: {e}")
355
  return f"Error generating prompt: {str(e)}", "", None
356
 
357
- def download_file(content: str, prefix: str = "file") -> List[str]:
358
- """Create a downloadable file with content and better error handling"""
359
- if not content:
360
- return []
361
- try:
362
- with tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.txt', prefix=prefix) as f:
363
- f.write(content)
364
- return [f.name]
365
- except Exception as e:
366
- logging.error(f"Error creating download file: {e}")
367
- return []
368
-
369
  # Main Interface
370
- with gr.Blocks(theme=gr.themes.Default()) as demo:
 
 
 
 
 
371
  # State variables
372
  pdf_content = gr.State("")
373
  snippets = gr.State([])
374
-
375
- # CSS for responsiveness
376
- demo.css = """
377
- .gradio-container {
378
- max-width: 90%; /* Adjust as needed */
379
- margin: 0 auto; /* Center the container */
380
- }
381
- @media (max-width: 768px) { /* Example breakpoint for smaller screens */
382
- .gradio-container {
383
- max-width: 98%;
384
- padding: 10px; /* Add padding for better mobile experience */
385
- }
386
- .gr-row {
387
- flex-direction: column; /* Stack elements vertically */
388
- }
389
- .gr-col {
390
- width: 100%; /* Make columns full width */
391
- margin-bottom: 10px; /* Add spacing between columns */
392
- }
393
- }
394
- """
395
 
396
  # Header
397
  gr.Markdown("# πŸ“„ Smart PDF Summarizer")
@@ -421,14 +396,15 @@ with gr.Blocks(theme=gr.themes.Default()) as demo:
421
  label="Context Size"
422
  )
423
 
 
424
  with gr.Row():
425
  for size_name, size_value in CONTEXT_SIZES.items():
426
  gr.Button(
427
- size_name,
428
  size="sm",
429
  scale=1
430
  ).click(
431
- lambda v=size_value: v, # Simplified
432
  None,
433
  context_size
434
  )
@@ -487,10 +463,10 @@ with gr.Blocks(theme=gr.themes.Default()) as demo:
487
  with gr.Row():
488
  with gr.Column(scale=1):
489
  model_choice = gr.Radio(
490
- choices=["OpenAI ChatGPT", "HuggingFace Inference", "Groq API"],
491
- value="OpenAI ChatGPT",
492
- label="πŸ€– Model Selection"
493
- )
494
 
495
  with gr.Column(visible=False) as openai_options:
496
  openai_api_key = gr.Textbox(
@@ -581,8 +557,15 @@ with gr.Blocks(theme=gr.themes.Default()) as demo:
581
  )
582
 
583
  def refresh_groq_models_list():
584
- updated_models = model_registry.refresh_groq_models()
585
- return gr.update(choices=list(updated_models.keys()))
 
 
 
 
 
 
 
586
 
587
  def toggle_custom_model(model_name):
588
  return gr.update(visible=model_name == "Custom Model")
@@ -601,14 +584,12 @@ with gr.Blocks(theme=gr.themes.Default()) as demo:
601
  return update_context_size("Groq API", model_name)
602
 
603
  def handle_model_selection(choice):
604
- """Handle model selection and update UI"""
605
- ctx_size = get_model_context_size(choice)
606
- return (
607
- gr.update(visible=choice == "HuggingFace Inference"), # hf_options
608
- gr.update(visible=choice == "Groq API"), # groq_options
609
- gr.update(visible=choice == "OpenAI ChatGPT"), # openai_options
610
- gr.update(value=ctx_size) # context_size
611
- )
612
 
613
  # PDF Processing Handlers
614
  def handle_pdf_process(pdf, fmt, ctx_size):
@@ -699,24 +680,24 @@ with gr.Blocks(theme=gr.themes.Default()) as demo:
699
 
700
  # Copy button handlers
701
  def handle_prompt_generation(snippet_text, template, snippet_choice, snippets_list):
702
- """Generate prompt from selected snippet"""
703
- if not snippet_text or not snippets_list:
704
- return "No text available for prompt generation.", "", None
705
-
706
  try:
 
 
 
707
  idx = get_snippet_index(snippet_choice)
708
- prompt = generate_prompt(snippets_list[idx], template or "Summarize the following text:")
 
709
 
710
- # Create downloadable prompt
 
 
711
  with tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.txt') as f:
712
  f.write(prompt)
713
 
714
- return "Prompt generated successfully!", prompt, [f.name]
715
-
716
  except Exception as e:
717
- error_msg = f"Error generating prompt: {str(e)}"
718
- logging.error(error_msg)
719
- return error_msg, "", None
720
 
721
  def handle_copy_action(text):
722
  """Handle copy to clipboard action"""
@@ -784,42 +765,29 @@ with gr.Blocks(theme=gr.themes.Default()) as demo:
784
  outputs=[context_size]
785
  )
786
 
787
- # Context size buttons
788
- for size_name, size_value in CONTEXT_SIZES.items():
789
- gr.Button(
790
- size_name,
791
- size="sm",
792
- scale=1
793
- ).click(
794
- lambda v=size_value: gr.update(value=v),
795
- None,
796
- context_size
797
- )
798
-
799
- # Download handlers (simplified)
800
- for btn, content in [
801
- (download_full_text, pdf_content),
802
- (download_snippet, generated_prompt),
803
- (download_prompt, generated_prompt),
804
- (download_summary, summary_output)
805
  ]:
806
  btn.click(
807
- lambda x: [x] if x else None,
808
  inputs=[content],
809
  outputs=[download_files]
810
  )
811
 
812
- # Copy button handlers
813
- for btn, elem_id in [
814
- (copy_prompt_button, "generated_prompt"),
815
- (copy_summary_button, "summary_output")
816
- ]:
817
- btn.click(
818
- fn=lambda _: f"const text = document.querySelector('#{elem_id} textarea').value; navigator.clipboard.writeText(text); return 'Copied to clipboard!';",
819
- inputs=None,
820
- outputs=progress_status,
821
- js=True
822
- )
823
 
824
  # ChatGPT handler
825
  open_chatgpt_button.click(
 
170
 
171
  def send_to_model_impl(prompt, model_selection, hf_model_choice, hf_custom_model, hf_api_key,
172
  groq_model_choice, groq_api_key, openai_api_key):
173
+ try:
174
+ if model_selection == "Clipboard only":
175
+ return "Use copy/paste for processing", []
176
+
177
+ if model_selection == "HuggingFace Inference":
178
+ if not hf_api_key:
179
+ return "Error: HuggingFace API key required", []
180
+ if not hf_model_choice:
181
+ return "Error: Select a HuggingFace model", []
182
+ model_id = hf_custom_model if hf_model_choice == "Custom Model" else model_registry.hf_models[hf_model_choice]
183
+ summary = send_to_hf_inference(prompt, model_id, hf_api_key)
184
+
185
+ elif model_selection == "Groq API":
186
+ if not groq_api_key:
187
+ return "Error: Groq API key required", []
188
+ if not groq_model_choice:
189
+ return "Error: Select a Groq model", []
190
+ summary = send_to_groq(prompt, groq_model_choice, groq_api_key)
191
+
192
+ elif model_selection == "OpenAI ChatGPT":
193
+ if not openai_api_key:
194
+ return "Error: OpenAI API key required", []
195
+ summary = send_to_openai(prompt, openai_api_key)
196
+
197
+ else:
198
+ return "Error: Invalid model selection", []
199
 
200
+ # Save summary for download
201
+ with tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.txt') as f:
202
+ f.write(summary)
203
+
204
+ return summary, [f.name]
205
+ except Exception as e:
206
+ error_msg = f"Error processing request: {str(e)}"
207
+ logging.error(error_msg)
208
+ return error_msg, []
209
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  def send_to_hf_inference(prompt: str, model_name: str, api_key: str) -> str:
211
  """Send prompt to HuggingFace using Inference API"""
212
  try:
 
273
  return f"Error with OpenAI API: {e}"
274
 
275
  def copy_text_js(element_id: str) -> str:
276
+ return f"""function() {{
277
+ let textarea = document.getElementById('{element_id}');
278
+ if (!textarea) return 'Element not found';
279
+ textarea.select();
280
+ try {{
281
+ document.execCommand('copy');
282
+ return 'Copied to clipboard!';
283
+ }} catch(err) {{
284
+ return 'Failed to copy: ' + err;
 
 
 
 
285
  }}
286
+ }}"""
287
 
288
  def open_chatgpt() -> str:
289
  """Open ChatGPT in new browser tab"""
 
357
  logging.error(f"Error generating prompt: {e}")
358
  return f"Error generating prompt: {str(e)}", "", None
359
 
 
 
 
 
 
 
 
 
 
 
 
 
360
  # Main Interface
361
+ with gr.Blocks(css="""
362
+ .gradio-container {max-width: 90%; margin: 0 auto;}
363
+ @media (max-width: 768px) {.gradio-container {max-width: 98%; padding: 10px;} .gr-row {flex-direction: column;} .gr-col {width: 100%; margin-bottom: 10px;}}
364
+ """) as demo:
365
+ gr.Markdown("# πŸ“„ Smart PDF Summarizer")
366
+
367
  # State variables
368
  pdf_content = gr.State("")
369
  snippets = gr.State([])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
370
 
371
  # Header
372
  gr.Markdown("# πŸ“„ Smart PDF Summarizer")
 
396
  label="Context Size"
397
  )
398
 
399
+ gr.Markdown("### Context Size")
400
  with gr.Row():
401
  for size_name, size_value in CONTEXT_SIZES.items():
402
  gr.Button(
403
+ size_name,
404
  size="sm",
405
  scale=1
406
  ).click(
407
+ lambda v=size_value: gr.update(value=v),
408
  None,
409
  context_size
410
  )
 
463
  with gr.Row():
464
  with gr.Column(scale=1):
465
  model_choice = gr.Radio(
466
+ choices=["Clipboard only", "OpenAI ChatGPT", "HuggingFace Inference", "Groq API"],
467
+ value="Clipboard only",
468
+ label="πŸ€– Model Selection"
469
+ )
470
 
471
  with gr.Column(visible=False) as openai_options:
472
  openai_api_key = gr.Textbox(
 
557
  )
558
 
559
  def refresh_groq_models_list():
560
+ try:
561
+ with gr.Progress() as progress:
562
+ progress(0, "Refreshing Groq models...")
563
+ updated_models = model_registry.refresh_groq_models()
564
+ progress(1, "Complete!")
565
+ return gr.update(choices=list(updated_models.keys()))
566
+ except Exception as e:
567
+ logging.error(f"Error refreshing models: {e}")
568
+ return gr.update()
569
 
570
  def toggle_custom_model(model_name):
571
  return gr.update(visible=model_name == "Custom Model")
 
584
  return update_context_size("Groq API", model_name)
585
 
586
  def handle_model_selection(choice):
587
+ return [
588
+ gr.update(visible=choice == "HuggingFace Inference"),
589
+ gr.update(visible=choice == "Groq API"),
590
+ gr.update(visible=choice == "OpenAI ChatGPT"),
591
+ gr.update(value=get_model_context_size(choice))
592
+ ]
 
 
593
 
594
  # PDF Processing Handlers
595
  def handle_pdf_process(pdf, fmt, ctx_size):
 
680
 
681
  # Copy button handlers
682
  def handle_prompt_generation(snippet_text, template, snippet_choice, snippets_list):
 
 
 
 
683
  try:
684
+ if not snippets_list:
685
+ return "No text available.", "", None
686
+
687
  idx = get_snippet_index(snippet_choice)
688
+ base_prompt = template if template else "Summarize the following text:"
689
+ content = snippets_list[idx]
690
 
691
+ prompt = f"{base_prompt}\n---\n{content}\n---"
692
+
693
+ # Save prompt for download
694
  with tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.txt') as f:
695
  f.write(prompt)
696
 
697
+ return "Prompt generated!", prompt, [f.name]
 
698
  except Exception as e:
699
+ logging.error(f"Error generating prompt: {e}")
700
+ return f"Error: {str(e)}", "", None
 
701
 
702
  def handle_copy_action(text):
703
  """Handle copy to clipboard action"""
 
765
  outputs=[context_size]
766
  )
767
 
768
+ # Download handlers
769
+ for btn, content, prefix in [
770
+ (download_full_text, pdf_content, "full_text"),
771
+ (download_snippet, generated_prompt, "snippet"),
772
+ (download_prompt, generated_prompt, "prompt"),
773
+ (download_summary, summary_output, "summary")
 
 
 
 
 
 
 
 
 
 
 
 
774
  ]:
775
  btn.click(
776
+ lambda x, p=prefix: download_file(x, p) if x else [],
777
  inputs=[content],
778
  outputs=[download_files]
779
  )
780
 
781
+ def download_file(content: str, prefix: str) -> List[str]:
782
+ if not content:
783
+ return []
784
+ try:
785
+ with tempfile.NamedTemporaryFile(delete=False, mode='w', suffix='.txt', prefix=prefix) as f:
786
+ f.write(content)
787
+ return [f.name]
788
+ except Exception as e:
789
+ logging.error(f"Error creating download file: {e}")
790
+ return []
 
791
 
792
  # ChatGPT handler
793
  open_chatgpt_button.click(