Skapa och distribuera en statisk webbapp till Azure

I den här självstudien skapar och distribuerar du lokalt ett React/TypeScript-klientprogram till en Azure Static Web App med en GitHub-åtgärd. Med React-appen kan du analysera en bild med Cognitive Services Visuellt innehåll.

Skapa eller använda en befintlig Azure-prenumeration

Du behöver ett Azure-användarkonto med en aktiv prenumeration. Skapa en kostnadsfritt.

Förutsättningar

  • Node.js och npm – installerade på din lokala dator.
  • Visual Studio Code – installerat på din lokala dator.
  • Git – används för att skicka till GitHub – som aktiverar GitHub-åtgärden.
  • GitHub-konto – för att förgrena och skicka till en lagringsplats
  • Använd Azure Cloud Shell med bash-miljön.
  • Ditt Azure-konto måste ha en tilldelad roll som Cognitive Services-deltagare för att du ska kunna godkänna villkoren för ansvarsfull AI och skapa en resurs. Om du vill tilldela den här rollen till ditt konto följer du stegen i dokumentationen Tilldela roller eller kontaktar administratören.

Vad är en Azure Static-webbapp

När du skapar statiska webbappar har du flera alternativ i Azure, baserat på vilken funktionalitet och kontroll du är intresserad av. Den här självstudien fokuserar på den enklaste tjänsten med många av de val som gjorts åt dig, så att du kan fokusera på din klientdelskod och inte på värdmiljön.

React (create-react-app) innehåller följande funktioner:

  • Visa meddelande om Azure-nyckel och slutpunkt för Cognitive Services Visuellt innehåll inte hittas
  • Gör att du kan analysera en bild med Cognitive Services Visuellt innehåll
    • Ange en offentlig bild-URL eller analysera bilden från samlingen
    • När analysen är klar
      • Visa bild
      • Visa Visuellt innehåll JSON-resultat

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

Om du vill distribuera den statiska webbappen använder du en GitHub-åtgärd som startar när en push-överföring till en specifik gren sker:

  • Infogar GitHub-hemligheter för Visuellt innehåll nyckel och slutpunkt i build
  • Skapar React-klienten (create-react-app)
  • Flyttar de resulterande filerna till din Azure Static Web App-resurs

1. Förgrena exempelrepo

Förgrena lagringsplatsen, i stället för att bara klona den till din lokala dator, för att ha en egen GitHub-lagringsplats att skicka ändringar till.

  1. Öppna ett separat webbläsarfönster eller en separat flik och logga in på GitHub.

  2. Gå till GitHub-exempellagringsplatsen.

    https://github.com/Azure-Samples/js-e2e-client-cognitive-services
    
  3. I det övre högra avsnittet på sidan väljer du Förgrening.

  4. Välj Kod och kopiera sedan plats-URL:en för din förgrening.

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

2. Skapa en lokal utvecklingsmiljö

  1. I ett terminal- eller bash-fönster klonar du din förgrening till den lokala datorn. Ersätt YOUR-ACCOUNT-NAME med ditt GitHub-kontonamn.

    git clone https://github.com/YOUR-ACCOUNT-NAME/js-e2e-client-cognitive-services
    
  2. Ändra till den nya katalogen och installera beroendena.

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

    Installationssteget installerar nödvändiga beroenden, inklusive @azure/cognitiveservices-computervision.

3. Kör det lokala exemplet

  1. Kör exemplet.

    npm start
    

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

  2. Stoppa appen. Stäng terminalfönstret eller använd control+c i terminalen.

4. Skapa resursgruppen

I ett terminal- eller bash-gränssnitt anger du Azure CLI-kommandot för att skapa en Azure-resursgrupp med namnet rg-demo:

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

5. Skapa en Visuellt innehåll resurs

När du skapar en resursgrupp kan du enkelt hitta resurserna och ta bort dem när du är klar. Den här typen av resurs kräver att du godkänner avtalet om ansvarsfull användning. Använd följande lista för att veta hur du snabbt kan skapa rätt resurs:

6. Skapa din första Visuellt innehåll resurs

Om det här är din första AI-tjänst måste du skapa tjänsten via portalen och godkänna avtalet om ansvarsfull användning som en del av resursskapandet. Om detta inte är din första resurs som kräver avtalet om ansvarsfull användning kan du skapa resursen med Azure CLI, som finns i nästa avsnitt.

Använd följande tabell för att skapa resursen i Azure-portalen.

Inställning Värde
Resursgrupp rg-demo
Name demo-ComputerVision
Sku S1
Plats eastus

7. Skapa ytterligare en Visuellt innehåll resurs

Kör följande kommando för att skapa en Visuellt innehåll resurs:

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

8. Hämta Visuellt innehåll resursslutpunkt och nycklar

  1. I resultatet letar du upp och kopierar properties.endpoint. Du behöver det senare.

    ...
    "properties":{
        ...
        "endpoint": "https://eastus.api.cognitive.microsoft.com/",
        ...
    }
    ...
    
  2. Kör följande kommando för att hämta dina nycklar.

    az cognitiveservices account keys list \
    --name demo-ComputerVision \
    --resource-group rg-demo
    
  3. Kopiera en av nycklarna. Du behöver den senare.

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

9. Lägg till miljövariabler i din lokala miljö

Om du vill använda resursen måste den lokala koden ha nyckeln och slutpunkten tillgänglig. Den här kodbasen lagrar dem i miljövariabler:

  • REACT_APP_AZURE_COMPUTER_VISION_KEY
  • REACT_APP_AZURE_COMPUTER_VISION_ENDPOINT
  1. Kör följande kommando för att lägga till dessa variabler i din miljö.

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

10. Lägg till miljövariabler i fjärrmiljön

När du använder Azure Static-webbappar måste miljövariabler som hemligheter skickas från GitHub-åtgärden till den statiska webbappen. GitHub-åtgärden skapar appen, inklusive den Visuellt innehåll nyckel och slutpunkt som skickas från GitHub-hemligheterna för lagringsplatsen, och skickar sedan koden med miljövariablerna till den statiska webbappen.

  1. I en webbläsare går du till din GitHub-lagringsplats och väljer Inställningar, sedan Hemligheter och sedan Ny lagringsplatshemlighet..

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

  2. Ange samma namn och värde för slutpunkten som du använde i föregående avsnitt. Skapa sedan en annan hemlighet med samma namn och värde för nyckeln som i föregående avsnitt.

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

11. Kör lokal react-app med ComputerVision-resurs

  1. Starta appen igen på kommandoraden:

    npm start
    

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

  2. Lämna textfältet tomt för att välja en bild från standardkatalogen och välj knappen Analysera .

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

    Avbildningen väljs slumpmässigt från en katalog med bilder som definierats i ./src/DefaultImages.js.

  3. Fortsätt att välja knappen Analysera för att se de andra bilderna och resultaten.

12. Skicka den lokala grenen till GitHub

I Visual Studio Code-terminalen skickar du den lokala grenen main till fjärrlagringsplatsen.

git push origin main

Du behövde inte checka in några ändringar eftersom inga ändringar har gjorts ännu.

13. Skapa en statisk webbappresurs

  1. Välj Azure-ikonen och högerklicka sedan på tjänsten Static Web Apps och välj sedan Skapa statisk webbapp (avancerat).

    Visual Studio Code screenshot with Visual Studio extension

  2. Om ett popup-fönster frågar om du vill fortsätta på grenen main väljer du Fortsätt.

  3. Ange följande information i följande fält, som visas en i taget.

    Fältnamn värde
    Välj en resursgrupp för nya resurser. Välj den resursgrupp som du skapade för din ComputerVision-resurs, demo-ComputerVision.
    Ange ett namn för den nya statiska webbappen. Demo-ComputerVisionAnalyzer
    Välj prisalternativ Välj kostnadsfritt.
    Välj platsen för programkoden. Välj samma plats som du valde när du skapade resursgruppen. eastus
    Välj byggförinställning för att konfigurera standardprojektstrukturen. React
    Välj platsen för programkoden. /
    Ange platsen för Din Azure Functions-kod. Ta standardvärdet.
    Ange sökvägen till byggutdata i förhållande till appens plats. build

14. Uppdatera GitHub-åtgärden med hemliga miljövariabler

Den Visuellt innehåll nyckeln och slutpunkten finns i lagringsplatsens hemlighetssamling men finns inte i GitHub-åtgärden ännu. Det här steget lägger till nyckeln och slutpunkten i åtgärden.

  1. Hämta GitHub-åtgärdsfilen genom att hämta ändringarna som gjorts från skapandet av Azure-resursen.

    git pull origin main
    
  2. I Visual Studio Code-redigeraren redigerar du GitHub-åtgärdsfilen som finns på ./.github/workflows/ för att lägga till hemligheterna.

    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. Lägg till och checka in ändringen i den lokala main grenen.

    git add . && git commit -m "add secrets to action"
    
  4. Skicka ändringen till fjärrlagringsplatsen och starta en ny build-and-deploy-åtgärd till din Azure Static-webbapp.

    git push origin main
    

15. Visa GitHub Action-byggprocessen

  1. Öppna GitHub-lagringsplatsen för den här självstudien i en webbläsare och välj Åtgärder.

  2. Välj den översta versionen i listan och välj sedan Skapa och distribuera jobb på menyn till vänster för att titta på byggprocessen. Vänta tills build and deploy har slutförts.

     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. Visa en statisk azure-fjärrwebbplats i webbläsaren

  1. I Visual Studio Code väljer du Azure-ikonen i menyn längst till höger, väljer sedan din static-webbapp och högerklickar sedan på Bläddra webbplats och väljer sedan Öppna för att visa den offentliga statiska webbplatsen.

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

Du hittar även URL:en för webbplatsen på:

  • azure-portalen för din resurs på sidan Översikt .
  • GitHub-åtgärdens build-and-deploy-utdata har webbplats-URL:en i slutet av skriptet

17. Rensa resurser för statisk webbapp

När du har slutfört den här självstudien måste du ta bort resursgruppen, som innehåller Visuellt innehåll-resursen och static-webbappen, för att se till att du inte debiteras för mer användning.

I VS Code väljer du Azure Explorer, högerklickar på resursgruppen som visas under prenumerationen och väljer Ta bort.

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

Kod: Lägg till Visuellt innehåll i den lokala React-appen

Använd npm för att lägga till Visuellt innehåll i filen package.json.

npm install @azure/cognitiveservices-computervision 

Kod: Lägg till Visuellt innehåll kod som separat modul

Koden Visuellt innehåll finns i en separat fil med namnet ./src/azure-cognitiveservices-computervision.js. Huvudfunktionen i modulen är markerad.

// ./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; 
}

Kod: Lägg till katalog med avbildningar som separat modul

Appen väljer en slumpmässig bild från en katalog om användaren inte anger en bild-URL. Funktionen för slumpmässig markering är markerad

// ./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;

Kod: Lägg till anpassad Visuellt innehåll modul i React-appen

Lägg till metoder i React app.js. Bildanalysen och visning av resultaten är markerade.

// ./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;

Nästa steg