OPT_Generator / app.py
ADARSHVINAYAK's picture
Update app.py
5dc953a verified
import os
import gradio as gr
from groq import Groq
import reportlab.lib.pagesizes as pagesizes
from reportlab.pdfgen import canvas
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.units import inch
from io import BytesIO
import docx
from docx.shared import Pt, Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH
import time
import tempfile
# Initialize the Groq client
GROQ_API_KEY = os.getenv('GROQ_API_KEY')
GROQ_MODEL = "llama-3.3-70b-versatile"
client = Groq(api_key=GROQ_API_KEY)
# Custom CSS for styling
custom_css = """
.generate-btn {
margin: 0 auto !important;
display: block !important;
}
.output-box {
background-color: black !important;
border-radius: 8px !important;
padding: 20px !important;
box-shadow: 0 2px 5px rgba(0,0,0,0.1) !important;
margin-top: 20px !important;
color: white !important;
}
.app-header {
text-align: center !important;
margin-bottom: 20px !important;
}
/* Fix text visibility */
.gradio-container input[type=text],
.gradio-container textarea {
color: #000000 !important;
background-color: #ffffff !important;
border: 1px solid #cccccc !important;
}
/* Make sure placeholder text is visible but distinct */
.gradio-container input::placeholder,
.gradio-container textarea::placeholder {
color: #888888 !important;
opacity: 1;
}
/* Ensure the output text is clearly visible */
.output-box, .markdown-text {
color: #000000 !important;
}
/* Loading indicator styling */
.loading-indicator {
text-align: center;
padding: 20px;
font-style: italic;
color: #555;
}
"""
def generate_opt_framework(topic):
"""Generate an OPT framework for the given topic using Groq API"""
if not topic:
return "Please enter a topic to generate an OPT framework."
prompt = f"""
Generate an OPT (Objectives, Products, Tasks) framework for: {topic}
Format your response as follows:
# OPT Framework for: {topic}
## Objectives
Clear, high-level goals that define what success looks like for this topic/project.
## Products
Specific, tangible deliverables that will help achieve the objectives.
## Tasks
Detailed, actionable steps required to create each product.
Make your response comprehensive but practical, with clear language and realistic items.
"""
try:
chat_completion = client.chat.completions.create(
model=GROQ_MODEL,
messages=[
{"role": "system", "content": "You are an expert at creating OPT frameworks to help with project planning and goal setting."},
{"role": "user", "content": prompt}
],
temperature=0.7,
max_tokens=1500
)
framework = chat_completion.choices[0].message.content
return framework
except Exception as e:
return f"Error generating OPT framework: {str(e)}"
def generate_automation_analysis(opt_content):
"""Generate automation analysis for the OPT framework tasks"""
if not opt_content or "Tasks" not in opt_content:
return "No tasks found to analyze for automation."
prompt = f"""
Analyze the following OPT framework and identify tasks that can be automated:
{opt_content}
For each task that can be automated:
1. Identify the task
2. Explain why it can be automated
3. Provide a step-by-step beginner's guide to automating this task
4. Suggest tools or software that could help with the automation
Format your response as a comprehensive automation analysis with clear sections and explanations.
"""
try:
chat_completion = client.chat.completions.create(
model=GROQ_MODEL,
messages=[
{"role": "system", "content": "You are an expert at identifying tasks that can be automated and providing guidance on automation techniques."},
{"role": "user", "content": prompt}
],
temperature=0.7,
max_tokens=2000
)
analysis = chat_completion.choices[0].message.content
return analysis
except Exception as e:
return f"Error generating automation analysis: {str(e)}"
def handle_topic_submission(topic):
"""Handle topic submission from text input"""
opt_framework = generate_opt_framework(topic)
return opt_framework, gr.update(visible=True), gr.update(visible=True)
def handle_example_topic(example_topic):
"""Handle clicking on example topic buttons"""
opt_framework = generate_opt_framework(example_topic)
return example_topic, opt_framework, gr.update(visible=True), gr.update(visible=True)
def handle_regenerate(topic):
"""Handle regeneration request"""
if not topic:
return "Please enter a topic first."
opt_framework = generate_opt_framework(topic)
return opt_framework
def analyze_with_progress(opt_content, progress=gr.Progress()):
"""Handle request for automation analysis with progress indication"""
# Initial loading state
progress(0, desc="Preparing analysis...")
yield "Analyzing tasks for automation potential. Please wait...", gr.update(visible=True)
# Simulate progress steps to provide visual feedback
progress(0.3, desc="Identifying tasks...")
time.sleep(0.5) # Just to show progress visually
progress(0.6, desc="Evaluating automation potential...")
time.sleep(0.5)
progress(0.8, desc="Generating step-by-step guides...")
time.sleep(0.5)
# Generate the actual analysis
analysis = generate_automation_analysis(opt_content)
# Complete the progress and return results
progress(1.0, desc="Complete!")
yield analysis, gr.update(visible=True)
def create_pdf_file(content, title):
"""Create a PDF document from the content and save to temp file"""
# Create a temporary file
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.pdf')
temp_filename = temp_file.name
temp_file.close()
doc = SimpleDocTemplate(temp_filename, pagesize=pagesizes.letter)
styles = getSampleStyleSheet()
story = []
# Add custom title style
title_style = ParagraphStyle(
'TitleStyle',
parent=styles['Heading1'],
fontSize=16,
alignment=1,
spaceAfter=0.5*inch
)
# Add title
story.append(Paragraph(f"OPT Framework and Automation Analysis: {title}", title_style))
story.append(Spacer(1, 0.25*inch))
# Process content
paragraphs = content.split('\n')
for para in paragraphs:
if para.startswith('# '):
story.append(Paragraph(para[2:], styles['Heading1']))
elif para.startswith('## '):
story.append(Paragraph(para[3:], styles['Heading2']))
elif para.startswith('### '):
story.append(Paragraph(para[4:], styles['Heading3']))
elif para.strip():
story.append(Paragraph(para, styles['Normal']))
else:
story.append(Spacer(1, 0.1*inch))
doc.build(story)
return temp_filename
def create_docx_file(content, title):
"""Create a DOCX document from the content and save to temp file"""
# Create a temporary file
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.docx')
temp_filename = temp_file.name
temp_file.close()
doc = docx.Document()
# Add title
title_para = doc.add_paragraph()
title_run = title_para.add_run(f"OPT Framework and Automation Analysis: {title}")
title_run.font.size = Pt(18)
title_run.font.bold = True
title_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
# Process content
paragraphs = content.split('\n')
for para in paragraphs:
if para.startswith('# '):
p = doc.add_paragraph()
run = p.add_run(para[2:])
run.font.size = Pt(16)
run.font.bold = True
elif para.startswith('## '):
p = doc.add_paragraph()
run = p.add_run(para[3:])
run.font.size = Pt(14)
run.font.bold = True
elif para.startswith('### '):
p = doc.add_paragraph()
run = p.add_run(para[4:])
run.font.size = Pt(12)
run.font.bold = True
elif para.strip():
doc.add_paragraph(para)
doc.save(temp_filename)
return temp_filename
def download_pdf(opt_content, analysis_content, topic):
"""Create PDF for download"""
combined_content = f"{opt_content}\n\n# Automation Analysis\n\n{analysis_content}"
pdf_path = create_pdf_file(combined_content, topic)
return pdf_path
def download_docx(opt_content, analysis_content, topic):
"""Create DOCX for download"""
combined_content = f"{opt_content}\n\n# Automation Analysis\n\n{analysis_content}"
docx_path = create_docx_file(combined_content, topic)
return docx_path
# Create the Gradio interface
with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue"), css=custom_css) as app:
# App header
gr.Markdown("# OPT Framework Generator", elem_classes=["app-header"])
# What is OPT Framework (unhidden)
gr.Markdown("""
## What is the OPT Framework?
The OPT Framework is a structured approach to planning that breaks down goals into three key components:
- **Objectives**: High-level goals that define what success looks like
- **Products**: Tangible deliverables that help achieve the objectives
- **Tasks**: Specific, actionable steps required to create each product
This framework brings clarity, focus, and momentum to any project, making execution more purposeful and efficient.
""")
# How to use section (collapsible)
with gr.Accordion("How to Use This App", open=False):
gr.Markdown("""
1. Enter your topic or project in the text box, or click one of the example buttons
2. Click "Generate OPT Framework" to create your custom framework
3. Click "Generate Another Version" if you want alternative options
4. Analyze tasks for automation potential
5. Download your complete analysis as PDF or DOCX for future reference
This tool helps you organize any project or goal into a clear, actionable plan with insights on which tasks can be automated.
(PS: Please wait for a few seconds before downloading the report)
""")
# Input section with text box and examples side by side
with gr.Row():
with gr.Column(scale=7): # 70% width for text input
topic_input = gr.Textbox(
label="Enter your project/goal",
placeholder="Enter anything you can think of... a project, goal, business idea, personal challenge, etc.",
lines=3
)
submit_btn = gr.Button("Generate OPT Framework", variant="primary", elem_classes=["generate-btn"])
with gr.Column(scale=3): # 30% width for examples
gr.Markdown("### Quick Examples:")
example_btns = [
gr.Button("Mobile App Development"),
gr.Button("Content Marketing Strategy"),
gr.Button("Home Renovation Project"),
gr.Button("Personal Fitness Goal"),
gr.Button("Writing a Novel")
]
# Output section with custom styling
opt_output = gr.Markdown(elem_classes=["output-box"], label="Generated OPT Framework")
with gr.Row(visible=False) as action_row:
regenerate_btn = gr.Button("Generate Another Version")
analyze_btn = gr.Button("Analyze Tasks for Automation")
# Loading indicator and analysis output
analysis_output = gr.Markdown(elem_classes=["output-box"], label="Automation Analysis", visible=False)
with gr.Row(visible=False) as download_container:
download_btn = gr.Button("Download Report (Please wait for a few seconds before downloading)")
with gr.Row(visible=False) as download_format_row:
time.sleep(1)
pdf_btn = gr.Button("PDF")
docx_btn = gr.Button("DOCX")
# Set up event handlers
submit_btn.click(
handle_topic_submission,
inputs=[topic_input],
outputs=[opt_output, action_row, analyze_btn]
)
for btn in example_btns:
btn.click(
handle_example_topic,
inputs=[btn],
outputs=[topic_input, opt_output, action_row, analyze_btn]
)
regenerate_btn.click(
handle_regenerate,
inputs=[topic_input],
outputs=[opt_output]
)
# Modified to use streaming output for better loading feedback
analyze_btn.click(
analyze_with_progress,
inputs=[opt_output],
outputs=[analysis_output, download_container],
show_progress=True
)
download_btn.click(
lambda: gr.update(visible=True),
outputs=[download_format_row]
)
pdf_btn.click(
download_pdf,
inputs=[opt_output, analysis_output, topic_input],
outputs=[gr.File(label="Download PDF")]
)
docx_btn.click(
download_docx,
inputs=[opt_output, analysis_output, topic_input],
outputs=[gr.File(label="Download DOCX")]
)
if __name__ == "__main__":
app.launch()