jsakshi commited on
Commit
ef3d0e6
·
verified ·
1 Parent(s): 2ede80e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +150 -64
app.py CHANGED
@@ -467,6 +467,9 @@ with gr.Blocks(theme=gr.themes.Soft()) as app:
467
  if __name__ == "__main__":
468
  app.launch(share=True)'''
469
 
 
 
 
470
  import gradio as gr
471
  import os
472
  import time
@@ -479,15 +482,22 @@ from dotenv import load_dotenv
479
  from huggingface_hub import HfApi, upload_file
480
  import json
481
  from functools import partial
 
 
 
 
 
482
 
483
  load_dotenv()
484
 
485
  # Configuration
486
  HF_TOKEN = os.getenv("HF_TOKEN")
 
 
487
  HF_USERNAME = "jsakshi"
488
  HEADERS = {"Authorization": f"Bearer {HF_TOKEN}"}
489
 
490
- # Simulated user authentication (in practice, use a proper auth system)
491
  AUTHORIZED_USERS = {"admin": "password123"} # username: password
492
 
493
  # Store edit history for undo/redo
@@ -495,49 +505,79 @@ edit_history = []
495
  current_history_index = -1
496
 
497
  def generate_initial_content(topic):
498
- # Same as original generate_blog_content but simplified for example
499
- prompt = f"Create a blog post about {topic} with title, subtitle, introduction, 3 sections, and conclusion."
500
- response = requests.post(
501
- "https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.2",
502
- headers=HEADERS,
503
- json={"inputs": prompt, "parameters": {"max_length": 2000}}
504
- )
505
- if response.status_code == 200:
 
 
 
 
 
 
 
 
 
506
  return response.json()[0]['generated_text']
507
- return f"# {topic}\n## Subtitle\nIntro text\n## Section 1\nText\n## Section 2\nText\n## Section 3\nText\n## Conclusion\nText"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
508
 
509
  def create_or_update_space(content_data, space_name=None, images=[]):
510
- api = HfApi(token=HF_TOKEN)
511
-
512
- if not space_name:
513
- space_id = f"blog-{uuid.uuid4().hex[:8]}"
514
- space_name = f"{HF_USERNAME}/{space_id}"
515
- api.create_repo(repo_id=space_name, repo_type="space", space_sdk="static", private=False)
516
-
517
- # Generate HTML with contenteditable attributes
518
- sections = re.split(r'(## .+)', content_data)
519
- html_content = '<div class="editable-container">'
520
- current_section = ""
521
-
522
- for part in sections:
523
- if part.strip():
524
- if part.startswith('## '):
525
- if current_section:
526
- html_content += f'<div class="section-content" contenteditable="true">{markdown.markdown(current_section)}</div></div>'
527
- html_content += f'<div class="section"><h2 class="editable-header" contenteditable="true">{part[3:]}</h2>'
528
- current_section = ""
529
- else:
530
- current_section += part
531
- if current_section:
532
- html_content += f'<div class="section-content" contenteditable="true">{markdown.markdown(current_section)}</div></div>'
533
- html_content += '</div>'
534
-
535
- # Add images
536
- for i, img in enumerate(images):
537
- html_content += f'<div class="image-container" draggable="true" data-index="{i}"><img src="{img}" class="editable-image" /><button class="delete-image">Delete</button></div>'
538
-
539
- complete_html = f"""<!DOCTYPE html>
540
- <html>
 
 
 
541
  <head>
542
  <meta charset="UTF-8">
543
  <title>Editable Blog</title>
@@ -548,8 +588,9 @@ def create_or_update_space(content_data, space_name=None, images=[]):
548
  .image-container {{ position: relative; margin: 20px 0; }}
549
  .editable-image {{ width: 100%; max-width: 500px; cursor: move; }}
550
  .delete-image {{ position: absolute; top: 5px; right: 5px; }}
551
- .editing-tools {{ position: fixed; top: 10px; left: 10px; background: white; padding: 10px; border: 1px solid #ccc; }}
552
  [contenteditable]:focus {{ outline: 2px solid #2D68C4; }}
 
553
  </style>
554
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
555
  </head>
@@ -569,6 +610,7 @@ def create_or_update_space(content_data, space_name=None, images=[]):
569
  <button onclick="redo()">Redo</button>
570
  </div>
571
  {html_content}
 
572
  <script>
573
  let currentSpace = "{space_name}";
574
  let images = {json.dumps(images)};
@@ -618,7 +660,7 @@ def create_or_update_space(content_data, space_name=None, images=[]):
618
  }}
619
  }}
620
 
621
- // Drag and drop
622
  document.querySelectorAll('.image-container').forEach(container => {{
623
  container.addEventListener('dragstart', e => {{
624
  e.dataTransfer.setData('text/plain', container.dataset.index);
@@ -658,30 +700,76 @@ def create_or_update_space(content_data, space_name=None, images=[]):
658
  </script>
659
  </body>
660
  </html>"""
661
-
662
- upload_file(
663
- path_or_fileobj=complete_html.encode(),
664
- path_in_repo="index.html",
665
- repo_id=space_name,
666
- repo_type="space"
667
- )
668
- return f"https://huggingface.co/spaces/{space_name}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
669
 
670
  def authenticate(username, password):
671
- return username in AUTHORIZED_USERS and AUTHORIZED_USERS[username] == password
 
 
 
 
 
 
672
 
673
  def generate_and_edit(topic, username, password):
 
 
 
 
674
  if not authenticate(username, password):
675
- return "Authentication failed", "", ""
676
 
 
 
 
 
 
677
  initial_content = generate_initial_content(topic)
678
- space_url = create_or_update_space(initial_content)
679
- return space_url, initial_content, "Blog generated successfully"
 
 
 
 
 
 
 
 
 
 
 
 
680
 
681
- # Mock update endpoint (in practice, this would be a server-side API)
682
- def update_content(space, content, images):
683
- create_or_update_space(content, space, images)
684
- return "Updated successfully"
 
 
685
 
686
  # Gradio interface
687
  with gr.Blocks(theme=gr.themes.Soft()) as app:
@@ -691,7 +779,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as app:
691
  with gr.Row():
692
  with gr.Column():
693
  username = gr.Textbox(label="Username", placeholder="admin")
694
- password = gr.Textbox(label="Password", type="password")
695
  topic_input = gr.Textbox(label="Blog Topic", placeholder="e.g., Future of AI")
696
  generate_btn = gr.Button("Generate & Edit", variant="primary")
697
 
@@ -700,9 +788,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as app:
700
  blog_link = gr.Markdown("Blog link will appear here...")
701
  blog_preview = gr.Markdown(label="Preview", value="Content preview will appear here...")
702
 
703
- # Update function (simulated)
704
- update_btn = gr.Button("Update Content", visible=False)
705
-
706
  generate_btn.click(
707
  fn=generate_and_edit,
708
  inputs=[topic_input, username, password],
@@ -710,4 +795,5 @@ with gr.Blocks(theme=gr.themes.Soft()) as app:
710
  )
711
 
712
  if __name__ == "__main__":
713
- app.launch(share=True)
 
 
467
  if __name__ == "__main__":
468
  app.launch(share=True)'''
469
 
470
+
471
+
472
+
473
  import gradio as gr
474
  import os
475
  import time
 
482
  from huggingface_hub import HfApi, upload_file
483
  import json
484
  from functools import partial
485
+ import logging
486
+
487
+ # Set up logging
488
+ logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
489
+ logger = logging.getLogger(__name__)
490
 
491
  load_dotenv()
492
 
493
  # Configuration
494
  HF_TOKEN = os.getenv("HF_TOKEN")
495
+ if not HF_TOKEN:
496
+ logger.error("HF_TOKEN not found in .env file")
497
  HF_USERNAME = "jsakshi"
498
  HEADERS = {"Authorization": f"Bearer {HF_TOKEN}"}
499
 
500
+ # Simulated user authentication (replace with proper auth in production)
501
  AUTHORIZED_USERS = {"admin": "password123"} # username: password
502
 
503
  # Store edit history for undo/redo
 
505
  current_history_index = -1
506
 
507
  def generate_initial_content(topic):
508
+ """Generate initial blog content using Hugging Face API."""
509
+ logger.info(f"Generating content for topic: {topic}")
510
+ try:
511
+ prompt = f"""Create a detailed blog post about {topic} including:
512
+ - A compelling title and subtitle
513
+ - An introduction
514
+ - 3 main sections with descriptive headings
515
+ - A conclusion
516
+ Use an informative tone."""
517
+ response = requests.post(
518
+ "https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.2",
519
+ headers=HEADERS,
520
+ json={"inputs": prompt, "parameters": {"max_length": 2000}}
521
+ )
522
+ if response.status_code != 200:
523
+ logger.error(f"API request failed: {response.status_code} - {response.text}")
524
+ return f"Error: API request failed with status {response.status_code}"
525
  return response.json()[0]['generated_text']
526
+ except Exception as e:
527
+ logger.error(f"Error generating content: {str(e)}")
528
+ return f"Error generating content: {str(e)}"
529
+
530
+ def generate_image(prompt):
531
+ """Generate an image using Stable Diffusion API."""
532
+ try:
533
+ response = requests.post(
534
+ "https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0",
535
+ headers=HEADERS,
536
+ json={"inputs": prompt}
537
+ )
538
+ if response.status_code == 200:
539
+ return response.content
540
+ logger.error(f"Image generation failed: {response.status_code} - {response.text}")
541
+ return None
542
+ except Exception as e:
543
+ logger.error(f"Error generating image: {str(e)}")
544
+ return None
545
 
546
  def create_or_update_space(content_data, space_name=None, images=[]):
547
+ """Create or update a Hugging Face Space with editable content."""
548
+ try:
549
+ api = HfApi(token=HF_TOKEN)
550
+ if not space_name:
551
+ space_id = f"blog-{uuid.uuid4().hex[:8]}"
552
+ space_name = f"{HF_USERNAME}/{space_id}"
553
+ api.create_repo(repo_id=space_name, repo_type="space", space_sdk="static", private=False)
554
+ logger.info(f"Created new space: {space_name}")
555
+
556
+ # Process content into editable sections
557
+ sections = re.split(r'(## .+)', content_data)
558
+ html_content = '<div class="editable-container">'
559
+ current_section = ""
560
+ for part in sections:
561
+ if part.strip():
562
+ if part.startswith('## '):
563
+ if current_section:
564
+ html_content += f'<div class="section-content" contenteditable="true">{markdown.markdown(current_section)}</div></div>'
565
+ html_content += f'<div class="section"><h2 class="editable-header" contenteditable="true">{part[3:]}</h2>'
566
+ current_section = ""
567
+ else:
568
+ current_section += part
569
+ if current_section:
570
+ html_content += f'<div class="section-content" contenteditable="true">{markdown.markdown(current_section)}</div></div>'
571
+ html_content += '</div>'
572
+
573
+ # Add images
574
+ image_html = ""
575
+ for i, img_path in enumerate(images):
576
+ image_html += f'<div class="image-container" draggable="true" data-index="{i}"><img src="{img_path}" class="editable-image" alt="Blog image" /><button class="delete-image">Delete</button></div>'
577
+
578
+ # Complete HTML with editing features
579
+ complete_html = f"""<!DOCTYPE html>
580
+ <html lang="en">
581
  <head>
582
  <meta charset="UTF-8">
583
  <title>Editable Blog</title>
 
588
  .image-container {{ position: relative; margin: 20px 0; }}
589
  .editable-image {{ width: 100%; max-width: 500px; cursor: move; }}
590
  .delete-image {{ position: absolute; top: 5px; right: 5px; }}
591
+ .editing-tools {{ position: fixed; top: 10px; left: 10px; background: white; padding: 10px; border: 1px solid #ccc; z-index: 1000; }}
592
  [contenteditable]:focus {{ outline: 2px solid #2D68C4; }}
593
+ body {{ font-family: Arial, sans-serif; line-height: 1.6; }}
594
  </style>
595
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
596
  </head>
 
610
  <button onclick="redo()">Redo</button>
611
  </div>
612
  {html_content}
613
+ {image_html}
614
  <script>
615
  let currentSpace = "{space_name}";
616
  let images = {json.dumps(images)};
 
660
  }}
661
  }}
662
 
663
+ // Drag and drop images
664
  document.querySelectorAll('.image-container').forEach(container => {{
665
  container.addEventListener('dragstart', e => {{
666
  e.dataTransfer.setData('text/plain', container.dataset.index);
 
700
  </script>
701
  </body>
702
  </html>"""
703
+
704
+ # Upload HTML
705
+ upload_file(
706
+ path_or_fileobj=complete_html.encode(),
707
+ path_in_repo="index.html",
708
+ repo_id=space_name,
709
+ repo_type="space"
710
+ )
711
+
712
+ # Upload images if provided as bytes
713
+ for i, img in enumerate(images):
714
+ if isinstance(img, bytes):
715
+ upload_file(
716
+ path_or_fileobj=img,
717
+ path_in_repo=f"image_{i}.png",
718
+ repo_id=space_name,
719
+ repo_type="space"
720
+ )
721
+ images[i] = f"image_{i}.png"
722
+
723
+ logger.info(f"Updated space: {space_name}")
724
+ return f"https://huggingface.co/spaces/{space_name}"
725
+ except Exception as e:
726
+ logger.error(f"Error creating/updating space: {str(e)}")
727
+ return None
728
 
729
  def authenticate(username, password):
730
+ """Authenticate user against hardcoded credentials."""
731
+ if not username or not password:
732
+ logger.warning("Empty username or password provided")
733
+ return False
734
+ is_valid = username in AUTHORIZED_USERS and AUTHORIZED_USERS[username] == password
735
+ logger.info(f"Authentication attempt for {username}: {'Success' if is_valid else 'Failed'}")
736
+ return is_valid
737
 
738
  def generate_and_edit(topic, username, password):
739
+ """Generate blog and create editable space."""
740
+ logger.info(f"Starting generate_and_edit for topic: {topic}")
741
+
742
+ # Check authentication
743
  if not authenticate(username, password):
744
+ return "Authentication failed: Incorrect username or password", "", "Error"
745
 
746
+ # Check HF_TOKEN
747
+ if not HF_TOKEN:
748
+ return "Authentication failed: HF_TOKEN not set in .env", "", "Error"
749
+
750
+ # Generate content
751
  initial_content = generate_initial_content(topic)
752
+ if "Error" in initial_content:
753
+ return "Failed to generate content", initial_content, "Error"
754
+
755
+ # Generate images
756
+ image_prompts = [
757
+ f"Professional illustration about {topic}, clean design, minimalist style.",
758
+ f"Data visualization related to {topic}, infographic style."
759
+ ]
760
+ images = []
761
+ for prompt in image_prompts:
762
+ img_data = generate_image(prompt)
763
+ if img_data:
764
+ images.append(img_data)
765
+ time.sleep(2) # Prevent rate limiting
766
 
767
+ # Create space
768
+ space_url = create_or_update_space(initial_content, images=images)
769
+ if not space_url:
770
+ return "Failed to create space", initial_content, "Error"
771
+
772
+ return space_url, initial_content, "Blog generated successfully"
773
 
774
  # Gradio interface
775
  with gr.Blocks(theme=gr.themes.Soft()) as app:
 
779
  with gr.Row():
780
  with gr.Column():
781
  username = gr.Textbox(label="Username", placeholder="admin")
782
+ password = gr.Textbox(label="Password", type="password", placeholder="password123")
783
  topic_input = gr.Textbox(label="Blog Topic", placeholder="e.g., Future of AI")
784
  generate_btn = gr.Button("Generate & Edit", variant="primary")
785
 
 
788
  blog_link = gr.Markdown("Blog link will appear here...")
789
  blog_preview = gr.Markdown(label="Preview", value="Content preview will appear here...")
790
 
 
 
 
791
  generate_btn.click(
792
  fn=generate_and_edit,
793
  inputs=[topic_input, username, password],
 
795
  )
796
 
797
  if __name__ == "__main__":
798
+ app.launch(share=True, debug=True)
799
+