import os import fitz import gradio as gr from openai import OpenAI client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) # 1) Extract full text from PDF def extract_text_from_pdf(pdf_file): text = "" with fitz.open(pdf_file.name) as doc: for page in doc: text += page.get_text() return text.strip() # 2) Summarize the full brief into bullet points def summarize_brief(full_text): prompt = f""" Please summarize the key main points of the following brand brief in bullet points: --- {full_text} --- """ response = client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": prompt}], temperature=0.7, ) return response.choices[0].message.content.strip() # 3) Generate 3 content ideas (without re-summarizing if summary already exists) def generate_ideas(brief_text, industry): prompt = f""" You are a creative strategist for a digital agency. A brand provided this brief: --- {brief_text} --- The creator's industry is: {industry} Suggest 3 short, punchy content ideas that align with this brief and are suitable for this industry. """ response = client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": prompt}], temperature=0.8, ) return response.choices[0].message.content.strip() # 4) Score the creator's draft versus the summarized brief. def score_draft(brief_text, draft_text): if not draft_text.strip(): return "No draft submitted." prompt = f""" Brand Brief: --- {brief_text} --- Creator's Draft: --- {draft_text} --- Score how well the creator's draft aligns with the brand brief. Return a score out of 10 and a 2–3 sentence explanation. """ response = client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": prompt}], temperature=0.7, ) return response.choices[0].message.content.strip() # 5) This function checks if there is already a summarized brief. # If yes, it uses that; otherwise it tries to summarize from text or PDF. def generate_ideas_from_brief(text_brief, pdf_brief, existing_brief, industry, draft_text): # Use the existing summarized brief if available. if existing_brief.strip(): summarized = existing_brief.strip() else: # If not, try the text_brief, then PDF if text_brief.strip(): summarized = summarize_brief(text_brief.strip()) elif pdf_brief is not None: full_brief = extract_text_from_pdf(pdf_brief) summarized = summarize_brief(full_brief) else: return "No summarized brief found. Please provide a brief.", "", "" ideas = generate_ideas(summarized, industry) match_score = score_draft(summarized, draft_text) if draft_text.strip() else "" return summarized, ideas, match_score # 6) Clear All: reset all inputs and outputs using gr.update def clear_all(): return ( gr.update(value=""), # text_brief gr.update(value=None), # pdf_brief gr.update(value="Lifestyle"), # industry gr.update(value=""), # draft_text gr.update(value=""), # output_brief (summarized brief) gr.update(value=""), # output_ideas gr.update(value="") # output_score ) # --- GRADIO UI --- industries = ["Lifestyle", "Fitness", "Music", "Fashion", "Food", "Tech", "Travel", "Gaming", "Parenting"] with gr.Blocks(css=""" body { font-family: 'Inter', sans-serif; background-color: #ffffff; } h1, h2, .gr-markdown h1 { color: black; font-weight: 700; } .gr-button { background-color: #00bfa6; color: white; border-radius: 6px; font-weight: bold; } .gr-button:hover { background-color: #009f8c; } """) as demo: gr.Markdown("# Sync’d AI") gr.Markdown("**Generate punchy content ideas and match creator drafts to briefs.**") with gr.Row(): text_brief = gr.Textbox(label="Brand Brief (Text Input)", lines=6, placeholder="Paste brand brief here...") pdf_brief = gr.File(label="Or Upload Brand Brief (PDF)", file_types=[".pdf"], file_count="single") industry = gr.Dropdown(choices=industries, label="Creator Industry", value="Lifestyle") draft_text = gr.Textbox(label="Creator's Draft (Optional)", placeholder="Paste the creator's draft here...", lines=4) with gr.Row(): generate_ideas_btn = gr.Button("Generate Ideas") submit_draft_btn = gr.Button("Submit Draft (Match Analysis)") clear_btn = gr.Button("Clear All") output_brief = gr.Textbox(label="Summarized Brief", lines=6) output_ideas = gr.Textbox(label="3 Content Ideas", lines=8) output_score = gr.Textbox(label="Match Score & Analysis", lines=4) # When a PDF is uploaded, auto-summarize and generate ideas. pdf_brief.change( fn=lambda pdf, ind, d: generate_ideas_from_brief("", pdf, "", ind, d), inputs=[pdf_brief, industry, draft_text], outputs=[output_brief, output_ideas, output_score], show_progress="full" ) # "Generate Ideas" button: # It checks if there's an existing summarized brief. generate_ideas_btn.click( fn=generate_ideas_from_brief, inputs=[text_brief, pdf_brief, output_brief, industry, draft_text], outputs=[output_brief, output_ideas, output_score], show_progress="full" ) # "Submit Draft" button for match analysis. submit_draft_btn.click( fn=score_draft, inputs=[output_brief, draft_text], outputs=output_score, show_progress="full" ) # "Clear All" button resets everything. clear_btn.click( fn=clear_all, inputs=[], outputs=[text_brief, pdf_brief, industry, draft_text, output_brief, output_ideas, output_score] ) demo.launch()