Blogs_Agent / app.py
Saqib772's picture
Update app.py
9c0d325 verified
import gradio as gr
from dotenv import load_dotenv
import os
import time
from typing import Dict, Any
# Load environment variables
load_dotenv()
# Import crew agents after environment setup
from crewai import Agent, Task, Crew, LLM
from crewai_tools import SerperDevTool
# Initialize tools
search_tool = SerperDevTool()
# Initialize LLM
llm = LLM(
model="gemini/gemini-2.0-flash",
temperature=0.7,
stream=False # Set to False for Gradio compatibility
)
def create_crew_for_topic(topic: str) -> Crew:
"""Create a crew with agents for the given topic"""
# Research Specialist Agent
research_agent = Agent(
role="Research Specialist",
goal=f"Research interesting facts about the topic: {topic}",
backstory="You are a highly skilled research assistant that can research the web and provide factual data",
llm=llm,
tools=[search_tool],
verbose=False
)
# Creative Writer Agent
writer_agent = Agent(
role="Creative Writer",
goal="Write a 250 words blog using the research and it must start with a hook, introduction para, body para, conclusion para and end with a call to action",
backstory="You are a highly skilled writer assistant that can write a blog post about the topic",
llm=llm,
verbose=False
)
# Create tasks
task1 = Task(
description=f"Research interesting 4-5 facts about the topic: {topic}",
expected_output="A bullet point list of 4-5 facts about the topic",
agent=research_agent
)
task2 = Task(
description=f"Write a 250 words blog using the research on {topic} and must be a casual tone",
expected_output="Blog post",
agent=writer_agent,
context=[task1]
)
# Create crew
crew = Crew(
agents=[research_agent, writer_agent],
tasks=[task1, task2],
verbose=False
)
return crew
def generate_blog(topic: str, progress=gr.Progress()) -> Dict[str, Any]:
"""Generate blog content using crew agents"""
if not topic.strip():
return {
"status": "error",
"message": "Please enter a topic for blog generation."
}
try:
progress(0.1, desc="Initializing crew agents...")
# Create crew for the topic
crew = create_crew_for_topic(topic)
progress(0.3, desc="Researching topic...")
# Execute the crew tasks
response = crew.kickoff(inputs={"topic": topic})
progress(0.8, desc="Finalizing blog post...")
# Simulate some processing time for better UX
time.sleep(0.5)
progress(1.0, desc="Blog generated successfully!")
return {
"status": "success",
"topic": topic,
"blog_content": response,
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S")
}
except Exception as e:
return {
"status": "error",
"message": f"An error occurred: {str(e)}"
}
def format_blog_output(result: Dict[str, Any]) -> str:
"""Format the blog output for display"""
if result["status"] == "error":
return f"❌ **Error**: {result['message']}"
blog_content = result["blog_content"]
topic = result["topic"]
timestamp = result["timestamp"]
formatted_output = f"""
# πŸ“ Blog Post: {topic}
**Generated on:** {timestamp}
---
{blog_content}
---
*This blog post was generated using AI-powered research and writing agents.*
"""
return formatted_output
# Create Gradio interface
with gr.Blocks(
title="Crew Agents - AI Blog Generator",
theme=gr.themes.Soft(),
css="""
.gradio-container {
max-width: 1200px !important;
margin: 0 auto !important;
}
.header {
text-align: center;
padding: 20px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 2px;
margin-bottom: 30px;
}
.output-section {
background: white !important;
padding: 25px !important;
border-radius: 5px !important;
border: none !important;
outline: none !important;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) !important;
}
/* Remove all borders from Gradio components */
.output-section * {
border: none !important;
outline: none !important;
}
.output-section .gr-box {
border: none !important;
outline: none !important;
}
/* Remove borders from Group components */
.gr-group {
border: none !important;
outline: none !important;
}
/* Remove borders from all form elements */
.gr-form {
border: none !important;
outline: none !important;
}
/* Target the specific border classes */
.border {
border: none !important;
}
.border-2 {
border: none !important;
}
.border-solid {
border: none !important;
}
.border-gray-200 {
border: none !important;
}
/* Remove any remaining borders */
* {
border-color: transparent !important;
}
"""
) as demo:
# Header
gr.HTML("""
<div class="header">
<h1>πŸ€– Crew Agents - AI Blog Generator</h1>
<p>Powered by CrewAI - Generate well-researched blog posts in seconds!</p>
</div>
""")
with gr.Row():
with gr.Column(scale=1):
# Input Section
with gr.Group():
gr.Markdown("## 🎯 **Enter Your Blog Topic**")
topic_input = gr.Textbox(
label="Blog Topic",
placeholder="e.g., How AI is transforming healthcare, The future of renewable energy...",
lines=3,
max_lines=5,
info="Describe what you want to write about. Be specific for better results!"
)
generate_btn = gr.Button(
"πŸš€ Generate Blog Post",
variant="primary",
size="lg"
)
# Example topics
gr.Markdown("""
**πŸ’‘ Example Topics:**
- How AI is revolutionizing agriculture
- The impact of climate change on coastal cities
- Future of remote work in 2026
- Sustainable fashion trends
""")
with gr.Column(scale=2):
# Output Section
with gr.Group():
gr.Markdown("## πŸ“ **Generated Blog Post**")
output_markdown = gr.Markdown(
value="Enter a topic above and click 'Generate Blog Post' to get started!",
label="Blog Content"
)
# Status indicator
status_text = gr.Textbox(
label="Status",
value="Ready to generate",
interactive=False
)
# Footer
gr.HTML("""
<div style="text-align: center; margin-top: 30px; padding: 20px; color: #666;">
<p>Built with ❀️ using <a href="https://github.com/joaomdmoura/crewAI" target="_blank">CrewAI</a> and <a href="https://ai.google.dev/" target="_blank">Google Gemini</a></p>
</div>
""")
# Event handlers
def on_generate(topic):
if not topic.strip():
return "Please enter a topic for blog generation.", "No topic provided"
# Update status
yield "Generating blog post...", "Processing..."
# Generate blog
result = generate_blog(topic)
if result["status"] == "success":
formatted_blog = format_blog_output(result)
yield formatted_blog, "Blog generated successfully!"
else:
yield f"❌ **Error**: {result['message']}", "Generation failed"
generate_btn.click(
fn=on_generate,
inputs=[topic_input],
outputs=[output_markdown, status_text]
)
# Enter key support
topic_input.submit(
fn=on_generate,
inputs=[topic_input],
outputs=[output_markdown, status_text]
)
# Launch the app
if __name__ == "__main__":
demo.launch(
server_name="0.0.0.0",
server_port=7860,
share=False,
show_error=True
)