Spaces:
Build error
Build error
Update app.py
Browse files
app.py
CHANGED
|
@@ -2,7 +2,7 @@ from dotenv import load_dotenv
|
|
| 2 |
import streamlit as st
|
| 3 |
import os
|
| 4 |
import google.generativeai as genai
|
| 5 |
-
import random
|
| 6 |
|
| 7 |
load_dotenv()
|
| 8 |
|
|
@@ -11,76 +11,57 @@ genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
|
|
| 11 |
# Funci贸n para obtener una menci贸n del producto de manera probabil铆stica
|
| 12 |
def get_random_product_mention():
|
| 13 |
mentions = ["Directa", "Indirecta", "Metaf贸rica"]
|
| 14 |
-
probabilities = [0.
|
| 15 |
return random.choices(mentions, probabilities)[0]
|
| 16 |
|
| 17 |
# Crear la instrucci贸n de menci贸n basada en la opci贸n seleccionada
|
| 18 |
def get_mention_instruction(product_mention, product):
|
| 19 |
if product_mention == "Directa":
|
| 20 |
return f"""
|
| 21 |
-
Directly introduce the product '{product}' as the clear solution to the problem the reader is facing. Ensure that the product is presented in a way that highlights its key benefits and demonstrates how it directly addresses the issue at hand.
|
| 22 |
"""
|
| 23 |
elif product_mention == "Indirecta":
|
| 24 |
return f"""
|
| 25 |
-
Subtly reference the product '{product}' as a potential solution to the reader's problem without naming it explicitly. Weave the product's core benefits into the description of how the reader can overcome the issue
|
| 26 |
"""
|
| 27 |
elif product_mention == "Metaf贸rica":
|
| 28 |
return f"""
|
| 29 |
-
Introduce the product '{product}' using a metaphor, connecting it symbolically to the solution the reader needs. The metaphor should
|
| 30 |
"""
|
| 31 |
return ""
|
| 32 |
|
| 33 |
# Funci贸n para obtener una t茅cnica de copywriting de manera aleatoria
|
| 34 |
def get_random_copywriting_technique():
|
| 35 |
techniques = [
|
| 36 |
-
"
|
| 37 |
-
"
|
| 38 |
-
"
|
| 39 |
-
"
|
| 40 |
-
"
|
| 41 |
-
"
|
| 42 |
]
|
| 43 |
-
return random.sample(techniques, k=random.randint(1, 3))
|
| 44 |
|
| 45 |
-
#
|
| 46 |
-
def get_gemini_response(target_audience, product,
|
| 47 |
product_mention = get_random_product_mention()
|
| 48 |
-
mention_instruction = get_mention_instruction(product_mention, product)
|
| 49 |
-
model_choice = "gemini-1.5-flash" # Modelo predeterminado
|
| 50 |
-
|
| 51 |
-
model = genai.GenerativeModel(model_choice)
|
| 52 |
|
| 53 |
# Obtener t茅cnicas aleatorias
|
| 54 |
copywriting_techniques = get_random_copywriting_technique()
|
| 55 |
techniques_text = " ".join(copywriting_techniques)
|
| 56 |
|
| 57 |
-
#
|
| 58 |
-
format_instruction = ""
|
| 59 |
-
if text_type == "Historia":
|
| 60 |
-
format_instruction = f"""
|
| 61 |
-
Write an engaging opening paragraph that introduces a relatable problem your audience is facing. Stir emotions by highlighting the impact of the problem on their life, and create curiosity with hints of a potential solution without revealing everything. The paragraph should be approximately {length} words long to maintain engagement and avoid losing the reader's attention.
|
| 62 |
-
"""
|
| 63 |
-
elif text_type == "Carta de venta":
|
| 64 |
-
format_instruction = f"""
|
| 65 |
-
Craft a persuasive lead paragraph for a sales letter that quickly identifies a common pain point your reader is experiencing. The paragraph should be around {length} words long and agitate the problem by emphasizing the negative consequences of not addressing it, and tease the possibility of a solution to spark curiosity.
|
| 66 |
-
"""
|
| 67 |
-
elif text_type == "Correo":
|
| 68 |
-
format_instruction = f"""
|
| 69 |
-
Write a concise but impactful opening paragraph for an email that captures the reader鈥檚 attention. The text should be approximately {length} words, addressing a challenge they are likely facing, and leave them intrigued by hinting at a valuable solution that will be revealed if they continue reading.
|
| 70 |
-
"""
|
| 71 |
-
elif text_type == "Landing page":
|
| 72 |
-
format_instruction = f"""
|
| 73 |
-
Design a compelling first paragraph for a landing page that immediately draws attention to a significant problem your target audience is encountering. The paragraph should be about {length} words long, stirring emotions and enticing them to keep scrolling by subtly suggesting a solution.
|
| 74 |
-
"""
|
| 75 |
-
|
| 76 |
-
# Crear el prompt completo basado en los campos del frontend
|
| 77 |
full_prompt = f"""
|
| 78 |
-
You are a creative writer skilled in the art of persuasion.
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
|
|
|
| 82 |
"""
|
| 83 |
-
|
|
|
|
|
|
|
| 84 |
response = model.generate_content([full_prompt])
|
| 85 |
|
| 86 |
# Comprobar si la respuesta es v谩lida y devolver el texto
|
|
@@ -89,74 +70,37 @@ Create an opening paragraph for a {text_type} of {length} words in Spanish that
|
|
| 89 |
else:
|
| 90 |
raise ValueError("Lo sentimos, intenta con una combinaci贸n diferente de entradas.")
|
| 91 |
|
| 92 |
-
#
|
| 93 |
st.set_page_config(page_title="First Line Alchemy", layout="wide")
|
| 94 |
|
| 95 |
-
#
|
| 96 |
-
if "accordion_expanded" not in st.session_state:
|
| 97 |
-
st.session_state["accordion_expanded"] = False # Por defecto est谩 cerrado
|
| 98 |
-
|
| 99 |
-
# Definir una funci贸n para manejar el cambio de estado del acorde贸n
|
| 100 |
-
def toggle_accordion():
|
| 101 |
-
st.session_state["accordion_expanded"] = not st.session_state["accordion_expanded"]
|
| 102 |
-
|
| 103 |
-
# Centrar el t铆tulo y el subt铆tulo
|
| 104 |
st.markdown("<h1 style='text-align: center;'>First Line Alchemy</h1>", unsafe_allow_html=True)
|
| 105 |
-
st.markdown("<h4 style='text-align: center;'>
|
| 106 |
-
|
| 107 |
-
# A帽adir CSS personalizado para el bot贸n
|
| 108 |
-
st.markdown("""
|
| 109 |
-
<style>
|
| 110 |
-
div.stButton > button {
|
| 111 |
-
background-color: #FFCC00; /* Color llamativo */
|
| 112 |
-
color: black; /* Texto en negro */
|
| 113 |
-
width: 90%;
|
| 114 |
-
height: 60px;
|
| 115 |
-
font-weight: bold;
|
| 116 |
-
font-size: 22px; /* Tama帽o m谩s grande */
|
| 117 |
-
text-transform: uppercase; /* Texto en may煤sculas */
|
| 118 |
-
border: 1px solid #000000; /* Borde negro de 1px */
|
| 119 |
-
border-radius: 8px;
|
| 120 |
-
display: block;
|
| 121 |
-
margin: 0 auto; /* Centramos el bot贸n */
|
| 122 |
-
}
|
| 123 |
-
div.stButton > button:hover {
|
| 124 |
-
background-color: #FFD700; /* Color al pasar el mouse */
|
| 125 |
-
color: black; /* Texto sigue en negro */
|
| 126 |
-
}
|
| 127 |
-
</style>
|
| 128 |
-
""", unsafe_allow_html=True)
|
| 129 |
|
| 130 |
-
|
| 131 |
-
col1, col2 = st.columns([2, 3]) # 2 + 3 = 5 parts in total
|
| 132 |
|
| 133 |
with col1:
|
| 134 |
-
# Create input fields
|
| 135 |
target_audience = st.text_input("驴Qui茅n es tu p煤blico objetivo?")
|
| 136 |
product = st.text_input("驴Qu茅 producto tienes en mente?")
|
| 137 |
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
text_type = st.selectbox("Tipo de texto", ["Historia", "Carta de venta", "Correo", "Landing page"])
|
| 141 |
length = st.slider("N煤mero de palabras", min_value=50, max_value=100, value=50)
|
| 142 |
mood = st.selectbox("Tono de voz", ["Conversacional", "Formal", "Persuasivo"])
|
| 143 |
-
emotionality = st.selectbox("Emocionalidad del texto", ["Triste", "Feliz", "
|
| 144 |
|
| 145 |
-
|
| 146 |
-
submit = st.button("Escribir mi Texto", on_click=toggle_accordion)
|
| 147 |
|
| 148 |
-
# Button to generate text (outside the accordion)
|
| 149 |
if submit:
|
| 150 |
-
if target_audience and product:
|
| 151 |
try:
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
<
|
| 157 |
-
<p>{}</p>
|
| 158 |
</div>
|
| 159 |
-
"""
|
| 160 |
except ValueError as e:
|
| 161 |
col2.error(f"Error: {str(e)}")
|
| 162 |
else:
|
|
|
|
| 2 |
import streamlit as st
|
| 3 |
import os
|
| 4 |
import google.generativeai as genai
|
| 5 |
+
import random
|
| 6 |
|
| 7 |
load_dotenv()
|
| 8 |
|
|
|
|
| 11 |
# Funci贸n para obtener una menci贸n del producto de manera probabil铆stica
|
| 12 |
def get_random_product_mention():
|
| 13 |
mentions = ["Directa", "Indirecta", "Metaf贸rica"]
|
| 14 |
+
probabilities = [0.05, 0.10, 0.85]
|
| 15 |
return random.choices(mentions, probabilities)[0]
|
| 16 |
|
| 17 |
# Crear la instrucci贸n de menci贸n basada en la opci贸n seleccionada
|
| 18 |
def get_mention_instruction(product_mention, product):
|
| 19 |
if product_mention == "Directa":
|
| 20 |
return f"""
|
| 21 |
+
Directly introduce the product '{product}' as the clear solution to the problem the reader is facing. Ensure that the product is presented in a way that highlights its key benefits and demonstrates how it directly addresses the issue at hand.
|
| 22 |
"""
|
| 23 |
elif product_mention == "Indirecta":
|
| 24 |
return f"""
|
| 25 |
+
Subtly reference the product '{product}' as a potential solution to the reader's problem without naming it explicitly. Weave the product's core benefits into the description of how the reader can overcome the issue.
|
| 26 |
"""
|
| 27 |
elif product_mention == "Metaf贸rica":
|
| 28 |
return f"""
|
| 29 |
+
Introduce the product '{product}' using a metaphor, connecting it symbolically to the solution the reader needs. The metaphor should creatively suggest how the product offers a resolution without explicitly stating its name.
|
| 30 |
"""
|
| 31 |
return ""
|
| 32 |
|
| 33 |
# Funci贸n para obtener una t茅cnica de copywriting de manera aleatoria
|
| 34 |
def get_random_copywriting_technique():
|
| 35 |
techniques = [
|
| 36 |
+
"If/Then: Create a condition and show how it leads to the desired result.",
|
| 37 |
+
"Questions: Pose a question to engage the reader and lead into the solution.",
|
| 38 |
+
"Honesty: Build trust by being transparent about limitations or challenges.",
|
| 39 |
+
"Sensationalist: Use an unusual or shocking statement to hook the reader.",
|
| 40 |
+
"Micro Openings: Use a very short and impactful opening to capture attention.",
|
| 41 |
+
"Authority: Refer to a credible figure or data to reinforce your point."
|
| 42 |
]
|
| 43 |
+
return random.sample(techniques, k=random.randint(1, 3))
|
| 44 |
|
| 45 |
+
# Generar respuesta del modelo
|
| 46 |
+
def get_gemini_response(target_audience, product, formula, length, mood, emotionality):
|
| 47 |
product_mention = get_random_product_mention()
|
| 48 |
+
mention_instruction = get_mention_instruction(product_mention, product)
|
|
|
|
|
|
|
|
|
|
| 49 |
|
| 50 |
# Obtener t茅cnicas aleatorias
|
| 51 |
copywriting_techniques = get_random_copywriting_technique()
|
| 52 |
techniques_text = " ".join(copywriting_techniques)
|
| 53 |
|
| 54 |
+
# Crear el prompt completo
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
full_prompt = f"""
|
| 56 |
+
You are a creative writer skilled in the art of persuasion. Write an opening paragraph using the {formula} formula to connect with a {target_audience}.
|
| 57 |
+
The tone should be {mood}, and the emotionality should convey {emotionality}.
|
| 58 |
+
{mention_instruction}
|
| 59 |
+
Use the following copywriting techniques: {techniques_text}.
|
| 60 |
+
The paragraph should be approximately {length} words long and emotionally resonate with the audience, enticing them to continue reading.
|
| 61 |
"""
|
| 62 |
+
|
| 63 |
+
model_choice = "gemini-1.5-flash"
|
| 64 |
+
model = genai.GenerativeModel(model_choice)
|
| 65 |
response = model.generate_content([full_prompt])
|
| 66 |
|
| 67 |
# Comprobar si la respuesta es v谩lida y devolver el texto
|
|
|
|
| 70 |
else:
|
| 71 |
raise ValueError("Lo sentimos, intenta con una combinaci贸n diferente de entradas.")
|
| 72 |
|
| 73 |
+
# Configuraci贸n de la p谩gina de Streamlit
|
| 74 |
st.set_page_config(page_title="First Line Alchemy", layout="wide")
|
| 75 |
|
| 76 |
+
# Interfaz de usuario
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
st.markdown("<h1 style='text-align: center;'>First Line Alchemy</h1>", unsafe_allow_html=True)
|
| 78 |
+
st.markdown("<h4 style='text-align: center;'>Transforma conceptos en l铆neas que cautivan e inspiran acci贸n.</h4>", unsafe_allow_html=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
|
| 80 |
+
col1, col2 = st.columns([2, 3])
|
|
|
|
| 81 |
|
| 82 |
with col1:
|
|
|
|
| 83 |
target_audience = st.text_input("驴Qui茅n es tu p煤blico objetivo?")
|
| 84 |
product = st.text_input("驴Qu茅 producto tienes en mente?")
|
| 85 |
|
| 86 |
+
with st.expander("Personaliza tu p谩rrafo de apertura"):
|
| 87 |
+
formula = st.selectbox("Selecciona una f贸rmula de copywriting", ["If/Then", "Questions", "Honesty", "Sensationalist", "Micro Openings", "Authority"])
|
|
|
|
| 88 |
length = st.slider("N煤mero de palabras", min_value=50, max_value=100, value=50)
|
| 89 |
mood = st.selectbox("Tono de voz", ["Conversacional", "Formal", "Persuasivo"])
|
| 90 |
+
emotionality = st.selectbox("Emocionalidad del texto", ["Triste", "Feliz", "Rom谩ntico", "Sorpresa", "Esperanza", "Ira", "Confianza"])
|
| 91 |
|
| 92 |
+
submit = st.button("Generar Texto")
|
|
|
|
| 93 |
|
|
|
|
| 94 |
if submit:
|
| 95 |
+
if target_audience and product:
|
| 96 |
try:
|
| 97 |
+
generated_text = get_gemini_response(target_audience, product, formula, length, mood, emotionality)
|
| 98 |
+
col2.markdown(f"""
|
| 99 |
+
<div style="border: 1px solid #000000; padding: 10px; border-radius: 8px; background-color: #ffffff;">
|
| 100 |
+
<h4>Tu p谩rrafo de apertura:</h4>
|
| 101 |
+
<p>{generated_text}</p>
|
|
|
|
| 102 |
</div>
|
| 103 |
+
""", unsafe_allow_html=True)
|
| 104 |
except ValueError as e:
|
| 105 |
col2.error(f"Error: {str(e)}")
|
| 106 |
else:
|