Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import google.generativeai as genai | |
| import os | |
| import time | |
| import re | |
| from collections import Counter | |
| # Configure Gemini with your API key | |
| genai.configure(api_key=os.getenv("GEMINI_API_KEY")) | |
| def extract_keywords(text): | |
| """Extract potential keywords from text""" | |
| text = re.sub(r'[^\w\s]', '', text.lower()) | |
| words = text.split() | |
| stop_words = {'the', 'is', 'at', 'which', 'on', 'and', 'a', 'to', 'are', 'as', 'was', 'will', 'an', 'be', 'or', 'do', 'if', 'you', 'all', 'any', 'can', 'had', 'her', 'his', 'how', 'man', 'new', 'now', 'old', 'see', 'two', 'way', 'who', 'boy', 'did', 'its', 'let', 'put', 'say', 'she', 'too', 'use'} | |
| meaningful_words = [word for word in words if len(word) > 3 and word not in stop_words] | |
| word_counts = Counter(meaningful_words) | |
| return [word for word, count in word_counts.most_common(10)] | |
| def analyze_content(content, keywords): | |
| if not content or not keywords: | |
| return "Please enter both content and keywords", "", "" | |
| # Extract existing keywords locally first | |
| existing_keywords = extract_keywords(content) | |
| existing_keywords_text = ", ".join(existing_keywords[:8]) if existing_keywords else "No significant keywords found" | |
| # Basic content analysis (local processing) | |
| word_count = len(content.split()) | |
| char_count = len(content) | |
| target_keywords = [kw.strip().lower() for kw in keywords.split(',')] | |
| content_analysis = f"""Word Count: {word_count} | |
| Character Count: {char_count} | |
| Readability: {"Good" if word_count > 300 else "Needs more content"} | |
| Target Keywords Found: {sum(1 for kw in target_keywords if kw in content.lower())}/{len(target_keywords)}""" | |
| try: | |
| # Use Gemini Flash model (more efficient, lower quota usage) | |
| model = genai.GenerativeModel('gemini-1.5-flash') | |
| # Shorter, more focused prompt to use less quota | |
| prompt = f"""Analyze this content for SEO with keywords: {keywords[:100]} | |
| Content: {content[:500]} | |
| Provide brief SEO recommendations: | |
| 1. Keyword optimization tips | |
| 2. Content structure advice | |
| 3. Technical SEO suggestions""" | |
| # Add delay to avoid rate limiting | |
| time.sleep(1) | |
| response = model.generate_content( | |
| prompt, | |
| generation_config=genai.types.GenerationConfig( | |
| max_output_tokens=500, | |
| temperature=0.7, | |
| ) | |
| ) | |
| return existing_keywords_text, content_analysis, response.text | |
| except Exception as e: | |
| error_msg = str(e) | |
| # If quota exceeded, return demo recommendations | |
| if "429" in error_msg or "quota" in error_msg.lower(): | |
| demo_recommendations = f"""π― **DEMO MODE - SEO RECOMMENDATIONS** | |
| **KEYWORD OPTIMIZATION:** | |
| - Target keyword "{target_keywords[0]}" density: {round((content.lower().count(target_keywords[0]) / word_count) * 100, 2)}% | |
| - Recommended: 1-2% keyword density | |
| - Add keywords to title, headings, and first paragraph | |
| **CONTENT STRUCTURE:** | |
| - Current length: {word_count} words ({"Good" if word_count > 500 else "Consider expanding"}) | |
| - Add H2/H3 subheadings with target keywords | |
| - Include bullet points and lists for readability | |
| **TECHNICAL SEO:** | |
| - Add internal links (2-3 recommended) | |
| - Optimize images with alt text | |
| - Include meta description with primary keyword | |
| - Ensure mobile-friendly formatting | |
| **PRIORITY ACTIONS:** | |
| 1. Add "{target_keywords[0]}" to first 100 words | |
| 2. Create keyword-rich H2 headings | |
| 3. Write compelling meta description | |
| 4. Add related internal links | |
| 5. Include call-to-action elements | |
| *Note: This is demo mode. For full AI analysis, try again later or use a fresh API key.*""" | |
| return existing_keywords_text, content_analysis, demo_recommendations | |
| else: | |
| return existing_keywords_text, content_analysis, f"Error: {error_msg[:200]}..." | |
| # Create Gradio interface | |
| with gr.Blocks( | |
| title="SEO Keyword Optimizer with Gemini AI", | |
| theme=gr.themes.Soft() | |
| ) as app: | |
| gr.Markdown(""" | |
| # π SEO Keyword Optimizer with Gemini AI | |
| **Enter your content and target keywords to get SEO optimization recommendations.** | |
| """) | |
| with gr.Row(): | |
| with gr.Column(): | |
| content_input = gr.Textbox( | |
| label="π Content to Analyze", | |
| placeholder="Paste your article, blog post, or webpage content here...", | |
| lines=10 | |
| ) | |
| with gr.Column(): | |
| keywords_input = gr.Textbox( | |
| label="π― Target Keywords (comma-separated)", | |
| placeholder="e.g., digital marketing, SEO strategy, content optimization", | |
| lines=3 | |
| ) | |
| analyze_btn = gr.Button("π Analyze Content", variant="primary") | |
| with gr.Row(): | |
| with gr.Column(): | |
| gr.Markdown("## π Existing Keywords") | |
| existing_output = gr.Textbox( | |
| label="Keywords Found", | |
| interactive=False, | |
| lines=3 | |
| ) | |
| with gr.Column(): | |
| gr.Markdown("## π Content Analysis") | |
| analysis_output = gr.Textbox( | |
| label="Content Metrics", | |
| interactive=False, | |
| lines=6 | |
| ) | |
| gr.Markdown("## π― Gemini's SEO Recommendations") | |
| recommendations_output = gr.Textbox( | |
| label="AI-Powered Recommendations", | |
| lines=15, | |
| interactive=False, | |
| show_copy_button=True | |
| ) | |
| analyze_btn.click( | |
| fn=analyze_content, | |
| inputs=[content_input, keywords_input], | |
| outputs=[existing_output, analysis_output, recommendations_output], | |
| show_progress=True | |
| ) | |
| if __name__ == "__main__": | |
| app.launch() |