Share via


Compilación e implementación de una aplicación web estática en Azure

En este tutorial va a compilar e implementar localmente una aplicación cliente de React/TypeScript en una aplicación web estática de Azure con una acción de GitHub. La aplicación de React le permite analizar una imagen con Computer Vision de Cognitive Services.

Creación o uso de una suscripción de Azure existente

Necesitará una cuenta de usuario de Azure con una suscripción activa. cree una de forma gratuita.

Requisitos previos

  • Node.js y npm: instalados en la máquina local.
  • Visual Studio Code: instalado en la máquina local.
    • Azure Static Web Apps: se usa para implementar la aplicación de React en la aplicación web estática de Azure.
  • Git: se usa para insertar en GitHub, lo que activa la acción de GitHub.
  • Cuenta de GitHub: para crear una bifurcación e insertar en un repositorio.
  • Use Azure Cloud Shell con el entorno de Bash.
  • La cuenta de Azure debe tener asignado un rol de colaborador de Cognitive Services a fin de que pueda aceptar los términos de IA responsable y crear un recurso. Para asignar este rol a su cuenta, siga los pasos descritos en la documentación Asignación de roles o póngase en contacto con el administrador.

¿Qué es una aplicación web estática de Azure?

Al compilar aplicaciones web estáticas, tiene varias opciones en Azure, en función del grado de funcionalidad y control que le interese. Este tutorial se centra en el servicio más sencillo, en el que muchas de las opciones se han elegido automáticamente, de modo que pueda centrarse en el código de front-end y no en el entorno de hospedaje.

La aplicación de React (create-react-app) proporciona la funcionalidad siguiente:

  • Mostrar un mensaje si no se encuentran la clave y el punto de conexión de Azure para Computer Vision de Cognitive Services
  • Permite analizar una imagen con Computer Vision de Cognitive Services
    • Escribir la dirección URL de una imagen pública o analizar una imagen de la colección
    • Una vez completado el análisis
      • Imagen para mostrar
      • Mostrar los resultados de Computer Vision en formato JSON

Partial browser screenshot of React Cognitive Service Computer Vision sample results.

Para implementar la aplicación web estática, use una acción de GitHub, que se inicia cuando se produce una inserción en una rama específica:

  • Inserta secretos de GitHub para la clave y el punto de conexión de Computer Vision en la compilación.
  • Compila la aplicación cliente de React (create-react-app).
  • Mueve los archivos resultantes al recurso de aplicación web estática de Azure.

1. Bifurcar el repositorio de ejemplo

Bifurque el repositorio, en lugar de simplemente clonarlo en el equipo local, con el fin de tener un repositorio de GitHub propio en el que insertar los cambios.

  1. Abra una pestaña o ventana del explorador independiente e inicie sesión en GitHub.

  2. Vaya al repositorio de ejemplo de GitHub.

    https://github.com/Azure-Samples/js-e2e-client-cognitive-services
    
  3. En la sección superior derecha de la página, seleccione Fork (Bifurcar).

  4. Seleccione Code (Código) y, a continuación, copie la dirección URL de la ubicación de la bifurcación.

    Partial screenshot of GitHub website, select **Code** then copy the location for your fork.

2. Creación de un entorno de desarrollo local

  1. En una ventana de terminal o de Bash, clone la bifurcación en el equipo local. Reemplace YOUR-ACCOUNT-NAME por el nombre de la cuenta de GitHub.

    git clone https://github.com/YOUR-ACCOUNT-NAME/js-e2e-client-cognitive-services
    
  2. Cambie al nuevo directorio e instale las dependencias.

    cd js-e2e-client-cognitive-services && npm install
    

    El paso de instalación instala las dependencias necesarias, incluidas @azure/cognitiveservices-computervision.

3. Ejecutar el ejemplo local

  1. Ejecute el ejemplo.

    npm start
    

    Partial browser screenshot of React Cognitive Service Computer Vision sample for image analysis before key and endpoint set.

  2. Detenga la aplicación. Cierre la ventana del terminal o pulse control+c en el terminal.

4. Creación del grupo de recursos

En un shell de terminal o de Bash, escriba el comando de la CLI de Azure para crear un grupo de recursos de Azure con el nombre rg-demo:

az group create \
    --location eastus \
    --name rg-demo \
    --subscription YOUR-SUBSCRIPTION-NAME-OR-ID

5. Creación de un recurso de Computer Vision

La creación de un grupo de recursos le permite encontrar fácilmente los recursos y eliminarlos cuando haya terminado. Este tipo de recurso requiere que acepte el contrato de uso responsable. Use la lista siguiente para saber cómo puede crear rápidamente el recurso correcto:

6. Creación del primer recurso de Computer Vision

Si este es su primer servicio de IA, debe crearlo mediante el portal y aceptar el contrato de uso responsable, como parte de la creación de ese recurso. Si este no es el primer recurso que requiere el contrato de uso responsable, puede crear el recurso con la CLI de Azure, que se encuentra en la sección siguiente.

Use la tabla siguiente para ayudar a crear el recurso dentro de Azure Portal.

Configuración Value
Resource group rg-demo
Nombre demo-ComputerVision
SKU S1
Location estado

7. Creación de un recurso de Computer Vision adicional

Ejecute el siguiente comando para crear un recurso de Computer Vision:

az cognitiveservices account create \
    --name demo-ComputerVision \
    --resource-group rg-demo \
    --kind ComputerVision \
    --sku S1 \
    --location eastus \
    --yes

8. Obtención del punto de conexión y las claves de recursos de Computer Vision

  1. En los resultados, busque y copie el valor de properties.endpoint. Lo necesitará más adelante.

    ...
    "properties":{
        ...
        "endpoint": "https://eastus.api.cognitive.microsoft.com/",
        ...
    }
    ...
    
  2. Ejecute el siguiente comando para obtener las claves.

    az cognitiveservices account keys list \
    --name demo-ComputerVision \
    --resource-group rg-demo
    
  3. Copie una de las claves, la necesitará más adelante.

    {
      "key1": "8eb7f878bdce4e96b26c89b2b8d05319",
      "key2": "c2067cea18254bdda71c8ba6428c1e1a"
    }
    

9. Agregar variables de entorno al entorno local

Para usar el recurso, el código local debe tener disponibles la clave y el punto de conexión. Esta base de código los almacena en variables de entorno:

  • REACT_APP_AZURE_COMPUTER_VISION_KEY
  • REACT_APP_AZURE_COMPUTER_VISION_ENDPOINT
  1. Ejecute el siguiente comando para agregar estas variables a su entorno.

    export REACT_APP_AZURE_COMPUTER_VISION_KEY="REPLACE-WITH-YOUR-KEY"
    export REACT_APP_AZURE_COMPUTER_VISION_ENDPOINT="REPLACE-WITH-YOUR-ENDPOINT"
    

10. Agregar variables de entorno al entorno remoto

Al usar aplicaciones web estáticas de Azure, se deben pasar las variables de entorno (por ejemplo, los secretos) desde la acción de GitHub a la aplicación web estática. La acción de GitHub compila la aplicación, incluye la clave y el punto de conexión de Computer Vision pasados desde los secretos de GitHub de ese repositorio y, a continuación, inserta el código con las variables de entorno en la aplicación web estática.

  1. En un explorador web, en el repositorio de GitHub, seleccione Settings (Configuración), luego Secrets (Secretos) y, a continuación, seleccione New repository secret (Nuevo secreto del repositorio).

    Partial browser screenshot of GitHub repository, creating new repository secret.

  2. Escriba el mismo nombre y el mismo valor para el punto de conexión que usó en la sección anterior. A continuación, cree otro secreto con el mismo nombre y el mismo valor para la clave que se usa en la sección anterior.

    Enter the same name and value for the endpoint. Then create another secret with the same name and value for the key.

11. Ejecución de una aplicación react local con el recurso ComputerVision

  1. Vuelva a iniciar la aplicación en la línea de comandos:

    npm start
    

    Partial browser screenshot of React Cognitive Service Computer Vision sample ready for URL or press enter.

  2. Deje el campo de texto en blanco para seleccionar una imagen del catálogo predeterminado y seleccione el botón Analyze (Analizar).

    Partial browser screenshot of React Cognitive Service Computer Vision sample results.

    La imagen se selecciona aleatoriamente de un catálogo de imágenes definido en ./src/DefaultImages.js.

  3. Vuelva a seleccionar el botón Analyze (Analizar) para ver las demás imágenes y resultados.

12. Inserción de la rama local en GitHub

En el terminal de Visual Studio Code, inserte la rama local main en el repositorio remoto.

git push origin main

No era necesario confirmar ningún cambio porque aún no se ha realizado ningún cambio.

13. Creación de un recurso de aplicación web estática

  1. Seleccione el icono de Azure, haga clic con el botón derecho en el servicio Static Web Apps y, a continuación, seleccione Create Static Web App (Advanced) (Crear aplicación web estática [avanzada]).

    Visual Studio Code screenshot with Visual Studio extension

  2. Si una ventana emergente le pregunta si desea continuar en la rama main, seleccione Continuar.

  3. Escriba la siguiente información en los campos siguientes, que se presentan de uno en uno.

    Nombre de campo value
    Seleccione un grupo de recursos para los nuevos recursos. Seleccione el grupo de recursos que creó para el recurso de ComputerVision, demo-ComputerVision.
    Escriba un nombre para la nueva aplicación web estática. Demo-ComputerVisionAnalyzer
    Selección de la opción de precios Seleccione Gratis.
    Seleccione la ubicación del código de la aplicación. Seleccione la misma ubicación que seleccionó al crear el grupo de recursos, eastus.
    Elija el valor preestablecido de compilación para configurar la estructura predeterminada del proyecto. React
    Elija la ubicación del código de la aplicación. /
    Escriba la ubicación del código de Azure Functions. Deje el valor predeterminado.
    Escriba la ruta de acceso de la salida de la compilación en relación con la ubicación de la aplicación. build

14. Actualización de la acción de GitHub con variables de entorno secretas

La clave de Computer Vision y el punto de conexión se encuentran en la colección de secretos del repositorio, pero aún no están en la acción de GitHub. En este paso se agregan la clave y el punto de conexión a la acción.

  1. Extraiga los cambios realizados al crear el recurso de Azure para obtener el archivo de la acción de GitHub.

    git pull origin main
    
  2. En el editor de Visual Studio Code, edite el archivo de la acción de GitHub que se encuentra en ./.github/workflows/ para agregar los secretos.

    name: Azure Static Web Apps CI/CD
    
    on:
      push:
        branches:
          - from-local
      pull_request:
        types: [opened, synchronize, reopened, closed]
        branches:
          - from-local
    
    jobs:
      build_and_deploy_job:
        if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
        runs-on: ubuntu-latest
        name: Build and Deploy Job
        steps:
          - uses: actions/checkout@v2
            with:
              submodules: true
          - name: Build And Deploy
            id: builddeploy
            uses: Azure/static-web-apps-deploy@v0.0.1-preview
            with:
              azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_RANDOM_NAME_HERE }}
              repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
              action: "upload"
              ###### Repository/Build Configurations - These values can be configured to match you app requirements. ######
              # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
              app_location: "/" # App source code path
              api_location: "api" # Api source code path - optional
              output_location: "build" # Built app content directory - optional
              ###### End of Repository/Build Configurations ######
            env:
              REACT_APP_AZURE_COMPUTER_VISION_ENDPOINT: ${{secrets.REACT_APP_AZURE_COMPUTER_VISION_ENDPOINT}}
              REACT_APP_AZURE_COMPUTER_VISION_KEY:  ${{secrets.REACT_APP_AZURE_COMPUTER_VISION_KEY}}
    
      close_pull_request_job:
        if: github.event_name == 'pull_request' && github.event.action == 'closed'
        runs-on: ubuntu-latest
        name: Close Pull Request Job
        steps:
          - name: Close Pull Request
            id: closepullrequest
            uses: Azure/static-web-apps-deploy@v0.0.1-preview
            with:
              azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_RANDOM_NAME_HERE }}
              action: "close"
    
  3. Agregue y confirme el cambio en la rama main local.

    git add . && git commit -m "add secrets to action"
    
  4. Inserte el cambio en el repositorio remoto, lo que inicia una nueva acción de compilación e implementación en la aplicación web estática de Azure.

    git push origin main
    

15. Visualización del proceso de compilación de acciones de GitHub

  1. En un explorador web, abra el repositorio de GitHub de este tutorial y seleccione Actions (Acciones).

  2. Seleccione la compilación superior de la lista y, a continuación, seleccione Build and Deploy Job (Compilar e implementar trabajo) en el menú de la izquierda para ver el proceso de compilación. Espere hasta que la compilación y la implementación finalicen correctamente.

     Select the top build in the list, then select `Build and Deploy Job` on the left-side menu to watch the build process. Wait until the build successfully finishes.

16. Visualización del sitio web estático remoto de Azure en el explorador

  1. En Visual Studio Code, seleccione el icono de Azure en el menú de la derecha, seleccione la aplicación web estática y, a continuación, haga clic con el botón derecho en Examinar sitio y, después, seleccione Abrir para ver el sitio web estático público.

Select `Browse site`, then select `Open` to view the public static web site.

También puede encontrar la dirección URL del sitio en:

  • la opción de Azure Portal para el recurso, en la página Información general.
  • la salida de la compilación e implementación de la acción de GitHub tiene la dirección URL del sitio al final del script.

17. Limpieza de recursos para la aplicación web estática

Una vez que haya completado este tutorial, deberá eliminar el grupo de recursos que incluye el recurso de Computer Vision para asegurarse de que no se le facturará por ningún uso adicional.

En VS Code, seleccione el explorador de Azure, haga clic con el botón derecho en el grupo de recursos que aparece en la suscripción y seleccione Eliminar.

Partial screen shot of VS Code, selecting resource group from list of resource groups, then right-clicking to select `Delete`.

Código: Adición de Computer Vision a la aplicación react local

Use npm para agregar Computer Vision al archivo package.json.

npm install @azure/cognitiveservices-computervision 

Código: Adición de código de Computer Vision como módulo independiente

El código de Computer Vision está contenido en un archivo independiente llamado ./src/azure-cognitiveservices-computervision.js. La función principal del módulo está resaltada.

// ./src/azure-cognitiveservices-computervision.js

// Azure SDK client libraries
import { ComputerVisionClient } from '@azure/cognitiveservices-computervision';
import { ApiKeyCredentials } from '@azure/ms-rest-js';

// List of sample images to use in demo
import RandomImageUrl from './DefaultImages';

// Authentication requirements
const key = process.env.REACT_APP_AZURE_COMPUTER_VISION_KEY;
const endpoint = process.env.REACT_APP_AZURE_COMPUTER_VISION_ENDPOINT;

console.log(`key = ${key}`)
console.log(`endpoint = ${endpoint}`)

// Cognitive service features
const visualFeatures = [
    "ImageType",
    "Faces",
    "Adult",
    "Categories",
    "Color",
    "Tags",
    "Description",
    "Objects",
    "Brands"
];

export const isConfigured = () => {
    const result = (key && endpoint && (key.length > 0) && (endpoint.length > 0)) ? true : false;
    console.log(`key = ${key}`)
    console.log(`endpoint = ${endpoint}`)
    console.log(`ComputerVision isConfigured = ${result}`)
    return result;
}

// Computer Vision detected Printed Text
const includesText = async (tags) => {
    return tags.filter((el) => {
        return el.name.toLowerCase() === "text";
    });
}
// Computer Vision detected Handwriting
const includesHandwriting = async (tags) => {
    return tags.filter((el) => {
        return el.name.toLowerCase() === "handwriting";
    });
}
// Wait for text detection to succeed
const wait = (timeout) => {
    return new Promise(resolve => {
        setTimeout(resolve, timeout);
    });
}

// Analyze Image from URL
export const computerVision = async (url) => {

    // authenticate to Azure service
    const computerVisionClient = new ComputerVisionClient(
        new ApiKeyCredentials({ inHeader: { 'Ocp-Apim-Subscription-Key': key } }), endpoint);

    // get image URL - entered in form or random from Default Images
    const urlToAnalyze = url || RandomImageUrl();
    
    // analyze image
    const analysis = await computerVisionClient.analyzeImage(urlToAnalyze, { visualFeatures });

    // text detected - what does it say and where is it
    if (includesText(analysis.tags) || includesHandwriting(analysis.tags)) {
        analysis.text = await readTextFromURL(computerVisionClient, urlToAnalyze);
    }

    // all information about image
    return { "URL": urlToAnalyze, ...analysis};
}
// analyze text in image
const readTextFromURL = async (client, url) => {
    
    let result = await client.read(url);
    let operationID = result.operationLocation.split('/').slice(-1)[0];

    // Wait for read recognition to complete
    // result.status is initially undefined, since it's the result of read
    const start = Date.now();
    console.log(`${start} -${result?.status} `);
    
    while (result.status !== "succeeded") {
        await wait(500);
        console.log(`${Date.now() - start} -${result?.status} `);
        result = await client.getReadResult(operationID);
    }
    
    // Return the first page of result. 
    // Replace[0] with the desired page if this is a multi-page file such as .pdf or.tiff.
    return result.analyzeResult; 
}

Código: agregar catálogo de imágenes como módulo independiente

La aplicación selecciona una imagen aleatoria de un catálogo si el usuario no escribe una dirección URL de imagen. La función de selección aleatoria está resaltada.

// ./src/DefaultImages.js

const describeURL = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/celebrities.jpg';
const categoryURLImage = 'https://moderatorsampleimages.blob.core.windows.net/samples/sample16.png';
const tagsURL = 'https://moderatorsampleimages.blob.core.windows.net/samples/sample16.png';
const objectURL = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-node-sdk-samples/master/Data/image.jpg';
const brandURLImage = 'https://docs.microsoft.com/en-us/azure/cognitive-services/computer-vision/images/red-shirt-logo.jpg';
const facesImageURL = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/faces.jpg';
const printedTextSampleURL = 'https://moderatorsampleimages.blob.core.windows.net/samples/sample2.jpg';
const multiLingualTextURL = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/MultiLingual.png';
const adultURLImage = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/celebrities.jpg';
const colorURLImage = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/celebrities.jpg';
// don't use with picture analysis
// eslint-disable-next-line
const mixedMultiPagePDFURL = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/MultiPageHandwrittenForm.pdf';
const domainURLImage = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-sample-data-files/master/ComputerVision/Images/landmark.jpg';
const typeURLImage = 'https://raw.githubusercontent.com/Azure-Samples/cognitive-services-python-sdk-samples/master/samples/vision/images/make_things_happen.jpg';

const DefaultImages = [
    describeURL,
    categoryURLImage,
    tagsURL,
    objectURL,
    brandURLImage,
    facesImageURL,
    adultURLImage,
    colorURLImage,
    domainURLImage,
    typeURLImage,
    printedTextSampleURL,
    multiLingualTextURL,
    //mixedMultiPagePDFURL
];

const RandomImageUrl = () => {
    return DefaultImages[Math.floor(Math.random() * Math.floor(DefaultImages.length))];
}

export default RandomImageUrl;

Código: Adición de un módulo de Computer Vision personalizado a la aplicación React

Agregue métodos al archivo app.js de React. Se resaltan el análisis de la imagen y la presentación de los resultados.

// ./src/App.js

import React, { useState } from 'react';
import './App.css';
import { computerVision, isConfigured as ComputerVisionIsConfigured } from './azure-cognitiveservices-computervision';

function App() {

  const [fileSelected, setFileSelected] = useState(null);
  const [analysis, setAnalysis] = useState(null);
  const [processing, setProcessing] = useState(false);
  
  const handleChange = (e) => {
    setFileSelected(e.target.value)
  }
  const onFileUrlEntered = (e) => {

    // hold UI
    setProcessing(true);
    setAnalysis(null);

    computerVision(fileSelected || null).then((item) => {
      // reset state/form
      setAnalysis(item);
      setFileSelected("");
      setProcessing(false);
    });

  };

  // Display JSON data in readable format
  const PrettyPrintJson = (data) => {
    return (<div><pre>{JSON.stringify(data, null, 2)}</pre></div>);
  }

  const DisplayResults = () => {
    return (
      <div>
        <h2>Computer Vision Analysis</h2>
        <div><img src={analysis.URL} height="200" border="1" alt={(analysis.description && analysis.description.captions && analysis.description.captions[0].text ? analysis.description.captions[0].text : "can't find caption")} /></div>
        {PrettyPrintJson(analysis)}
      </div>
    )
  };
  
  const Analyze = () => {
    return (
    <div>
      <h1>Analyze image</h1>
      {!processing &&
        <div>
          <div>
            <label>URL</label>
            <input type="text" placeholder="Enter URL or leave empty for random image from collection" size="50" onChange={handleChange}></input>
          </div>
          <button onClick={onFileUrlEntered}>Analyze</button>
        </div>
      }
      {processing && <div>Processing</div>}
      <hr />
      {analysis && DisplayResults()}
      </div>
    )
  }
  
  const CantAnalyze = () => {
    return (
      <div>Key and/or endpoint not configured in ./azure-cognitiveservices-computervision.js</div>
    )
  }
  
  function Render() {
    const ready = ComputerVisionIsConfigured();
    if (ready) {
      return <Analyze />;
    }
    return <CantAnalyze />;
  }

  return (
    <div>
      {Render()}
    </div>
    
  );
}

export default App;

Pasos siguientes