mroccuper commited on
Commit
d1ced8d
·
verified ·
1 Parent(s): ea8f6b3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -42
app.py CHANGED
@@ -2,106 +2,105 @@ import gradio as gr
2
  import requests
3
  from bs4 import BeautifulSoup
4
  import google.generativeai as genai
5
- import os
6
- import time
7
-
8
- # Configure Gemini API
9
- GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
10
- if not GEMINI_API_KEY:
11
- raise ValueError("GEMINI_API_KEY not found in environment variables")
12
-
13
- genai.configure(api_key=GEMINI_API_KEY)
14
 
15
  def fetch_article_content(url):
16
- """Fetch article content with timeout and fallback"""
17
  try:
18
  headers = {'User-Agent': 'Mozilla/5.0'}
19
- response = requests.get(url, headers=headers, timeout=8) # 8s timeout
20
  response.raise_for_status()
21
  soup = BeautifulSoup(response.text, 'html.parser')
22
 
23
- # Extract text from <p> tags
24
- paragraphs = soup.find_all('p')[:10] # Limit to 10 paragraphs
25
  content = ' '.join([p.get_text(strip=True) for p in paragraphs])
26
- return content[:2000] # Limit to 2000 chars for prompt safety
27
  except Exception as e:
28
- return f"Error fetching article: {str(e)}"
29
 
30
- def generate_platform_post(article_text):
31
- """Generate optimized post using Gemini API with timeout"""
32
  try:
 
 
33
  model = genai.GenerativeModel('gemini-1.5-pro')
34
 
35
  prompt = f"""
36
- Convert this article into a short, engaging post suitable for Reddit or Quora.
37
 
38
- Article content:
39
  {article_text}
40
 
41
  Output format:
42
  Title: [short title]
43
- Post: [clean HTML with paragraphs and one image tag]
44
 
45
  Requirements:
46
- - Keep title under 100 characters
47
- - Include one <img> tag with alt text
48
- - Use minimal styling
49
  - Mobile-friendly
50
- - No markdown
51
  """
52
 
53
- # Timeout mechanism
54
- start_time = time.time()
55
- response = model.generate_content(prompt)
56
- print(f"AI Response received in {time.time()-start_time:.2f} seconds")
57
-
58
  return parse_gemini_response(response.text)
59
  except Exception as e:
60
- return {"title": "Generation Failed", "content": f"<p>AI Error: {str(e)}</p>"}
61
 
62
  def parse_gemini_response(response):
63
- """Robust parsing with fallbacks"""
64
  try:
65
  title = response.split("Title:")[1].split("Post:")[0].strip()[:100]
66
  content = response.split("Post:")[1].strip()
67
  except:
68
- title = "Content Generation Error"
69
  content = "<p>Failed to parse AI response</p>"
70
 
71
  return {"title": title, "content": content}
72
 
73
- def process_url(url):
74
  """Main processing pipeline with status updates"""
 
 
 
 
 
 
 
 
75
  yield {"title": "Fetching Article...", "content": "<p>Connecting to URL...</p>"}
76
 
77
  article_text = fetch_article_content(url)
78
- if article_text.startswith("Error"):
79
- yield {"title": "Fetch Error", "content": f"<p>{article_text}</p>"}
80
  return
81
 
82
- yield {"title": "Generating Post...", "content": "<p>Creating content with AI...</p>"}
83
 
84
- result = generate_platform_post(article_text)
85
  yield result
86
- # Gradio Interface
87
- url_input = gr.Textbox(label="Article URL", placeholder="https://example.com/article...", lines=1)
 
 
 
88
  title_output = gr.Textbox(label="Generated Title")
89
  content_output = gr.HTML(label="Formatted Post")
90
 
91
  app = gr.Interface(
92
  fn=process_url,
93
- inputs=url_input,
94
  outputs=[
95
  gr.Textbox(label="Generated Title"),
96
  gr.HTML(label="Formatted Post")
97
  ],
98
  examples=[
99
- ["https://example.com/sample-article"]
100
  ],
101
  title="Article to Reddit/Quora Post Converter",
102
  description="Convert news articles into optimized posts with AI-generated formatting and image descriptions",
103
  allow_flagging="never",
104
- live=False
 
105
  )
106
 
107
  if __name__ == "__main__":
 
2
  import requests
3
  from bs4 import BeautifulSoup
4
  import google.generativeai as genai
 
 
 
 
 
 
 
 
 
5
 
6
  def fetch_article_content(url):
7
+ """Fetch article content with basic error handling"""
8
  try:
9
  headers = {'User-Agent': 'Mozilla/5.0'}
10
+ response = requests.get(url, headers=headers, timeout=8)
11
  response.raise_for_status()
12
  soup = BeautifulSoup(response.text, 'html.parser')
13
 
14
+ # Extract first 8 paragraphs
15
+ paragraphs = soup.find_all('p')[:8]
16
  content = ' '.join([p.get_text(strip=True) for p in paragraphs])
17
+ return content[:2000] # Keep it concise
18
  except Exception as e:
19
+ return f"FETCH_ERROR: {str(e)}"
20
 
21
+ def generate_platform_post(article_text, api_key):
22
+ """Generate post using user-provided API key"""
23
  try:
24
+ # Configure Gemini with user's API key
25
+ genai.configure(api_key=api_key)
26
  model = genai.GenerativeModel('gemini-1.5-pro')
27
 
28
  prompt = f"""
29
+ Create a Reddit/Quora-style post from this article:
30
 
 
31
  {article_text}
32
 
33
  Output format:
34
  Title: [short title]
35
+ Post: [clean HTML with 1 image tag + alt text]
36
 
37
  Requirements:
38
+ - Title < 100 characters
39
+ - Include <img> with descriptive alt text
40
+ - Minimal styling
41
  - Mobile-friendly
 
42
  """
43
 
44
+ response = model.generate_content(prompt, timeout=15)
 
 
 
 
45
  return parse_gemini_response(response.text)
46
  except Exception as e:
47
+ return {"title": "AI ERROR", "content": f"<p>API Error: {str(e)}</p>"}
48
 
49
  def parse_gemini_response(response):
50
+ """Robust response parsing"""
51
  try:
52
  title = response.split("Title:")[1].split("Post:")[0].strip()[:100]
53
  content = response.split("Post:")[1].strip()
54
  except:
55
+ title = "Formatting Error"
56
  content = "<p>Failed to parse AI response</p>"
57
 
58
  return {"title": title, "content": content}
59
 
60
+ def process_url(url, api_key):
61
  """Main processing pipeline with status updates"""
62
+ if not api_key or len(api_key.strip()) < 30:
63
+ yield {"title": "API Key Required", "content": "<p>Please enter your Gemini API key above</p>"}
64
+ return
65
+
66
+ if not url.startswith("http"):
67
+ yield {"title": "Invalid URL", "content": "<p>Please enter a valid article URL</p>"}
68
+ return
69
+
70
  yield {"title": "Fetching Article...", "content": "<p>Connecting to URL...</p>"}
71
 
72
  article_text = fetch_article_content(url)
73
+ if article_text.startswith("FETCH_ERROR:"):
74
+ yield {"title": "Fetch Failed", "content": f"<p>{article_text.replace('FETCH_ERROR: ', '')}</p>"}
75
  return
76
 
77
+ yield {"title": "Generating Post...", "content": "<p>Creating content with Gemini...</p>"}
78
 
79
+ result = generate_platform_post(article_text, api_key)
80
  yield result
81
+
82
+ # Create Gradio interface
83
+ url_input = gr.Textbox(label="Article URL", placeholder="https://example.com/article...")
84
+ api_key_input = gr.Textbox(label="Gemini API Key", placeholder="AIzaXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", type="password")
85
+
86
  title_output = gr.Textbox(label="Generated Title")
87
  content_output = gr.HTML(label="Formatted Post")
88
 
89
  app = gr.Interface(
90
  fn=process_url,
91
+ inputs=[url_input, api_key_input],
92
  outputs=[
93
  gr.Textbox(label="Generated Title"),
94
  gr.HTML(label="Formatted Post")
95
  ],
96
  examples=[
97
+ ["https://example.com/sample-article", "AIzaXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"]
98
  ],
99
  title="Article to Reddit/Quora Post Converter",
100
  description="Convert news articles into optimized posts with AI-generated formatting and image descriptions",
101
  allow_flagging="never",
102
+ live=False,
103
+ theme="default"
104
  )
105
 
106
  if __name__ == "__main__":