import os
from dotenv import load_dotenv
from openai import OpenAI
import gradio as gr
# --- Load environment keys ---
load_dotenv(override=True)
openai_api_key = os.getenv("OPENAI_API_KEY")
google_api_key = os.getenv("GOOGLE_API_KEY")
# --- Model config ---
MODEL_MAP = {
"GPT-4o-mini": {
"model": "gpt-4o-mini",
"key": openai_api_key,
"endpoint": "https://api.openai.com/v1"
},
"Gemini-Flash": {
"model": "gemini-2.5-flash",
"key": google_api_key,
"endpoint": "https://generativelanguage.googleapis.com/v1beta/openai/"
}
}
class PageBuilder:
def __init__(self, model_choice="GPT-4o-mini"):
self.set_model(model_choice)
def set_model(self, model_choice: str):
spec = MODEL_MAP[model_choice]
self.client = OpenAI(
api_key=spec["key"],
base_url=spec["endpoint"]
)
self.model_name = spec["model"]
def build_page(self, raw_text: str, theme: str) -> str:
"""
Ask the model for a self-contained HTML page (HTML +
"""
return html_page.replace("", fix + "\n") if "" in html_page else fix + html_page
def build_interface():
with gr.Blocks(
title="PrettyPage",
theme=gr.themes.Soft(primary_hue="indigo", neutral_hue="slate")
) as demo:
gr.Markdown(
"""
✨ PrettyPage Generator
Paste any text. Get a clean, beautiful, responsive webpage using your exact words.
""",
)
with gr.Row():
model_choice = gr.Radio(
choices=list(MODEL_MAP.keys()),
value="GPT-4o-mini",
label="Model",
info="Which model should generate the page?"
)
theme_choice = gr.Dropdown(
choices=[
"Minimal",
"Professional",
"Colorful",
"Modern Gradient"
],
value="Professional",
label="Style Theme",
info="Controls colors / layout vibe"
)
input_text = gr.Textbox(
label="Your Text Content",
lines=12,
placeholder=(
"Paste your notes, article, README, sales copy, lesson, etc.\n"
"We'll turn this into a styled webpage without changing your words."
),
)
generate_btn = gr.Button("🎨 Generate Page", variant="primary")
gr.Markdown("---")
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("**Generated HTML (copy & save as .html):**")
html_code_output = gr.Textbox(
label="HTML Source",
interactive=False,
lines=20,
max_lines=20,
show_copy_button=True
)
with gr.Column(scale=1):
gr.Markdown("**Live Preview:**")
live_preview = gr.HTML(
value=(
""
"Your page preview will appear here.
"
),
)
# click handler: build the page fresh each time
def handle_generate(user_text, chosen_model, chosen_theme):
porter = PageBuilder(chosen_model)
html_page = porter.build_page(user_text, chosen_theme)
fixed_preview = apply_readability_fix(html_page)
# left pane shows code, right pane renders preview
return html_page, fixed_preview
generate_btn.click(
fn=handle_generate,
inputs=[input_text, model_choice, theme_choice],
outputs=[html_code_output, live_preview],
)
gr.Markdown(
"""
Tip: Save the HTML Source above as index.html and open it in your browser.
"""
)
return demo
if __name__ == "__main__":
demo = build_interface()
demo.launch(inbrowser=True)