Spaces:
Runtime error
Runtime error
import streamlit as st | |
import openai | |
import os | |
import requests | |
import pandas as pd | |
import io | |
from wordcloud import WordCloud | |
import matplotlib.pyplot as plt | |
from PIL import Image | |
import base64 | |
from collections import Counter | |
import numpy as np | |
import nltk | |
from nltk.corpus import stopwords | |
from nltk.tokenize import word_tokenize | |
nltk.download('stopwords') | |
nltk.download('punkt') | |
st.sidebar.image("logo.jpg", use_column_width=True) | |
st.sidebar.markdown('### Configuración IA') | |
# Solicita el API key de OpenAI en el panel lateral | |
api_key = st.sidebar.text_input('Ingresa tu API key de OpenAI:', type="password") | |
temperature = st.sidebar.slider('Ajuste de Temperature:', min_value=0.1, max_value=2.0, value=1.0, step=0.1) | |
max_tokens = st.sidebar.slider('Max Tokens:', min_value=50, max_value=1500, value=1000, step=50) | |
openai.api_key = api_key | |
# Muestra la imagen en la parte superior | |
st.markdown('---') | |
st.markdown('## Crea Automáticamente Contenido con tu IA Personalizada') | |
def plot_histogram(articulo): | |
# Tokenizar el artículo en palabras | |
palabras = word_tokenize(articulo, language='spanish') | |
# Obtener las stopwords en español | |
stop_words = set(stopwords.words('spanish')) | |
# Filtrar las palabras para eliminar las stopwords y palabras no alfabéticas | |
palabras_filtradas = [word for word in palabras if word.isalpha() and word.lower() not in stop_words] | |
# Obtener la frecuencia de cada palabra | |
freq = Counter(palabras_filtradas) | |
# Ordenar las palabras por frecuencia y tomar las 8 más comunes | |
common_words = freq.most_common(8) | |
labels, values = zip(*common_words) | |
# Mostrar el histograma | |
plt.figure(figsize=(12, 8)) | |
plt.bar(labels, values) | |
plt.xticks(rotation=90) # Rotar las etiquetas del eje x para una mejor visualización | |
# Ajustar los márgenes para asegurar que las etiquetas no se corten | |
plt.subplots_adjust(left=0.1, bottom=0.2) | |
# Aumentar el tamaño de la fuente de las etiquetas y el título | |
plt.xlabel('Palabras clave', fontsize=14) | |
plt.ylabel('Frecuencia', fontsize=14) | |
plt.title('Top 8 Palabras clave más frecuentes', fontsize=16) | |
plt.xticks(fontsize=12) | |
plt.yticks(fontsize=12) | |
# Guardar la imagen en un buffer y mostrarla en Streamlit | |
buf = io.BytesIO() | |
plt.savefig(buf, format="png") | |
buf.seek(0) | |
tab1.image(buf, caption="Histograma de frecuencia de palabras (8 más comunes)", use_column_width=True) | |
# Función para generar imágenes con DALL·E | |
def generar_imagenes(descripcion, num_imagenes=1): | |
response = openai.Image.create( | |
prompt=descripcion, | |
n=num_imagenes, | |
size="1024x1024", | |
response_format="url", | |
model ="dall-e-3", | |
) | |
urls = [data['url'] for data in response.data] | |
print(urls) # Añade esta línea para ver las URLs generadas. | |
return urls | |
def get_image_download_link(img_url, filename="imagen.png", text="Descargar imagen"): | |
""" | |
Genera un link para descargar una imagen. | |
""" | |
response = requests.get(img_url) | |
img_data = response.content | |
b64 = base64.b64encode(img_data).decode() | |
return f'<a href="data:image/png;base64,{b64}" download="{filename}">{text}</a>' | |
# Función para generar artículos | |
def generar_articulo(tema): | |
prompt_articulo = "Eres un experto en marketing de contenidos y generador de artículos en profundidad" | |
mensajes = [ | |
{"role": "system", "content": prompt_articulo}, | |
{"role": "user", "content": f"Quiero que hagas un artículo sobre \"{tema}\" con índice, titulares, desarrollo de temas y un resumen al final."} | |
] | |
respuesta = openai.ChatCompletion.create( | |
model="gpt-3.5-turbo", | |
messages=mensajes, | |
temperature=temperature, | |
max_tokens=max_tokens, | |
top_p=1, | |
frequency_penalty=0, | |
presence_penalty=0 | |
) | |
return respuesta.choices[0].message['content'] | |
# Función para generar estudio de palabras clave | |
def generar_estudio_palabras(tema): | |
prompt_keywords = "Eres un experto en SEO y análisis de palabras clave. Por favor, genera una lista de palabras clave en español relacionadas con el tema. No escribas nada más" | |
mensajes = [ | |
{"role": "system", "content": prompt_keywords}, | |
{"role": "user", "content": f"¿Cuáles son las palabras clave relacionadas con \"{tema}\"?"} | |
] | |
respuesta = openai.ChatCompletion.create( | |
model="gpt-3.5-turbo", | |
messages=mensajes, | |
temperature=1, | |
max_tokens=200, | |
top_p=1, | |
frequency_penalty=0, | |
presence_penalty=0 | |
) | |
return respuesta.choices[0].message['content'].split(',') | |
def mostrar_palabras_clave(palabras_clave): | |
# Dividir la cadena de palabras clave en una lista | |
palabras_lista = palabras_clave[0].split('\n') | |
# Eliminar cualquier cadena vacía que pueda haber en la lista | |
palabras_lista = [palabra for palabra in palabras_lista if palabra] | |
# Mostrar las palabras clave en formato de lista en Streamlit | |
tab2.write("Aquí tienes una lista de palabras clave relacionadas con:") | |
for palabra in palabras_lista: | |
tab2.markdown(f"- {palabra}") | |
def contar_palabras(titulos): | |
nltk.download('stopwords') | |
nltk.download('punkt') | |
palabras = [] | |
for titulo in titulos: | |
tokens = word_tokenize(titulo.lower()) | |
palabras.extend(tokens) | |
stop_words = set(stopwords.words('spanish')) | |
palabras_filtradas = [p for p in palabras if p not in stop_words and p.isalpha()] | |
return Counter(palabras_filtradas) | |
def generar_nube_palabras(palabras): | |
wordcloud = WordCloud(width=800, height=400, background_color='white').generate(' '.join(palabras)) | |
plt.figure(figsize=(10, 5)) | |
plt.imshow(wordcloud, interpolation='bilinear') | |
plt.axis('off') | |
# Guardar la imagen en un buffer y mostrarla en Streamlit | |
buf = io.BytesIO() | |
plt.savefig(buf, format="png") | |
buf.seek(0) | |
tab2.image(buf, caption="Nube de palabras clave", use_column_width=True) | |
def generar_ideas_articulos(titulos): | |
ideas = [] | |
for titulo in titulos: | |
prompt = f"Basándote en el título '{titulo}', proporcióna una idea original para un artículo que pueda posicionarse bien en los motores de búsqueda." | |
mensajes = [ | |
{"role": "system", "content": prompt} | |
] | |
respuesta = openai.ChatCompletion.create( | |
model="gpt-3.5-turbo", | |
messages=mensajes, | |
temperature=0.7, | |
max_tokens=150, | |
top_p=1, | |
frequency_penalty=0, | |
presence_penalty=0 | |
) | |
idea = respuesta.choices[0].message['content'] | |
ideas.append(idea) | |
return ideas | |
# Crear pestañas | |
tab4, tab2, tab1, tab3 = st.tabs(["Mejores Ideas Competencia", "Estudio de Palabras Clave", "Generar Artículo", "Generar Imagen con DALL·E"]) | |
with tab1: | |
tab1.subheader("Generar un artículo") | |
tema = tab1.text_input('Introduce el tema para el artículo:') | |
if tab1.button('Generar Artículo'): | |
articulo = generar_articulo(tema) | |
tab1.text_area("Artículo Generado:", articulo, height=400) | |
st.download_button("Descargar Artículo", articulo, "mi_articulo.txt") | |
# Llama a plot_histogram() sólo después de haber definido articulo | |
plot_histogram(articulo) | |
with tab2: | |
tab2.subheader("Estudio de palabras clave") | |
tema_keywords = tab2.text_input('Introduce el tema para el estudio de palabras clave:') | |
# Inicializa el estado del botón si aún no está definido | |
if "btn_estudio_pressed" not in st.session_state: | |
st.session_state.btn_estudio_pressed = False | |
# Botón que cambia el estado cuando se presiona | |
if tab2.button('Generar Estudio'): | |
st.session_state.btn_estudio_pressed = not st.session_state.btn_estudio_pressed | |
# Verifica el estado para decidir si ejecutar el código | |
if st.session_state.btn_estudio_pressed: | |
palabras_clave = generar_estudio_palabras(tema_keywords) | |
generar_nube_palabras(palabras_clave) | |
mostrar_palabras_clave(palabras_clave) # Añade esta línea | |
with tab3: | |
tab3.subheader("Generar una imagen con DALL·E") | |
descripcion = tab3.text_input('Introduce una descripción para la imagen:') | |
if tab3.button('Generar Imagen'): | |
urls_imagenes = generar_imagenes(descripcion) | |
# Establece las columnas para las imágenes (2x2) | |
col1, col2 = tab3.columns(2) | |
for i, url in enumerate(urls_imagenes): | |
# Si es imagen impar, la muestra en la columna 1, si no, en la columna 2 | |
if i % 2 == 0: | |
col = col1 | |
else: | |
col = col2 | |
# Mostrar la imagen | |
img = Image.open(requests.get(url, stream=True).raw) | |
col.image(img, caption=descripcion, use_column_width=True) | |
# Botón de descarga debajo de cada imagen | |
col.markdown(get_image_download_link(url, filename=f"imagen_{i+1}.png"), unsafe_allow_html=True) | |
with tab4: | |
tab4.subheader("Generar ideas de artículos posicionados de la competencia") | |
# Entrada de texto para el término de búsqueda | |
busqueda = tab4.text_input("Introduce el término de búsqueda:") | |
if tab4.button('Buscar Compentencia y Generar Ideas'): | |
# Consulta a la API de spaceserp con el término de búsqueda y tu API key | |
url = f"https://api.spaceserp.com/google/search?apiKey={st.secrets['clavespaceserp']}&q={busqueda}&gl=es&hl=es" | |
response = requests.get(url) | |
if response.status_code == 200: | |
data = response.json() | |
titulos_serp = [result["title"] for result in data["organic_results"]] | |
# Genera ideas de artículos basadas en estos títulos | |
ideas_articulos = generar_ideas_articulos(titulos_serp) | |
# Convertir los resultados en un DataFrame y mostrarlo en una tabla | |
df = pd.DataFrame({ | |
'Título SERP': titulos_serp, | |
'Idea para Artículo': ideas_articulos | |
}) | |
tab4.table(df) | |
# Contar las palabras clave más usadas en los títulos | |
frecuencia_palabras = contar_palabras(titulos_serp) | |
# Generar el histograma con Streamlit y matplotlib | |
palabras, frecuencias = zip(*frecuencia_palabras.most_common(30)) | |
fig, ax = plt.subplots(figsize=(10, 8)) | |
ax.barh(palabras, frecuencias) | |
ax.set_title("Palabras clave más utilizadas") | |
ax.invert_yaxis() # invertir el eje y para que las palabras más frecuentes estén en la parte superior | |
tab4.pyplot(fig) | |
else: | |
tab4.warning("Hubo un error al consultar la API de spaceserp.") | |