import gradio as gr import os import openai import subprocess import base64 def encode_image(image_path): with open(image_path, 'rb') as image_file: return base64.b64encode(image_file.read()).decode('utf-8') def extract_code_pieces(text: str, concat: bool = True) -> list[str]: """Extract code pieces from a text string. Args: text: str, model prediciton text. Rets: code_pieces: list[str], code pieces in the text. """ code_pieces = [] while "```python" in text: st_idx = text.index("```python") + 10 # end_idx = text.index("```", st_idx) if "```" in text[st_idx:]: end_idx = text.index("```", st_idx) else: end_idx = len(text) code_pieces.append(text[st_idx:end_idx].strip()) text = text[end_idx+3:].strip() if concat: return '\n\n'.join(code_pieces) return code_pieces SYSTEM_MESSAGE = """* You are an expert presentation slides designer who creates modern, fashionable, and stylish slides using Python code. Your job is to generate the required PPTX slide by writing and executing a Python script. Make sure to follow the guidelines below and do not skip any of them: 1. Ensure your code can successfully execute. If needed, you can also write tests to verify your code. 2. Maintain proper spacing and arrangements of elements in the slide: make sure to keep sufficient spacing between different elements; do not make elements overlap or overflow to the slide page. 3. Carefully select the colors of text, shapes, and backgrounds, to ensure all contents are readable. 4. The slides should not look empty or incomplete. When filling the content in the slides, maintain good design and layout.""" # INSTRUCTION = """Follow the instruction below to create the slide. # If the instruction is long and specific, follow the instruction carefully and add all elements as required; # if it is short and concise, you will need to create some content (text, image, layout) and implement it into the slide. # {} # Finally, your code should save the pptx file to path "{}".""" with open('agent_no_image_new_lib.prompt', 'r') as f: INSTRUCTION = f.read() import glob import time def list_files_in_directory(directory): """Lists all files in the given directory.""" return set(glob.glob(os.path.join(directory, "*"))) def cleanup_temp_files(temp_files): """Deletes a list of temporary files if they exist.""" for temp_file in temp_files: try: if os.path.exists(temp_file): os.remove(temp_file) print(f"Deleted temporary file: {temp_file}") except Exception as e: print(f"Failed to delete {temp_file}: {e}") def create_pptx(api_key, instruction, model_name="gpt-4o", max_tokens=4096): try: # Set OpenAI API key openai.api_key = api_key # Create OpenAI client client = openai.OpenAI(api_key=api_key) # Prepare messages for the chat completion messages = [{"role": "system", "content": SYSTEM_MESSAGE}] pptx_path = "output.pptx" instruction_message = INSTRUCTION.replace("INSERT_INSTRUCTION_HERE", instruction) messages.append({"role": "user", "content": instruction_message}) # Capture the directory state before execution working_directory = os.getcwd() files_before = list_files_in_directory(working_directory) # Retry up to 3 times for attempt in range(3): try: # Call OpenAI's GPT model response = client.chat.completions.create( model=model_name, messages=messages, max_tokens=max_tokens, n=1, ) generated_code = extract_code_pieces(response.choices[0].message.content, concat=True) generated_code = generated_code.replace("from library import", "from mysearchlib import") generated_code = generated_code.replace("generate_image(", f"generate_image({repr(api_key)},") generated_code = "from mysearchlib import *\n\n" + generated_code # Save the generated code code_file = "generated_slide_code.py" with open(code_file, "w") as f: f.write(generated_code) # Execute the generated code result = subprocess.run(["python", code_file], capture_output=True, text=True, check=True) print(result.stdout) # Capture the directory state after execution files_after = list_files_in_directory(working_directory) temp_files = files_after - files_before # Identify newly created files # Convert the pptx to jpg for preview preview_image = "image_previews/output.jpg" command = [ "libreoffice", "--headless", "--convert-to", "jpg", "--outdir", "image_previews", pptx_path ] subprocess.run(command) temp_files.add(preview_image) # If successful, return the result return "Slide generated successfully! Download your slide below.", pptx_path, preview_image except subprocess.CalledProcessError as e: print(f"Attempt {attempt + 1} failed: {e.stderr}") # Fallback: Use default code if all attempts fail print("All 3 attempts failed. Running default code.") default_code = f""" from pptx import Presentation ppt = Presentation() slide = ppt.slides.add_slide(ppt.slide_layouts[5]) title = slide.shapes.title title.text = "Insert Title Here" content = slide.placeholders[0] content.text = "{instruction}" ppt.save("output.pptx") """ code_file = "default_slide_code.py" with open(code_file, "w") as f: f.write(default_code) # Execute the default code subprocess.run(["python", code_file], capture_output=True, text=True, check=True) # Convert the pptx to jpg for preview preview_image = "image_previews/output.jpg" command = [ "libreoffice", "--headless", "--convert-to", "jpg", "--outdir", "image_previews", pptx_path ] subprocess.run(command) return "Default slide generated after 3 attempts failed.", pptx_path, preview_image except Exception as e: return f"An error occurred: {str(e)}", None, None finally: # Cleanup temporary files files_before.add("output.pptx") temp_files = list_files_in_directory(working_directory) - files_before cleanup_temp_files(temp_files) # Create a Gradio interface def gradio_demo(api_key, instruction): status, pptx_path, preview_image = create_pptx(api_key, instruction) return status, pptx_path, preview_image iface = gr.Interface( fn=gradio_demo, inputs=[ gr.Textbox(label="OpenAI API Key", type="password"), gr.Textbox(label="Instruction", placeholder="Enter your slide instruction here...") ], outputs=[ gr.Textbox(label="Status"), gr.File(label="Download Slide"), gr.Image(label="Slide Preview", type="filepath") ], title="AutoPresent", description="Automatically Generate a presentation slide" ) if __name__ == "__main__": iface.launch(share=True)