Partilhar via


Exemplo: Criar uma competência personalizada com o Python (Arquivado)

Este exemplo é arquivado e sem suporte. Explicou como criar uma competência personalizada da API Web com o Python e o Visual Studio Code. O exemplo utilizou uma Função do Azure que implementa a interface de competências personalizada.

Pré-requisitos

Criar uma Função do Azure

Este exemplo utiliza uma Função do Azure para demonstrar o conceito de alojar uma API Web, mas são possíveis outras abordagens. Desde que cumpra os requisitos de interface de uma competência cognitiva, a abordagem que adotar é imaterial. Funções do Azure, no entanto, facilitar a criação de uma competência personalizada.

Criar um projeto para a função

O modelo de projeto Funções do Azure no Visual Studio Code cria um projeto local que pode ser publicado numa aplicação de funções no Azure. As aplicações de funções permitem-lhe agrupar funções como unidades lógicas para a gestão, implementação e partilha de recursos.

  1. No Visual Studio Code, prima F1 para abrir a paleta de comandos. Na paleta de comandos, procure e selecione Azure Functions: Create new project....
  2. Selecione uma localização do diretório para a área de trabalho do seu projeto e escolha Selecionar. Não utilize uma pasta de projeto que já faça parte de outra área de trabalho.
  3. Selecione um idioma para o projeto da aplicação de funções. Para este tutorial, selecione Python.
  4. Selecione a versão python (a versão 3.7.5 é suportada por Funções do Azure).
  5. Selecione um modelo para a primeira função do projeto. Selecione acionador HTTP para criar uma função acionada por HTTP na nova aplicação de funções.
  6. Indique um nome de função. Neste caso, vamos utilizar o Concatenador
  7. Selecione Função como o nível de Autorização. Irá utilizar uma chave de acesso de função para chamar o ponto final HTTP da função.
  8. Especifique como pretende abrir o projeto. Para este passo, selecione Adicionar à área de trabalho para criar a aplicação de funções na área de trabalho atual.

O Visual Studio Code cria o projeto da aplicação de funções numa nova área de trabalho. Este projeto contém os ficheiros host.json e local.settings.jsonconfiguration, além de quaisquer ficheiros de projeto específicos de linguagem.

Também é criada uma nova função acionada por HTTP na pasta Concatenador do projeto da aplicação de funções. No interior, haverá um ficheiro chamado "__init__.py", com este conteúdo:

import logging

import azure.functions as func


def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        return func.HttpResponse(f"Hello {name}!")
    else:
        return func.HttpResponse(
             "Please pass a name on the query string or in the request body",
             status_code=400
        )

Agora, vamos modificar esse código para seguir a interface de competências personalizada. Substitua o código predefinido pelo seguinte conteúdo:

import logging
import azure.functions as func
import json

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    try:
        body = json.dumps(req.get_json())
    except ValueError:
        return func.HttpResponse(
             "Invalid body",
             status_code=400
        )
    
    if body:
        result = compose_response(body)
        return func.HttpResponse(result, mimetype="application/json")
    else:
        return func.HttpResponse(
             "Invalid body",
             status_code=400
        )


def compose_response(json_data):
    values = json.loads(json_data)['values']
    
    # Prepare the Output before the loop
    results = {}
    results["values"] = []
    
    for value in values:
        output_record = transform_value(value)
        if output_record != None:
            results["values"].append(output_record)
    return json.dumps(results, ensure_ascii=False)

## Perform an operation on a record
def transform_value(value):
    try:
        recordId = value['recordId']
    except AssertionError  as error:
        return None

    # Validate the inputs
    try:         
        assert ('data' in value), "'data' field is required."
        data = value['data']        
        assert ('text1' in data), "'text1' field is required in 'data' object."
        assert ('text2' in data), "'text2' field is required in 'data' object."
    except AssertionError  as error:
        return (
            {
            "recordId": recordId,
            "errors": [ { "message": "Error:" + error.args[0] }   ]       
            })

    try:                
        concatenated_string = value['data']['text1'] + " " + value['data']['text2']  
        # Here you could do something more interesting with the inputs

    except:
        return (
            {
            "recordId": recordId,
            "errors": [ { "message": "Could not complete operation for record." }   ]       
            })

    return ({
            "recordId": recordId,
            "data": {
                "text": concatenated_string
                    }
            })

O método transform_value executa uma operação num único registo. Pode modificar o método para satisfazer as suas necessidades específicas. Lembre-se de efetuar qualquer validação de entrada necessária e de devolver erros e avisos se a operação não puder ser concluída.

Depurar o código localmente

O Visual Studio Code facilita a depuração do código. Prima "F5" ou aceda ao menu Depurar e selecione Iniciar Depuração.

Pode definir quaisquer pontos de interrupção no código ao premir "F9" na linha de interesse.

Assim que começar a depurar, a função será executada localmente. Pode utilizar uma ferramenta como o Postman ou o Fiddler para emitir o pedido para localhost. Anote a localização do ponto final local na janela Terminal.

Criar uma aplicação de funções no Azure

Quando estiver satisfeito com o comportamento da função, pode publicá-lo. Até agora tem trabalhado localmente. Nesta secção, irá criar uma aplicação de funções no Azure e, em seguida, implementar o projeto local na aplicação que criou.

Criar a aplicação a partir do Visual Studio Code

  1. No Visual Studio Code, prima F1 para abrir a paleta de comandos. Na paleta de comandos, procure e selecione Criar Aplicação de Funções no Azure.

  2. Se tiver várias subscrições ativas, selecione a subscrição desta aplicação.

  3. Introduza um nome globalmente exclusivo para a aplicação de funções. Escreva um nome válido para um URL.

  4. Selecione uma pilha de runtime e escolha a versão de idioma na qual tem estado a executar localmente.

  5. Selecione uma localização para a sua aplicação. Se possível, escolha a mesma região que também aloja o seu serviço de pesquisa.

A criação da aplicação demora alguns minutos. Quando estiver pronto, verá a nova aplicação em Recursos e Aplicação de Funções da subscrição ativa.

Implementar no Azure

  1. Ainda no Visual Studio Code, prima F1 para abrir a paleta de comandos. Na paleta de comandos, procure e selecione Implementar na Aplicação de Funções....

  2. Selecione a aplicação de funções que criou.

  3. Confirme que pretende continuar e, em seguida, selecione Implementar. Pode monitorizar o estado da implementação na janela de saída.

  4. Mude para o portal do Azure, navegue para Todos os Recursos. Procure a aplicação de funções que implementou com o nome globalmente exclusivo que forneceu num passo anterior.

    Dica

    Também pode clicar com o botão direito do rato na aplicação de funções no Visual Studio Code e selecionar Abrir no Portal.

  5. No portal, à esquerda, selecione Funções e, em seguida, selecione a função que criou.

  6. Na página de descrição geral da função, selecione Obter URL da Função na barra de comandos na parte superior. Isto permite-lhe copiar o URL para chamar a função.

    Captura de ecrã a mostrar o comando Obter URL da Função no portal do Azure.

Testar a função no Azure

Com a chave de anfitrião e o URL predefinidos que copiou, teste a função a partir de portal do Azure.

  1. À esquerda, em Programador, selecione Código + Teste.

  2. Selecione Testar/Executar na barra de comandos.

  3. Para entrada, utilize Post, a chave predefinida e, em seguida, cole no corpo do pedido:

    {
        "values": [
            {
                "recordId": "e1",
                "data":
                {
                    "text1":  "Hello",
                    "text2":  "World"
                }
            },
            {
                "recordId": "e2",
                "data": "This is an invalid input"
            }
        ]
    }
    
  4. Selecione Executar.

    Captura de ecrã a mostrar a especificação de entrada.

Este exemplo deve produzir o mesmo resultado que viu anteriormente ao executar a função no ambiente local.

Adicionar a um conjunto de competências

Agora que tem uma nova competência personalizada, pode adicioná-la ao seu conjunto de competências. O exemplo abaixo mostra-lhe como chamar a competência para concatenar o Título e o Autor do documento num único campo, a que chamamos merged_title_author.

Substitua [your-function-url-here] pelo URL da nova Função do Azure.

{
    "skills": [
      "[... other existing skills in the skillset are here]",  
      {
        "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
        "description": "Our new search custom skill",
        "uri": "https://[your-function-url-here]",        
          "context": "/document/merged_content/organizations/*",
          "inputs": [
            {
              "name": "text1",
              "source": "/document/metadata_title"
            },
            {
              "name": "text2",
              "source": "/document/metadata_author"
            },
          ],
          "outputs": [
            {
              "name": "text",
              "targetName": "merged_title_author"
            }
          ]
      }
  ]
}

Lembre-se de adicionar um "outputFieldMapping" na definição do indexador para enviar "merged_title_author" para um campo "fullname" no índice de pesquisa.

"outputFieldMappings": [
    {
        "sourceFieldName": "/document/content/merged_title_author",
        "targetFieldName": "fullname"
    }
]