Spaces:
Sleeping
Sleeping
import streamlit as st | |
import os | |
import random | |
from pathlib import Path | |
# Import our clean OpenAI client implementation | |
from openai_client import generate_completion | |
# Set page configuration | |
st.set_page_config( | |
page_title="Shakespearean Text Generator", | |
page_icon="π", | |
layout="wide", | |
initial_sidebar_state="expanded" | |
) | |
# Custom CSS for styling | |
def local_css(): | |
st.markdown(""" | |
<style> | |
.main { | |
background-color: #f5f5f0; | |
background-image: url("https://www.transparenttextures.com/patterns/old-paper.png"); | |
} | |
.stApp { | |
font-family: 'Garamond', 'Georgia', serif; | |
} | |
h1, h2, h3 { | |
font-family: 'Garamond', 'Georgia', serif; | |
color: #5c3317; | |
} | |
.stButton>button { | |
background-color: #5c3317; | |
color: white; | |
border-radius: 5px; | |
font-family: 'Garamond', 'Georgia', serif; | |
font-weight: bold; | |
} | |
.stButton>button:hover { | |
background-color: #8b4513; | |
color: white; | |
} | |
.stTextArea>div>div>textarea { | |
border: 2px solid #8b4513; | |
border-radius: 5px; | |
font-family: 'Garamond', 'Georgia', serif; | |
} | |
.sidebar .sidebar-content { | |
background-color: #f5f5f0; | |
background-image: url("https://www.transparenttextures.com/patterns/old-paper.png"); | |
} | |
.decoration { | |
text-align: center; | |
font-size: 24px; | |
color: #5c3317; | |
margin: 10px 0; | |
} | |
.shakespeare-quote { | |
font-style: italic; | |
text-align: center; | |
color: #5c3317; | |
padding: 10px; | |
border-left: 3px solid #8b4513; | |
margin: 10px 0; | |
} | |
.copy-btn { | |
position: absolute; | |
top: 10px; | |
right: 10px; | |
z-index: 1000; | |
} | |
</style> | |
""", unsafe_allow_html=True) | |
# Function to scan and get all system prompts | |
def get_system_prompts(): | |
prompts = {} | |
base_dir = Path("system-prompts") | |
# Check if the directory exists | |
if not base_dir.exists(): | |
st.error(f"System prompts directory not found: {base_dir}") | |
return {"Default": "system-prompts/basic-transformation/foundational.md"} | |
# Find all markdown files | |
md_files = list(base_dir.glob("**/*.md")) | |
# If no files found, return a default | |
if not md_files: | |
st.warning("No system prompt files found. Using default.") | |
return {"Default": "system-prompts/basic-transformation/foundational.md"} | |
for prompt_file in md_files: | |
# Create a friendly name from the path | |
relative_path = prompt_file.relative_to(base_dir) | |
friendly_name = str(relative_path).replace(".md", "").replace("/", " > ") | |
# Store the path and friendly name | |
prompts[friendly_name] = str(prompt_file) | |
return prompts | |
# Function to read the content of a system prompt | |
def read_system_prompt(prompt_path): | |
try: | |
with open(prompt_path, "r") as f: | |
return f.read() | |
except FileNotFoundError: | |
st.error(f"System prompt file not found: {prompt_path}") | |
return "You are Shakespeare, the greatest playwright and poet. Transform the user's text into Shakespearean English, maintaining the original meaning but using the vocabulary, grammar, and style of Shakespeare's works." | |
except Exception as e: | |
st.error(f"Error reading system prompt: {str(e)}") | |
return "You are Shakespeare, the greatest playwright and poet. Transform the user's text into Shakespearean English, maintaining the original meaning but using the vocabulary, grammar, and style of Shakespeare's works." | |
# Function to transform text using OpenAI API | |
def transform_text(api_key, system_prompt, user_text, model="gpt-4"): | |
""" | |
Wrapper function that uses our clean OpenAI client implementation | |
""" | |
return generate_completion(api_key, system_prompt, user_text, model) | |
# Main app | |
def main(): | |
# Apply custom CSS | |
local_css() | |
# Display banner image with animation | |
st.image("shakespearegpt.png", use_container_width=True) | |
# App title and description | |
st.title("Shakespearean Text Generator") | |
st.markdown(""" | |
<div class="decoration">βοΈ βοΈ βοΈ</div> | |
<p style="font-size: 18px; text-align: center;"> | |
Transform thy modern text into eloquent Shakespearean prose!<br> | |
Select a transformation style, enter thy text, and watch as 'tis transformed into the language of the Bard. | |
</p> | |
<div class="decoration">βοΈ βοΈ βοΈ</div> | |
""", unsafe_allow_html=True) | |
# Random Shakespeare quote | |
quotes = [ | |
"All the world's a stage, and all the men and women merely players.", | |
"The course of true love never did run smooth.", | |
"To be, or not to be, that is the question.", | |
"What's in a name? That which we call a rose by any other name would smell as sweet.", | |
"Some are born great, some achieve greatness, and some have greatness thrust upon them.", | |
"Love all, trust a few, do wrong to none.", | |
"We know what we are, but know not what we may be.", | |
"The fool doth think he is wise, but the wise man knows himself to be a fool.", | |
"All that glitters is not gold.", | |
"Be not afraid of greatness. Some are born great, some achieve greatness, and others have greatness thrust upon them." | |
] | |
st.markdown(f""" | |
<div class="shakespeare-quote"> | |
"{random.choice(quotes)}"<br> | |
<small>- William Shakespeare</small> | |
</div> | |
""", unsafe_allow_html=True) | |
# Sidebar for API key and settings | |
with st.sidebar: | |
st.header("π OPENAI API KEY") | |
api_key = st.text_input("ENTER THY OPENAI API KEY", type="password") | |
st.markdown("Thy API key is required to use the OpenAI GPT models for text transformation.") | |
# Model selection | |
st.header("βοΈ SETTINGS") | |
model = st.selectbox( | |
"SELECT THY GPT MODEL", | |
["gpt-4", "gpt-3.5-turbo"], | |
index=0 | |
) | |
st.divider() | |
# About section | |
st.header("π About") | |
st.markdown(""" | |
This application uses OpenAI's GPT models to transform text into Shakespearean English. | |
The system prompts used for transformation are from a curated collection designed to mimic | |
various Shakespearean styles for different types of content. | |
<div class="decoration">βοΈ βοΈ βοΈ</div> | |
"O for a Muse of fire, that would ascend<br> | |
The brightest heaven of invention!"<br> | |
<small>- Henry V</small> | |
""", unsafe_allow_html=True) | |
# Main content area with two columns | |
col1, col2 = st.columns(2) | |
with col1: | |
st.header("π INPUT") | |
# Get all system prompts | |
prompts = get_system_prompts() | |
prompt_names = list(prompts.keys()) | |
# Dropdown to select transformation | |
selected_prompt_name = st.selectbox("SELECT TRANSFORMATION STYLE", prompt_names) | |
selected_prompt_path = prompts[selected_prompt_name] | |
# Display the selected prompt description | |
with st.expander("VIEW TRANSFORMATION DESCRIPTION"): | |
st.markdown(read_system_prompt(selected_prompt_path)) | |
# Text input area | |
user_text = st.text_area("ENTER THY TEXT", height=300, | |
placeholder="Type or paste thy modern text here...") | |
# Transform button with animation | |
transform_col1, transform_col2, transform_col3 = st.columns([1, 2, 1]) | |
with transform_col2: | |
if st.button("β¨ TRANSFORM TO SHAKESPEAREAN β¨", use_container_width=True): | |
if not api_key: | |
st.error("Prithee, enter thy OpenAI API key in the sidebar.") | |
elif not user_text: | |
st.error("Thou must enter some text to transform.") | |
else: | |
with st.spinner("Transforming... The Bard is at work!"): | |
system_prompt = read_system_prompt(selected_prompt_path) | |
st.session_state.transformed_text = transform_text(api_key, system_prompt, user_text, model) | |
with col2: | |
st.header("π SHAKESPEAREAN OUTPUT") | |
# Initialize session state for transformed text if it doesn't exist | |
if "transformed_text" not in st.session_state: | |
st.session_state.transformed_text = "" | |
# Display transformed text with styling | |
st.markdown('<div style="position: relative;">', unsafe_allow_html=True) | |
transformed_text = st.text_area( | |
"TRANSFORMED TEXT", | |
value=st.session_state.transformed_text, | |
height=300, | |
placeholder="The Bard's words shall appear here..." | |
) | |
# Buttons for copy and clear | |
col_copy, col_space, col_clear = st.columns([1, 1, 1]) | |
with col_copy: | |
if st.button("π COPY TEXT", use_container_width=True): | |
# Use Streamlit's built-in functionality for clipboard | |
st.code(transformed_text, language="text") | |
st.success("Text copied to clipboard! You can also use the copy button in the code block above.") | |
with col_clear: | |
if st.button("π§Ή CLEAR TEXT", use_container_width=True): | |
st.session_state.transformed_text = "" | |
st.rerun() | |
# Add a fun element - Shakespeare emoji reactions | |
if st.session_state.transformed_text: | |
st.markdown('<div class="decoration" style="margin-top: 20px;">', unsafe_allow_html=True) | |
reactions = ["π", "π", "π", "ποΈ", "π", "βοΈ", "π°", "π§ββοΈ"] | |
st.markdown(f""" | |
<div style="text-align: center; margin-top: 20px;"> | |
<p>Shakespeare would be {random.choice(['proud', 'delighted', 'amused', 'impressed'])}!</p> | |
<p style="font-size: 24px;">{' '.join(random.sample(reactions, 4))}</p> | |
</div> | |
""", unsafe_allow_html=True) | |
if __name__ == "__main__": | |
main() |