Tutorial de Streamlit: Crea Apps CRUD en Python
Tutorial de Streamlit: Crea Apps CRUD en Python
com
Aprenda Streamlit
Por: Nick Antonaccio ( nick@[Link] )
Contenido:
9. Más ejemplos de aplicaciones sencillas para demostrar los conceptos básicos de Streamlit en la práctica
9.1 Tiempo entre fechas
9.2 Visor de cámara web en vivo
9.3 Lanzamiento de moneda
2. Requisitos previos
Debes tener conocimientos básicos de Python para comenzar este tutorial. Si no has escrito código en Python (ni en ningún otro lenguaje) antes, es
posible que quieras comenzar cones:[Link] Este minicurso gratuito de más de 200 páginas enseña todo lo que necesitas saber para crear
varias docenas de aplicaciones web completas, utilizando otro marco de trabajo Python puro (Anvil), sin necesidad de conocimientos previos de
programación. Muchas de las ideas de aplicaciones y los ejemplos de código Python genérico explicados en ese minicurso de Anvil se comparten
con este tutorial, por lo que es un prerrequisito perfecto para principiantes para este texto.
3. ¿Qué es Streamlit?
Streamlit es una biblioteca de Python que permite a los desarrolladores crear rápidamente interfaces de usuario interactivas y enriquecidas (diseños de páginas
web) conmuy poco códigoPuede utilizar Streamlit junto con cualquier sistema de base de datos disponible en Python, para formar un sistema fácil de [Link]
completaKit de herramientas de desarrollo web, especialmente adecuado para proyectos internos en los que la productividad y las iteraciones de desarrollo
rápidas son una prioridad. Una parte importante de este tutorial se centrará en la creación de aplicaciones de gestión de datos CRUD mediante la integración
de Streamlit con comandos SQL y el sistema de base de datos SQLite. Otra gran sección del tutorial demuestra los patrones de código de Streamlit en la
práctica utilizando pequeñas aplicaciones de ejemplo.
El siguiente ejemplo es una aplicación completa que permite a los usuariosdocrear,Rcabeza,túactualizar, yDEliminar entradas de la base de
datos con formularios Streamlit. Estas 22 líneas son lascompletoListado de códigos necesarios para crear y configurar cada parte de la
aplicación, incluida la interfaz de usuario y todas las interacciones con la base de datos:
para la fila en [Link]('SELECT rowid, nombre, letras, nota FROM db ORDER BY nombre'):
con [Link](fila[1]):
con [Link](f'ID-{fila[0]}'):
nombre=st.text_input('Nombre', fila[1])
letras=[Link]('Letras', ['A', 'B', 'C'], ast.literal_eval(row[2])) nota=st.text_area('Nota',
fila[3])
si st.form_submit_button('Guardar'):
[Link](
'ACTUALIZAR db ESTABLECER nombre=?, letras=?, nota=? DONDE
nombre=?;', (nombre, str(letras), nota, str(fila[1]))
)
[Link]() ; st.experimental_rerun()
si st.form_submit_button("Eliminar"): [Link](f'ELIMINAR DE db
DONDE rowid="{row[0]}";') [Link]() ; st.experimental_rerun()
Aquí hay una versión en vivo de la aplicación, que está alojada de forma gratuita mediante Streamlit Cloud:
Streamlit está diseñado para ser utilizado como una herramienta de presentación para científicos de datos, por lo que su mayor fortaleza
es integrar las mejores bibliotecas de visualización, análisis, aprendizaje automático e inteligencia artificial de Python: Pandas, Numpy,
Matplotlib, Tensorflow, OpenCV, PyTorch, Theano, Plotly, Altair, Bokeh, GraphViz, PyDeck, Vegalite, así como todas las bibliotecas estándar
y cualquier otra biblioteca/herramienta en el mundo Python.
Streamlit requieresolo Pythonpara construir interfaces web ricas (absolutamente sin necesidad de HTML/CCS/JS) y permite a los
desarrolladores usar cualquier código Python de forma nativa en el back-end para realizar tareas complejas de gestión de datos, IA,
aprendizaje automático, consumo de API y conectividad en minutos.
Puede ejecutar aplicaciones web Streamlit/Python inmediatamente en iPhone, iPad, Android, Windows, Mac, Linux, Chromebook, [Link] ninguna
instalaciónen esos dispositivos. Los únicos requisitos para ejecutar Streamlit son una instalación básica de Python en una máquina Windows, Mac o
Linux local (es decir, conectada a Wi-Fi) o en una plataforma de servidor en la nube, una instalación rápida de la biblioteca Streamlit y cualquier
editor de texto.
Streamlit es gratuito y de código abierto y está respaldado por una empresa bien [Link] iluminada por el sol proporciona una solución de
alojamiento gratuita y conveniente que permite una implementación instantánea, sin las tareas que consumen tiempo ni los costos que suelen asociarse con
la publicación de aplicaciones web. La integración de GIT está incorporada directamente en la plataforma de alojamiento gratuita de Streamlit (las
aplicaciones alojadas se actualizan automáticamente cada vez que se confirman los archivos en el repositorio de Github de un proyecto). No hay dependencia
de ningún proveedor: puede alojar aplicaciones en el sitio localmente o mediante AWS, Google Cloud, Azure, Digital Ocean, Heroku, etc.
5. Primeros pasos
có[Link]
El editor de código en vivo que se muestra arriba se ejecuta en su navegador y muestra inmediatamente los resultados del código Streamlit editado.
Incluso puede ejecutar este editor en el navegador web de cualquier dispositivo móvil moderno:
(El editor de código en vivo utilizado aquí fue creado en Streamlit por Sam Dobson, basado en el trabajo de Okld, utilizando el editor JS
Ace).
[Link]('Hola')
Haz clic en el botón "Aplicar" en la esquina inferior derecha del editor (o presiona las teclas CTRL+Enter en tu teclado) y verás una nueva
actualización de la aplicación debajo del editor. Haz clic en el botón "Haz clic en mí" que se acaba de mostrar y verás aparecer un mensaje
de "¡Hola mundo!":
Eso es todo: solo dos líneas de código y tenemos una aplicación web interactiva.
Tenga en cuenta que Streamlit utiliza el método '[Link]()' para mostrar valores. El método '[Link]()' se utiliza para presentar un widget de
botón en el que se puede hacer clic. Se utiliza una evaluación 'if' para ejecutar un código Python cada vez que se hace clic en el botón.
IMPORTANTE: de forma predeterminada en las aplicaciones Streamlit,El script completo se vuelve a ejecutar cada vez que un usuario interactúa con cualquier tipo de
widget de [Link] más sobre cómo funciona esto más adelante en el tutorial.
Si recibe algún error al ejecutar un script en el editor de código en vivo, haga clic en el botón "Administrar aplicación" en la esquina
inferior derecha de la pantalla para ver información de depuración detallada.
Ahora reemplace el código en el editor con lo siguiente (luego haga clic en "Aplicar" o presione CTRL+Enter):
si [Link]('Hora actual'):
[Link]([Link]())
Con ese fragmento de código, ahora estamos usando una función de la biblioteca estándar de Python,directamente dentro del mismo archivo de script único
que produce la interfaz del navegador webEl código de front-end y back-end se encuentra en un solo archivo. En lugar de quedarse atascados en una
consola de escritorio imprimiendo texto, los usuarios pueden interactuar con este código Python en un teléfono móvil, una tableta o cualquier otro
dispositivo que tenga un navegador.
solicitudes de importación
Tenga en cuenta que el método 'st.text_input()' en el código anterior se utiliza para mostrar un widget de entrada de campo de [Link] valor
escrito por el usuario en el widget text_input se almacena en la variable 'nombre'Al igual que con el botón del ejemplo anterior, aquí usamos una
evaluación "si" para ejecutar algún código Python cada vez que el usuario cambie esa variable (ingresada en el widget text_input). Tenga en cuenta
que cada vez que el usuario interactúa con el widget st.text_input(),Se vuelve a ejecutar todo el script, utilizando ese nuevo valor de variable
asignado al contenido de texto del widget..
Observe también el widget '[Link]()', que agrega un título de texto grande al diseño de la aplicación.
Ahora veamos otro ejemplo de API web para familiarizarnos más con los métodos de Streamlit. Tenga en cuenta que en eleditor de código en vivo En el
entorno que estamos utilizando, la biblioteca Streamlit se importa de forma predeterminada. En cualquier otro entorno, deberá importar Streamlit, por lo
que todos los ejemplos de este tutorial incluirán Streamlit en las importaciones de la biblioteca. Streamlit se importa convencionalmente como 'st':
[Link]('Imágenes de Pokémon')
mypokemon=['charizard','pikachu','eevee','snorlax','garchomp','lucario']
pokemon=[Link]('Selecciona un Pokémon', mypokemon)
si pokemon:
r=[Link](f'[Link] para la imagen
en r['sprites'].values():
Si img no es Ninguno:
si str(img)[-4:]=='.png':
[Link](img)
El ejemplo anterior utiliza un widget '[Link]()' para permitir a los usuarios elegir personajes de Pokémon de una lista desplegable.
Se utilizan un bucle 'for' y algunas evaluaciones 'if' para analizar el json devuelto por la API de [Link], y se utiliza un widget
'[Link]()' para mostrar las imágenes vinculadas que se encuentran en los resultados:
Es importante darse cuenta de que la mayor parte del ejemplo anterior es soloCódigo básico de Python, exactamente como lo que usarías en un
REPL de Python de línea de comandos o en scripts de consola de escritorio simples. En estos ejemplos, solo agregamos algunos métodos 'st.()' para
obtener información del usuario y mostrar resultados en la página web. El código Python típico se ejecutaen el servidordonde se ejecuta Streamlit y
se ejecutan los widgets de la interfaz de usuario de Streamliten el navegadorStreamlit se encarga de transportar todos los datos entre el servidor y
los navegadores web de los clientes de forma transparente. Es extraordinariamente fácil de aprender.
A continuación se muestra otro ejemplo de API similar para aclarar cómo incorporar Streamlit con el código Python típico de "estilo consola":
bebidas=[Link](
para '[Link]
) .json()
ingredientes=[]
para beber en bebidas['bebidas']:
[Link](bebida['strIngrediente1'])
bebidas=[Link](
para '[Link]
) .json()
ingredientes=[]
para beber en bebidas['bebidas']:
[Link](bebida['strIngrediente1'])
Esta es la magia de Streamlit: la maquinaria completa necesaria para las interacciones cliente-servidor tradicionalmente complicadas se
crea con un archivo de código, utilizando un proceso de pensamiento lineal sencillo y familiar. Puede pasar variables en unguión único,
casi como si todo el código se estuviera ejecutando en una sola máquina y Streamlit enviara y recibiera los datos entre la computadora
servidor y los navegadores del cliente, sin ningún esfuerzo por parte del desarrollador. Esto es bastante diferente de la rutina tradicional
de desarrollo de pila completa.
[Link]('Título')
[Link]('Encabezado')
[Link]('Subtítulo')
[Link]('Título')
[Link]('print("esto es un código")')
[Link]('Texto')
[Link]('- *Markdown*') [Link]('\sum_{k=0}^{n-1} ar^k')
[Link]([Link]({'a':[1, 2, 3],'b':['A', 'B', 'C']})) [Link]({'a':[1, 2, 3],'b':
['A', 'B', 'C']})
gráfico_de_área_de_st.(df)
gráfico de barras [Link](df)
mapa de árbol=pd.read_csv('á[Link]')
[Link](mapa de árbol)
[Link](mapa de árbol)
5.7 Simplemente asigne y pase variables
La mayoría de los métodos anteriores se ejecutan en el navegador para mostrar elementos de la interfaz de usuario, pero algunos, como
file_uploader, download_button, image, audio y video, transfieren datos entre el servidor y el cliente de forma inherente.
Todos los widgets de entradaSe pueden asignar variables a los archivos y esas variables se pueden usar en código Python normal que se ejecuta
en el servidor. Por ejemplo, el código siguiente obtiene un valor del usuario en el navegador y luego escribe esos datos en el disco duro del
servidor, utilizando algunas operaciones de archivo típicas en código Python de "estilo consola":
Eso es solo la punta del iceberg. Streamlit tiene soporte integrado para muchas de las bibliotecas de visualización y gráficos de Python
más populares, así como un mundo de poderosos componentes gratuitos creados por la comunidad, que permiten interesantes
funciones de diseño/disposición/IU (incluidas cuadrículas de datos complejas), procesamiento avanzado de gráficos/audio/video, mapeo
geográfico, videoconferencia en tiempo real, integraciones con aplicaciones de terceros como Discourse y Disqus, y mucho más, todo con
muy poco código y todo usandoPython puro.
[Link]
Como has visto, cada vez que un usuario interactúa con un widget de entrada Streamlit, la respuesta predeterminada es que elguión completose vuelve a
evaluar con el nuevo valor ingresado en ese widget. Esto generalmente les ahorra a los desarrolladores de Streamlit mucho trabajo al asignar funciones de
devolución de llamadas y administrar el estado, pero puede generar algunos desafíos.
6.1 Disposición
En la mayoría de las aplicaciones, habrá situaciones en las que no desea que Streamlit vuelva a evaluar todo el script cada vez que se
ingresa un valor en un widget, o situaciones en las que necesita guardar valores ingresados previamente, por ejemplo. La más común de
esas situaciones ocurre cuando se utilizan formularios, donde solo desea procesar un grupo de valores ingresados una vez que el
usuario los haya ingresado todos:
Puede incluir tantos formularios como necesite en una página e incluir tantos widgets st.form_submit_button() como necesite en
cada formulario para procesar los datos de distintas maneras. Cada formulario debe tener un nombre único:
área_mensaje=[Link]()
con [Link]('Formulario 1', clear_on_submit=True):
nombre=st.text_input('Nombre') si
st.form_submit_button('Actualizar'):
# ejecutar algún código de base de datos
message_area.write(f'Nombre actualizado a {nombre}')
si st.form_submit_button('Eliminar'):
# ejecutar algún código de base de datos
message_area.write(f'Nombre {nombre} eliminado')
Hay una serie deOtros contenedores que se puede utilizar para colocar widgets en la pantalla en los diseños deseados. Aquí hay dos
formas sintácticas diferentes de colocar widgets en contenedores [Link]():
st.text_area('texto2')
con col6:
[Link]('## Subencabezado\n- elemento 1\n- elemento 2')
El primer método anterior es útil cuando desea especificar el contenedor de columnas en el que se debe posicionar un solo widget,
especialmente cuando se crean instancias de varios widgets desde secciones separadas de un script.
El segundo método es útil cuando desea posicionar una mayor cantidad de widgets en una columna determinada, todos en un solo bloque
contiguo de código, utilizando un administrador de contexto "with", sangrado debajo de la etiqueta de columna deseada.
El siguiente scriptnomuestra un incremento, como es de esperar, porque Streamlit vuelve a ejecutar el script cada vez que se hace clic
en el botó[Link] variable 'total' se restablece a cero cada vez que se vuelve a ejecutar el script.:
total=0
si [Link]('+'):
total+=1
[Link](total)
Para almacenar valores persistentes durante cada nueva ejecución de un script Streamlit, utilice st.session_state():
@[Link]
def long_function(repeticiones):
total=0
para repeticiones en rango (repeticiones):
total+=1
devolver total
[Link](f'primera ejecución:{función_larga(val)}')
[Link](f'segunda ejecución, el valor almacenado en caché aparece rápidamente: {long_function(val)}')
Tenga en cuenta que la primera ejecución de cualquier número grande seleccionado requiere un cálculo largo. Cada vez que se vuelve a ejecutar
esa función con el mismo valor seleccionado, el valor de retorno aparece inmediatamente, porque la función de cálculo utiliza el valor de caché
guardado para cuando el argumento de entrada es idéntico.
Para borrar cualquier valor de caché guardado, haga clic en el menú de hamburguesas en la esquina superior derecha de la interfaz de usuario de
Streamlit y seleccione 'Borrar caché c'.
(NOTA: Si tiene experiencia trabajando con SQL en Python, puede leer rápidamente las siguientes dos secciones de este tutorial.
Reutilizaremos algunas líneas de estas secciones repetidamente).
Las operaciones CRUD (Crear/Leer/Actualizar/Eliminar) son un componente clave de la mayoría de las aplicaciones útiles, especialmente las que
se utilizan para la gestión de datos empresariales (contabilidad, inventario, facturación, nóminas, puntos de venta, programación,
comunicaciones, gestión de proyectos, gestión de propiedades, etc.). Streamlit y Python son una gran combinación para crear funcionalidades
CRUD para aplicaciones web de forma rápida y sencilla.
En este tutorial, simplificaremos las cosas y utilizaremos algunos comandos SQL básicos para almacenar y recuperar datos utilizando el sistema
de base de datos SQLite. SQLite está integrado en Python, por lo que no es necesario instalar nada adicional (viene de forma gratuita como parte
integrada de todas las distribuciones modernas de Python). Hay muchas opciones de Python que se pueden utilizar para migrar de SQLlite a otros
RDBMS, siempre que necesite capacidad de nivel empresarial. Los ORM (mapeadores relacionales de objetos) como SQLalchemy eliminan la
necesidad de código SQL y ayudan a unificar la conectividad entre sistemas de bases de datos populares como PostgreSQL, MySQL, MSSQL,
Oracle y otros.
Hay muchos tutoriales en línea que explican cómo usar SQL en Python, pero para nuestros propósitos, cubriremos solo algunos
fragmentos fundamentales que le permiten crear una tabla de base de datos, luego insertar, eliminar, actualizar y recuperar filas de
datos.
Primero, para usar Sqlite, debes importar 'sqlite3' desde la biblioteca estándar de Python:
importar sqlite3
Para conectar con una base de datos SQLite, utilizaremos el método .connect de la biblioteca sqlite3, especificando el nombre de un
archivo de base de datos SQLite. Si este archivo no existe, se creará. Asignaremos la variable 'con' para hacer referencia a esta conexión:
con=[Link]('[Link]')
A continuación, utilizará el método .cursor de la base de datos conectada para enviar comandos SQL a la base de datos conectada. Asignaremos
la variable 'cur' para hacer referencia a este cursor:
cur=[Link]()
A continuación, se utiliza el método .execute del cursor para enviar una cadena que contiene comandos SQL. El primer comando SQL que
necesitaremos para crear una tabla en la base de datos es 'CREATE TABLE'. Incluiremos la cláusula 'IF NOT EXISTS', de modo que esta operación
solo se realice si la tabla no se ha creado ya. Las tablas se pueden considerar como filas y columnas de información, similares a una cuadrícula de
una hoja de cálculo. La definición de los nombres de las columnas y el tipo de datos que puede contener cada columna se denomina 'esquema' de
la tabla. Llamaremos a esta tabla 'db' y crearemos un esquema con 3 columnas llamadas 'nombre', 'letras' y 'nota', todas las cuales almacenarán
valores de texto:
Para insertar valores de datos en la tabla creada anteriormente, utilice el comando 'INSERT INTO'. El código siguiente agrega una nueva fila de
datos a las columnas 'name', 'letters' y 'note' de la tabla 'db', utilizando 3 marcadores de posición '?', que se rellenan con los valores ('','[]',''):
Cada vez que se complete una operación, utilice el método .commit del objeto de conexión de base de datos para guardar los datos en la base de
datos (antes de hacer esto, los comandos SQL simplemente se almacenan en la memoria RAM y los resultados aún no se guardan en el archivo de
base de datos):
[Link]()
Para actualizar los valores de una fila de la tabla de la base de datos (también llamada "registro"), utilice el comando SQL "UPDATE". El siguiente
código actualiza el registro vacío que creamos anteriormente, con algunos valores significativos:
[Link](
'UPDATE db SET nombre=?, letras=?, nota=? WHERE nombre=?;', ('John
Smith, '["A", "B"]', 'Tiene un nombre popular', '')
)
[Link]()
Para ver los registros de la base de datos, utilice el comando SQL 'SELECT'. El código siguiente devuelve las
columnas 'rowid', 'name', 'letters' y 'note' de las tablas 'db' y las ordena según los valores de la columna 'name':
Tenga en cuenta que la columna "rowid" es una "clave", generada y aumentada automáticamente por SQLite, de modo que cada fila tiene un
identificador único. Esto se hace para que las filas se puedan diferenciar y hacer referencia a ellas específicamente, incluso si hay valores duplicados
en otros campos. El rowid se utiliza para garantizar que se realicen operaciones en una fila deseada; por ejemplo, para eliminar la entrada correcta
para una persona en particular llamada John Smith, cuando potencialmente hay varias filas con el nombre "John Smith" en el campo de nombre.
Para eliminar registros, utilice el comando 'DELETE'. El código siguiente elimina el registro con rowid 1 de la tabla 'db':
Dependiendo del sistema de base de datos, encontrará soporte para una amplia variedad de tipos de datos (fechas y horas, imágenes y datos
binarios, valores json, etc.). Algunos sistemas de bases de datos como PostgreSQL tienen soporte integrado para valores nativos de Python como
listas y diccionarios, en forma de tipos de datos json. Sqlite es tan simple como las bases de datos, por lo que para guardar estructuras de datos
como listas, diccionarios, conjuntos y tuplas, simplemente podemos serializar los datos en cadenas, utilizando la función str() de Python. Al leer
cadenas de vuelta desde una base de datos, podemos utilizar el método ast.literal_eval() para convertir las estructuras de datos guardadas
nuevamente en tipos de datos de lista, diccionario, conjunto y tupla funcionales.
Ast.literal_eval() es mucho más seguro que usar la función eval() de Python, ya que funciona solo para evaluar estructuras de datos (en lugar de
código ejecutable). Esto ayuda a desinfectar el código malicioso almacenado por los usuarios en la base de datos. No desea que el código ejecutable
que haya sido almacenado por un usuario, por ejemplo, pueda borrar el contenido de su disco duro o proporcionar derechos de administrador
involuntariamente a un usuario. ¡Eso es potencialmente bastante fácil de hacer si alguna vez usa eval() sobre valores almacenados en una base de
datos!
Un patrón típico que podemos usar para almacenar listas de Python en una base de datos se parece a esto (observe la función str() aplicada a
la lista 'letras', en la declaración de actualización de SQL):
nombre='Juan Pérez'
letras=['A','B','C']
nota='John es de Ohio'
[Link](
'ACTUALIZAR db ESTABLECER nombre=?, letras=?, nota=? DONDE
nombre=?;', (nombre, str(letras), nota, nombre)
)
[Link]()
Podemos recuperar los datos guardados de la base de datos utilizando un patrón como este (observe el método ast.literal_eval()
aplicado al campo 'letras', recuperado por la declaración de selección SQL):
para la fila en [Link]('SELECT rowid, nombre, letras, nota FROM db ORDER BY nombre'):
nombre=fila[1]
letras=ast.literal_eval(fila[2]) nota=fila[3]
También utilizaremos métodos de fecha y hora para formatear las fechas correctamente en los próximos ejemplos.
Al trabajar con otros sistemas de bases de datos, es preferible utilizar los tipos de datos nativos empleados por cada RDBMS en
particular, en lugar de serializar los tipos de datos en cadenas, como se requiere para SQLite.
Para comenzar a crear aplicaciones de base de datos con interfaces de usuario Streamlit que aparezcan en un navegador, solo necesitamos mezclar algunos métodos
de widgets Streamlit en el código SQL. Aquí están todas las importaciones, así como todo el código de configuración de la base de datos que necesitamos, tomado
textualmente de las secciones anteriores de este tutorial:
Para agregar una nueva fila a la base de datos, podemos usar un widget [Link](). Este código SQL también está tomado textualmente de los
ejemplos del tutorial anterior:
En este primer ejemplo, utilizaremos un bucle "for" para generar widgets [Link]() para cada fila devuelta de una consulta de base
de datos (un comando SQL select). Dentro de cada [Link](), colocaremos un widget [Link](), que se utiliza para mostrar un grupo
de widgets st.text_input(), [Link]() y st.text_area(), cada uno de los cuales presenta un valor seleccionado de la base de datos
(nuevamente, el código SQL SELECT aquí se toma textualmente de la sección anterior de este tutorial):
para la fila en [Link]('SELECT rowid, nombre, letras, nota FROM db ORDER BY nombre'):
con [Link](fila[1]):
con [Link](f'ID-{fila[0]}'):
nombre=st.text_input('Nombre', fila[1])
letras=[Link]('Letras', ['A', 'B', 'C'], ast.literal_eval(fila[2])) nota=st.text_area('Nota',
fila[3])
Tenga en cuenta que los widgets [Link]() anteriores deben tener claves únicas (el primer argumento del método [Link]()), por lo que se
utiliza una cadena formateada para concatenar 'ID-' con el valor 'rowid' de la fila de la base de datos que se muestra:
[Link](f'ID-{fila[0]}')
7.4 Finalización de una aplicación CRUD básica: agregar botones para actualizar y eliminar
Podemos agregar widgets st.form_submit_button() al código de formulario anterior para ejecutar instrucciones SQL de actualización y eliminación en
cualquier valor de fila mostrado. Tenga en cuenta que los botones en el código siguiente están contenidos en formularios separados creados por el bucle for,
por lo que cada valor de fila al que se hace referencia en las instrucciones de actualización y eliminación (que se ejecutan cuando el usuario hace clic en
cualquier widget de botón) se refiere al registro particular único que se muestra en cada formulario. Esto significa que al hacer clic en cualquier botón
"Actualizar" o "Eliminar" se realizan esas operaciones en la fila de valores de la base de datos que se muestra en ese formulario específico:
para la fila en [Link]('SELECT rowid, nombre, letras, nota FROM db ORDER BY nombre'):
con [Link](fila[1]):
con [Link](f'ID-{fila[0]}'):
nombre=st.text_input('Nombre', fila[1])
letras=[Link]('Letras', ['A', 'B', 'C'], ast.literal_eval(row[2])) nota=st.text_area('Nota',
fila[3])
si st.form_submit_button('Guardar'):
[Link](
'ACTUALIZAR db ESTABLECER nombre=?, letras=?, nota=? DONDE
nombre=?;', (nombre, str(letras), nota, str(fila[1]))
)
[Link]()
st.experimental_rerun() st.form_submit_button("Eliminar"):
si [Link](f'ELIMINAR DE db DONDE rowid="{row[0]}";')
[Link]()
st.experimental_rerun()
Tenga en cuenta que el método st.experimental_rerun() se ejecuta después de las operaciones de actualización y eliminación. Esto simplemente
actualiza toda la visualización de la página con los valores de consulta recién actualizados leídos desde la base de datos.
Lo creas o no, eso es todo lo que necesitamos para crear una aplicación web CRUD de base de datos completa con Streamlit. Este es el código
completo (el mismo ejemplo presentado en la introducción de este tutorial):
Pegue ese ejemplo en el editor de código en vivo encó[Link] , para verlo correr!
7.5 Cómo trabajar con imágenes, sonidos y vídeos - Aplicación de base de datos de imágenes
Podemos tomar el ejemplo anterior como modelo, cambiar un poco el esquema de la base de datos, usar algunos widgets para cargar y mostrar
imágenes, y tendremos un pequeño sistema de base de datos perfectamente utilizable para manejar fotos:
con=[Link]('[Link]')
cur=[Link]()
[Link]('CREAR TABLA SI NO EXISTE pics(id TEXTO, img BLOB, nota TEXTO)')
[Link]('Imágenes SQLite') si
[Link]('Agregar nueva imagen'):
[Link]('INSERTAR EN pics(id, img, nota) VALORES(?,?,?)', ('', '', '')) [Link]()
para la fila en [Link]('SELECT rowid, id, img, note FROM pics ORDER BY id'):
con [Link](fila[1]):
con [Link](f'ID-{fila[0]}', clear_on_submit=True):
id=st.text_input('id', fila[1]) si fila[2]:
img=fila[2]
[Link](fila[2])
archivo=st.file_uploader('Imagen', ['png', 'jpg', 'gif', 'bmp']) si archivo:
img=[Link]()
nota=st.text_area('nota', si fila[3])
st.form_submit_button('Enviar'):
[Link](
'ACTUALIZAR imágenes ESTABLECER id=?, img=?, nota=? DONDE
id=?;', (id, img, nota, str(row[1]))
)
[Link]()
st.experimental_rerun() st.form_submit_button("Eliminar"):
si [Link](f'''ELIMINAR DE imágenes DONDE rowid="{row[0]}";''')
[Link]()
st.experimental_rerun()
El ejemplo anterior es básicamente el mismo programa que en la sección anterior, con algunos widgets desactivados para
mostrar y cargar imágenes, así como las siguientes evaluaciones "si" adicionales para mostrar imágenes o no, dependiendo de si
ya se ha cargado una imagen:
si fila[2]:
img=fila[2]
[Link](fila[2])
archivo=st.file_uploader('Imagen', ['png', 'jpg', 'gif', 'bmp']) si archivo:
img=[Link]()
7.6 Cómo trabajar con fechas y horas - Aplicación de base de datos de calendario
A continuación se muestra una variación más del ejemplo anterior que demuestra cómo trabajar con fechas y horas en SQL, cómo formatear esos
valores utilizando la biblioteca datetime de Python y mostrarlos/interactuar con ellos utilizando los métodos de entrada/visualización de Streamlit:
[Link]()
str([Link]().time()
[Link](fila[1], '%Y-%m-%d').fecha()
[Link](fila[1], '%Y-%m-%d').fecha()
Una búsqueda rápida en Google proporcionará un sinfín de tutoriales sobre los métodos de fecha y hora de Python, si desea obtener más información.
8.1 Cómo pasar por alto diseños repetidos con [Link]() y usar [Link]()
La técnica [Link]() que se muestra en los ejemplos de bases de datos anteriores es útil en muchos casos, pero puede resultar complicada
cuando hay muchas filas para mostrar. Y en el caso de la visualización de imágenes, no es conveniente hacer que el usuario haga clic en un menú
desplegable para ver cada imagen individual.
A continuación, se muestra un ejemplo en el que se utiliza [Link]() para diseñar imágenes y widgets de formularios en la pantalla. Este tipo de diseño es
útil para cualquier tipo de visualización de inventario o para otros tipos de aplicaciones con diseños repetidos con desplazamiento, donde cada fila de
resultados tiene la misma configuración visual de "tarjeta". Imagine, por ejemplo, cómo se muestran los resultados de Amazon y Ebay, no necesariamente en
cuadrículas similares a hojas de cálculo, sino con un diseño de diseño visual repetido utilizado para mostrar cada registro en un conjunto de resultados:
con=[Link]('[Link]')
cur=[Link]()
[Link]('CREAR TABLA SI NO EXISTE pics(id TEXTO, img BLOB, nota TEXTO)')
[Link]('Imágenes SQLite') si
[Link]('Agregar nueva imagen'):
[Link]('INSERTAR EN pics(id, img, nota) VALORES(?,?,?)', ('', '', '')) [Link]()
para la fila en [Link]('SELECT rowid, id, img, note FROM pics ORDER BY id'):
con [Link](f'ID-{fila[0]}', clear_on_submit=True):
imgcol, notecol = [Link]([3, 2])
id=notecol.text_input('id', fila[1])
nota=notecol.text_area('nota', fila[3]) si fila[2]:
img=fila[2]
[Link](fila[2])
archivo=imgcol.file_uploader('Imagen', ['png', 'jpg', 'gif', 'bmp']) si
archivo:
img=[Link]()
si notecol.form_submit_button('Guardar'):
[Link](
'ACTUALIZAR imágenes ESTABLECER id=?, img=?, nota=? DONDE
id=?;', (id, img, nota, str(row[1]))
)
[Link]()
st.experimental_rerun() notecol.form_submit_button("Eliminar"):
si [Link](f'''ELIMINAR DE fotos DONDE rowid="{row[0]}";''')
[Link]()
st.experimental_rerun()
La mayor parte del código anterior es idéntico al ejemplo de la sección anterior, con solo un poco de refactorización para usar diseños de
columnas. Observe en particular la línea:
Esto crea dos columnas de visualización llamadas 'imagecol' y 'notecol', con tamaños horizontales en una proporción de 3:2. Luego, en
lugar de usar st.(),.()se utiliza para colocar widgets en una columna determinada. Por ejemplo, la siguiente línea coloca un widget
st.text_input() en la columna 'notecol', mostrando inicialmente el valor row[1] seleccionado de la base de datos y asigna el valor ingresado
por el usuario a la variable 'id':
id=notecol.text_input('id', fila[1])'
Cada uno de los diseños repetidos del ejemplo anterior podría ser tan complicado como se desee. Simplemente incluya
cualquier diseño que cree en un bucle "for" y obtendrá un método simple y componible para ofrecer diseños repetidos con
desplazamiento en aplicaciones de todo tipo.
8.2 Diseños tradicionales de formularios únicos
Existen otros patrones de visualización y diseño que se utilizan comúnmente en diversas situaciones de aplicación. Uno de los patrones de diseño más
comunes es presentar un formulario único para visualizar o editar los detalles de las filas, con un widget de lista desplegable que se utiliza para seleccionar
una fila en particular de la base de datos.
En el código siguiente, encontrará las mismas consultas SQL utilizadas en los ejemplos anteriores, pero con un solo formulario completado con los
resultados de un solo registro seleccionado de la base de datos:
con=[Link]('[Link]')
cur=[Link]()
[Link]('CREAR TABLA SI NO EXISTE db(nombre TEXTO, letras TEXTO, nota TEXTO)')
Tenga en cuenta que el widget de cuadro de selección sugiere un brevelista de selección de autocompletar, siempre que un usuariocomienza a escribir un valor parcialEsto
es muy útil cuando la lista de elementos seleccionables en un menú desplegable es grande, de modo que los usuarios nunca necesitan desplazarse por una larga lista de
elementos para encontrar un valor en particular.
El resto del código anterior utiliza instrucciones SQL para crear, actualizar y eliminar registros de la base de datos de la misma manera que
los ejemplos anteriores. Se utilizan varias evaluaciones condicionales "if" para determinar si el contenido del formulario se debe utilizar
para crear un nuevo registro o para actualizar el registro que se muestra existente:
nombre_a_actualizar=[Link]('', nombres)
si nombre_a_actualizar!='':
createorupdate='actualizar'
Si el valor seleccionado en el menú desplegable es una cadena vacía, se crea un nuevo registro. De lo contrario, el registro que se muestra se
actualiza con los cambios introducidos por el usuario (este ejemplo utiliza las mismas instrucciones SQL textuales de los ejemplos anteriores):
si createorupdate=='crear':
[Link](
"'
INSERTAR EN db(nombre, letras, nota)
VALORES(?,?,?)
''', (nombre, str(letras), nota)
)
[Link]()
demás:
[Link](
"'
ACTUALIZAR base de datos
8.3 Uso de cuadrículas de marcos de datos para visualizar el contenido de la base de datos
Podemos crear una vista de cuadrícula compacta de todas las filas de la base de datos devueltas por una consulta SQL, utilizando un widget [Link](). [Link]()
está pensado para mostrar los marcos de datos de Pandas, que se pueden generar fácilmente a partir de las listas devueltas por las consultas de la base de datos:
con=[Link]('[Link]')
cur=[Link]()
[Link]('CREAR TABLA SI NO EXISTE db(nombre TEXTO, letras TEXTO, nota TEXTO)')
[Link]("Leer")
[Link] de datos(
[Link](
mis filas,
columnas=['rowid', 'nombre', 'letras', 'nota']), altura=800
)
Observe el uso de [Link]() para actualizar el diseño anterior. Explicaremos cómo funciona esto con más detalle en una sección
posterior titulada "Flujo del programa Streamlit".
El siguiente ejemplo combina el formulario anterior y las visualizaciones del marco de datos en un diseño de columnas una al lado de la otra:
con=[Link]('[Link]')
cur=[Link]()
[Link]('CREAR TABLA SI NO EXISTE db(nombre TEXTO, letras TEXTO, nota TEXTO)')
[Link]("Crear/Actualizar/Eliminar")
nombres=[str(fila[0]) para la fila en [Link](f"SELECT nombre FROM db;")]
[Link](0, '')
nombre_a_actualizar=[Link]('', nombres)
si nombre_a_actualizar!='':
createorupdate='actualizar'
fila_a_actualizar=[Link](
f'''SELECT * FROM db WHERE nombre="{nombre_a_actualizar}";'''
) .fetchall()[0]
nameval=fila_a_actualizar[0]
lettersval=ast.literal_eval(fila_a_actualizar[1])
noteval=fila_a_actualizar[2]
demás:
createorupdate='crear'
nombreval=''
letrasval=[]
notaval=''
con [Link]("Crear o actualizar una fila de datos", clear_on_submit=True):
nombre=st.text_input('Nombre', valor=nameval) letras=[Link]('Letras', ['A', 'B',
'C'], predeterminado=lettersval) nota=st.text_area('Notas', marcador de posición='Algún
texto', valor=noteval)
si st.form_submit_button("Enviar"):
si createorupdate=='crear':
[Link](
"'
INSERTAR EN db(nombre, letras, nota)
VALORES(?,?,?)
''', (nombre, str(letras), nota)
)
[Link]()
demás:
[Link](
"'
ACTUALIZAR base de datos
con col2:
[Link]("Leer")
si [Link]('Vuelva a marcar para actualizar la pantalla', valor=Verdadero):
misfilas=[
lista(fila) para fila en [Link](
"'
SELECCIONAR rowid, nombre, letras, nota
DE base de datos
9. Más ejemplos de aplicaciones sencillas para demostrar los conceptos básicos de Streamlit en la práctica
Esta sección del tutorial consta de una variedad de ejemplos de aplicaciones simples. Algunos son triviales, pero todos juntos
demuestran cómo componer bloques de construcción comunes necesarios para implementar funcionalidades utilizadas en muchos tipos
comunes de aplicaciones.
Verás que la mayoría de las aplicaciones de esta sección requieren solo unas pocas líneas de código Streamlit para implementar la entrada del
usuario y la salida mostrada. La mayor parte del código es Python genérico, que se utiliza para realizar cálculos, manipulaciones de listas,
evaluaciones condicionales, bucles, operaciones CRUD, etc.
Este ejemplo calcula la cantidad de días entre dos fechas ingresadas por el usuario. Utiliza dos widgets st.date_input() y
muestra los resultados calculados con [Link]():
inicio=st.date_input('Fecha de inicio')
fin=st.date_input('Fecha de finalización')
si inicio y fin: [Link](fin-
inicio)
9.2 Visor de cámara web en vivo
Esta aplicación permite al usuario ver imágenes en vivo de varias cámaras en línea. Los únicos widgets necesarios son
[Link]() y [Link]():
cámara=[Link](
'Elige una cámara',
[
'',
'pitriverbridge/[Link]',
'johnsongrade/[Link]', 'perez/
[Link]',
'mthebron/[Link]',
'eurekaway/[Link]',
'sr70us395/[Link]',
'bogard/[Link]',
'eastriverside/[Link]',
]
)
si leva:
[Link]('[Link] + leva)
9.3 Lanzamiento de moneda
Esta aplicación utiliza el método st.experimental_rerun() para recargar la página cada vez que se hace clic en el botón:
[Link](1)
monedas = ['[Link] '[Link] moneda =
[Link](monedas)
[Link](moneda)
si [Link]('Voltear'):
st.experimental_rerun()
9,4 Número de palabras
Este ejemplo simplemente divide el texto ingresado en un widget st.text_area() y muestra un recuento de los valores en esa lista,
utilizando el widget [Link]():
palabras = [Link]()
[Link](f'Número de palabras en su texto:\n\n{len(words)}')
pig_latin += palabra
[Link](pig_latin.strip(' '))
9.6 Calculadora
Aquí hay una calculadora gráfica de juguete creada con widgets [Link](). Su único propósito es demostrar un poco más sobre el
diseño visual y el uso de columnas, así como el flujo del programa y el uso de st.session_state() para almacenar valores de variables:
Con esta aplicación, puedes ver el widget [Link](), que se utiliza aquí como algo similar a un [Link](), pero que guarda su estado
seleccionado en cada nueva ejecución (Verdadero, siempre que la casilla de verificación esté marcada). Este ejemplo también demuestra cómo
generar dinámicamenteun número variable de widgets de entrada de formulario, utilizando un bucle 'for', basado en los valores numéricos
necesarios para mostrar un madlib determinado:
Aquí hay un editor simple que permite al usuario ingresar texto con etiquetas markdown en un widget st.text_area() y
muestra el resultado visual usando un widget [Link]():
Esta es una aplicación de sala de chat básica y trivial. Los usuarios escriben su nombre y un mensaje, y esa información se publica para que otros
usuarios que utilicen la aplicación la lean y respondan. También se agrega una marca de tiempo a cada publicación.
Tenga en cuenta que en este ejemplo, las publicaciones de mensajes se escriben en un solo archivo, por lo que si algún usuario intentara escribir en
el archivo al mismo tiempo, existe la posibilidad de que el archivo se dañe. Por lo tanto, este ejemplo solo tiene como objetivo demostrar algunos
patrones de interfaz de Streamlit simples, no para uso en producción. Los dos ejemplos de tutoriales siguientes se basarán en el diseño básico aquí,
pero guardarán los mensajes en una base de datos, de modo que sea más adecuado para el uso en producción.
Observe el argumento 'label_visibility' utilizado en el método st.text_area(), que oculta la etiqueta predeterminada sobre el widget de
texto. Además de eso, algunos métodos [Link](), st.text_input(), [Link](), st.form_submit_button() y st.experimental_rerun() son
todo el código Streamlit necesario para que esta aplicación funcione:
columna1, col2=[Link]([2,3])
con columna2:
con col1:
con [Link]('Nuevo mensaje', clear_on_submit=True):
nombre=st.text_input('Nombre')
mensaje=st.text_area('Mensaje') marca
de tiempo=[Link]()
si st.form_submit_button('Agregar mensaje'):
newmsg=f'--- {nombre} {marca de tiempo}\n\n{mensaje}\n\n{msg}' con
open('[Link]', 'w') como archivo:
[Link](nuevomsg)
st.experimental_rerun()
9.10 Sala de chat (con datos de mensajes guardados en la base de datos SQLite)
Este ejemplo se basa en la estructura básica del ejemplo de chat anterior, pero guarda los datos en un solo campo en una tabla de base
de datos, de modo que se adapta mejor al uso en producción. Para entornos de producción reales, las aplicaciones que se basan en estos
modelos simples se migran mejor de SQLite a cualquier sistema de base de datos multiusuario, como PostgreSQL, MySQL, MSSQL, etc.
La mayoría de los comandos SQL en esta versión de la aplicación de chat deberían resultar familiares a partir de los ejemplos anteriores.
Observe el final comentado de la primera línea. Simplemente elimine el comentario de esa parte de la línea y ejecute la aplicación nuevamente para eliminar
por completo la base de datos y comenzar de nuevo (esto hará que todos los mensajes guardados se borren de forma permanente):
columna1, col2=[Link]([2,3])
con columna2:
Este ejemplo se basa más en los dos ejemplos anteriores, para ampliar el ejemplo de chat de modo que los usuarios puedan
comunicarse dentro de múltiples hilos de chat, todos en la misma interfaz (muy similar a un foro web simple):
# st.set_page_config(layout="ancho", page_title="Foro")
Este es el prototipo más pequeño posible de una aplicación de caja registradora para comercio minorista. Esta primera versión no
guarda ningún recibo. Es solo un diseño de pantalla simple que muestra los artículos ingresados para la compra y calcula los
subtotales, los impuestos y las ventas totales.
Tenga en cuenta que esta aplicación y todos los demás ejemplos del texto están destinados únicamente a demostrar patrones de código [Link] apto
para uso en producción:
timestamp=[Link]() st.session_state.[Link]({'item':
artículo, 'price': precio}) [Link]('---')
itemcol, pricecol=[Link]([4,1])
subtotal=0
para itm en st.session_state.purchased:
[Link](itm['item'])
[Link](itm['precio'])
subtotal += (itm['precio'])
[Link]('---')
plccol, lblcol, numcol=[Link]([3,1,1])
[Link]('Subtotal')
[Link]('{:.2f}'.format(subtotal))
[Link]('Impuesto')
[Link]('{:.2f}'.format(subtotal* . 06))
[Link]('Total')
[Link]('{:.2f}'.format(subtotal * 1.06))
9.13 Caja registradora, segunda parte: guardar recibos y generar informes de ventas
Para agregar la capacidad de guardar los recibos generados por la aplicación de caja registradora, agregaremos algunos comandos SQL conocidos
que guardan y recuperan los artículos vendidos durante cada transacción de venta, junto con una marca de tiempo que marca cuándo se guardó
cada recibo. Guardaremos la lista de artículos vendidos en cada recibo y la marca de tiempo, ambos como cadenas en una tabla de base de datos
SQLite, como ha visto en ejemplos anteriores.
Para generar informes de ventas, utilizaremos ast.literal_eval() para deserializar la estructura de lista que contiene los artículos vendidos en cada recibo de
venta. Utilizaremos la biblioteca datetime para evaluar los rangos de fechas de inicio y finalización de cada informe y simplemente sumaremos todos los
artículos vendidos en cada recibo seleccionado para generar el cálculo del total de ventas:
con=[Link]('[Link]')
cur=[Link]()
[Link]('CREAR TABLA SI NO EXISTE ventas(artículos TEXTO, marca de tiempo TEXTO)') si
'comprado' no está en st.session_state:
st.session_state.comprado=[]
con [Link]('Agregar elemento', clear_on_submit=True):
itmcol, prccol, btncol=[Link]([6,2,1])
artículo=itmcol.text_input('Artículo', marcador de posición='artículo', visibilidad_de_etiqueta='colapsado')
precio=prccol.number_input('Precio', visibilidad_de_etiqueta='colapsado')
si btncol.form_submit_button('Agregar'):
timestamp=[Link]() st.session_state.[Link]({'item':
artículo, 'price': precio}) [Link]('---')
itemcol, pricecol=[Link]([4,1])
subtotal=0
para itm en st.session_state.purchased:
[Link](itm['item'])
[Link](itm['precio'])
subtotal += (itm['precio'])
[Link]('---')
plccol, lblcol, numcol=[Link]([3,1,1])
[Link]('Subtotal')
[Link]('{:.2f}'.format(subtotal))
[Link]('Impuesto')
[Link]('{:.2f}'.format(subtotal* . 06))
[Link]('Total')
[Link]('{:.2f}'.format(subtotal si * 1.06))
[Link]('Guardar'):
si st.session_state.purchased==[]:
[Link]('**No hay nada que ahorrar en este recibo**')
else:
[Link]('INSERTAR EN ventas(artículos, marca de tiempo) VALORES(?,?)', (
str(st.session_state.purchase), str([Link]())
))
[Link]()
st.session_state.purchased=[]
[Link]('**RECIBO GUARDADO**') con
[Link]('Informe', clear_on_submit=True):
fecha1=st.date_input('Fecha de inicio')
fecha2=st.date_input('Fecha de finalización')
si st.form_submit_button('Generar informe de ventas'):
ventas_total = 0
para la fila en [Link]('''
SELECCIONAR rowid, artículos, marca de tiempo DE ORDEN DE VENTAS POR marca de
tiempo '''):
saledate=[Link](fila[2], '%Y-%m-%d %H:%M:%S.%f').date() si (
Esta aplicación ofrece un botón para que los usuarios registren su entrada y su turno de trabajo. Tenga en cuenta que esta aplicación y todos los
demás ejemplos del texto están destinados únicamente a demostrar patrones de código [Link] apto para uso en producción.:
[Link]()
[Link]('Reloj de turno')
nombres=[str(fila[0]) para la fila en [Link]('SELECT nombre FROM empleados')]
selected_name=[Link]('Seleccionar empleado', nombres)
si [Link]('Iniciar sesión'):
[Link](
'INSERTAR EN shifts(nombre,inicio de sesión) VALORES(?,?)',
(nombre_seleccionado,str([Link]()))
)
[Link]()
[Link]('Registrado En')
si [Link]('Cerrar sesión'):
[Link](
'INSERTAR EN shifts(nombre, cerrar sesión) VALORES(?,?)',
(nombre_seleccionado,str([Link]()))
)
[Link]()
[Link]('Registrado Afuera')
Si la fila[2] no es Ninguna:
logout=[Link](fila[2], de lo '%Y-%m-%d %H:%M:%S.%f')
contrario:
cerrar sesión=Ninguno
si fila[0]==nombre_seleccionado:
Si el cierre de sesión es Ninguno:
si inicio de sesión >= [Link](date1, [Link](0, 0)):
inicios de sesió[Link](inicio de sesión)
fecha de inicio = inicio de sesión
demás:
si cerrar sesión <= [Link](date2, [Link](0, 0)):
cierres de sesió[Link](cerrar sesión)
si total_horas == 0:
total_hours = (cierre de sesión - fecha de inicio) de lo
contrario:
total_hours += (cerrar sesión - fecha de
inicio) [Link](f'Horas totales: {total_hours}')
Esta aplicación permite a los usuarios descargar y cargar archivos desde y hacia cuentas de servidores FTP, utilizando la información de inicio de sesión guardada para
cada servidor. Los usuarios eligen entre una lista de servidores predefinidos en los que iniciar sesión y eligen los archivos que desean descargar. Los archivos
seleccionados desde un disco duro local también se pueden cargar en un servidor elegido:
servidores = {
'cuenta1' : ['[Link]', 'nombreusuario1', 'contraseña1', '/micarpeta'], 'cuenta2' :
['[Link]', 'nombreusuario2', 'contraseña2', '/public_html'], 'cuenta3' :
['[Link]', 'nombreusuario3', 'contraseña3', '/unacarpeta']
}
def subir_archivo_ftp(
Servidor FTP,
FTP_USUARIO,
Contraseña FTP,
CARPETA FTP,
NOMBRE_ARCHIVO_FTP,
archivo
):
ftp = [Link](FTP_HOST)
[Link](FTP_USER, Contraseña FTP
[Link](CARPETA_FTP)
con open(FTP_FILENAME, "wb") como archivo binario:
archivo_binario.write(archivo)
con open(FTP_FILENAME, 'rb') como miarchivo:
intentar:
Hasta ahora, hemos utilizado el cómodo editor en línea decó[Link] para explorar las características de Streamlit.
Para uso en producción, Streamlit se configura localmente en tan solo unos minutos en la mayoría de las computadoras modernas y se puede alojar
automáticamente mediante cualquier proveedor de servicios en la nube conocido, con o sin contenedores Docker (o puede alojar aplicaciones de forma
gratuita en el servicio en la nube de Streamlit).
Para comenzar a usar Streamlit en su PC local, necesitará una versión de 64 bits de Python de [Link] instalada, que se ejecute en un sistema
operativo de 64 bits. Cuando tenga Python instalado, ejecute 'pip install streamlit' en la línea de comandos de su sistema operativo (ejecute 'cmd' en
Windows o la Terminal en una Mac para acceder a la línea de comandos):
Una vez finalizado el proceso de instalación de pip, puedes comprobar que Streamlit se está ejecutando ejecutando 'streamlit hello' en el símbolo del
sistema. Streamlit debería abrir el navegador de forma predeterminada en [Link] donde iniciarás la ejecución de la aplicación de
demostración:
Para crear su primera aplicación Streamlit, puede utilizar cualquier editor de texto para crear un nuevo archivo de texto. El uso de un IDE como Microsoft
Visual Studio Code (gratis en [Link] puede proporcionar una función de autocompletado de código útil, además de
funciones de ejecución integradas y de gestión de proyectos útiles, pero incluso se puede utilizar el Bloc de notas para comenzar a editar aplicaciones
Streamlit. Comience guardando el siguiente código en un nuevo archivo llamado '[Link]':
En la línea de comandos, navegue hasta la carpeta donde guardó [Link]. Por ejemplo, si guardó [Link] en
la carpeta Documentos, escriba "CD documents" (si nunca usó el comando "CD" en la consola de su computadora,
puede encontrar muchos tutoriales con una búsqueda rápida en Google):
Puede escribir "dir" en la línea de comandos para mostrar una lista de los archivos en la carpeta actual, para asegurarse de que se
encuentra en la carpeta correcta. Ahora escriba "streamlit run [Link]" y su navegador se abrirá, mostrando la aplicación web
creada con el código anterior. Haga clic en el botón "Say Hello" y la aplicación lo saludará con el mensaje "¡Hola mundo!".
De vuelta en la ventana de la consola, verás que se proporcionan 2 direcciones para la aplicación. La primera dirección es "http://
localhost:8501", que es la dirección que puedes usar para ver la aplicación en la máquina donde se ejecuta Streamlit. La segunda dirección
contiene la dirección IP de la computadora en la que se ejecuta la aplicación Streamlit. Puedes escribir esa URL en la barra de direcciones
de cualquier navegador moderno en cualquier computadora o teléfono móvil/tableta conectado a tu red WIFI de área local, y verás que la
aplicación se ejecuta en ese dispositivo. Streamlit ajusta automáticamente los diseños de manera responsiva, de modo que se muestren
correctamente en máquinas móviles y de escritorio sin ningún cambio de código. Si tienes un dispositivo móvil u otra computadora
conectada a tu red WIFI, prueba tu aplicación. Cuando hayas terminado, puedes cerrar el servidor de aplicaciones Streamlit enfocando la
ventana de la línea de comandos y presionando las teclas CTRL + C en tu teclado.
A continuación, intente ejecutar cualquiera de los ejemplos de base de datos CRUD o un ejemplo de aplicación API de la sección anterior del tutorial. Simplemente escriba
"streamlit run" para ejecutar el código Streamlit, utilizando cualquier nombre de archivo que cree.
Streamlit se puede utilizar de esta manera, ejecutándose en una red de área local, para usuarios que prefieren ejecutar aplicaciones internas con archivos
confidenciales almacenados únicamente en máquinas locales. Ejecutar una instalación local también proporciona una configuración sencilla para el ciclo de
desarrollo, antes de publicar las aplicaciones en línea.
Cabe señalar que siempre que se modifica el archivo fuente de una aplicación Streamlit, la aplicación detectará el cambio en el código fuente y
preguntará al usuario si la aplicación debe volver a ejecutarse con el nuevo código. Esto hace que los ciclos de depuración y creación sean mucho
más rápidos, sin necesidad de herramientas externas además de Streamlit. Simplemente edite el código Streamlit, mantenga la aplicación
ejecutándose en un navegador, seleccione "siempre volver a ejecutar" en la aplicación y la aplicación en ejecución se actualizará automáticamente
cada vez que guarde los cambios en el código:
Hay varias formas de crear aplicaciones Streamlit con múltiples pantallas de información.
Cualquier widget Streamlit se puede colocar en un diseño de barra lateral utilizando la sintaxis: [Link].(). Esto resulta útil para crear
fácilmente múltiples diseños de pantalla con un único script simple:
si menú=='Página 2':
[Link]('Página 2')
[Link]({'foo':'bar','baz':'boz','stuff':['menú de cosas=='Página 1','cosas 2']})
si 3':
[Link]('Página 3')
11.2 Aplicaciones multipágina reales a partir de varios scripts
Para crear sitios reales de varias páginas compuestos por varios scripts, consulte:
[Link]
[Link]
12. Uso de FastAPI para servir datos manipulados por aplicaciones Streamlit
Las aplicaciones web modernas suelen comunicarse a través de llamadas a la API HTTP (Rest). Puedes usar una biblioteca como FastAPI para leer y escribir
datos en la misma base de datos a la que se conectan tus aplicaciones Streamlit. Esta funcionalidad permite que las aplicaciones creadas en cualquier lenguaje
de programación interactúen con tus aplicaciones Streamlit.
A continuación, se muestra un ejemplo sencillo que demuestra cómo utilizar FastAPI para proporcionar datos creados por el ejemplo de
base de datos Streamlit en la sección anterior del tutorial. Simplemente colóquelo en la misma carpeta que el código Streamlit:
importar sqlite3
con=[Link]('[Link]')
cur=[Link]()
importar uvicornio
desde fastapi importar FastAPI
app = FastAPI()
@[Link]("/{col}")
definición asíncrona get_col(col: str):
devuelve [fila por fila en [Link](f"SELECT {col} FROM db;")]
si __nombre__ == '__principal__':
[Link](aplicación, host='[Link]', puerto=8000)
Vaya a [Link] en su navegador y verá todas las filas de la base de datos, devueltas por la API en formato json. Vaya a
[Link] , [Link] o [Link] y verá las columnas seleccionadas de la base de
datos devueltas. El json generado por este código FastAPI puede ser consumido por cualquier marco web, para permitir que las
aplicaciones escritas en cualquier plataforma interoperar y compartir datos fácilmente.
El siguiente ejemplo incorpora tanto el código Streamlit como el código FastAPI en un único script y permite al usuario ejecutar el servidor
FastAPI directamente desde la interfaz Streamlit (actualmente configurada para el sistema operativo Windows). Se trata de una solución
verdaderamente completa, con interfaz de usuario, base de datos e interfaz API en menos de 50 líneas de código:
para la fila en [Link]('SELECT rowid, nombre, letras, nota FROM db ORDER BY nombre'):
con [Link](fila[1]):
con [Link](f'ID-{fila[0]}', borrar_al_enviar=Verdadero):
nombre=st.text_input('Nombre', fila[1])
letras=[Link]('letras', ['A', 'B', 'C'], ast.literal_eval(row[2])) nota=st.text_area('Nota',
fila[3])
si st.form_submit_button('Guardar'):
[Link](
'ACTUALIZAR db ESTABLECER nombre=?, letras=?, nota=? DONDE
nombre=?;', (nombre, str(letras), nota, str(fila[1]))
)
[Link]()
st.experimental_rerun() st.form_submit_button("Eliminar"):
si [Link](f'ELIMINAR DE db DONDE rowid="{row[0]}";')
[Link]()
st.experimental_rerun()
apicode='''import sqlite3
con=[Link]('[Link]')
cur=[Link]()
importar uvicornio
desde fastapi importar FastAPI
app = FastAPI()
@[Link]("/{col}")
definición asíncrona get_col(col: str):
devuelve [fila por fila en [Link](f"SELECT {col} FROM db;")] si __name__
== '__main__':
[Link](aplicación, host='[Link]', puerto=8000)'''
si [Link]('Ejecutar API web'):
con open("[Link]", "w") como archivo: [Link](apicode) import os ;
[Link]('start cmd /K python [Link]') [Link](f"""[Ver API](http://
localhost:8000/*) Si la API no se inicia, ejecute 'python [Link]' en la consola de
su sistema operativo y navegue a localhost:8000/*""",
unsafe_allow_html=True)
St.set_page_config() debe ser el primer método Streamlit utilizado en una aplicación y solo se puede configurar una vez en cada aplicación. Tenga
en cuenta que st.set_page_config()No se ejecutará en el editor de código en vivoSe utiliza en este tutorial porque ese método ya está incluido en el
código del editor.
Para realizar otros ajustes de diseño en tu aplicación, puedes incluir estilos CSS en un widget [Link](), con el argumento 'unsafe_allow_html'
establecido en True. El siguiente CSS oculta el enlace predeterminado 'Made With Streamlit' (en la parte inferior de la página) y el menú de
hamburguesa (esquina superior derecha) en las aplicaciones, y elimina el espacio vacío predeterminado en la parte superior de las aplicaciones.
Esto puede ser útil al producir aplicaciones públicas:
[Link](
'''<estilo>
#MenúPrincipal{visibilidad: oculta;} pie de página{visibilidad: oculta;}
# raíz>div:nth-child(1)>div>div>div>div>sección>div{relleno-superior: .2rem;
</style>''', unsafe_allow_html=Verdadero
)
A continuación se muestra una versión más grande del ejemplo CRUD de formulario único anterior, donde el diseño más amplio es útil:
[Link](
'''<estilo>
#MenúPrincipal{visibilidad: oculta;} pie de página{visibilidad: oculta;}
# raíz>div:nth-child(1)>div>div>div>div>sección>div{relleno-superior: .2rem;
</style>''', unsafe_allow_html=Verdadero
)
con=[Link]('[Link]')
cur=[Link]()
[Link](
"'
CREAR TABLA SI NO EXISTE crud (
namecol TEXTO,
contraseñacol TEXTO,
edadcol TEXTO,
regalocol TEXTO,
colorcol TEXTO,
letra col TEXTO,
notascol TEXTO
)
''' # key_col ENTERO NO NULO CLAVE PRIMARIA,
)
st.título('CRUD Ejemplo')
columna1, col2=[Link]([2,3])
con columna1:
[Link]("Crear/Actualizar/Eliminar")
names=[
str(fila[0]) para fila en [Link](
f"SELECCIONAR nombrecol DE crud;"
)
]
[Link](0, '')
nombre_a_actualizar=[Link]('', nombres)
si nombre_a_actualizar!='':
createorupdate='actualizar'
fila_a_actualizar=[Link](
f'SELECT * FROM crud WHERE namecol="{nombre_a_actualizar}";'
) .fetchall()[0]
nameval=fila_a_actualizar[0] passval=fila_a_actualizar[1]
ageval=int(fila_a_actualizar[2]) giftval=fila_a_actualizar[3]
colorval=fila_a_actualizar[4]
lettersval=ast.literal_eval(fila_a_actualizar[5])
notesval=fila_a_actualizar[6]
demás:
createorupdate='crear'
nombreval=''
contraseña=''
edadval=30
regaloval=''
colorval=Ninguno
letrasval=[]
notasval=''
con [Link]("Crear o actualizar una fila de datos", clear_on_submit=True):
nombre=st.text_input('Nombre', valor=nameval)
contraseña=st.text_input('Contraseña', tipo='contraseña', valor=passval)
edad=st.number_input(
'Edad', valor mínimo=1, valor máximo=120, valor=ageval, paso=1
)
regalos=['rosas', 'joyas', 'cena', 'viaje', 'dinero'] si giftval!='':
chosengift=[Link](giftval) de lo
contrario:
regaloelegido=0
regalo=[Link]('Regalo', regalos, index=chosengift)
colores=['rojo', 'verde', 'azul', 'negro']
si colorval!=Ninguno:
chosencolor=colores.índice(colorval) de lo
contrario:
color elegido=0
color=[Link]('Color', colores, índice=colorelegido)
letras=[Link](
'Letras', ['A', 'B', 'C', 'D'], predeterminado=lettersval
)
notas=st.text_area('Notas', placeholder='Algún texto', value=notesval) si
st.form_submit_button("Enviar"):
si createorupdate=='crear':
[Link](
"'
INSERTAR EN crud(
nombrecol,
contraseñacol,
edadcol,
regalocol,
colorcol,
cartacol,
notascol
)
VALORES(?,?,?,?,?,?,?)
''', (nombre, contraseña, edad, regalo, color, str(letras), notas)
)
[Link]() # [Link]() de lo
contrario:
[Link](
"'
ACTUALIZACIÓN crud
ESTABLECER nombrecol = ? ,
contraseñacol = ? ,
edadcol = ? ,
regalocol = ? ,
colorcol = ? ,
letracol = ? ,
notascol = ?
DONDE nombrecol = ?;
''', (
nombre,
contraseña,
edad,
regalo,
color,
str(letras),
notas,
str(nombreval)
)
)
[Link]() # [Link]()
st.experimental_rerun()
si st.form_submit_button("Eliminar"):
[Link](
f'''ELIMINAR DE crud DONDE namecol="{nombre_a_actualizar}";'''
)
[Link]()
[Link](f"{name_to_update} ha sido eliminado")
con col2:
[Link]("Leer")
si [Link]('Vuelva a marcar para actualizar la pantalla', valor=Verdadero):
misfilas=[
lista(fila) para fila en [Link](
"'
SELECCIONAR
alborotador,
nombrecol,
contraseñacol,
edadcol,
regalocol,
colorcol,
cartacol,
notascol
DE porquería
La documentación de la API y el código de ejemplo para todos los widgets y funciones disponibles en Streamlit, así como tutoriales e información
sobre el alojamiento con la nube de Streamlit, están disponibles en:
[Link]
El blog es una excelente manera de mantenerse al día con las nuevas funciones (¡Streamlit está evolucionando rápidamente!):
[Link]
[Link]
La comunidad de Streamlit ha creado algunos componentes de terceros extremadamente potentes. El componente aggrid es una versión de
Streamlit del conocido grid de JavaScript, que ofrece muchas funciones que no están disponibles en el widget [Link]() nativo de
Streamlit:
[Link]
El componente WebRTC es útil si desea realizar cualquier tipo de procesamiento de video. Incluso existe una aplicación de videoconferencia con
todas las funciones creada con solo unas pocas líneas de código:
[Link]
El componente Autenticación de usuario es útil cuando desea proporcionar funciones de inicio de sesión con nombre de usuario y contraseña a una aplicación.
[Link]
A Nick le apasiona ayudar a otros dueños de empresas a mejorar sus condiciones operativas y sus resultados finales con tecnología. Para obtener
más información, consulte:
[Link]
Para contratar a Nick como tutor o si desea que se desarrolle un producto de software, llame o envíe un mensaje de texto al 215-630-6759 o envíe un
mensaje a nick@[Link]