Créer et déployer une application web statique sur Azure
Dans ce tutoriel, créez et déployez localement une application cliente React/TypeScript sur une application web statique Azure avec une action GitHub. L’application React vous permet d’analyser une image avec Vision par ordinateur de Cognitive Services.
Créer ou utiliser un abonnement Azure existant
Vous devez disposer d’un compte d’utilisateur Azure avec un abonnement actif. Créez-en un gratuitement.
Prérequis
- Node.js et npm installés sur votre machine locale.
- Visual Studio Code installé sur votre machine locale.
- Azure Static Web Apps : utilisé pour déployer l’application React sur une application web statique Azure.
- Git : utilisé pour l’envoi (push) vers GitHub, qui active l’action GitHub.
- Compte GitHub pour dupliquer (fork) et envoyer dans un dépôt
- Utilisez Azure Cloud Shell à l’aide de l’environnement Bash.
- Votre compte Azure doit disposer d’un rôle Contributeur Cognitive Services attribué pour vous permettre d’accepter les termes de l’IA responsable et de créer une ressource. Pour que ce rôle soit attribué à votre compte, suivez les étapes de la documentation Attribuer des rôles ou contactez votre administrateur.
Qu’est-ce qu’une application web statique Azure ?
Lors de la création d’applications web statiques, vous disposez de plusieurs options sur Azure, en fonction du degré de fonctionnalité et de contrôle qui vous intéressent. Ce tutoriel est consacré au service le plus facile où un grand nombre de choix sont faits pour vous, ce qui vous permet de vous concentrer sur le code de votre front-end et non pas sur l’environnement d’hébergement.
L’application React (create-react-app) offre les fonctionnalités suivantes :
- Afficher un message si la clé et le point de terminaison Azure pour Vision par ordinateur de Cognitive Services sont introuvables
- Vous permet d’analyser une image avec Cognitive Services Vision par ordinateur
- Entrer une URL d’image publique ou analyser une image de la collection
- Une fois l’analyse terminée
- Afficher l’image
- Afficher les résultats JSON de Vision par ordinateur
Pour déployer l’application web statique, utilisez une action GitHub, qui commence lorsqu’une transmission (push) vers une branche spécifique se produit :
- Insère des secrets GitHub pour la clé et le point de terminaison de Vision par ordinateur dans la build
- Génère le client React (create-react-app)
- Déplace les fichiers résultants vers votre ressource d’application web statique Azure
1. Fork the sample repo
Dupliquez le dépôt au lieu de simplement le cloner sur votre ordinateur local, afin de disposer de votre propre dépôt GitHub pour y envoyer des modifications.
Ouvrez une fenêtre ou un onglet de navigateur distinct, puis connectez-vous à GitHub.
Accédez à l’exemple de référentiel GitHub.
https://github.com/Azure-Samples/js-e2e-client-cognitive-services
Dans la section supérieure droite de la page, sélectionnez Fork (Dupliquer).
Sélectionnez Code, puis copiez l’URL de l’emplacement pour votre duplication.
2. Créer un environnement de développement local
Dans un terminal ou une fenêtre bash, clonez votre duplication sur votre ordinateur local. Remplacez
YOUR-ACCOUNT-NAME
par le nom de votre compte GitHub.git clone https://github.com/YOUR-ACCOUNT-NAME/js-e2e-client-cognitive-services
Accédez au nouveau répertoire et installez les dépendances.
cd js-e2e-client-cognitive-services && npm install
L’étape d’installation installe les dépendances requises, notamment @azure/cognitiveservices-computervision.
3. Exécuter l’exemple local
Exécutez l’exemple.
npm start
Arrêtez l’application. Fermez la fenêtre de terminal ou utilisez
control+c
dans le terminal.
4. Créer votre groupe de ressources
Dans un terminal ou un shell Bash, entrez la commande Azure CLI pour créer un groupe de ressources Azure avec le nom rg-demo
:
az group create \
--location eastus \
--name rg-demo \
--subscription YOUR-SUBSCRIPTION-NAME-OR-ID
5. Créer une ressource Vision par ordinateur
La création d’un groupe de ressources vous permet de trouver facilement les ressources et de les supprimer quand vous avez terminé. Ce type de ressource vous demande d’accepter l’accord d’utilisation responsable. Utilisez la liste suivante pour savoir comment créer rapidement la bonne ressource :
- Votre première ressource Vision par ordinateur - accepter l’accord d’utilisation responsable
- Ressource Vision par ordinateur supplémentaire - accord d’utilisation responsable déjà accepté
6. Créez votre première ressource Vision par ordinateur
S’il s’agit de votre premier service IA, vous devez créer le service via le portail et accepter l’accord d’utilisation responsable dans le cadre de la création de cette ressource. S’il ne s’agit pas de votre première ressource exigeant l’accord d’utilisation responsable, vous pouvez créer la ressource avec Azure CLI, comme indiqué dans la section suivante.
Utilisez le tableau suivant pour vous aider à créer la ressource dans le portail Azure.
Paramètre | Valeur |
---|---|
Groupe de ressources | rg-demo |
Nom | demo-ComputerVision |
Sku | S1 |
Emplacement | eastus |
7. Créer une ressource Vision par ordinateur supplémentaire
Exécutez la commande suivante pour créer un groupe de ressources Vision par ordinateur :
az cognitiveservices account create \
--name demo-ComputerVision \
--resource-group rg-demo \
--kind ComputerVision \
--sku S1 \
--location eastus \
--yes
8. Obtenir Vision par ordinateur point de terminaison et clés de ressource
Dans les résultats, recherchez et copiez l’élément
properties.endpoint
. Vous en aurez besoin ultérieurement.... "properties":{ ... "endpoint": "https://eastus.api.cognitive.microsoft.com/", ... } ...
Exécutez la commande suivante pour obtenir vos clés.
az cognitiveservices account keys list \ --name demo-ComputerVision \ --resource-group rg-demo
Copiez une des clés, car vous en aurez besoin plus tard.
{ "key1": "8eb7f878bdce4e96b26c89b2b8d05319", "key2": "c2067cea18254bdda71c8ba6428c1e1a" }
9. Ajouter des variables d’environnement à votre environnement local
Pour utiliser votre ressource, la clé et le point de terminaison doivent être disponibles dans le code local. Cette base de code stocke celles-ci dans des variables d’environnement :
- REACT_APP_AZURE_COMPUTER_VISION_KEY
- REACT_APP_AZURE_COMPUTER_VISION_ENDPOINT
Exécutez la commande suivante pour ajouter ces variables à votre environnement.
10. Ajouter des variables d’environnement à votre environnement distant
Quand vous utilisez des applications web statiques Azure, les variables d’environnement, comme les secrets, doivent être passées de l’action GitHub à l’application web statique. L’action GitHub génère l’application, y compris la clé et le point de terminaison de Vision par ordinateur passés depuis les secrets GitHub pour ce dépôt, puis envoie le code avec les variables d’environnement à l’application web statique.
Dans un navigateur web, dans votre dépôt GitHub, sélectionnez Settings (Paramètres), puis Secrets, puis New repository secret (Nouveau secret de dépôt).
Entrez le même nom et la même valeur pour le point de terminaison que ce que vous avez utilisé dans la section précédente. Créez ensuite un autre secret avec le même nom et la même valeur pour la clé que celle utilisée dans la section précédente.
11. Exécuter l’application React locale avec la ressource ComputerVision
Redémarrez l’application à partir de la ligne de commande :
npm start
Laissez le champ texte vide pour sélectionner une image du catalogue par défaut, puis sélectionnez le bouton Analyze.
L’image est sélectionnée de façon aléatoire dans un catalogue d’images défini dans
./src/DefaultImages.js
.Continuez de sélectionner le bouton Analyze pour voir les autres images et les résultats correspondants.
12. Envoyer (push) la branche locale vers GitHub
Dans le terminal Visual Studio Code, envoyez la branche locale main
à votre dépôt distant.
git push origin main
Vous n’avez pas besoin de valider les changements, car aucun n’a été effectué pour le moment.
13. Créer une ressource d’application web statique
Sélectionnez l’icône Azure, cliquez avec le bouton droit sur le service Static Web Apps, puis sélectionnez Créer une application web statique (avancé).
Si une fenêtre contextuelle vous demande si vous voulez continuer sur la branche
main
, sélectionnez Continuer.Entrez les informations suivantes dans les champs ci-dessous, présentés l’un après l’autre.
Nom du champ value Sélectionnez un groupe de ressources pour les nouvelles ressources. Sélectionnez le groupe de ressources que vous avez créé pour votre ressource ComputerVision, demo-ComputerVision
.Entrez un nom pour la nouvelle application web statique. Demo-ComputerVisionAnalyzer
Sélectionner une option de tarif Sélectionnez gratuit. Sélectionnez l’emplacement du code de votre application. Sélectionnez la même localisation que celle que vous avez choisie quand vous avez créé votre groupe de ressources, eastus
.Choisissez Générer une présélection pour configurer la structure de projet par défaut. React
Choisissez la localisation du code de votre application. /
Entrez la localisation de votre code Azure Functions. Laissez la valeur par défaut. Entrez le chemin de la sortie de votre build relative à l’emplacement de votre application. build
14. Mettre à jour l’action GitHub avec des variables d’environnement secrètes
La clé et le point de terminaison de Vision par ordinateur se trouvent dans la collection de secrets du dépôt, mais ils ne sont pas encore dans l’action GitHub. Cette étape ajoute la clé et le point de terminaison à l’action.
Extrayez les modifications apportées depuis la création de la ressource Azure pour obtenir le fichier d’actions GitHub.
git pull origin main
Dans l’éditeur Visual Studio Code, éditez le fichier d’actions GitHub qui se trouve dans
./.github/workflows/
pour y ajouter les secrets.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"
Ajoutez et commitez la modification apportée à la branche
main
locale.git add . && git commit -m "add secrets to action"
Envoyez la modification au dépôt distant, en démarrant une nouvelle action de génération et de déploiement (build-and-deploy) sur votre application web statique Azure.
git push origin main
15. Afficher le processus de génération GitHub Action
Dans un navigateur web, ouvrez votre dépôt GitHub pour ce tutoriel, puis sélectionnez Actions.
Sélectionnez la build en haut de la liste, puis sélectionnez Build and Deploy Job (Travail de génération et de déploiement) dans le menu de gauche pour regarder le processus de génération. Attendez la fin du travail Build And Deploy.
16. Afficher le site web statique Azure distant dans le navigateur
- Dans Visual Studio Code, sélectionnez l’icône Azure dans le menu tout à droite, sélectionnez votre application web statique, cliquez avec le bouton droit sur Parcourir le site, puis sélectionnez Ouvrir pour afficher le site web statique public.
Vous pouvez également trouver l’URL du site ici :
- le portail Azure pour votre ressource, dans la page Vue d’ensemble.
- la sortie de la génération et du déploiement de l’action GitHub contient l’URL du site à la fin du script
17. Nettoyer les ressources pour l’application web statique
Une fois que vous avez terminé ce tutoriel, vous devez supprimer le groupe de ressources, qui comprend la ressource Vision par ordinateur et l’application web statique, pour être sûr qu’aucune utilisation supplémentaire ne vous est facturée.
Dans VS Code, sélectionnez l’Explorateur Azure, cliquez avec le bouton droit sur votre groupe de ressources qui est listé sous l’abonnement, puis sélectionnez Supprimer.
Code : Ajouter Vision par ordinateur à l’application React locale
Utilisez npm pour ajouter Vision par ordinateur au fichier package.json.
npm install @azure/cognitiveservices-computervision
Code : ajouter du code Vision par ordinateur en tant que module distinct
Le code de Vision par ordinateur est contenu dans un fichier distinct nommé ./src/azure-cognitiveservices-computervision.js
. La fonction main du module est mise en surbrillance.
// ./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;
}
Code : Ajouter un catalogue d’images en tant que module distinct
L’application sélectionne aléatoirement une image dans un catalogue si l’utilisateur n’entre pas l’URL d’une image. La fonction de sélection aléatoire est mise en surbrillance.
// ./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;
Code : Ajouter un module de Vision par ordinateur personnalisé à l’application React
Ajoutez des méthodes au fichier app.js
de l’application React. L’analyse de l’image et l’affichage des résultats sont mis en surbrillance.
// ./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;