JeCabrera commited on
Commit
c1dbcb8
·
verified ·
1 Parent(s): d8a23c9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +245 -29
app.py CHANGED
@@ -1,31 +1,247 @@
1
- "download_button": """
2
- <style>
3
- [data-testid="stDownloadButton"] {
4
- text-align: center;
5
- display: flex;
6
- justify-content: center;
7
- margin-top: 5px;
8
- width: 90%;
9
- margin-left: auto;
10
- margin-right: auto;
11
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
- [data-testid="stDownloadButton"] button {
14
- width: 100%;
15
- border-radius: 5px;
16
- height: 3em;
17
- background: linear-gradient(to right, #00D100, #009900);
18
- color: white;
19
- font-weight: bold;
20
- transition: all 0.3s ease;
21
- border: none;
22
- text-transform: uppercase;
23
- letter-spacing: 1px;
24
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
- [data-testid="stDownloadButton"] button:hover {
27
- background: linear-gradient(to right, #00C000, #008800);
28
- transform: translateY(-2px);
29
- box-shadow: 0 4px 8px rgba(0,0,0,0.1);
30
- }
31
- </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dotenv import load_dotenv
2
+ import streamlit as st
3
+ import os
4
+ import google.generativeai as genai
5
+ from puv_formulas import puv_formulas
6
+ from styles import apply_styles
7
+ import PyPDF2
8
+ import docx
9
+ from PIL import Image
10
+ import datetime # Add this import for timestamp
11
+
12
+ # Cargar variables de entorno
13
+ load_dotenv()
14
+
15
+ # Configurar API de Google Gemini
16
+ genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
17
+
18
+ # Función para obtener la respuesta del modelo Gemini
19
+ def get_gemini_response(product_service, target_audience, skills, formula_type, temperature, file_content="", image_parts=None):
20
+ # Check if we have at least one source of information
21
+ has_file_content = bool(file_content.strip())
22
+ has_image = image_parts is not None
23
+ has_text_input = target_audience or product_service or skills
24
+
25
+ if not (has_file_content or has_image or has_text_input):
26
+ return "Debes proporcionar al menos un tipo de información: público objetivo, producto/servicio, habilidades o un archivo de referencia."
27
+
28
+ # If we only have file content but no other inputs, we can proceed
29
+ if (has_file_content or has_image) and not has_text_input:
30
+ # File-only mode
31
+ business_info = "Analyze the provided reference material to extract business information.\n"
32
+ else:
33
+ # Regular mode with validation
34
+ if not target_audience:
35
+ return "El campo de público objetivo es obligatorio cuando no se proporciona un archivo de referencia completo."
36
+
37
+ if not product_service and not skills:
38
+ return "Debes proporcionar al menos tu producto/servicio o tus habilidades cuando no se proporciona un archivo de referencia completo."
39
+
40
+ # Adjust prompt based on what's provided
41
+ business_info = f"Target Audience: {target_audience}\n"
42
+
43
+ if product_service:
44
+ business_info += f"Product/Service: {product_service}\n"
45
+
46
+ if skills:
47
+ business_info += f"My Skills/Expertise: {skills}\n"
48
+
49
+ formula = puv_formulas[formula_type]
50
+
51
+ # Add file content if available
52
+ reference_info = ""
53
+ if file_content:
54
+ reference_info = f"\nREFERENCE MATERIAL:\n{file_content}\n"
55
+
56
+ model = genai.GenerativeModel('gemini-2.0-flash')
57
+ full_prompt = f"""
58
+ You are a UVP (Unique Value Proposition) expert. Analyze (internally only, do not output the analysis) the following information:
59
+ BUSINESS INFORMATION:
60
+ {business_info}
61
+ Formula Type: {formula_type}
62
+ {formula["description"]}
63
+ {reference_info}
64
+
65
+ EXAMPLE TO FOLLOW:
66
+ {formula["examples"]}
67
+
68
+ First, analyze (but don't output) these points:
69
+ 1. TARGET AUDIENCE ANALYSIS - Pain Points:
70
+ - What specific frustrations does this audience experience?
71
+ - What are their biggest daily challenges?
72
+ - What emotional problems do they face?
73
+ - What have they tried before that didn't work?
74
+ - What's stopping them from achieving their goals?
75
+
76
+ 2. PRODUCT/SERVICE ANALYSIS - Benefits:
77
+ - What tangible results do clients get?
78
+ - What specific transformation does it offer?
79
+ - What's the unique method or differentiator?
80
+ - What competitive advantages does it have?
81
+ - What emotional benefits does it provide?
82
+
83
+ 3. SKILLS/EXPERTISE ANALYSIS - Credibility:
84
+ - How do these skills directly address the audience's pain points?
85
+ - What unique perspective do these skills bring to the solution?
86
+ - How do these skills enhance the product/service delivery?
87
+ - What credibility elements can be highlighted?
88
+ - How do these skills differentiate from competitors?
89
+
90
+ Based on your internal analysis of the target audience pain points and product benefits (do not include this analysis in the output), create THREE different UVPs in Spanish language following the formula structure provided.
91
+ CRITICAL INSTRUCTIONS:
92
+ - Each UVP must be specific and measurable
93
+ - Focus on the transformation journey
94
+ - Use natural, conversational language
95
+ - Avoid generic phrases and buzzwords
96
+ - Maximum 2 lines per UVP
97
+ - DO NOT include any analysis in the output
98
+ - ONLY output the three UVPs
99
+
100
+ Output EXACTLY in this format (no additional text) in Spanish language:
101
+ 1. [First UVP]
102
+ 2. [Second UVP]
103
+ 3. [Third UVP]
104
+ """
105
+
106
+ # Handle text-only or text+image requests
107
+ if image_parts:
108
+ response = model.generate_content([full_prompt, image_parts], generation_config={"temperature": temperature})
109
+ else:
110
+ response = model.generate_content([full_prompt], generation_config={"temperature": temperature})
111
+
112
+ return response.parts[0].text if response and response.parts else "Error generating content."
113
+
114
+ # Configurar la aplicación Streamlit
115
+ st.set_page_config(page_title="UVP Generator", page_icon="💡", layout="wide")
116
+
117
+ # Aplicar estilos
118
+ st.markdown(apply_styles(), unsafe_allow_html=True)
119
+
120
+ # Título de la app
121
+ st.markdown("<h1>Generador de PUV</h1>", unsafe_allow_html=True)
122
+ st.markdown("<h3>Crea Propuestas Únicas de Valor poderosas que atraigan a tus clientes ideales y comuniquen tu valor de manera efectiva.</h3>", unsafe_allow_html=True)
123
+
124
+ # Sidebar manual
125
+ with open("manual.md", "r", encoding="utf-8") as file:
126
+ manual_content = file.read()
127
+ st.sidebar.markdown(manual_content)
128
+
129
+ # Crear dos columnas
130
+ col1, col2 = st.columns([1, 1])
131
+
132
+ # Columna izquierda para inputs
133
+ with col1:
134
+ product_service = st.text_area(
135
+ "¿Cuál es tu producto o servicio?",
136
+ placeholder="Ejemplo: Curso de copywriting con IA, Programa de coaching..."
137
+ )
138
+
139
+ skills = st.text_area(
140
+ "Mis habilidades:",
141
+ placeholder="Ejemplo: Experiencia en marketing digital, certificación en SEO..."
142
+ )
143
+
144
+ # Move the generate button here, right after skills
145
+ generate_button = st.button("Generar PUV")
146
+
147
+ with st.expander("Opciones avanzadas"):
148
+ target_audience = st.text_area(
149
+ "¿Cuál es tu público objetivo?",
150
+ placeholder="Ejemplo: Coaches que quieren atraer más clientes..."
151
+ )
152
+
153
+ # Añadir cargador de archivos
154
+ uploaded_file = st.file_uploader("📄 Archivo o imagen de referencia",
155
+ type=['txt', 'pdf', 'docx', 'jpg', 'jpeg', 'png'])
156
+
157
+ file_content = ""
158
+ is_image = False
159
+ image_parts = None
160
+
161
+ if uploaded_file is not None:
162
+ file_type = uploaded_file.name.split('.')[-1].lower()
163
 
164
+ # Manejar archivos de texto
165
+ if file_type in ['txt', 'pdf', 'docx']:
166
+ if file_type == 'txt':
167
+ try:
168
+ file_content = uploaded_file.read().decode('utf-8')
169
+ except Exception as e:
170
+ st.error(f"Error al leer el archivo TXT: {str(e)}")
171
+ file_content = ""
172
+
173
+ elif file_type == 'pdf':
174
+ try:
175
+ pdf_reader = PyPDF2.PdfReader(uploaded_file)
176
+ file_content = ""
177
+ for page in pdf_reader.pages:
178
+ file_content += page.extract_text() + "\n"
179
+ except Exception as e:
180
+ st.error(f"Error al leer el archivo PDF: {str(e)}")
181
+ file_content = ""
182
+
183
+ elif file_type == 'docx':
184
+ try:
185
+ doc = docx.Document(uploaded_file)
186
+ file_content = "\n".join([para.text for para in doc.paragraphs])
187
+ except Exception as e:
188
+ st.error(f"Error al leer el archivo DOCX: {str(e)}")
189
+ file_content = ""
190
 
191
+ # Manejar archivos de imagen
192
+ elif file_type in ['jpg', 'jpeg', 'png']:
193
+ try:
194
+ image = Image.open(uploaded_file)
195
+ image_bytes = uploaded_file.getvalue()
196
+ image_parts = {
197
+ "mime_type": uploaded_file.type,
198
+ "data": image_bytes
199
+ }
200
+ is_image = True
201
+ except Exception as e:
202
+ st.error(f"Error al procesar la imagen: {str(e)}")
203
+ is_image = False
204
+
205
+ formula_type = st.selectbox(
206
+ "Fórmula PUV:",
207
+ options=list(puv_formulas.keys())
208
+ )
209
+ temperature = st.slider(
210
+ "Nivel de creatividad:",
211
+ min_value=0.0,
212
+ max_value=2.0,
213
+ value=1.0,
214
+ step=0.1,
215
+ help="Valores más altos generan propuestas más creativas pero menos predecibles."
216
+ )
217
+
218
+ with col2:
219
+ if generate_button:
220
+ with st.spinner("Creando tu PUV..."):
221
+ response = get_gemini_response(
222
+ product_service,
223
+ target_audience,
224
+ skills,
225
+ formula_type,
226
+ temperature,
227
+ file_content,
228
+ image_parts
229
+ )
230
+ st.write("### Propuestas Únicas de Valor")
231
+ st.write(response)
232
+
233
+ # Add download button if we have a valid response
234
+ if response and not response.startswith("Error") and not response.startswith("Debes"):
235
+ # Get current timestamp for the filename
236
+ timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
237
+
238
+ # Prepare content for download
239
+ download_content = response
240
+
241
+ # Download button
242
+ st.download_button(
243
+ label="DESCARGAR PUV",
244
+ data=download_content,
245
+ file_name=f"propuestas_unicas_valor_{timestamp}.txt",
246
+ mime="text/plain"
247
+ )