Nexus_Post_AI / app.py
krishbaresha's picture
Update app.py
8e173cc verified
import gradio as gr
import os
import json
from Pdf_utils import extract_text_from_pdf
from ocr_utils import extract_text_from_image
from Prompt_Builder import build_prompt
from openai import OpenAI
# ----------------------------
# CONFIG & SECRETS
# ----------------------------
GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
OCR_API_KEY = os.environ.get("OCR_API_KEY")
client = OpenAI(
api_key=GROQ_API_KEY,
base_url="https://api.groq.com/openai/v1",
)
# ----------------------------
# UI CUSTOMIZATION (Vanta.js + Glassmorphism)
# ----------------------------
css = """
footer {visibility: hidden}
.gradio-container {
background: rgba(10, 25, 47, 0.7) !important;
backdrop-filter: blur(15px) !important;
border: 1px solid rgba(255, 255, 255, 0.1) !important;
border-radius: 20px !important;
color: white !important;
}
#vanta-canvas {
position: fixed;
top: 0; left: 0; width: 100vw; height: 100vh;
z-index: -1;
}
#output-box {
background: rgba(0, 0, 0, 0.3) !important;
padding: 20px;
border-radius: 10px;
}
"""
vanta_head = """
<div id="vanta-canvas"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.net.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
VANTA.NET({
el: "#vanta-canvas",
mouseControls: true,
touchControls: true,
gyroControls: false,
minHeight: 200.00,
minWidth: 200.00,
scale: 1.00,
scaleMobile: 1.00,
color: 0x3fbbee,
backgroundColor: 0x0a192f,
points: 15.00,
maxDistance: 20.00,
spacing: 16.00
})
});
</script>
"""
# ----------------------------
# CORE LOGIC WITH UX ALERTS
# ----------------------------
def generate_nexus_post(file, user_text, url, url_desc, hashtags, custom_p, suggestions, model_name):
# Validation Check
if not file and not user_text.strip():
raise gr.Error("Bhai, kam az kam kuch text ya file toh do! Input empty hai.")
# User Feedback Notification
gr.Info("🚀 Processing your request... Sit tight!")
file_text = ""
if file:
try:
if file.name.lower().endswith(".pdf"):
gr.Info("📄 Reading PDF...")
file_text = extract_text_from_pdf(file.name)
else:
gr.Info("🖼️ Running OCR on Image...")
file_text = extract_text_from_image(file.name, OCR_API_KEY)
except Exception as e:
raise gr.Error(f"File processing error: {str(e)}")
# Prompt Building
final_prompt = build_prompt(user_text, file_text, {"url": url, "description": url_desc}, [], hashtags.split(","), custom_p, suggestions)
try:
gr.Info("🤖 AI is ghostwriting your post...")
completion = client.chat.completions.create(
model=model_name,
messages=[{"role": "user", "content": final_prompt}],
temperature=0.7,
timeout=45.0 # Pre-emptively stop if API is stuck
)
gr.Info("✅ Done! Post generated.")
return completion.choices[0].message.content
except Exception as e:
raise gr.Error(f"API Error: {str(e)}")
# ----------------------------
# GRADIO INTERFACE
# ----------------------------
with gr.Blocks(theme=gr.themes.Default(), css=css) as demo:
gr.HTML(vanta_head)
with gr.Column():
gr.Markdown("# 🚀 Nexus Post AI\n### Professional LinkedIn Ghostwriter")
with gr.Row():
with gr.Column(scale=1):
file_input = gr.File(label="Upload Context (PDF/Image)")
user_msg = gr.Textbox(label="Core Idea", placeholder="What's this post about?", lines=3)
with gr.Accordion("🔗 Links & Tags", open=False):
link_url = gr.Textbox(label="Reference URL")
link_d = gr.Textbox(label="Link Description")
tags = gr.Textbox(label="Hashtags (comma separated)")
with gr.Column(scale=1):
model_drop = gr.Dropdown(
choices=["llama-3.3-70b-versatile", "mixtral-8x7b-32768"],
value="llama-3.3-70b-versatile",
label="AI Model"
)
ai_adds = gr.CheckboxGroup(
label="Enhancements",
choices=["Strong Hook", "Storytelling", "Bullet Points", "Emojis", "Call-to-Action"]
)
custom_inst = gr.Textbox(label="Custom Instructions", placeholder="e.g. 'Make it professional'")
# Button with explicit loading
submit_btn = gr.Button("🔥 GENERATE POST", variant="primary")
output_display = gr.Markdown(label="Generated Drafts", elem_id="output-box")
# The Logic Trigger
submit_btn.click(
fn=generate_nexus_post,
inputs=[file_input, user_msg, link_url, link_d, tags, custom_inst, ai_adds, model_drop],
outputs=output_display,
show_progress="full", # Full screen overlay for clear status
scroll_to_output=True
)
demo.launch()