Ejercicio: Escritura de una aplicación de funciones en Azure Functions para analizar fotografías

Completado

En esta unidad, usará Azure Functions para escribir una aplicación que se desencadena cada vez que se carga una imagen en el contenedor photos de la cuenta de almacenamiento. La aplicación de funciones usará el modelo de Custom Vision que ha creado para determinar si la fotografía contiene un oso polar.

Creación de una aplicación de función en Azure

Puede escribir una aplicación de funciones en Azure Functions en Azure Portal, o bien hacerlo de forma externa mediante herramientas como Visual Studio. En este ejercicio, escribirá una aplicación de funciones en el portal. Usará JavaScript para escribirla y la ejecutará mediante el tiempo de ejecución Node.js de Azure Functions. La aplicación de funciones se desencadena cada vez que se carga una imagen al contenedor photos que ha creado en Blob Storage. Después, la aplicación de funciones pasa cada blob que se carga en Custom Vision para analizarlo en busca de osos polares.

  1. En el explorador, vuelva a Azure Portal. En Servicios de Azure, seleccione Crear un recurso. En el menú de recursos, seleccione Proceso y, luego, Aplicación de funciones.

    Screenshot that shows numbered elements in the Azure portal that you select to create a new function app resource.

    Creación de una aplicación de funciones en Azure

  2. En Crear aplicación de funciones, en la pestaña Conceptos básicos, escriba o seleccione los valores siguientes:

    • Suscripción: seleccione la suscripción que desea usar.
    • Grupo de recursos: seleccione polar-bear-rg.
    • Nombre de la aplicación de funciones: escriba un nombre que sea único en Azure para la nueva aplicación.
    • Publicar: deje Código seleccionado.
    • Pila en tiempo de ejecución: seleccione Node.js.
    • Región: seleccione Centro-sur de EE. UU.
    • Sistema operativo: seleccione el sistema.
    • Tipo de plan: seleccione Consumo (sin servidor).
    • Seleccione Siguiente: Hospedaje.

    Screenshot that shows the basic settings to select or enter for a new function app.

    Configuración de las opciones básicas de una nueva aplicación de funciones

  3. En la pestaña Hospedaje, seleccione la cuenta de almacenamiento que ha creado para cargar las fotografías de fauna. Después, seleccione Revisar y crear.

    Screenshot that shows the hosting tab settings for a new function app.

    Configuración de las opciones de hospedaje para una nueva aplicación de funciones

  4. Espere a que finalice la validación y, después, seleccione Crear.

  5. Espere a que se implemente la aplicación de funciones y después ábrala en Azure Portal. En el menú de recursos, en Funciones, seleccione Funciones y después Crear.

    Screenshot that highlights the elements to select to add a function in the Azure portal.

    Adición de una función

  6. En Agregar función:

    1. En Entorno de desarrollo, seleccione Develop in portal (Desarrollar en el portal).
    2. En Plantilla, seleccione Desencadenador de Azure Blob Storage.

    Screenshot that highlights the elements to select for a new function.

    Configuración de las opciones y elección de una plantilla para una función

    Nota:

    Si se le pide que instale la extensión Microsoft.Azure.WebJobs.Extensions.Storage, seleccione Instalar.

    Espere a que finalice la instalación y, después, seleccione Continuar.

    (Si no se le pide que instale la extensión, es posible que tenga que esperar uno o dos minutos antes de continuar con el paso siguiente).

  7. En Detalles de la plantilla:

    1. En Nueva función, escriba BlobTrigger.

    2. En Ruta de acceso, escriba photos/{nombre} para que la aplicación de funciones se desencadene cuando se carguen los blobs en el contenedor photos.

    3. En Conexión de cuenta de Storage, seleccione Nuevo.

      Nota:

      Copie y guarde el valor que se muestra en Conexión de cuenta de Storage. Usará el valor en un paso posterior.

    4. En Nueva conexión de cuenta de almacenamiento, seleccione la cuenta que ha creado antes y después Aceptar.

    Screenshot that shows settings to use to set up the template to create a blob-triggered function.

    Configuración de la plantilla para crear una función desencadenada por blobs

  8. Seleccione Agregar. La vista del portal cambia para mostrar la nueva aplicación.

  9. En la página de información general de la nueva función de desencadenador, en Desarrollador, seleccione Código y prueba. Se abre el archivo index.js para el desencadenador en el portal.

    Screenshot that highlights the portal elements to select to open the index dot J S file for the blob-triggered function.

    Apertura del archivo index.js para la función de desencadenador

  10. Copie el código siguiente y reemplace el código de la aplicación de funciones en Azure Portal por el siguiente:

    module.exports = function (context, myBlob) {
        var predictionUrl = process.env.PREDICTION_URL;
        var predictionKey = process.env.PREDICTION_KEY;
        var storageConnectionString = process.env.<CONNECTION_STRING_NAME>;
    
        var storage = require('azure-storage');
        var blobService = storage.createBlobService(storageConnectionString);
        var blobName = context.bindingData.name;
        var blobUri = context.bindingData.uri;
    
        // Read the blob's metadata
        blobService.getBlobMetadata('photos', blobName, (err, result, response) => {
            if (!err) {
                var latitude = result.metadata.latitude;
                var longitude = result.metadata.longitude;
                var id = result.metadata.id;
    
                // Generate a shared access signature for the Custom Vision service
                var now = new Date();
                var expiry = new Date(now).setMinutes(now.getMinutes() + 3);
    
                var policy = {
                    AccessPolicy: {
                        Permissions: storage.BlobUtilities.SharedAccessPermissions.READ,
                        Start: now,
                        Expiry: expiry
                    },
                };
    
                var sas = blobService.generateSharedAccessSignature('photos', blobName, policy);
    
                // Pass the blob URL to the Custom Vision service
                var request = require('request');
    
                var options = {
                    url: predictionUrl,
                    method: 'POST',
                    headers: {
                        'Prediction-Key': predictionKey
                    },
                    body: {
                        'Url': blobUri + '?' + sas
                    },
                    json: true
                };
    
                request(options, (err, result, body) => {
                    if (!err) {
                        var probability =  body.predictions.find(p => p.tagName.toLowerCase() === 'polar-bear').probability;
                        var isPolarBear = probability > 0.8; // 80% threshold
                         if (isPolarBear) {
                            context.log('POLAR BEAR detected by ' + id + ' at ' + latitude + ', ' + longitude);
                        }
                        else {
                            context.log('Other wildlife detected by ' + id + ' at ' + latitude + ', ' + longitude);
                        }
    
                        context.done();
                    }
                    else {
                        context.log(err);
                        context.done();
                    }
                });
            }
            else {
                context.log(err);
                context.done();
            }
        });
    };
    

    La aplicación de funciones modificada usa el módulo request de npm para llamar al servicio Custom Vision, y se pasa la dirección URL de la imagen que se va a analizar. Analiza los resultados JSON y recupera el valor que indica la probabilidad de que la imagen contenga un oso polar. Después, escribe los resultados en el registro de salida. El umbral para determinar si una imagen contiene un oso polar es 80 %:

    var isPolarBear = probability > 0.8; // 80% threshold
    

    Otro aspecto importante de este código es su uso de una firma de acceso compartido.

    El contenedor photos que ha creado es privado. Para acceder a los blobs almacenados ahí, debe tener acceso a la cuenta de almacenamiento o disponer de la clave de acceso de la cuenta de almacenamiento. Una firma de acceso compartido permite que otros usuarios y servicios accedan a blobs individuales, pero solo durante un intervalo de tiempo especificado y, opcionalmente, con acceso de solo lectura.

    El código que ha pegado en el portal usa el SDK de Azure Storage para Node.js (azure-storage) a fin de generar una firma de acceso compartido de solo lectura para el blob asociado a la dirección URL que se pasa a Custom Vision. El código anexa la firma de acceso compartido a la dirección URL del blob como una cadena de consulta. La firma de acceso compartido es válida durante 3 minutos y solo permite acceso de lectura. El código puede enviar blobs privados a Custom Vision para el análisis sin ponerlos en un contenedor público donde cualquiera los podría descargar.

  11. Reemplace <CONNECTION_STRING_NAME> en la línea 4 por la cadena de conexión de la cuenta de almacenamiento que ha guardado antes (por ejemplo, polarbearstorage_STORAGE). Esta cadena de conexión se ha agregado a la configuración de la aplicación cuando ha agregado la función BlobTrigger a la aplicación de funciones. Su nombre se deriva del de la cuenta de almacenamiento. Si es necesario, puede buscar la cadena de conexión de la cuenta de almacenamiento en la configuración de la aplicación de la aplicación de funciones.

    Después de agregar la cadena de conexión de la cuenta de almacenamiento, seleccione Guardar para terminar de realizar cambios en el archivo index.js. Cuando se guarda el archivo, el registro de salida de la función se abre en la parte inferior de la página.

  12. En Azure Portal, abra una consola.

    • En la página de información general de la aplicación de funciones, en el menú de recursos, seleccione Consola en Herramientas de desarrollo.

    Screenshot that shows how to open a console for a function app.

    Apertura de una consola de aplicación de funciones

  13. En la consola, ejecute los comandos siguientes para instalar el paquete request de npm y el SDK de Azure Storage para Node.js, de modo que la aplicación de funciones pueda usarlos.

    npm install request
    npm install azure-storage
    

    Nota:

    Ignore los mensajes de advertencia que aparezcan. Por motivos de simplicidad se usa una versión anterior de una biblioteca de JavaScript.

  14. Espere a que finalicen los comandos de instalación. Después, agregará dos opciones de configuración de la aplicación a la aplicación de funciones.

    1. En el menú de recursos, en Configuración, seleccione Configuración.
    2. En Configuración de la aplicación, seleccione Nueva configuración de la aplicación.
    3. En Agregar o editar la configuración de la aplicación, agregue una configuración denominada PREDICTION_URL. Establezca el valor en la dirección URL de predicción de Custom Vision que ha guardado en la unidad anterior. Deje la opción Configuración de ranura de implementación desactivada. Seleccione Aceptar.
    4. Repita el paso anterior para agregar una configuración denominada PREDICTION_KEY. Establezca el valor en la clave de predicción de Custom Vision que ha guardado en la unidad anterior. Deje desactivada la opción Configuración de ranura de implementación. Seleccione Aceptar.

    Screenshot that shows selections to make in the Azure portal for application settings for a function app.

    Configuración de las opciones para la aplicación de funciones

    Para finalizar, seleccione Guardar. Si se le solicita, seleccione Continuar para finalizar la acción de guardar.

    Nota:

    En lugar de codificar de forma rígida la clave de autenticación y la dirección URL de Custom Vision en el código de la aplicación de funciones, los valores se almacenan en la configuración de la aplicación. Los valores son más seguros cuando se guardan en la configuración de la aplicación.

  15. Para volver a la aplicación de funciones BlobTrigger, en el menú de recursos, en Funciones, seleccione Funciones y después BlobTrigger:

    Screenshot that shows selections to make in the Azure portal to view the blob trigger function app.

    Apertura de la aplicación de funciones BlobTrigger

  16. En el menú de recursos, en Desarrollador, seleccione Código y prueba. Debajo del código que se muestra, seleccione la flecha arriba Registros. Se abre el panel de salida del registro.

    Screenshot that shows how to open the output log for a function.

    Apertura del registro de salida de la función

    Mantenga abierto el panel Registros, ya que lo usará en un paso posterior.

  17. Para abrir el contenedor de Blob Storage photos, en el menú de recursos, en Almacenamiento de datos, seleccione Contenedores. En la lista de contenedores, seleccione el contenedor photos.

    Screenshot that highlights the items you select in the Azure portal to open the photos container.

    Apertura del contenedor photos de la cuenta de Blob Storage

  18. Después, cargue una imagen en el contenedor photos para probar la aplicación de funciones.

    1. En el panel del contenedor photos, seleccione Cargar.
    2. En Cargar blob, en Archivos, seleccione el icono de carpeta.
    3. En el Explorador de Windows, vaya a la carpeta photos del directorio del proyecto.
    4. Seleccione el archivo image_12.jpg y después Abrir.
    5. En Cargar blob, seleccione Cargar. Una vez que haya finalizado la carga, seleccione X para cerrar el panel.

    Screenshot that shows how to upload a photo to a container.

    Carga de una fotografía en el contenedor

    Este es el aspecto de image_12. jpg:

    Image 12 dot j p g, which shows a polar bear.

    La imagen 12 en Blob Storage

  19. En el explorador, vuelva al registro de la aplicación de funciones. Confirme que la aplicación de funciones se ha ejecutado y que Custom Vision indica que image_12.jpg contiene un oso polar.

    Screenshot that shows the output log details for uploading and analyzing image 12 dot j p g.

    Visualización de los detalles del registro de salida para cargar y analizar la imagen 12

En la salida del registro aparece el texto undefined at undefined, undefined porque la función ha intentado leer la latitud, la longitud y el id. de la cámara de los metadatos del blob e incluirlos en la salida. Esos valores de metadatos no existen porque ha cargado el blob manualmente. Esta condición cambiará cuando las cámaras virtuales carguen fotografías en Blob Storage.

Ejecución de la matriz de la cámara

Después, ejecute el grupo de cámaras simuladas que ha creado antes. Luego, comprobará la salida del registro de la aplicación de funciones para comprobar que las imágenes se cargan en Blob Storage y se analizan en busca de osos polares.

  1. Vuelva al directorio del proyecto en un símbolo del sistema o una ventana de terminal. Ejecute el código siguiente para ejecutar run.js:

    node run.js
    
  2. En Azure Portal, vuelva a la función BlobTrigger y observe el registro de salida durante un minuto o dos. Confirme que la función se desencadena y que llama a Custom Vision para determinar si cada fotografía cargada en el contenedor photos contiene un oso polar.

    Screenshot that shows logs in a terminal, with the log entry Polar Bear detected for one of the cameras and the camera's latitude and longitude.

    Hay osos polares

  3. Vuelva al símbolo del sistema o la ventana de terminal en la que se ejecuta run.js y presione Ctrl+C.

¡Enhorabuena! Ha creado un sistema que transmite fotografías de fauna a Blob Storage y usa un modelo de Custom Vision de Azure AI para determinar qué fotografías contienen osos polares. El siguiente paso es hacer que el resultado sea más visual y eso comienza con la creación de una base de datos SQL mediante Azure SQL Database.