Criar e implantar um aplicativo Web estático no Azure
Neste tutorial, crie e implante localmente um aplicativo cliente em React/TypeScript para um aplicativo Web estático do Azure com uma ação do GitHub. O aplicativo React permite que você analise uma imagem com a Pesquisa Visual Computacional dos Serviços Cognitivos.
Criar ou usar uma assinatura existente do Azure
Você precisará de uma conta de usuário do Azure com uma assinatura ativa. Crie um gratuitamente.
Pré-requisitos
- Node.js e npm – instalados em seu computador local.
- Visual Studio Code – instalado no computador local.
- Aplicativos Web Estáticos do Azure – usados para implantar o aplicativo React no aplicativo Web estático do Azure.
- Git – usado para enviar por push para o GitHub, o que ativa a ação do GitHub.
- Conta do GitHub – para criar fork e enviar por push para um repositório
- Use o Azure Cloud Shell usando o ambiente bash.
- Sua conta do Azure deve ter a função Colaborador dos Serviços Cognitivos atribuída para que você concorde com os termos e condições da IA responsável e crie um recurso. Para que essa função seja atribuída à sua conta, siga as etapas descritas na documentação Atribuir funções ou entre em contato com o administrador.
O que é um aplicativo Web estático do Azure
Ao criar aplicativos Web estáticos, você tem várias opções no Azure, com base no grau de funcionalidade e controle de seu interesse. Este tutorial se concentra no serviço mais fácil, com muitas das opções feitas para você, para que você possa se concentrar no código de front-end e não no ambiente de hospedagem.
O React (create-react-app) oferece a seguinte funcionalidade:
- Exibir uma mensagem se a chave e o ponto de extremidade do Azure para a Pesquisa Visual Computacional dos Serviços Cognitivos não forem encontrados
- Permite analisar uma imagem com o Cognitive Services Computer Vision
- Inserir uma URL de imagem pública ou analisar imagem de uma coleção
- Quando a análise estiver concluída
- Exibir imagem
- Exibir resultados em JSON da Pesquisa Visual Computacional
Para implantar o aplicativo Web estático, use uma ação do GitHub, que começa quando ocorre um push para uma ramificação específica:
- Insere segredos do GitHub para chave e ponto de extremidade da Pesquisa Visual Computacional no build
- Cria o cliente React (create-react-app)
- Move os arquivos resultantes para o recurso de aplicativo Web estático do Azure
1. Garfe o repositório de amostra
Crie um fork do repositório em vez de apenas cloná-lo no computador local, para ter seu próprio repositório do GitHub para o qual enviar as alterações por push.
Abra uma janela ou guia separada do navegador e entre no GitHub.
Navegue até o repositório de exemplo do GitHub.
https://github.com/Azure-Samples/js-e2e-client-cognitive-services
Na seção superior direita da página, selecione Criar fork.
Selecione Código e, em seguida, copie a URL do local para seu fork.
2. Criar um ambiente de desenvolvimento local
Em uma janela de terminal ou bash, clone o fork no computador local. Substitua
YOUR-ACCOUNT-NAME
pelo nome da sua conta do GitHub.git clone https://github.com/YOUR-ACCOUNT-NAME/js-e2e-client-cognitive-services
Altere para o novo diretório e instale as dependências.
cd js-e2e-client-cognitive-services && npm install
A etapa de instalação instala as dependências necessárias, incluindo @azure/cognitiveservices-computervision.
3. Execute a amostra local
Execute o exemplo.
npm start
Interrompa o aplicativo. Feche a janela do terminal ou use
control+c
no terminal.
4. Crie seu grupo de recursos
Em um shell de terminal ou do bash, insira o comando CLI do Azure para criar um grupo de recursos do Azure, com o nome rg-demo
:
az group create \
--location eastus \
--name rg-demo \
--subscription YOUR-SUBSCRIPTION-NAME-OR-ID
5. Crie um recurso de Visão Computacional
A criação de um grupo de recursos permite que você encontre facilmente os recursos e exclua-os quando terminar. Esse tipo de recurso requer que você concorde com o contrato de Uso Responsável. Use a seguinte lista para saber como você pode criar rapidamente o recurso correto:
- Seu primeiro recurso de Pesquisa Visual Computacional – concordar com o contrato de Uso Responsável
- Pesquisa Visual Computacional adicional – você já concordou com o contrato de Uso Responsável
6. Crie seu primeiro recurso de Visão Computacional
Se esse for seu primeiro serviço de IA, você precisará criar o serviço por meio do portal e concordar com o contrato de Uso Responsável, como parte da criação do recurso. Se esse não for seu primeiro recurso que exige o contrato de Uso Responsável, você poderá criar o recurso com a CLI do Azure, encontrado na próxima seção.
Use a tabela a seguir para ajudar a criar o recurso dentro do portal do Azure.
Configuração | Valor |
---|---|
Grupo de recursos | rg-demo |
Nome | demo-ComputerVision |
Sku | S1 |
Localidade | eastus |
7. Crie um recurso adicional de Visão Computacional
Execute o seguinte comando para criar um recurso da Pesquisa Visual Computacional:
az cognitiveservices account create \
--name demo-ComputerVision \
--resource-group rg-demo \
--kind ComputerVision \
--sku S1 \
--location eastus \
--yes
8. Obtenha o ponto de extremidade e as chaves do recurso de Visão Computacional
Nos resultados, localize e copie o
properties.endpoint
. Você precisará disso posteriormente.... "properties":{ ... "endpoint": "https://eastus.api.cognitive.microsoft.com/", ... } ...
Execute o comando a seguir para obter as chaves.
az cognitiveservices account keys list \ --name demo-ComputerVision \ --resource-group rg-demo
Copie uma das chaves; você precisará dela mais tarde.
{ "key1": "8eb7f878bdce4e96b26c89b2b8d05319", "key2": "c2067cea18254bdda71c8ba6428c1e1a" }
9. Adicione variáveis de ambiente ao seu ambiente local
Para usar o recurso, o código local precisa ter a chave e o ponto de extremidade disponíveis. Essa base de código as armazena em variáveis de ambiente:
- REACT_APP_AZURE_COMPUTER_VISION_KEY
- REACT_APP_AZURE_COMPUTER_VISION_ENDPOINT
Execute o comando a seguir para adicionar essas variáveis ao seu ambiente.
10. Adicione variáveis de ambiente ao seu ambiente remoto
Ao usar aplicativos Web estáticos do Azure, as variáveis de ambiente, como segredos, precisam ser passadas da ação do GitHub para o aplicativo Web estático. A ação do GitHub cria o aplicativo, incluindo a chave e o ponto de extremidade da Pesquisa Visual Computacional passados dos segredos do GitHub para esse repositório e, em seguida, envia por push o código com as variáveis de ambiente para o aplicativo Web estático.
Em um navegador da Web, no repositório do GitHub, selecione Configurações, Segredos e Novo segredo de repositório.
Insira o mesmo nome e valor para o ponto de extremidade usado na seção anterior. Em seguida, crie outro segredo com o mesmo nome e valor para a chave, conforme usado na seção anterior.
11. Execute o aplicativo react local com o recurso ComputerVision
Inicie o aplicativo novamente, na linha de comando:
npm start
Deixe o campo de texto vazio para selecionar uma imagem do catálogo padrão e selecione o botão Analisar.
A imagem é selecionada aleatoriamente em um catálogo de imagens definido em
./src/DefaultImages.js
.Continue para selecionar o botão Analisar para ver as outras imagens e os resultados.
12. Envie a filial local para o GitHub
No terminal do Visual Studio Code, envie por push o branch local main
para o repositório remoto.
git push origin main
Não é preciso fazer commit de alterações porque nenhuma alteração foi executada ainda.
13. Criar um recurso de aplicativo Web estático
Clique no ícone Azure, clique com o botão direito do mouse no serviço Aplicativos Web Estáticos, depois clique em Criar Aplicativo Web Estático (Avançado).
Caso uma janela pop-up pergunte se você deseja continuar no branch
main
, clique em Continuar.Insira as informações a seguir nos campos subsequentes, apresentados um de cada vez.
Nome do campo value Selecione um grupo de recursos para novos recursos. Selecione o grupo de recursos criado para o recurso ComputerVision: demo-ComputerVision
.Insira o nome do novo aplicativo Web estático. Demo-ComputerVisionAnalyzer
Selecionar uma opção de preço Selecione a opção gratuito. Selecione o local do código do aplicativo. Escolha a mesma localização selecionada durante a criação do grupo de recursos: eastus
.Escolha a predefinição de build para configurar a estrutura de projeto padrão. React
Selecione a localização do código do aplicativo. /
Insira a localização do código do Azure Functions. Use o valor padrão. Insira o caminho da saída do build em relação ao local do seu aplicativo. build
14. Atualize a ação do GitHub com variáveis de ambiente secretas
A chave da Pesquisa Visual Computacional e o ponto de extremidade estão na coleção de segredos do repositório, mas ainda não estão na ação do GitHub. Esta etapa adiciona a chave e o ponto de extremidade à ação.
Puxe as alterações feitas na criação do recurso do Azure para obter o arquivo de ação do GitHub.
git pull origin main
No editor do Visual Studio Code, edite o arquivo de ação do GitHub encontrado em
./.github/workflows/
para adicionar os segredos.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"
Adicione e confirme a alteração no branch
main
local.git add . && git commit -m "add secrets to action"
Envie por push a alteração para o repositório remoto, iniciando uma nova ação build-and-deploy para o aplicativo Web estático do Azure.
git push origin main
15. Veja o processo de compilação da Ação do GitHub
Em um navegador da Web, abra o repositório do GitHub deste tutorial e selecione Ações.
Selecione o primeiro build da lista e, em seguida, selecione Trabalho de Compilar e Implantar no menu do lado esquerdo para ver o processo de build. Aguarde até que Compilar e Implantar seja concluído com êxito.
16. Exibir site estático remoto do Azure no navegador
- No Visual Studio Code, selecione o ícone Azure no menu da extrema direita, selecione seu aplicativo Web estático, clique com o botão direito do mouse em Procurar site e, em seguida, selecione Abrir para exibir o site estático público.
Você também pode encontrar a URL para o site nos seguintes locais:
- no portal do Azure para o recurso, na página Visão geral.
- na saída do build-and-deploy da ação do GitHub tem a URL do site no final do script
17. Limpar recursos para aplicativo Web estático
Depois de concluir este tutorial, você precisará remover o grupo de recursos, que inclui o recurso da Pesquisa Visual Computacional e o aplicativo Web Estático, para garantir que você não seja cobrado por mais nenhum uso.
No VS Code, selecione o Azure Explorer, clique com o botão direito do mouse no grupo de recursos listado na assinatura e selecione Excluir.
Código: Adicionar Visão Computacional ao aplicativo React local
Use npm para adicionar a Pesquisa Visual Computacional ao arquivo package.json.
npm install @azure/cognitiveservices-computervision
Código: Adicionar código de Visão Computacional como módulo separado
O código da Pesquisa Visual Computacional está contido em um arquivo separado chamado ./src/azure-cognitiveservices-computervision.js
. A função principal do módulo é realçada.
// ./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: Adicionar catálogo de imagens como módulo separado
O aplicativo selecionará uma imagem aleatória de um catálogo se o usuário não inserir uma URL de imagem. A função de seleção aleatória está realçada
// ./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: Adicionar módulo de Visão Computacional personalizado ao aplicativo React
Adicione métodos ao React app.js
. A análise de imagem e a exibição de resultados estão realçadas.
// ./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;