JeCabrera's picture
Update app.py
c3a5730 verified
raw
history blame
12.1 kB
import streamlit as st
import google.generativeai as genai
import os
from dotenv import load_dotenv
from styles import get_custom_css
from formulas import offer_formulas
import PyPDF2
import docx
from PIL import Image
import io
# Set page to wide mode to use full width
st.set_page_config(layout="wide")
# Load environment variables
load_dotenv()
# Configure Google Gemini API
genai.configure(api_key=os.getenv('GOOGLE_API_KEY'))
model = genai.GenerativeModel('gemini-1.5-flash')
# Initialize session state variables if they don't exist
if 'submitted' not in st.session_state:
st.session_state.submitted = False
if 'offer_result' not in st.session_state:
st.session_state.offer_result = ""
# Hide Streamlit menu and footer
st.markdown("""
<style>
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
header {visibility: hidden;}
</style>
""", unsafe_allow_html=True)
# Custom CSS
st.markdown(get_custom_css(), unsafe_allow_html=True)
# App title and description
st.markdown('<h1 style="text-align: center;">Great Offer Generator</h1>', unsafe_allow_html=True)
st.markdown('<h3 style="text-align: center;">Transform your skills into compelling offers!</h3>', unsafe_allow_html=True)
# Create two columns for layout - left column 40%, right column 60%
col1, col2 = st.columns([4, 6])
# Main input section in left column
with col1:
input_tab1, input_tab2, input_tab3 = st.tabs(["Entrada Manual", "Subir Archivo", "Subir Imagen"])
with input_tab1:
skills = st.text_area('💪 Tus Habilidades', height=70,
help='Lista tus habilidades y experiencia clave')
product_service = st.text_area('🎯 Producto/Servicio', height=70,
help='Describe tu producto o servicio')
with input_tab2:
uploaded_file = st.file_uploader("Sube un archivo con tu información", type=['txt', 'pdf', 'docx'])
if uploaded_file is not None:
file_type = uploaded_file.name.split('.')[-1].lower()
if file_type == 'txt':
file_content = uploaded_file.read().decode('utf-8')
st.success(f"Archivo cargado correctamente: {uploaded_file.name}")
elif file_type == 'pdf':
try:
import PyPDF2
pdf_reader = PyPDF2.PdfReader(uploaded_file)
file_content = ""
for page in pdf_reader.pages:
file_content += page.extract_text() + "\n"
st.success(f"Archivo PDF cargado correctamente: {uploaded_file.name}")
except Exception as e:
st.error(f"Error al leer el archivo PDF: {str(e)}")
file_content = ""
elif file_type == 'docx':
try:
import docx
doc = docx.Document(uploaded_file)
file_content = "\n".join([para.text for para in doc.paragraphs])
st.success(f"Archivo DOCX cargado correctamente: {uploaded_file.name}")
except Exception as e:
st.error(f"Error al leer el archivo DOCX: {str(e)}")
file_content = ""
with st.expander("Vista previa del contenido"):
st.write(file_content[:500] + "..." if len(file_content) > 500 else file_content)
with input_tab3:
uploaded_image = st.file_uploader("Sube una imagen de tu producto o servicio", type=['jpg', 'jpeg', 'png'])
if uploaded_image is not None:
image = Image.open(uploaded_image)
st.image(image, caption="Imagen cargada", use_container_width=True)
image_bytes = uploaded_image.getvalue()
image_parts = [
{
"mime_type": uploaded_image.type,
"data": image_bytes
}
]
st.success(f"Imagen cargada correctamente: {uploaded_image.name}")
with st.expander('⚙️ Configuración Avanzada'):
target_audience = st.text_area('👥 Público Objetivo', height=70,
help='Describe tu cliente o público ideal')
formula_type = st.selectbox(
'📋 Tipo de Fórmula',
options=list(offer_formulas.keys()),
help='Selecciona el tipo de fórmula para tu oferta'
)
temperature = st.slider('🌡️ Nivel de Creatividad', min_value=0.0, max_value=2.0, value=0.7,
help='Valores más altos hacen que el resultado sea más creativo pero menos enfocado')
def generate_offer():
has_manual_input = bool(skills or product_service)
has_file_input = bool('uploaded_file' in locals() and uploaded_file is not None)
has_image_input = bool('uploaded_image' in locals() and uploaded_image is not None)
if not (has_manual_input or has_file_input or has_image_input):
st.error('Por favor proporciona al menos una entrada: texto, archivo o imagen')
return
valid_input = (
(has_manual_input and (has_file_input or has_image_input)) or
(not has_manual_input and (has_file_input or has_image_input)) or
has_file_input or
has_image_input
)
if not valid_input:
st.error('Por favor ingresa una combinación válida:\n' +
'- Texto + (archivo o imagen)\n' +
'- Solo archivo o imagen\n' +
'- Solo archivo\n' +
'- Solo imagen')
return
st.session_state.submitted = True
if has_manual_input:
st.session_state.skills = skills if skills else ""
st.session_state.product_service = product_service if product_service else ""
if has_file_input:
st.session_state.file_content = file_content
if has_image_input:
st.session_state.image_parts = image_parts
if has_image_input:
if has_manual_input and has_file_input:
st.session_state.input_type = "all"
elif has_manual_input:
st.session_state.input_type = "manual_image"
elif has_file_input:
st.session_state.input_type = "file_image"
else:
st.session_state.input_type = "image"
else:
if has_manual_input and has_file_input:
st.session_state.input_type = "both"
elif has_file_input:
st.session_state.input_type = "file"
elif has_manual_input:
st.session_state.input_type = "manual"
st.session_state.target_audience = target_audience
st.session_state.temperature = temperature
st.session_state.formula_type = formula_type
st.button('Generar Oferta 🎉', on_click=generate_offer)
# Results column
with col2:
if st.session_state.submitted:
with st.spinner('Creando tu oferta perfecta...'):
base_prompt = f"""You are a professional copywriter specializing in creating irresistible offers.
Create a compelling and persuasive offer using the {st.session_state.formula_type} formula.
Target Audience: {st.session_state.target_audience if hasattr(st.session_state, 'target_audience') and st.session_state.target_audience else 'General audience'}
"""
if st.session_state.input_type == "manual":
prompt = base_prompt + f"""
Based on the following information:
Skills: {st.session_state.skills}
Product/Service: {st.session_state.product_service}
"""
elif st.session_state.input_type == "file":
prompt = base_prompt + f"""
Based on the following information from the uploaded file:
File Content: {st.session_state.file_content}
"""
elif st.session_state.input_type == "image":
prompt = base_prompt + f"""
Based on the image provided, create an offer that highlights the visual elements and appeals to the target audience.
"""
elif st.session_state.input_type == "both":
prompt = base_prompt + f"""
Based on the following combined information:
Skills: {st.session_state.skills}
Product/Service: {st.session_state.product_service}
Additional Information from File: {st.session_state.file_content}
Please consider both the manual input and file content to create a comprehensive offer.
"""
elif st.session_state.input_type == "manual_image":
prompt = base_prompt + f"""
Based on the following information and the image provided:
Skills: {st.session_state.skills}
Product/Service: {st.session_state.product_service}
Please analyze both the text information and the visual elements in the image to create a comprehensive offer.
"""
elif st.session_state.input_type == "file_image":
prompt = base_prompt + f"""
Based on the following information from the uploaded file and the image provided:
File Content: {st.session_state.file_content}
Please analyze both the file content and the visual elements in the image to create a comprehensive offer.
"""
else:
prompt = base_prompt + f"""
Based on all the following information:
Skills: {st.session_state.skills}
Product/Service: {st.session_state.product_service}
Additional Information from File: {st.session_state.file_content}
Please analyze the text information, file content, and the visual elements in the image to create the most comprehensive offer.
"""
prompt += f"""
Formula Description:
{offer_formulas[st.session_state.formula_type]["description"]}
Please create a professional, engaging, and irresistible offer that highlights the value proposition and creates urgency.
IMPORTANT: Provide ONLY the final offer text. Do not include any explanations, labels, formatting instructions, brackets, or call to action at the end."""
try:
generation_config = genai.GenerationConfig(temperature=st.session_state.temperature)
if "image" in st.session_state.input_type:
response = model.generate_content([prompt, st.session_state.image_parts[0]], generation_config=generation_config)
else:
response = model.generate_content(prompt, generation_config=generation_config)
st.session_state.offer_result = response.text
st.markdown('### Oferta Generada')
st.markdown(st.session_state.offer_result)
col_download, col_empty = st.columns([8, 2])
with col_download:
st.download_button(
label="Descargar Oferta",
data=st.session_state.offer_result,
file_name="oferta_generada.txt",
mime="text/plain"
)
except Exception as e:
st.error(f'Ocurrió un error: {str(e)}')
st.session_state.submitted = False
# Footer
st.markdown('---')
st.markdown('Made with ❤️ by Jesús Cabrera')