JaishnaCodz commited on
Commit
20bfd0b
·
verified ·
1 Parent(s): 0231648

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +142 -35
app.py CHANGED
@@ -5,47 +5,72 @@ from nltk import download, sent_tokenize
5
  import google.generativeai as genai
6
  import os
7
  import re
 
 
 
8
 
9
  # Download NLTK data
10
  download('punkt')
11
  download('punkt_tab')
12
 
13
- # Configure Gemini API using Hugging Face Spaces secrets
14
  api_key = os.environ.get("GEMINI_API_KEY")
15
  if not api_key:
16
- raise ValueError("GEMINI_API_KEY not found in environment variables. Please set it in Hugging Face Spaces secrets.")
 
17
  genai.configure(api_key=api_key)
18
- model = genai.GenerativeModel('gemini-2.5')
19
 
20
- # Prompt for Gemini to analyze text
 
 
 
 
 
 
 
 
 
 
 
21
  PROMPT = """
22
  You are an AI content reviewer. Analyze the provided text for the following:
23
- 1. **Grammar Issues**: Identify and suggest corrections for grammatical errors.
24
- 2. **Legal Policy Violations**: Flag content that may violate common legal policies (e.g., copyright infringement, defamation, incitement to violence).
25
- 3. **Crude/Abusive Language**: Detect crude, offensive, or abusive language.
26
- 4. **Sensitive Topics**: Identify content related to sensitive topics such as racism, gender bias, or other forms of discrimination.
27
 
28
  Return the results in the following markdown format:
29
- ```markdown
30
  # Blog Review Report
31
 
32
  ## Grammar Corrections
33
- - [List grammar issues and suggested corrections]
 
 
 
 
 
 
 
 
 
 
34
 
35
  ## Legal Policy Violations
36
- - [List any potential legal violations or "None detected"]
 
 
 
37
 
38
  ## Crude/Abusive Language
39
  - [List instances of crude or abusive language or "None detected"]
40
 
41
  ## Sensitive Topics
42
  - [List instances of sensitive topics or "None detected"]
43
- ```
44
 
45
- For each issue, provide the original sentence, the issue, and the suggested correction or explanation. Be precise and concise.
46
  """
47
 
48
- def fetch_url_content(url):
49
  try:
50
  response = requests.get(url, timeout=10)
51
  response.raise_for_status()
@@ -56,50 +81,132 @@ def fetch_url_content(url):
56
  except Exception as e:
57
  return f"Error fetching URL: {str(e)}"
58
 
59
- def review_blog(input_text, input_type):
60
- # Handle input type
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  if input_type == "URL":
62
- input_text = fetch_url_content(input_text)
 
63
  if input_text.startswith("Error"):
64
- return input_text, None
65
 
66
  # Tokenize input for analysis
67
  sentences = sent_tokenize(input_text)
68
  analysis_text = "\n".join(sentences)
69
 
 
 
 
 
 
 
 
 
 
70
  # Query Gemini with the prompt
71
  try:
72
- response = model.generate_content(PROMPT + "\n\nText to analyze:\n" + analysis_text)
73
  report = response.text.strip()
74
  # Ensure the response is markdown by removing any code fences
75
- report = re.sub(r'^```markdown\n|```$', '', report, flags=re.MULTILINE)
76
  except Exception as e:
77
  report = f"Error analyzing content with Gemini: {str(e)}"
 
 
 
 
 
78
 
79
- return report, report
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
- # Gradio UI
82
- with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
83
  gr.Markdown("# 📝 AI Blog Reviewer")
84
  gr.Markdown("Enter blog text or a URL to review for grammar, legal issues, crude language, and sensitive topics. The report is generated in markdown format.")
85
 
86
- input_type = gr.Radio(["Text", "URL"], label="Input Type", value="Text")
87
- blog_input = gr.Textbox(lines=8, label="Blog Content or URL", placeholder="Paste your blog text or URL here...")
88
- review_btn = gr.Button("Review Blog")
 
 
 
 
89
 
90
  gr.Markdown("### 📄 Review Report")
91
  report_output = gr.Markdown()
92
  download_btn = gr.File(label="Download Report", visible=False)
93
 
94
- def handle_review_output(report, file_report):
95
- if file_report and not file_report.startswith("Error"):
96
- return report, gr.update(visible=True, value={"content": file_report, "filename": "blog_review_report.md"})
97
- return report, gr.update(visible=False)
98
-
99
- review_btn.click(
100
- review_blog,
101
- inputs=[blog_input, input_type],
102
- outputs=[report_output, download_btn]
103
  )
104
 
105
  demo.launch()
 
5
  import google.generativeai as genai
6
  import os
7
  import re
8
+ import tempfile
9
+ import asyncio
10
+ import time
11
 
12
  # Download NLTK data
13
  download('punkt')
14
  download('punkt_tab')
15
 
16
+ # Configure Gemini API using environment variable
17
  api_key = os.environ.get("GEMINI_API_KEY")
18
  if not api_key:
19
+ raise ValueError("GEMINI_API_KEY not found in environment variables. Please set it in your environment.")
20
+
21
  genai.configure(api_key=api_key)
 
22
 
23
+ # Use gemini-1.5-flash for faster and more accessible text analysis
24
+ try:
25
+ model = genai.GenerativeModel('gemini-1.5-flash')
26
+ except Exception as e:
27
+ # Fallback: List available models if the specified model is not found
28
+ print(f"Error initializing model: {str(e)}")
29
+ print("Available models:")
30
+ for m in genai.list_models():
31
+ print(m.name)
32
+ raise ValueError("Failed to initialize gemini-1.5-flash. Check available models above and update the model name.")
33
+
34
+ # Prompt for Gemini to analyze text with specified output format
35
  PROMPT = """
36
  You are an AI content reviewer. Analyze the provided text for the following:
37
+ 1. Grammar Issues: Identify and suggest corrections for grammatical errors.
38
+ 2. Legal Policy Violations: Flag content that may violate common legal policies (e.g., copyright infringement, defamation, incitement to violence).
39
+ 3. Crude/Abusive Language: Detect crude, offensive, or abusive language.
40
+ 4. Sensitive Topics: Identify content related to sensitive topics such as racism, gender bias, or other forms of discrimination.
41
 
42
  Return the results in the following markdown format:
 
43
  # Blog Review Report
44
 
45
  ## Grammar Corrections
46
+ 1. [Heading of issue]
47
+ - CONTENT: [Exact line or part of text with the issue]
48
+ - SUGGESTION: [Suggested correction]
49
+ - ISSUE: [Description of the issue]
50
+
51
+ 2. [Heading of next issue]
52
+ - CONTENT: [Exact line or part of text with the issue]
53
+ - SUGGESTION: [Suggested correction]
54
+ - ISSUE: [Description of the issue]
55
+
56
+ [Continue numbering for additional issues or state "None detected"]
57
 
58
  ## Legal Policy Violations
59
+ - CONTENT: [Exact line or part of text with the issue]
60
+ SUGGESTION: [Suggested action or correction]
61
+ ISSUE: [Description of the legal violation]
62
+ [Or state "None detected"]
63
 
64
  ## Crude/Abusive Language
65
  - [List instances of crude or abusive language or "None detected"]
66
 
67
  ## Sensitive Topics
68
  - [List instances of sensitive topics or "None detected"]
 
69
 
70
+ For each issue, provide the exact text, a suggested correction or action, and a concise explanation. Be precise and ensure the output strictly follows the specified format.
71
  """
72
 
73
+ async def fetch_url_content(url):
74
  try:
75
  response = requests.get(url, timeout=10)
76
  response.raise_for_status()
 
81
  except Exception as e:
82
  return f"Error fetching URL: {str(e)}"
83
 
84
+ async def review_blog(text_input, url_input, progress=gr.Progress()):
85
+ # Determine input type based on which field is populated
86
+ if text_input and not url_input:
87
+ input_type = "Text"
88
+ input_text = text_input
89
+ elif url_input and not text_input:
90
+ input_type = "URL"
91
+ input_text = url_input
92
+ else:
93
+ return "Review Blog", "Error: Please provide input in either the Text or URL tab, but not both.", gr.update(visible=False)
94
+
95
+ # Handle empty input
96
+ if not input_text:
97
+ return "Review Blog", "Error: No input provided.", gr.update(visible=False)
98
+
99
+ # Handle URL input
100
  if input_type == "URL":
101
+ progress(0, desc="Fetching content...")
102
+ input_text = await fetch_url_content(input_text)
103
  if input_text.startswith("Error"):
104
+ return "Review Blog", input_text, gr.update(visible=False)
105
 
106
  # Tokenize input for analysis
107
  sentences = sent_tokenize(input_text)
108
  analysis_text = "\n".join(sentences)
109
 
110
+ # Simulate progress for API call
111
+ progress(0, desc="Generating report...")
112
+ start_time = time.time()
113
+ for i in range(1, 10):
114
+ await asyncio.sleep(1) # Simulate progress every second
115
+ progress(i / 10, desc=f"Generating report... ({int(i * 10)}%)")
116
+ if time.time() - start_time > 30: # Timeout after 30 seconds
117
+ return "Review Blog", "Error: API request timed out after 30 seconds.", gr.update(visible=False)
118
+
119
  # Query Gemini with the prompt
120
  try:
121
+ response = await asyncio.to_thread(model.generate_content, PROMPT + "\n\nText to analyze:\n" + analysis_text)
122
  report = response.text.strip()
123
  # Ensure the response is markdown by removing any code fences
124
+ report = re.sub(r'^markdown\n|$', '', report, flags=re.MULTILINE)
125
  except Exception as e:
126
  report = f"Error analyzing content with Gemini: {str(e)}"
127
+ # Fallback: List available models for debugging
128
+ print("Available models:")
129
+ for m in genai.list_models():
130
+ print(m.name)
131
+ return "Review Blog", report, gr.update(visible=False)
132
 
133
+ # Create a temporary file to store the report
134
+ try:
135
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.md', delete=False, encoding='utf-8') as temp_file:
136
+ temp_file.write(report)
137
+ temp_file_path = temp_file.name
138
+ progress(1.0, desc="Report generated!")
139
+ return "Review Blog", report, gr.update(visible=True, value=temp_file_path)
140
+ except Exception as e:
141
+ return "Review Blog", f"Error creating temporary file: {str(e)}", gr.update(visible=False)
142
+
143
+ # Custom CSS for hover effect, loading state, and Inter font
144
+ custom_css = """
145
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
146
+ .gradio-container {
147
+ font-family: 'Inter', sans-serif !important;
148
+ }
149
+ .review-btn {
150
+ transition: all 0.3s ease;
151
+ font-weight: 500;
152
+ background-color: #2c3e50;
153
+ color: white;
154
+ border-radius: 8px;
155
+ padding: 10px 20px;
156
+ }
157
+ .review-btn:hover {
158
+ background-color: #4CAF50;
159
+ color: white;
160
+ transform: scale(1.05);
161
+ }
162
+ .review-btn:disabled {
163
+ opacity: 0.7;
164
+ cursor: not-allowed;
165
+ }
166
+ .review-btn:disabled::after {
167
+ content: ' ⏳';
168
+ }
169
+ .tab-nav button {
170
+ font-family: 'Inter', sans-serif;
171
+ font-weight: 500;
172
+ }
173
+ input, textarea {
174
+ font-family: 'Inter', sans-serif;
175
+ }
176
+ .gr-progress {
177
+ background-color: #e0e0e0;
178
+ border-radius: 8px;
179
+ overflow: hidden;
180
+ }
181
+ .gr-progress > div {
182
+ background-color: #4CAF50;
183
+ height: 20px;
184
+ transition: width 0.3s ease;
185
+ }
186
+ """
187
 
188
+ # Gradio UI with Tabs
189
+ with gr.Blocks(theme=gr.themes.Monochrome(), css=custom_css) as demo:
190
  gr.Markdown("# 📝 AI Blog Reviewer")
191
  gr.Markdown("Enter blog text or a URL to review for grammar, legal issues, crude language, and sensitive topics. The report is generated in markdown format.")
192
 
193
+ with gr.Tabs():
194
+ with gr.TabItem("Text"):
195
+ text_input = gr.Textbox(lines=8, label="Blog Content", placeholder="Paste your blog text here...")
196
+ with gr.TabItem("URL"):
197
+ url_input = gr.Textbox(lines=1, label="Blog URL", placeholder="Enter the blog URL here...")
198
+
199
+ status_button = gr.Button(value="Review Blog", elem_classes=["review-btn"])
200
 
201
  gr.Markdown("### 📄 Review Report")
202
  report_output = gr.Markdown()
203
  download_btn = gr.File(label="Download Report", visible=False)
204
 
205
+ # Bind the review button to process inputs
206
+ status_button.click(
207
+ fn=review_blog,
208
+ inputs=[text_input, url_input],
209
+ outputs=[status_button, report_output, download_btn]
 
 
 
 
210
  )
211
 
212
  demo.launch()