Web

Sed, el editor de secuencias, y un poco de expresiones regulares. Sys Admin y DevOps.

El comando SED en UNIX significa editor de flujo y puede realizar muchas funciones en el archivo, como buscar, encontrar y reemplazar, insertar o eliminar. Aunque el uso más común del comando SED en UNIX es para sustitución o para buscar y reemplazar. Al usar SED, puede editar archivos incluso sin abrirlos, que es una forma mucho más rápida de encontrar y reemplazar algo en el archivo, que primero abrir ese archivo en VI Editor y luego cambiarlo.

  • SED es un potente editor de secuencias de texto. Puede hacer inserción, eliminación, búsqueda y reemplazo (sustitución).
  • El comando SED en Unix admite la expresión regular, lo que le permite realizar coincidencias de patrones complejos.

Sintaxis

OPCIONES sed... [GUIÓN] [ARCHIVO DE ENTRADA...] 

Ejemplo:
considere el siguiente archivo de texto como una entrada.

$cat > file.txt
Unix es un gran sistema operativo. Unix es de código abierto. Unix es un sistema operativo libre.
aprender sistema operativo.
unix linux cuál eliges.
unix es fácil de aprender.unix es un sistema operativo multiusuario.Aprender unix .unix es un poderoso.

Reemplazar o sustituir una cadena: el comando Sed se usa principalmente para reemplazar el texto en un archivo. El siguiente comando sed simple reemplaza la palabra «unix» con «linux» en el archivo.

$sed 's/unix/linux/' file.txt
linux es un gran sistema operativo. Unix es de código abierto. Unix es un sistema operativo libre.
aprender sistema operativo.
linux linux cuál eliges.
linux es fácil de aprender.unix es un sistema operativo multiusuario.Aprender unix .unix es poderoso.
Aquí la “s” especifica la operación de sustitución. Los “/” son delimitadores. El "unix" es el patrón de búsqueda y el "linux" es la cadena de reemplazo.

De forma predeterminada, el comando sed reemplaza la primera ocurrencia del patrón en cada línea y no reemplazará la segunda, tercera... ocurrencia en la línea.

Reemplazo de la enésima ocurrencia de un patrón en una línea: Use las banderas /1, /2, etc. para reemplazar la primera, segunda ocurrencia de un patrón en una línea. El siguiente comando reemplaza la segunda aparición de la palabra «unix» con «linux» en una línea.

$sed 's/unix/linux/2' file.txt
Unix es un gran sistema operativo. Linux es de código abierto. Unix es un sistema operativo libre.
aprender sistema operativo.
unix linux cuál eliges.
Unix es fácil de aprender. Linux es un sistema operativo multiusuario. Aprenda Unix. Unix es un poderoso.

Reemplazo de todas las ocurrencias del patrón en una línea: el indicador de sustitución /g (reemplazo global) especifica el comando sed para reemplazar todas las ocurrencias de la cadena en la línea.

$sed 's/unix/linux/g' file.txt
linux es un gran sistema operativo. Linux es de código abierto. linux es un sistema operativo libre.
aprender sistema operativo.
linux linux cuál eliges.
linux es fácil de aprender. linux es un sistema operativo multiusuario. Aprenda linux. linux es un poderoso.

Reemplazar desde la enésima aparición a todas las apariciones en una línea: use la combinación de /1, /2, etc. y /g para reemplazar todos los patrones desde la enésima aparición de un patrón en una línea. El siguiente comando sed reemplaza la tercera, cuarta, quinta… palabra «unix» con la palabra «linux» en una línea.

$sed 's/unix/linux/3g' file.txt
Unix es un gran sistema operativo. Unix es de código abierto. linux es un sistema operativo libre.
aprender sistema operativo.
unix linux cuál eliges.
unix es fácil de aprender.unix es un sistema operativo multiusuario.Aprender linux .linux es un poderoso.

Como vemos, el comando Sed es muy útil para realizar operaciones de búsqueda y reemplazo de patrones de texto.

Expresiones Regulares (RE)

Veamos ahora un ejemplo de cómo utilizar Espresiones Regulares con el comando Sed.

Colocar entre paréntesis el primer carácter de cada palabra: este ejemplo de sed imprime el primer carácter de cada palabra entre paréntesis.

$ echo "Bienvenido al mundo de Linux" | sed 's/\b\([a-zA-Z]\)/(\1)/g'

La expresión regular ‘s/\b([a-zA-Z])/(\1)/g’ se puede interpretar de la siguiente manera:

  • La letra ‘s’ al principio indica que se trata de una operación de reemplazo (substitución).
  • El primer conjunto de caracteres dentro de las barras inclinadas (‘/’) representa el patrón de búsqueda a ser reemplazado. En este caso, el patrón de búsqueda es ‘\b\([a-zA-Z]\)’, que busca un carácter de palabra que sea una letra mayúscula o mayúscula al inicio de una palabra.
  • El segundo conjunto de caracteres dentro de las barras inclinadas (‘/’) representa el texto de reemplazo. En este caso, el texto de reemplazo es ‘(\1)’, que reemplaza el patrón de búsqueda con la misma letra mayúscula que se encontró, pero esta vez entre paréntesis.
  • La letra ‘g’ al final indica que se debe realizar la operación de reemplazo en todas las instancias encontradas en el texto, no sólo en la primera.

Entonces, esta expresión regular busca todas las letras mayúsculas que comienzan una palabra y las reemplaza por la misma letra entre paréntesis.

Con el comando Sed puedes realizar un gran número de modificaciones y sustituciones de texto, incluso también se puede usar para eliminar líneas de un archivo en particular. 

Para que conozcas más sobre la sintaxis de este comando y su uso con expresiones regulares tanto básicas (BRE) como extendidas (ERE) te recomendamos que visites la documentación de GNU al respecto.

Base de datos de Pistas Musicales mas artistas en PostgreSQL. Normalización de datos, parte 2.

En este ejercicio leeremos una biblioteca de iTunes en valores separados por comas (CSV) y produciremos tablas correctamente normalizadas como se especifica a continuación.

iTunes

Haremos algunas cosas de manera diferente en esta tarea. No usaremos una tabla «en bruto» separada, solo usaremos declaraciones ALTER TABLE para eliminar columnas después de que no las necesitemos (es decir, las convertimos en claves foráneas).

Utilizaremos este CSV que contiene la información de las pistas musicales. No usaremos una tabla «en bruto» separada, solo usaremos declaraciones ALTER TABLE para eliminar columnas después de que no las necesitemos (es decir, las convertimos en claves foráneas).

Esta vez construiremos una relación de muchos a muchos usando una tabla de junction/through/join entre pistas y artistas.

El script para construir las tablas que vamos a utilizar:

CREATE TABLE album (
    id SERIAL,
    title VARCHAR(128) UNIQUE,
    PRIMARY KEY(id)
);

CREATE TABLE track (
    id SERIAL,
    title TEXT, 
    artist TEXT, 
    album TEXT, 
    album_id INTEGER REFERENCES album(id) ON DELETE CASCADE,
    count INTEGER, 
    rating INTEGER, 
    len INTEGER,
    PRIMARY KEY(id)
);

CREATE TABLE artist (
    id SERIAL,
    name VARCHAR(128) UNIQUE,
    PRIMARY KEY(id)
);

CREATE TABLE tracktoartist (
    id SERIAL,
    track VARCHAR(128),
    track_id INTEGER REFERENCES track(id) ON DELETE CASCADE,
    artist VARCHAR(128),
    artist_id INTEGER REFERENCES artist(id) ON DELETE CASCADE,
   

Luego procedemos a copiar los datos contenidos en el CSV a la tabla track (recuerda ingresar a la línea de comandos con la instrucción psql):

\copy track(title,artist,album,count,rating,len) FROM 'library.csv' WITH DELIMITER ',' CSV;

Seguidamente actualizamos las tablas album y artist con los datos únicos (SELECT DISTINCT) de los campos album y artists de la tabla track. De igual forma los campos track y artist de la tabla tracktoartist desde los campos title y artist de la tabla track.

INSERT INTO album (title) SELECT DISTINCT album FROM track;

INSERT INTO artist (name) SELECT DISTINCT artist FROM track;

UPDATE track SET album_id = (SELECT album.id FROM album WHERE album.title = track.album);

INSERT INTO tracktoartist (track, artist) SELECT DISTINCT title, artist FROM track; 

Una vez hecho esto actualizamos los campos track_id y artist_id de la tabla tracktoartist con los respectivos «id’s» de las tablas track y artist.

UPDATE tracktoartist SET track_id = (SELECT track.id FROM track WHERE track.title = tracktoartist.tracK);

UPDATE tracktoartist SET artist_id = (SELECT artist.id FROM artist WHERE artist.name = tracktoartist.artist);

De esta forma habremos normalizado esta información de Pistas Musicales creando las respectivas relaciones de modo que ahora podemos ejecutar una consulkat como la siguiente:

SELECT track.title, album.title, artist.name
FROM track
JOIN album ON track.album_id = album.id
JOIN tracktoartist ON track.id = tracktoartist.track_id
JOIN artist ON tracktoartist.artist_id = artist.id
LIMIT 3;

Obtendremos un resultado como el siguiente:

Para finalizar podemos eliminar los datos que nos sobran, las columnas album y artist de la tabla track y los campos track y artist de la tabla tracktoartist, a traves de la instrucción ALTER TABLEDROP COLUMN.

 

Unesco Heritage Sites dataset en PostgreSQL y normalización de datos.

En esta entrega leeremos algunos datos del Patrimonio de la Humanidad de la Unesco en formato de valores separados por comas (CSV), los cargaremos en una base de datos PostgreSQL mediante el comando COPY y crearemos tablas correctamente normalizadas.

Precolumbian Chiefdom settlements with stone spheres of the Diquís © Ko Hon Chiu Vincent

Acerca del conjunto de datos

Un sitio del Patrimonio Mundial es un hito o área protegida legalmente por una convención internacional administrada por la Organización de las Naciones Unidas para la Educación, la Ciencia y la Cultura (UNESCO). Los sitios del Patrimonio Mundial son designados por la UNESCO por tener importancia cultural, histórica, científica o de otro tipo. Se considera que los sitios contienen «patrimonio cultural y natural en todo el mundo considerado de valor excepcional para la humanidad».

Para ser seleccionado, un Sitio del Patrimonio Mundial debe ser un hito único que sea identificable geográfica e históricamente y que tenga un significado cultural o físico especial. Por ejemplo, los sitios del Patrimonio Mundial pueden ser ruinas antiguas o estructuras históricas, edificios, ciudades,[a] desiertos, bosques, islas, lagos, monumentos, montañas o áreas silvestres. Un Sitio del Patrimonio Mundial puede significar un logro notable de la humanidad y servir como evidencia de nuestra historia intelectual en el planeta, o puede ser un lugar de gran belleza natural.

El dataset puede descargarse en desde el siguiente link: Unesco Heritage Sites dataset. Los datos corresponden al año 2018. Sin embargo si desea contar con datos más actualizados puede descargarlos desde los siguientes sitios (dataset 2021 a la fecha de hoy):

Procedimiento

Una vez descargado el dataset procedemos a crear las tablas parea la carga de datos. Puedes nombrar la base de datos como gustes y los nombre de las tablas también puedes modificarlos, aunque esta nomenclatura permite una mejor comprensión de su contenido.

DROP TABLE unesco_raw;
CREATE TABLE unesco_raw (
  name TEXT,
  description TEXT,
  justification TEXT,
  year INTEGER,
  longitude FLOAT,
  latitude FLOAT,
  area_hectares FLOAT,
  category TEXT,
  category_id INTEGER,
  state TEXT,
  state_id INTEGER,
  region TEXT,
  region_id INTEGER,
  iso TEXT,
  iso_id INTEGER
);

Para cargar los datos CSV para esta asignación, use el siguiente comando COPY desde la lonea de comando de PpostgreSQL (psql) . Agregar HEADER hace que el cargador CSV omita la primera línea en el archivo CSV. El comando \copy debe ser una línea larga.

\copy unesco_raw(nombre,descripción,justificación,año,longitud,latitud,área_hectáreas,categoría,estado,región,iso) FROM 'whc-sites-2018-small.csv' WITH DELIMITER ',' CSV HEADER;

Revisamos los datos.

Consulta SQL en DBeaver

Ahora procedemos a normalizar los datos con la ayuda de tablas adicionales que podemos llamar «look up tables».

La normalización es el proceso de seguir una serie de reglas (formas normales), para asegurar que nuestras relaciones estén ordenadas y regularizadas con el fin de mejorar dichas relaciones. Están enfocadas en evitar la redundancia de datos e inconsistencias en el diseño de nuestras tablas.

Lo primero que determinamos es que existe redundancia de datos en campos como «categoría» donde encontramos «Sitio cultural», «Sitio natural » y «Sitio mixto». Estos datos los podemos trasladar a otra tabla y crear una relación con la tabla «unesco_raw» para eliminar esta réplica de datos.

Caso similar podemos apreciar en los campos «state», «region» e «iso».

Entonces procedemos a crear tablas para estos datos que contendrán los datos respectivos de «category», «state», «region» e «iso» de forma única (campos UNIQUE) con su respentido identificados (id SERIAL).

CREATE TABLE category (
  id SERIAL,
  name VARCHAR(128) UNIQUE,
  PRIMARY KEY(id)
);
CREATE TABLE state (
  id SERIAL,
  name VARCHAR(128) UNIQUE,
  PRIMARY KEY(id)
);
CREATE TABLE region (
  id SERIAL,
  name VARCHAR(128) UNIQUE,
  PRIMARY KEY(id)
);
CREATE TABLE iso (
  id SERIAL,
  name VARCHAR(128) UNIQUE,
  PRIMARY KEY(id)
);

Cargamos los datos de «unesco_raw» a las tablas que hemos creado, seleccionando los valores únicos (SELECT DISTINCT).

INSERT INTO category(name) SELECT DISTINCT category FROM 
unesco_raw;
INSERT INTO state(name) SELECT DISTINCT state FROM unesco_raw;
INSERT INTO region(name) SELECT DISTINCT region FROM 
 unesco_raw;
INSERT INTO iso(name) SELECT DISTINCT iso FROM unesco_raw;

Ahora actualizamos la tabla «unesco_raw» con los datos de las tablas que hemos creado, agregarndo la categoría de sitio por su identificador (id) para crear la relación. En este caso utilizaremos una consulta compuesta para obtener primero el identificador de categoría de la tabla «category» para luego actualizar el campo «category_id» en «unesco_raw».

Igual procedemos con los datos de las tablas «state», «regiosn» e «iso».

UPDATE unesco_raw SET category_id = (
  SELECT category.id FROM category WHERE category.name = unesco_raw.category);
UPDATE unesco_raw SET state_id = ( 
  SELECT state.id FROM state WHERE state.name = unesco_raw.state );
UPDATE unesco_raw SET region_id = (
    SELECT region.id FROM region WHERE region.name = unesco_raw.region);
UPDATE unesco_raw SET iso_id = (
    SELECT iso.id FROM iso WHERE iso.name = unesco_raw.iso);

De esta forma ya contamos con los identificadores para las categoría, los estados, las regiones y las nomenclaturas ISO.

Consulta SQL en DBeaver

Para poder descartar la información redundante procedemos a crear una tabla final, definitiva que llamaremos simplemente «unesco» de la siguiente forma:

CREATE TABLE unesco (
    name TEXT,
    description TEXT,
    justification TEXT,
    year INTEGER,
    longitude FLOAT,
    latitude FLOAT,
    area_hectares FLOAT,
    category_id INTEGER,
    state_id INTEGER,
    region_id INTEGER,
    iso_id INTEGER
);

Copiamos toda la información exceptuando los datos de las columnas categoría, los estados, las regiones y las nomenclaturas ISO, e incluyendo los identificadores de las demás tablas creadas para establecer las respectivas relaciones.

INSERT INTO
  unesco(
    name,
    description,
    justification,
    year,
    longitude,
    latitude,
    area_hectares,
    category_id,
    state_id,
    region_id,
    iso_id
  ) select
  name,
  description,
  justification,
  year,
  longitude,
  latitude,
  area_hectares,
  category_id,
  state_id,
  region_id,
  iso_id from unesco_raw;

De esta forma obtendremos la información del dataset World Heritage List de una forma mejor estructurada, sin redundancia de datos, aprovechando las ventajas que nos ofrece una base de datos relacional como PostgreSQL.

Ahpora podemos eliminar la tabla «unesco_raw» usando DROP TABLE, y revisar la información obtenida con una consulta como la siguiente:

SELECT unesco.name, year, category.name, state.name, region.name, iso.name
  FROM unesco
  JOIN category ON unesco.category_id = category.id
  JOIN iso ON unesco.iso_id = iso.id
  JOIN state ON unesco.state_id = state.id
  JOIN region ON unesco.region_id = region.id
  ORDER BY state.name, unesco.name
  LIMIT 3;

El resultado sería el siguiente:

Consulta SQL en DBeaver

En una siguiente entrega utilizaremos estos datos almacenados en PostgreSQL para general un mapa interactivo con geolocalización de cada sitio de la Unesco.

World Heritage List, UNESCO

¿Qué sucedió con CentOS?

En diciembre de 2020, el desarrollador principal de CentOS anunció un cambio en la dirección del proyecto. En lugar de seguir centrándose en CentOS Linux, se centrarían en CentOS Stream, una distribución de nivel intermedio que se centra en proporcionar una vista previa de lo que estará en la próxima versión de Red Hat Enterprise Linux (RHEL).

Este cambio significó que CentOS 8, que estaba programado para recibir actualizaciones hasta 2029, tendría un ciclo de vida acortado hasta finales de 2021. Además, CentOS 7, que se esperaba que recibiera actualizaciones hasta 2024, también se vio afectado por este cambio.

Este cambio fue recibido con críticas por parte de muchos usuarios y empresas que dependían de CentOS Linux como una distribución estable y de largo plazo. Como resultado, algunos proyectos de la comunidad, como AlmaLinux y Rocky Linux, surgieron para llenar el vacío dejado por CentOS Linux.

Alma Linux

AlmaLinux es una distribución de Linux basada en RHEL (Red Hat Enterprise Linux) y creada como una alternativa de código abierto a CentOS Linux, que dejó de ser una distribución de Linux de largo plazo después de que Red Hat anunciara cambios en su modelo de negocio en diciembre de 2020.

AlmaLinux es mantenida por CloudLinux, una empresa que se especializa en sistemas operativos para servidores web y hosting. Se creó como una respuesta a la demanda de una alternativa estable y de largo plazo a CentOS Linux, para que las empresas y usuarios que dependían de ella pudieran continuar utilizando un sistema operativo basado en RHEL sin tener que pagar por una suscripción de Red Hat Enterprise Linux.

La primera versión estable de AlmaLinux se lanzó en marzo de 2021, y se espera que tenga un ciclo de vida similar al de CentOS Linux. Además, AlmaLinux ha anunciado que seguirá siendo compatible con las herramientas y aplicaciones de RHEL, lo que significa que los usuarios de RHEL pueden migrar fácilmente a AlmaLinux sin experimentar problemas de compatibilidad.

En resumen, AlmaLinux es una distribución de Linux estable y de largo plazo, basada en RHEL, que se creó para satisfacer la necesidad de una alternativa de código abierto a CentOS Linux después de que este proyecto dejara de ser una distribución de Linux de largo plazo.

Rocky Linux

Rocky Linux es una distribución de Linux de código abierto basada en RHEL (Red Hat Enterprise Linux) y creada como una alternativa a CentOS Linux después de que Red Hat anunciara cambios en su modelo de negocio en diciembre de 2020, lo que llevó a que CentOS Linux dejara de ser una distribución de Linux de largo plazo.

Rocky Linux fue fundada por Gregory Kurtzer, el fundador original de CentOS Linux, y fue desarrollada por la comunidad. Kurtzer inició el proyecto poco después de que Red Hat anunciara el cambio en la dirección de CentOS Linux.

Rocky Linux se ha comprometido a seguir siendo una distribución de Linux de largo plazo y estable, con un ciclo de vida similar al de CentOS Linux. La distribución tiene como objetivo ofrecer una alternativa de código abierto a Red Hat Enterprise Linux para los usuarios que deseen una distribución de Linux estable y de largo plazo, pero que no quieren pagar por una suscripción de RHEL.

La primera versión estable de Rocky Linux se lanzó en junio de 2021, y desde entonces ha habido varias actualizaciones. Además, Rocky Linux ha anunciado que seguirá siendo compatible con las herramientas y aplicaciones de RHEL, lo que significa que los usuarios de RHEL pueden migrar fácilmente a Rocky Linux sin experimentar problemas de compatibilidad.

En resumen, Rocky Linux es una distribución de Linux de código abierto estable y de largo plazo, basada en RHEL, que se creó para ofrecer una alternativa a CentOS Linux después de que Red Hat anunciara cambios en su modelo de negocio.

PostgreSQL, parte 3: Funciones y Procedimientos

Introducción

El lenguaje de procedimientos PL/pgSQL agrega muchos elementos de procedimientos, por ejemplo, estructuras de control, bucles y cálculos complejos, para ampliar el SQL estándar. Le permite desarrollar funciones complejas y procedimientos almacenados en PostgreSQL que pueden no ser posibles usando SQL simple.

El lenguaje de procedimiento PL/pgSQL es similar a Oracle PL/SQL . Las siguientes son algunas de las razones para aprender PL/pgSQL:

  • PL/pgSQL es fácil de aprender y fácil de usar.
  • PL/pgSQL viene con PostgreSQL por defecto. Las funciones definidas por el usuario y los procedimientos almacenados desarrollados en PL/pgSQL se pueden utilizar como cualquier función integrada y procedimiento almacenado.
  • PL/pgSQL hereda todos los tipos, funciones y operadores definidos por el usuario.
  • PL/pgSQL tiene muchas características que le permiten desarrollar funciones complejas y procedimientos almacenados.
  • PL/pgSQL se puede definir para que el servidor de base de datos de PostgreSQL confíe en él.

Las funciones creadas con PL/pgSQL se pueden usar en cualquier lugar donde se puedan usar las funciones integradas. Por ejemplo, es posible crear funciones de cálculo condicional complejas y luego usarlas para definir operadores o usarlas en expresiones de índice.

En PostgreSQL 9.0 y versiones posteriores, PL/pgSQL está instalado de forma predeterminada. Sin embargo, sigue siendo un módulo cargable, por lo que los administradores especialmente conscientes de la seguridad podrían optar por eliminarlo.

Cómo crear un campo updated_at que automaticamente registre la fecha cuando el registro se modifica con PostgreSQL?

Función para actualizar campo de fecha «updated_at»

Para crear un campo updated_at que se actualice automáticamente cuando se modifica un registro por ejemplo en una base de datos MySQL, puedes utilizar la función CURRENT_TIMESTAMP junto con el atributo ON UPDATE.

Aquí está el código para crear una tabla con un campo updated_at:

CREATE TABLE ejemplo (
   id INT PRIMARY KEY,
   nombre VARCHAR(50),
   descripcion VARCHAR(255),
   updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

En este ejemplo, el campo updated_at se establece con un valor predeterminado de la fecha y hora actual utilizando la función CURRENT_TIMESTAMP, y también se agrega el atributo ON UPDATE CURRENT_TIMESTAMP, lo que significa que se actualizará automáticamente con la fecha y hora actual cada vez que se modifique el registro.

Sin embargo, para crear un campo updated_at que se actualice automáticamente cuando se modifica un registro en PostgreSQL, se debe utilizar una función llamada trigger.

Aquí está el código para crear una tabla con un campo updated_at:

CREATE TABLE ejemplo (
   id SERIAL PRIMARY KEY,
   nombre VARCHAR(50),
   descripcion VARCHAR(255),
   updated_at TIMESTAMP
);

En este ejemplo, el campo updated_at se deja sin valor predeterminado ya que será actualizado automáticamente a través de la función trigger.

A continuación, puedes crear una función trigger que se active cada vez que se modifique un registro en la tabla ejemplo, y actualizará automáticamente el valor del campo updated_at con la fecha y hora actual.

CREATE OR REPLACE FUNCTION actualizar_updated_at()
RETURNS TRIGGER AS $$
BEGIN
   NEW.updated_at = NOW();
   RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Esta función trigger utiliza la función NOW() para obtener la fecha y hora actuales y actualizar el campo updated_at del registro modificado.

Por último, puedes crear el trigger que se activará cada vez que se realice una operación UPDATE en la tabla ejemplo, y ejecutará la función trigger actualizar_updated_at().

CREATE TRIGGER trigger_actualizar_updated_at
BEFORE UPDATE ON ejemplo
FOR EACH ROW
EXECUTE FUNCTION actualizar_updated_at();

Este trigger se activará antes de que se actualice cualquier registro en la tabla ejemplo, y ejecutará la función trigger actualizar_updated_at(), que actualizará el campo updated_at con la fecha y hora actuales.

Con estos pasos, el campo updated_at se actualizará automáticamente cada vez que se modifique un registro en la tabla ejemplo. Puedes ajustar los nombres de la tabla y los campos para que se adapten a tus necesidades específicas.

Artículos previos:

PostgreSQL conn, parte 2 técnicas avanzadas, en ChatGPT (OpenAI)

PostgreSQL conn en ChatGPT (OpenAI), Psycopg v2 o v3?

Headless Browsing: Screenshot de sitio web con Python y pyppeteer.

La automatización del navegador es usar Python para ejecutar pasos e integrar información de un navegador web en nuestro flujo de datos, como parte de los procesos DevOps y Build Automation con Python.

En este caso concreto realizaremos la apertura de la página web «https://learnsql.com/«, tomaremos una captura de pantalla y la guardaremos en el directorio de nuestro proyecto. Su nivel de dificultad es mínimo pero su integración a un flijo de datos requerirá configuraciones adicionales.

Como sabemos, para realizar esto por ejemplo en Windows se requiere presionar la tecla del logotipo de Windows + Mayús + S. El escritorio se oscurecerá mientras seleccionas un área para la captura de pantalla. Sin embargo, podemos utilizar un código que automatiza esta función en Python. Lo primero es instalar las librerías necesarias, pyppeteer y asyncio:

pip install pyppeteer
pip install asyncio

Luego escribimos un código abreviado para abrir la página web y tomar una captura de pantalla, al cual nombraremos «web_screenshot.py»:

import asyncio
from pyppeteer import launch

async def main():
    browser = await launch(options={'args': ['--no-sandbox']})
    page = await browser.newPage()
    await page.goto('https://learnsql.com/')
    await page.screenshot({'path': 'example.png'})
    await browser.close()

asyncio.get_event_loop().run_until_complete(main())

Nota : cuando ejecuta pyppeteer por primera vez, descarga la última versión de Chromium (~150 MB) si no se encuentra en su sistema. Si no prefiere este comportamiento, asegúrese de tener instalado un binario de Chrome adecuado. Una forma de hacer esto es ejecutar pyppeteer-installel comando antes de usar esta biblioteca.

[INFO] Starting Chromium download.

Una vez terminada la ejecución del script podrá encontrar el screenshot de la página web «learnsql.com» en el directorio de su proyecto que se ha guardado con el nombre de «example.png».

Proyect Files

Puede abrir la imagen para ver su contenido.

example.png

Este script puede configurarlo para una lista de URLs y obtener los screenshots de cada una, guardando las respectivas imágenes obtenidas en un directorio particular el cual podrá servidor como directorio «images», «assets», o «static» en su sitio web o aplicación.

Muchas proveedores de SaaS, y paneles de control web, han integrado en sus procesos el despliege de screenshot como parte de la información que ofrecen a sus osuarios, respecto de webs o aplicaciones que hospedan o administran.

El caso de Vercel, que automatiza la este proceso una vez que se ha hecho el deploy satisfactorio de la aplicación, y subsiguientes deploys.

Automatización en AirFlow

Para ejecutar automáticamente este script «web_screenshot.py» de Python con Apache Airflow, primero debe definir un DAG (Grafo Acíclico Dirigido) en un archivo Python que indique cómo y cuándo se debe ejecutar el archivo de Python. Luego, puede usar el programador de tareas incorporado de Airflow para planificar y ejecutar la DAG según lo programado.

Crea un DAG simple para ejecutar el código escrito en el archivo de Python llamado «web_screenshot.py» todos los días a las 3 a.m.

from datetime import datetime, timedelta
from airflow import DAG
from airflow.operators.python_operator import PythonOperator

# definir la función que se ejecutará
def mi_funcion():
    exec(open('/ruta/a/web_screenshot.py').read())

# definir el DAG
default_args = {
    'owner': 'yo',
    'depends_on_past': False,
    'start_date': datetime(2023, 3, 11, 3, 0),
    'retries': 1,
    'retry_delay': timedelta(minutes=5),
}

dag = DAG(
    'demo',
    default_args=default_args,
    description='Ejecución de web_screenshot.py todos los días a las 3 a.m.',
    schedule_interval=timedelta(days=1),
)

# definir el operador PythonOperator que ejecutará mi_funcion
mi_operador = PythonOperator(
    task_id='mi_tarea',
    python_callable=mi_funcion,
    dag=dag,
)

# definir la dependencia del operador
mi_operador

En este ejemplo, la función mi_funcion() simplemente ejecuta el archivo «web_screenshot.py». Luego, se define un DAG llamado «demo» con un operador PythonOperator llamado «mi_tarea» que ejecutará mi_funcion().

El DAG está programado para comenzar a las 3 a.m. el día en que se defina y se repetirá diariamente (schedule_interval=timedelta(days=1)). Si desea programar la ejecución en un intervalo de tiempo diferente, simplemente modifique el argumento start_date y schedule_interval según sea necesario.

Una vez que haya definido su DAG, puede guardar el archivo Python y agregarlo al directorio «dags» en su instalación de Airflow. Airflow automáticamente detectará y cargará el DAG en su sistema, y se ejecutará según lo programado. Puede monitorear el progreso del DAG en la interfaz web de Airflow.

Utilidades avanzadas

La automatización dentro de un pipeline o flujo de datos entre procesos es parte del fundamento del DevOps. Con AirFlow puedes crear DAGs que analizen y verifiquen la integridad de procesos, reporten fallas mediante envio de correo electrónico, realizar labores de mantenimiento o respaldo en Bases de Datos, e incluso ejecutar trabajos de entrenamiento y predicción en sistemas de Inteligencia Artificial sobre nuevos datasets.

Para conocer más sobre la automatización con AirFlow puedes visitar su centro de documentación.

Cloud Composer

Servicio totalmente gestionado de orquestación de flujos de trabajo integrado en Apache Airflow sobre Google Cloud.

Capacitación recomendada

Para ahondar más en el tema de la automatización DevOps con Python te recomiendo seguir el programa especializado Python Scripting for DevOps Specialization en Coursera.

Lea también Tutorial ¿Cómo configurar Airflow en un servidor Ubuntu? Parte 1

Tutorial ¿Cómo configurar Airflow en un servidor Ubuntu? Parte 1

AirFlow corriendo en localhost:8080

Para configurar Airflow en un servidor Ubuntu, sigue estos pasos:

Instala Python en el servidor Ubuntu si aún no lo has hecho. Puedes hacerlo ejecutando el siguiente comando:

Por lo general las distribuciones de Linux ya traen por defecto Python instalado, así que sin problema puedes saltar el paso anterior.

Instala Apache Airflow y sus dependencias usando pip. Puedes hacerlo ejecutando el siguiente comando:

Configura la base de datos de Airflow. Puedes hacerlo ejecutando los siguientes comandos incorporando tus credenciales:

airflow db init
airflow users create --username admin --password admin --firstname FIRST_NAME --lastname LAST_NAME --role Admin --email admin@example.com

El primer comando inicializa la base de datos de Airflow y el segundo comando crea un usuario administrador para Airflow. Toma en consideración que esta configuración se realiza por defecto sobre SQLite así que tendrás un entorno configurado para desarrollo no para ´producción, para lo cual deberás configurar otro motor de base de datos que utilice AirFlow.

Inicia el servidor web de Airflow ejecutando el siguiente comando:

airflow webserver -p 8080

Esto iniciará el servidor web de Airflow en el puerto 8080.

Inicia el scheduler de Airflow ejecutando el siguiente comando en otra ventana de terminal:

El scheduler es responsable de programar y ejecutar las tareas en Airflow.

Accede a la interfaz web de Airflow en tu navegador web navegando a http://<IP del servidor Ubuntu>:8080. Ingresa con las credenciales de usuario que creaste anteriormente.

Crea un archivo DAG (directed acyclic graph) para definir y programar tus tareas en Airflow. Puedes crear el archivo DAG en un directorio específico que hayas configurado en el archivo de configuración de Airflow.

A partir de aca te recomendamos leer y seguir la documentación oficial de AirFlow en How-to Guides

Verifica que tus tareas se ejecuten correctamente en Airflow y realiza cualquier ajuste necesario en el archivo DAG. Siguiendo estos pasos, deberías poder configurar Airflow en un servidor Ubuntu y comenzar a programar y ejecutar tareas. Ten en cuenta que es importante seguir las mejores prácticas de seguridad al configurar tu servidor y Airflow.

En el siguiente tutorial mostraremos como cambiar la base de datos default que utiliza Airflow de SQLite a Postgresql.

ETL pipeline Comprendiendo a Elon Musk por sus tweets Parte 1

Creación de un conjunto de datos de Twitter con Pandas en Python utilizando la biblioteca Snscrape. Persistencia de datos en MySQL. Este código busca tweets de Elon Musk desde el 1 de enero de 2021 hasta el 1 de enero de 2022 y guarda los resultados en un archivo CSV llamado «tweets.csv».

Instalar Snscrape y Pandas utilizando pip en tu entorno virtual de Python:

pip install snscrape pandas

Importar las bibliotecas necesarias:

import snscrape.modules.twitter as sntwitter import pandas as pd

Definir una consulta de búsqueda utilizando el formato de consulta de búsqueda de Twitter:

query = «from:elonmusk since:2021-01-01 until:2022-01-01»

image

Opcionalmente, puedes guardar el dataframe en un archivo CSV para su posterior uso:

Captura de pantalla dataset

Para limpiar los datos obtenidos del archivo «tweets.csv» creado anteriormente, podemos utilizar Pandas para cargar el archivo CSV en un dataframe y luego realizar diversas operaciones de limpieza y preprocesamiento de datos.

image

Este es solo un ejemplo básico de algunas de las operaciones de limpieza que se pueden realizar en los datos de los tweets. Dependiendo de los datos específicos que se estén utilizando, puede ser necesario realizar otras operaciones de limpieza y preprocesamiento de datos.

Para guardar el dataset de tweets limpios en un nuevo archivo CSV llamado «tweets_limpios.csv», podemos utilizar el método to_csv() del dataframe de Pandas.

Aquí te dejo un ejemplo de cómo podrías hacerlo:

image

Para guardar los datos del archivo «tweets_limpios.csv» en una base de datos MySQL, necesitaremos instalar la librería de Python mysql-connector-python. También necesitaremos crear una base de datos y una tabla en MySQL para almacenar los datos.

A continuación te dejo un ejemplo de cómo podrías hacerlo:

Primero, instala la librería mysql-connector-python utilizando el siguiente comando en la terminal o en el símbolo del sistema (si estás utilizando Windows):

pip install mysql-connector-python

A continuación, crea una base de datos y una tabla en MySQL utilizando los siguientes scripts SQL:

image

Este script creará una base de datos llamada tweets_db y una tabla llamada tweets con dos columnas: id (un número de identificación único para cada tweet) y tweet_text (el texto del tweet).

Ahora, puedes utilizar el siguiente script de Python para leer los datos del archivo «tweets_limpios.csv» y guardarlos en la base de datos:

image

Asegúrate de cambiar los valores de host, user y password en la función mysql.connector.connect() para que coincidan con tu configuración de MySQL.

Este script carga los datos del archivo CSV en un dataframe de Pandas y luego se conecta a la base de datos MySQL utilizando la librería mysql-connector-python. A continuación, se crea un cursor para ejecutar comandos SQL y se inserta cada tweet en la tabla de la base de datos utilizando un bucle for y la función cursor.execute(). Finalmente, se cierra la conexión con la base de datos y se imprime un mensaje para confirmar que los datos se han guardado correctamente.

Espero que esto te ayude a guardar los datos del archivo «tweets_limpios.csv» en una base de datos MySQL.

Código en GitHub >> https://github.com/DaveSV/ETL-pipeline-Elon-Musk-1

En la Parte 2 de este tutorial avanzaremos a programar, monitorear y administrar todo el flujo de trabajo de estos datos con Airflow.

¿ Qué es el Diseño Web 3.0?

Nos encanta el diseño web, y es nuestra pasión. El diseño web es parte de nuestra vida. Desde el año 2000, hemos observado lo que sucede en el mundo del diseño web todos los días. Estamos involucrados en el proceso de diseño web, y se han diseñado millones de páginas web con nuestra participación activa. Y ahora, nos gustaría compartir algunas de nuestras interesantes ideas con usted.

Ccompartimos el secreto sobre cómo crear los diseños web más modernos del mundo. Aprenderá las reglas básicas del diseño web moderno para crear sitios web, blogs y temas de clase mundial. Descubrirá cómo volverse único, cómo destacarse de la competencia y cómo atraer la atención de sus clientes.

Este artículo consta de varios capítulos:

En el Capítulo 1 , descubriremos cómo está cambiando el diseño web. Además, aprenderá sobre el nacimiento de la nueva generación de diseñadores web, que están diseñando páginas web en Diseño Web 3.0.

En el Capítulo 2 , hablaremos sobre los creadores de sitios web que se están quedando atrás de las tendencias y frenando la evolución del diseño web.

En el Capítulo 3 , aprenderá a crear diseños web modernos de una forma nueva, rápida y fácilmente.

Capítulo 1. El diseño web está cambiando

Lo primero de lo que hablaremos es del diseño web . Está cambiando rápidamente. Para comprender esto, debe revisar la evolución del diseño web: desde los primeros sitios hasta los sitios web de moda de hoy. Intentaremos predecir qué tipo de diseños web serán populares en un futuro próximo.

Hay tres etapas en la evolución del diseño web. En la imagen a continuación, hemos coloreado cada etapa y agregado años a la línea de tiempo.

diseño-historia.jpg

Evolución del diseño web

Primeros sitios web

Los primeros sitios web estaban basados ​​en texto. Y es difícil decir que tenían algún diseño web.

Transición al Diseño Web 1.0

Más tarde, se produjo la transición al Diseño Web 1.0. Aparecieron algunos elementos gráficos en los sitios web, que se volvieron más atractivos. Las páginas web tienen tablas. Luego, las tablas se transformaron en Layouts y Grids. Las tablas brindaban cierta flexibilidad, pero no eran compatibles con dispositivos móviles y no era necesario en ese momento.

Muchas personas crearon sus propios sistemas de gestión de contenido (CMS). Por lo tanto, los webmasters no tuvieron que editar los archivos HTML ni subirlos a los servidores. Pero era posible modificar el contenido en línea en tiempo real.

La evolución del diseño web y la difusión de los teléfonos móviles llevaron a nuevos cambios.

Transición al Diseño Web 2.0

La siguiente transición fue al Diseño Web 2.0. Las páginas web tenían cuadrículas y los diseñadores web podían organizar elementos con diseños.

Bootstrap aceleró la velocidad del desarrollo web. Simplificó el proceso y lo hizo más conveniente. Bootstrap admitió dispositivos móviles desde el principio con Grids.

Bootstrap’s Grid se estiró automáticamente al ancho completo de las pantallas. Redujo significativamente el tiempo que el desarrollador dedicaba a la codificación para admitir computadoras de escritorio, portátiles, tabletas y teléfonos.

receptivo.jpg

Sitio web moderno en varios dispositivos

WordPress, Joomla y Drupal se convirtieron en los sistemas de gestión de contenido más populares. Reemplazaron los sistemas autoescritos, que eran imperfectos y costosos de escribir y mantener y que también tenían una funcionalidad limitada. Gracias a WordPress y Joomla, cualquiera puede crear un blog o sitio web. Y hoy, más del 20 % de los sitios se construyen con esos sistemas.

WordPress y Joomla siempre admitieron temas y plantillas, lo que hizo posible modificar el diseño sin cambiar el contenido. Era posible crear temas manualmente o comprar temas ya hechos. Además, los webmasters podrían usar Theme Builder. Hay una gran cantidad de temas y plantillas disponibles.

En 2008, llegó Artisteer. Se convirtió en el generador de temas más popular en ese momento. Con Artisteer, cualquiera puede crear temas y plantillas de sitios web en minutos. Millones de sitios web usan temas diseñados en Artisteer.

¿Está muerto el diseño web?

Parecería que todos deberían estar contentos: diseñadores web, desarrolladores web y usuarios. Sin embargo, había un nuevo problema. Los diseñadores web comenzaron a hacer una pregunta: «¿Está muerto el diseño web?». Puede encontrar artículos que hacen la misma pregunta en todas las plataformas conocidas, como Medium, Mashable, SmashingMagazine, Quora y Reddit. Desde 2015, los diseñadores web se han hecho la misma pregunta.

En la imagen de abajo puedes ver los resultados de búsqueda de Google para esta frase.

Buscar en Google.png

Resultados de búsqueda en Google

¿Por qué está pasando esto? Bootstrap alcanzó el apogeo de su popularidad en 2015-2016. Puedes ver esto en el gráfico a continuación.

bootstrap-popularidad.jpg

Bootstrap en Tendencias de Google

La causa principal de este problema estaba en Bootstrap y análogos. Los diseños web de Bootstrap se parecían tanto entre sí que era como si estuvieran hechos con una plantilla. Muchos creadores de sitios web empeoran la situación al tener Bootstrap como el núcleo de sus sistemas. El diseño de un sitio web de Bootstrap comienza con una imagen general, y otras partes encajan en la estructura de dos, tres y cuatro celdas. Muchos temas y plantillas en Bootstrap impulsaron la distribución de este problema.

Ver en la imagen de abajo.

bootstrap-designs.jpg

Resultados de Pinterest para «diseño web bootstrap»

En 2015, Ben Hunt publicó el libro titulado “Web Design Is Dead”. La idea principal del libro es que la popularidad de los temas y plantillas de 50 dólares casi acabó con la demanda del trabajo del diseñador web. Un diseño web personalizado cuesta mucho más porque requiere tiempo, conocimientos y habilidades. Además del diseño, requiere codificación HTML y CSS personalizada.

¿Sigue siendo un problema hoy en día? Sí, lo es. Después de cuatro años, el problema sigue sin resolverse. En la imagen a continuación, puede ver las sugerencias de búsqueda de Google. La gente sigue haciéndose esta pregunta hoy.

google-2018.png

Consejos de búsqueda en Google

Los diseñadores web comenzaron a encontrar soluciones. No podían mantenerse alejados y ver cómo el diseño web , la pasión de sus vidas, se atascaba en el progreso. Siempre hay diseñadores que quieren hacer de la Web un lugar mejor. Steve Jobs dijo una vez: «Piensa diferente» sobre este tipo de personas. Estas personas siempre buscan nuevas ideas.

Diseño de impresión

El diseño web es muy joven. Tiene unas dos décadas. El diseño de impresión llegó mucho antes que el diseño web y tiene cientos de años de historia.

grafica-diseño-historia.jpg

Evolución del diseño de impresión. Copyright de onlinedesignteacher.com

Las herramientas de diseño de impresión siempre permitieron a los creativos colocar elementos libremente. Los diseñadores no estaban limitados en su creatividad. Y los editores siempre fueron libres en sus ideas. No tenían que pensar en HTML, CSS o dispositivos móviles.

La fórmula del diseño de impresión:

POSICIONAMIENTO LIBRE + CREATIVIDAD = DISEÑO DE IMPRESIÓN MODERNO

diseños-de-impresion.jpg

Diseño de impresión en Pinterest

Hoy en día, muchos editores han reducido significativamente las tiradas de impresión y se han puesto en línea. Las páginas impresas se han convertido en páginas web en la Web. Pero esas páginas web perdieron la creatividad y la libertad del diseño impreso. Los diseñadores no querían perder las ideas impresas que habían recopilado durante años. Comenzaron a diseñar con ideas impresas en línea.

El nacimiento del diseño web 3.0

A partir de 2016, comenzamos a notar que las ideas de Print Design aparecían regularmente en diseños de páginas web en Pinterest, Behance y Dribbble. Esos nuevos diseños web diferían con:

  1. Posicionamiento libre.
  2. Superposición de elementos.
  3. Rompiendo las limitaciones de las Grids tipo Bootstrap.

¡Significó el nacimiento del Diseño Web 3.0!

Reconocimiento de voz usando Transformers en Python.

Resumen: Reconocimiento automático de voz (ASR) usando el transformador wav2vec2 con la ayuda de la biblioteca de transformadores Huggingface en Python

El reconocimiento automático de voz (ASR) es la tecnología que nos permite convertir el habla humana en texto digital. Este tutorial se sumergirá en el modelo de vanguardia actual llamado Wav2vec2 utilizando la biblioteca de transformadores Huggingface en Python.

Wav2Vec2  es un modelo preentrenado que se entrenó solo en el audio del habla (autosupervisado) y luego siguió un ajuste fino en los datos del habla transcritos ( conjunto de datos LibriSpeech ). Ha superado a los modelos semisupervisados ​​anteriores.

Al igual que en el modelado de lenguaje enmascarado, Wav2Vec2 codifica el audio del habla a través de una red neuronal convolucional de múltiples capas y luego enmascara tramos de las representaciones del habla latente resultantes. Estas representaciones luego se alimentan a una red de transformadores para construir representaciones contextualizadas; Consulte el documento Wav2Vec2 para obtener más información.

Para comenzar, instalemos las bibliotecas requeridas:

$ pip3 install transformers==4.11.2 soundfile sentencepiece torchaudio pydub pyaudio

Usaremos torchaudio para cargar archivos de audio. Tenga en cuenta que necesita instalar PyAudio si va a usar el código en su entorno y PyDub si está en un entorno Colab. Los vamos a usar para grabar desde el micrófono en Python.

Empezando

Importemos nuestras bibliotecas:

from transformers import *
import torch
import soundfile as sf
# import librosa
import os
import torchaudio

A continuación, cargando el procesador y los pesos del modelo de wav2vec2:

# model_name = "facebook/wav2vec2-base-960h" # 360MB
model_name = "facebook/wav2vec2-large-960h-lv60-self" # 1.18GB

processor = Wav2Vec2Processor.from_pretrained(model_name)
model = Wav2Vec2ForCTC.from_pretrained(model_name)

Hay dos arquitecturas de modelo y pesos más utilizados para wav2vec. wav2vec2-base-960hes una arquitectura base con aproximadamente 360 ​​MB de tamaño, logró una tasa de error de palabra (WER) del 3,4 % en el conjunto de prueba limpio y se entrenó en 960 horas del conjunto de datos LibriSpeech en audio de voz muestreado de 16 kHz.

Por otro lado, wav2vec2-large-960h-lv60-selfes un modelo más grande con aproximadamente 1,18 GB de tamaño (probablemente no se ajuste a la memoria RAM de su computadora portátil) pero logró un 1,9 % de WER (cuanto más bajo, mejor) en el conjunto de prueba limpio. Entonces, este es mucho mejor para el reconocimiento, pero más pesado y toma más tiempo para la inferencia. Siéntase libre de elegir cuál se adapta mejor a usted.

Wav2Vec2 se entrenó usando la clasificación temporal conexionista (CTC) , por eso estamos usando la Wav2Vec2ForCTCclase para cargar el modelo.

A continuación, aquí hay algunas muestras de audio:

# audio_url = "https://github.com/x4nth055/pythoncode-tutorials/raw/master/machine-learning/speech-recognition/16-122828-0002.wav"
audio_url = "https://github.com/x4nth055/pythoncode-tutorials/raw/master/machine-learning/speech-recognition/30-4447-0004.wav"
# audio_url = "https://github.com/x4nth055/pythoncode-tutorials/raw/master/machine-learning/speech-recognition/7601-291468-0006.wav"

Preparación del archivo de audio

Siéntase libre de elegir cualquiera de los archivos de audio anteriores. A continuación, la celda carga el archivo de audio:

# load our wav file
speech, sr = torchaudio.load(audio_url)
speech = speech.squeeze()
# or using librosa
# speech, sr = librosa.load(audio_file, sr=16000)
sr, speech.shape

(16000, torch.Size([274000]))

La torchaudio.load()función carga el archivo de audio y devuelve el audio como un vector y la frecuencia de muestreo. También descarga automáticamente el archivo si es una URL. Si es una ruta en el disco, también lo cargará.Tenga en cuenta que también usamos el squeeze()método, es para eliminar las dimensiones con el tamaño de 1. es decir, convertir el tensor de (1, 274000)(274000,).

A continuación, debemos asegurarnos de que el archivo de audio de entrada al modelo tenga una frecuencia de muestreo de 16000 Hz porque wav2vec2 está entrenado para eso:

# resample from whatever the audio sampling rate to 16000
resampler = torchaudio.transforms.Resample(sr, 16000)
speech = resampler(speech)
speech.shape

torch.Size([274000])

Usamos Resamplede torchaudio.transforms , que nos ayuda a convertir el archivo de audio cargado sobre la marcha de una frecuencia de muestreo a otra.

Antes de hacer la inferencia, pasamos el vector de audio al procesador wav2vec2:

# tokenize our wav
input_values = processor(speech, return_tensors="pt", sampling_rate=16000)["input_values"]
input_values.shape

torch.Size([1, 274000])

CopiarEspecificamos el argumento sampling_ratey pasamos "pt"return_tensorspara obtener los tensores de PyTorch en los resultados.

Realización de inferencia

Ahora pasemos el vector a nuestro modelo:

# perform inference
logits = model(input_values)["logits"]
logits.shape

torch.Size([1, 856, 32])

Pasando los logits a torch.argmax()para obtener la predicción probable:

# use argmax to get the predicted IDs
predicted_ids = torch.argmax(logits, dim=-1)
predicted_ids.shape

torch.Size([1, 856, 32])

Al decodificarlos de nuevo a texto, también bajamos el texto, ya que está en mayúsculas:

# decode the IDs to text
transcription = processor.decode(predicted_ids[0])
transcription.lower()

and missus goddard three ladies almost always at the service of an invitation from hartfield and who were fetched and carried home so often that mister woodhouse thought it no hardship for either james or the horses had it taken place only once a year it would have been a grievance

Terminando el código

Ahora recopilemos todo nuestro código anterior en una sola función, que acepta la ruta de audio y devuelve la transcripción:

def get_transcription(audio_path):
  # load our wav file
  speech, sr = torchaudio.load(audio_path)
  speech = speech.squeeze()
  # or using librosa
  # speech, sr = librosa.load(audio_file, sr=16000)
  # resample from whatever the audio sampling rate to 16000
  resampler = torchaudio.transforms.Resample(sr, 16000)
  speech = resampler(speech)
  # tokenize our wav
  input_values = processor(speech, return_tensors="pt", sampling_rate=16000)["input_values"]
  # perform inference
  logits = model(input_values)["logits"]
  # use argmax to get the predicted IDs
  predicted_ids = torch.argmax(logits, dim=-1)
  # decode the IDs to text
  transcription = processor.decode(predicted_ids[0])
  return transcription.lower()

CopiarImpresionante, puede pasar cualquier ruta de archivo de voz de audio:

get_transcription("http://www0.cs.ucl.ac.uk/teaching/GZ05/samples/lathe.wav")

a late is a big tool grab every dish of sugar

Aplicándolo al idioma español

Este modelo funciona muy bien, pero con audios y modelos pre-entrenados en idioma inglés. Lo hemos adecuado a que funcione con audios en español, tanto de archivos como grabados en directo, utilizando en este caso modelos de Hugging Face entrenados en idioma español.

Más archivos de audio en este link.

Puedes acceder al link de Hugging Face y mirar los demas modelos filtrando por idioma.

Conclusión

Impresionante, ahora si quieres usar tu voz, he preparado un fragmento de código en los cuadernos para grabar con tu micrófono. Siéntase libre de elegir el entorno que está utilizando:

Como indiqué, tenga en cuenta que hay otros pesos wav2vec2 entrenados por otras personas en idiomas diferentes al inglés. Consulte la página de modelos y filtre en el idioma de su deseo para obtener el modelo deseado, por ejemplo los desarrollados por Open AI.