st.text_input: campo de texto de una línea
st.text_input genera un campo de entrada de texto de una sola línea, equivalente al <input type="text"> de HTML. Es el widget más básico para capturar datos del usuario y se utiliza en formularios de búsqueda, filtros, campos de nombre, email y cualquier entrada corta.
El widget devuelve siempre una cadena de texto (string). Si el campo está vacío, devuelve "". Esto es importante tenerlo en cuenta para las validaciones, ya que una cadena vacía se evalúa como False en contextos booleanos de Python:
import streamlit as st
# Campo de texto básico
nombre = st.text_input("Nombre de usuario")
# Con valor por defecto y placeholder
email = st.text_input(
"Dirección de email",
value="usuario@ejemplo.com",
placeholder="nombre@dominio.com",
help="Introduce un email válido para recibir notificaciones"
)
# Campo de contraseña
password = st.text_input("Contraseña", type="password")
# Campo de búsqueda
busqueda = st.text_input("Buscar en los datos", placeholder="Escribe para filtrar...")
# Mostrar resultado
if nombre:
st.write(f"Bienvenido, **{nombre}**!")
El parámetro max_chars limita la longitud máxima de la entrada, y help muestra un icono de interrogación con un tooltip explicativo al pasar el ratón.
flowchart TD
A[Captura entrada usuario] --> B{"Tipo dato esperado?"}
B -->|Texto corto| C[st.text_input devuelve str]
B -->|Texto largo| D[st.text_area multilinea]
B -->|Número| E[st.number_input int o float]
B -->|Fecha| F[st.date_input date]
B -->|Hora| G[st.time_input time]
C --> H["type=password oculta caracteres"]
E --> I[min max step format]
F --> J[min_value y max_value rango]
H --> K[Validación regex en frontmatter]
I --> L[Cast a float seguro]
J --> M[Filtrado coherente]
K --> N[Errores con st.error]
L --> N
M --> N
st.text_area: campo de texto multilínea
st.text_area genera un campo de texto expandible verticalmente, ideal para entradas más largas como descripciones, comentarios, fragmentos de código o consultas SQL. A diferencia de st.text_input, permite saltos de línea y el usuario puede redimensionar el área manualmente:
import streamlit as st
# Área de texto básica
comentario = st.text_area("Comentarios", height=150)
# Con placeholder y valor por defecto
descripcion = st.text_area(
"Descripción del proyecto",
value="Este proyecto analiza las ventas del primer trimestre de 2026...",
height=200,
placeholder="Describe brevemente el objetivo del análisis",
max_chars=500
)
# Contador de caracteres restantes
if descripcion:
chars_restantes = 500 - len(descripcion)
if chars_restantes < 50:
st.warning(f"Te quedan {chars_restantes} caracteres.")
else:
st.caption(f"{len(descripcion)}/500 caracteres")
st.number_input: entradas numéricas
st.number_input genera un campo específico para valores numéricos, con botones de incremento/decremento y validación automática de rango. El tipo de dato devuelto (entero o decimal) depende del tipo del parámetro value: si el valor inicial es un int, devuelve enteros, y si es un float, devuelve decimales:
import streamlit as st
# Entero con rango
edad = st.number_input("Edad", min_value=0, max_value=120, value=25, step=1)
# Decimal con paso personalizado
precio = st.number_input(
"Precio (€)",
min_value=0.0,
max_value=10000.0,
value=99.99,
step=0.01,
format="%.2f"
)
# Porcentaje
tasa = st.number_input("Tasa de descuento (%)", min_value=0.0, max_value=100.0, value=5.0, step=0.5)
# Sin límites (para parámetros de modelos)
learning_rate = st.number_input("Learning rate", value=0.001, step=0.0001, format="%.4f")
st.write(f"Edad: {edad} años | Precio: €{precio:.2f} | Tasa: {tasa:.1f}%")
El parámetro
formatcontrola cómo se muestra el número en el campo. Acepta especificadores de formato de Python como"%.2f"(dos decimales),"%.4f"(cuatro decimales) o"%d"(sin decimales). Esto afecta solo a la visualización, no al valor devuelto.
st.date_input: selector de fecha
st.date_input genera un calendario interactivo donde el usuario puede seleccionar una fecha concreta o un rango de fechas. Devuelve un objeto datetime.date para selecciones únicas o una tupla de dos fechas para rangos:
import streamlit as st
from datetime import date, timedelta
# Fecha única con valor por defecto
fecha = st.date_input("Fecha de análisis", value=date.today())
# Fecha con rango limitado
fecha_inicio = st.date_input(
"Fecha de inicio",
value=date(2026, 1, 1),
min_value=date(2020, 1, 1),
max_value=date.today()
)
# Rango de fechas (devuelve tupla)
rango = st.date_input(
"Período de análisis",
value=(date(2026, 1, 1), date.today()),
min_value=date(2020, 1, 1),
max_value=date.today()
)
if isinstance(rango, tuple) and len(rango) == 2:
inicio, fin = rango
dias = (fin - inicio).days
st.write(f"Período: {inicio} → {fin} ({dias} días)")
st.time_input: selector de hora
import streamlit as st
from datetime import time
hora_reunion = st.time_input("Hora de reunión", value=time(9, 0))
st.write(f"Reunión programada para las {hora_reunion.strftime('%H:%M')}")
Validación de entradas y mensajes de error
Un patrón robusto combina los widgets con validación y mensajes de estado:
import streamlit as st
import re
st.title("Formulario de registro")
nombre = st.text_input("Nombre completo *")
email = st.text_input("Email *")
edad = st.number_input("Edad", min_value=0, max_value=120, value=25)
descripcion = st.text_area("Comentarios (opcional)", height=100)
errores = []
def validar_email(email_str):
patron = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return re.match(patron, email_str) is not None
if st.button("Registrar", type="primary"):
if not nombre.strip():
errores.append("El nombre es obligatorio.")
elif len(nombre.strip()) < 3:
errores.append("El nombre debe tener al menos 3 caracteres.")
if not email.strip():
errores.append("El email es obligatorio.")
elif not validar_email(email):
errores.append("El formato del email no es válido.")
if errores:
for error in errores:
st.error(error)
else:
st.success(f"Registro exitoso: {nombre} ({email}), {edad} años.")
if descripcion:
st.info(f"Comentarios recibidos: {descripcion[:50]}...")
El patrón de recopilar todos los errores en una lista antes de mostrarlos proporciona una mejor experiencia de usuario que mostrar los errores uno a uno, ya que permite al usuario corregir todos los campos problemáticos de una sola vez en lugar de descubrir errores de forma secuencial.
Para formularios complejos con múltiples campos de entrada, es recomendable utilizar
st.formque agrupa todos los widgets y solo provoca un rerun al pulsar el botón de envío, evitando validaciones parciales en cada interacción individual.
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Streamlit es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de Streamlit
Explora más contenido relacionado con Streamlit y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
Crear campos de texto de una línea con st.text_input y gestionar sus opciones. Usar st.text_area para entradas de texto multilínea con altura personalizable. Configurar st.number_input con rangos, pasos y formato de visualización. Implementar selectores de fecha con st.date_input y de hora con st.time_input. Validar entradas del usuario y mostrar mensajes de error apropiados.