generador3 / app.py
salomonsky's picture
Update app.py
e2fb9d9 verified
import streamlit as st
import pandas as pd
import random
import zipfile
from faker import Faker
from unidecode import unidecode
from pathlib import Path
from datetime import datetime
from PyDictionary import PyDictionary
faker = Faker('es_MX')
def generar_rfc(nombre, apellido, anio, mes, dia):
return f"{apellido[:2].upper()}{nombre[:2].upper()}{str(anio)[-2:]}{mes:02}{dia:02}{random.randint(10, 99)}"
def generar_telefono_por_estado(estado):
ladas = {'Ciudad de Mexico': '55', 'Jalisco': '33', 'Nuevo Leon': '81', 'Veracruz': '229', 'Yucatan': '999',
'Puebla': '222', 'Chiapas': '961', 'Tamaulipas': '834', 'Queretaro': '442', 'Coahuila': '871'}
return f"{ladas.get(estado, '55')}{random.randint(1000000, 9999999)}"
def generar_nss():
return f"{random.randint(100, 999)}-{random.randint(10, 99)}-{random.randint(1000, 9999)}"
def limpiar_correo(correo):
return unidecode(correo.replace(" ", "").lower())
def generar_correo_aleatorio():
try:
diccionario = PyDictionary()
palabra = random.choice(list(diccionario.meaning("word").keys()))
except Exception:
palabra = faker.word()
dominio = random.choice(["gmail.com", "hotmail.com"])
return limpiar_correo(f"{palabra}{random.randint(1, 999)}@{dominio}")
def generar_datos(cantidad, columnas, progreso):
try:
estados = ['Ciudad de Mexico', 'Jalisco', 'Nuevo Leon', 'Veracruz', 'Yucatan',
'Puebla', 'Chiapas', 'Tamaulipas', 'Queretaro', 'Coahuila']
bancos, datos = ['BBVA', 'Banorte', 'Santander', 'Citibanamex', 'HSBC',
'AMEX', 'Inbursa', 'Bancoppel'], []
for i in range(cantidad):
estado = random.choice(estados)
nombre, apellido = faker.first_name(), faker.last_name()
dia, mes, anio = faker.date_of_birth().day, faker.date_of_birth().month, faker.date_of_birth().year
fila = {'Nombre': f"{nombre} {apellido}" if 'Nombre' in columnas else None,
'RFC': generar_rfc(nombre, apellido, anio, mes, dia) if 'RFC' in columnas else None,
'Telefono': generar_telefono_por_estado(estado) if 'Telefono' in columnas else None,
'Estado': estado if 'Estado' in columnas else None,
'Direccion': faker.address() if 'Direccion' in columnas else None,
'Correo Electronico': generar_correo_aleatorio() if 'Correo Electronico' in columnas else None,
'Tarjeta': ''.join([str(random.randint(0, 9)) for _ in range(16)]) if 'Tarjeta' in columnas else None,
'Banco': random.choice(bancos) if 'Banco' in columnas else None,
'Score de Credito': random.randint(300, 850) if 'Score de Credito' in columnas else None,
'NSS': generar_nss() if 'NSS' in columnas else None}
datos.append({k: v for k, v in fila.items() if v is not None})
if i % max(1, cantidad // 100) == 0: # Actualiza progreso proporcionalmente
progreso.progress(i / cantidad)
progreso.progress(1.0)
return pd.DataFrame(datos)
except Exception as e:
raise RuntimeError(f"Error al generar datos: {e}")
def guardar_varios_archivos(dfs, formato):
archivos = []
try:
for i, df in enumerate(dfs):
timestamp = datetime.now().strftime("_%H%M%S")
archivo_nombre = f"leads_buro_{i+1}{timestamp}." + ("csv" if formato == "CSV" else "xlsx")
if formato == "CSV":
df.to_csv(archivo_nombre, index=False)
else:
df.to_excel(archivo_nombre, index=False, engine='openpyxl')
archivos.append(archivo_nombre)
return archivos
except Exception as e:
raise RuntimeError(f"Error al guardar archivos: {e}")
def crear_zip(archivos):
try:
zip_nombre = "archivos_generados.zip"
with zipfile.ZipFile(zip_nombre, 'w') as zipf:
for archivo in archivos:
zipf.write(archivo, Path(archivo).name)
for archivo in archivos: # Limpia archivos temporales
Path(archivo).unlink(missing_ok=True)
return zip_nombre
except Exception as e:
raise RuntimeError(f"Error al crear archivo ZIP: {e}")
def main():
st.set_page_config(layout="wide")
st.sidebar.title("Configuraci贸n")
opciones_columnas = ["Nombre", "Telefono", "RFC", "Estado", "Direccion",
"Correo Electronico", "Tarjeta", "Banco", "Score de Credito", "NSS"]
columnas = [col for col in opciones_columnas if st.sidebar.checkbox(col, value=False)]
num_archivos = st.sidebar.slider("N煤mero de archivos (1M registros c/u):", min_value=1, max_value=25, value=1)
formato_descarga = st.sidebar.radio("Selecciona el formato de descarga:", ["CSV", "XLS"])
if st.sidebar.button("Generar Datos"):
try:
if not columnas:
st.error("Debe seleccionar al menos una columna.")
return
progreso = st.progress(0)
st.write(f"Generando {num_archivos} archivo(s) de 1 mill贸n de registros...")
dfs = [generar_datos(1_000_000, columnas, progreso) for _ in range(num_archivos)]
st.subheader("Previsualizaci贸n de datos (primeros 100 registros del primer archivo):")
st.dataframe(dfs[0].head(100))
archivos_generados = guardar_varios_archivos(dfs, formato_descarga)
if len(archivos_generados) > 1:
zip_nombre = crear_zip(archivos_generados)
with open(zip_nombre, "rb") as file:
st.download_button("Descargar todos en ZIP", data=file, file_name=zip_nombre, mime="application/zip")
else:
with open(archivos_generados[0], "rb") as file:
st.download_button(f"Descargar {formato_descarga}", data=file,
file_name=archivos_generados[0],
mime="text/csv" if formato_descarga == "CSV" else
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
st.success("Archivos generados y listos para descargar.")
except Exception as e:
st.error(f"Error durante la generaci贸n: {e}")
if __name__ == "__main__":
main()