In this tutorial, we will generate detailed, multi-slide pitch decks for companies using a self-hosted Presenton’s API and a Python script that leverages OpenAI for intelligent question generation and structure creation.

This tutorial extends Generate a PPT via API in 5 Minutes and shows you how to automate the creation of professional pitch decks from company URLs using Python and AI.

So, do check it before continuing with this and make sure you have Presenton running locally or on any server, and you are able to generate presentations with it.


1. Prepare Your Environment

You’ll need the following setup:

a. OpenAI API Key

Get your API key from OpenAI Platform and set it as an environment variable:

export OPENAI_API_KEY='your-openai-api-key-here'

b. Presenton Instance

Ensure Presenton is running locally on http://localhost:5000 or update the URL in the script to match your setup.


2. Install Python Requirements

You’ll need several libraries for web scraping, AI integration, and API calls:

pip install requests beautifulsoup4 openai pydantic

3. Write the Python Script

Let’s build the script step by step.

a. Import Libraries

import requests
import json
import os
import sys
from urllib.parse import urlparse
from bs4 import BeautifulSoup
import openai
from typing import Dict, List, Optional
from pydantic import BaseModel, Field

b. Define Pydantic Models for Structured Outputs

class QuestionsResponse(BaseModel):
    """Structured response for questions"""
    questions: List[str] = Field(description="List of exactly 3 questions to ask the user about their business")

class PitchDeckGenerator:
    def __init__(self):
        self.presenton_base_url = "http://localhost:5000"
        self.openai_client = None
        self.last_questions = []  # Store the generated questions
        self.setup_openai()

c. Setup OpenAI Client

def setup_openai(self):
    """Setup OpenAI client with API key"""
    api_key = os.getenv('OPENAI_API_KEY')
    if not api_key:
        print("❌ Error: OPENAI_API_KEY environment variable not set")
        print("Please set your OpenAI API key: export OPENAI_API_KEY='your-key-here'")
        sys.exit(1)
    
    self.openai_client = openai.OpenAI(api_key=api_key)

d. Fetch Company Information from URL

def fetch_company_info(self, url: str) -> Dict[str, str]:
    """Fetch company information from URL"""
    print(f"🔍 Fetching information from: {url}")
    
    try:
        # Add protocol if missing
        if not url.startswith(('http://', 'https://')):
            url = 'https://' + url
        
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
        }
        
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()
        
        soup = BeautifulSoup(response.content, 'html.parser')
        
        # Extract title, description, h1, and first paragraph
        title = soup.find('title')
        title_text = title.get_text().strip() if title else "No title found"
        
        meta_desc = soup.find('meta', attrs={'name': 'description'})
        description = meta_desc.get('content', '') if meta_desc else ""
        
        h1 = soup.find('h1')
        h1_text = h1.get_text().strip() if h1 else ""
        
        first_p = soup.find('p')
        first_p_text = first_p.get_text().strip() if first_p else ""
        
        company_info = {
            'url': url,
            'title': title_text,
            'description': description,
            'h1': h1_text,
            'first_paragraph': first_p_text
        }
        
        print(f"✅ Successfully fetched company information")
        print(f"   Title: {title_text}")
        print(f"   Description: {description[:100]}...")
        
        return company_info
        
    except Exception as e:
        print(f"❌ Error fetching company information: {str(e)}")
        return {'url': url, 'title': '', 'description': '', 'h1': '', 'first_paragraph': ''}

e. Generate Questions Using OpenAI with Structured Outputs

def generate_questions(self, company_info: Dict[str, str]) -> List[str]:
    """Generate questions using OpenAI based on company information"""
    print("🤖 Generating questions using OpenAI...")
    
    prompt = f"""
Based on this company information, generate exactly 3 relevant questions to ask the user to better understand their business for creating a pitch deck:

Company URL: {company_info['url']}
Company Title: {company_info['title']}
Company Description: {company_info['description']}
H1: {company_info['h1']}
First Paragraph: {company_info['first_paragraph']}

Generate 3 specific, relevant questions that will help create a compelling pitch deck. 
Focus on understanding their business model, target market, unique value proposition, and growth plans.

The questions should be clear, specific, and designed to gather essential information for creating a professional pitch deck.
"""
    
    try:
        response = self.openai_client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[{"role": "user", "content": prompt}],
            tools=[{
                "type": "function",
                "function": {
                    "name": "get_questions",
                    "description": "Get exactly 3 questions to ask the user about their business",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "questions": {
                                "type": "array",
                                "items": {"type": "string"},
                                "description": "List of exactly 3 questions to ask the user about their business"
                            }
                        },
                        "required": ["questions"]
                    }
                }
            }],
            tool_choice={"type": "function", "function": {"name": "get_questions"}},
            max_tokens=300,
            temperature=0.7
        )
        
        # Extract questions from the tool call response
        tool_call = response.choices[0].message.tool_calls[0]
        arguments = json.loads(tool_call.function.arguments)
        questions = arguments.get('questions', [])
        
        # Ensure we have exactly 3 questions
        if len(questions) < 3:
            fallback_questions = [
                "What is your company's main product or service?",
                "Who is your target market?",
                "What makes your solution unique?"
            ]
            questions = questions + fallback_questions[:3-len(questions)]
        else:
            questions = questions[:3]
        
        print("✅ Generated questions:")
        for i, question in enumerate(questions, 1):
            print(f"   {i}. {question}")
        
        # Store the questions for later use in structure generation
        self.last_questions = questions
        
        return questions
        
    except Exception as e:
        print(f"❌ Error generating questions: {str(e)}")
        return [
            "What is your company's main product or service?",
            "Who is your target market?",
            "What makes your solution unique?"
        ]

f. Get User Answers Interactively

def get_user_answers(self, questions: List[str]) -> List[str]:
    """Get user answers to the generated questions"""
    print("\n📝 Please answer the following questions:")
    answers = []
    
    for i, question in enumerate(questions, 1):
        print(f"\nQuestion {i}: {question}")
        answer = input("Your answer: ").strip()
        answers.append(answer)
    
    return answers

g. Generate Pitch Deck Structure

def generate_pitch_deck_structure(self, company_info: Dict[str, str], answers: List[str]) -> str:
    """Generate pitch deck structure using OpenAI"""
    print("🤖 Generating pitch deck structure...")
    
    prompt = f"""
Create a comprehensive pitch deck structure in markdown format for this company:

Company Information:
- URL: {company_info['url']}
- Title: {company_info['title']}
- Description: {company_info['description']}
- H1: {company_info['h1']}

Questions Asked and User Answers:
{chr(10).join([f"Q: {question}\nA: {answer}\n" for question, answer in zip(self.last_questions, answers)])}

Generate a pitch deck structure with 8-12 slides covering:
1. Title slide with company name and tagline
2. Problem statement
3. Solution overview
4. Market opportunity
5. Business model
6. Competitive advantage
7. Go-to-market strategy
8. Financial projections
9. Team
10. Funding ask (if applicable)
11. Contact information

Use the questions and answers provided to create a more targeted and relevant pitch deck structure.
Format as markdown with clear slide titles and bullet points for content.
"""
    
    try:
        response = self.openai_client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[{"role": "user", "content": prompt}],
            max_tokens=1500,
            temperature=0.7
        )
        
        structure = response.choices[0].message.content.strip()
        print("✅ Generated pitch deck structure")
        return structure
        
    except Exception as e:
        print(f"❌ Error generating structure: {str(e)}")
        return self.get_default_structure(company_info)

h. Generate Presentation Using Presenton API

def generate_presentation(self, company_info: Dict[str, str], structure: str) -> Optional[Dict]:
    """Generate presentation using Presenton API"""
    print("🎨 Generating presentation using Presenton API...")
    
    presentation_prompt = f"""
Create a professional pitch deck for {company_info['title']}.

Company Information:
- Website: {company_info['url']}
- Description: {company_info['description']}

Pitch Deck Structure:
{structure}

Create a compelling pitch deck with professional slides, clear messaging, and engaging visuals.
Focus on storytelling and making the business case compelling.
"""
    
    try:
        url = f"{self.presenton_base_url}/api/v1/ppt/generate/presentation"
        
        data = {
            'prompt': presentation_prompt,
            'n_slides': 10,
            'language': 'English',
            'theme': 'light',
            'export_as': 'pdf'
        }
        print("Presentation generation can take a couple of minutes, please wait...")
        
        response = requests.post(url, data=data, timeout=500)
        response.raise_for_status()
        
        result = response.json()
        print("✅ Presentation generated successfully!")
        print(f"   Presentation ID: {result.get('presentation_id')}")
        print(f"   Download path: {result.get('path')}")
        print(f"   Edit URL: {self.presenton_base_url}{result.get('edit_path')}")
        
        return result
        
    except requests.exceptions.RequestException as e:
        print(f"❌ Error connecting to Presenton API: {str(e)}")
        print("Make sure Presenton is running on localhost:5000")
        return None
    except Exception as e:
        print(f"❌ Error generating presentation: {str(e)}")
        return None

i. Main Execution Flow

def run(self):
    """Main execution flow"""
    print("🚀 Pitch Deck Generator")
    print("=" * 50)
    
    # Get company URL
    company_url = input("Enter the company website URL: ").strip()
    if not company_url:
        print("❌ No URL provided. Exiting.")
        return
    
    # Fetch company information
    company_info = self.fetch_company_info(company_url)
    
    # Generate questions
    questions = self.generate_questions(company_info)
    
    # Get user answers
    answers = self.get_user_answers(questions)
    
    # Generate pitch deck structure
    structure = self.generate_pitch_deck_structure(company_info, answers)
    
    # Generate presentation
    result = self.generate_presentation(company_info, structure)
    
    if result:
        print("\n🎉 Pitch deck generation completed!")
        print(f"📄 You can download the pitch deck from: {self.presenton_base_url}{result.get('path')}")
        print(f"✏️  Edit the pitch deck at: {self.presenton_base_url}{result.get('edit_path')}")
    else:
        print("\n❌ Failed to generate presentation. Please check your setup.")

def main():
    """Main entry point"""
    generator = PitchDeckGenerator()
    generator.run()

if __name__ == "__main__":
    main()

Download complete code from github.


4. Run the Script

Save your script as pitch-deck-agent.py and run:

python pitch-deck-agent.py

The script will:

  1. Ask for a company URL
  2. Fetch company information automatically
  3. Generate 3 AI-powered questions
  4. Collect your answers interactively
  5. Create a comprehensive pitch deck structure
  6. Generate a professional PDF presentation

5. Example Workflow

🚀 Pitch Deck Generator
==================================================
Enter the company website URL: example.com

🔍 Fetching information from: https://example.com
✅ Successfully fetched company information
   Title: Example Company - Innovative Solutions
   Description: Leading provider of innovative solutions...

🤖 Generating questions using OpenAI...
✅ Generated questions:
   1. What is your company's main product or service?
   2. Who is your target market?
   3. What makes your solution unique?

📝 Please answer the following questions:

Question 1: What is your company's main product or service?
Your answer: We provide cloud-based project management software

Question 2: Who is your target market?
Your answer: Small to medium businesses with 10-500 employees

Question 3: What makes your solution unique?
Your answer: Our AI-powered automation reduces project time by 40%

🤖 Generating pitch deck structure...
✅ Generated pitch deck structure

🎨 Generating presentation using Presenton API...
Presentation generation can take a couple of minutes, please wait...
✅ Presentation generated successfully!
   Presentation ID: abc123
   Download path: /downloads/presentation.pdf
   Edit URL: http://localhost:5000/edit/abc123

🎉 Pitch deck generation completed!
📄 You can download the pitch deck from: http://localhost:5000/downloads/presentation.pdf
✏️  Edit the pitch deck at: http://localhost:5000/edit/abc123

6. How It Works

  • Company Information Extraction: The script fetches meta descriptions, titles, and content from company websites
  • AI-Powered Question Generation: Uses GPT-4o-mini with structured outputs to generate exactly 3 relevant questions
  • Interactive Q&A: Guides users through targeted questions to gather essential information
  • Intelligent Structure Creation: Uses the Q&A context to create personalized pitch deck outlines
  • Professional Presentation Generation: Leverages Presenton API to create polished PDF presentations

7. Key Features

  • Structured Outputs: Uses OpenAI’s function calling for reliable question generation
  • Web Scraping: Automatically extracts company information from URLs
  • Contextual Generation: Questions and structure are based on actual company data
  • Professional Output: Generates high-quality PDF presentations
  • Error Handling: Comprehensive fallbacks and error management

8. Next Steps

Need help? See the full documentation or open an issue on GitHub.