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 = """
""" # ---------------------------- # 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()