Partager via


Exemple : Créer une compétence personnalisée à l’aide de Python (archivé)

Cet exemple est archivé et n’est pas pris en charge. Il a expliqué comment créer une compétence personnalisée d’API web à l’aide de Python et de Visual Studio Code. L’exemple utilisait une fonction Azure qui implémente l’interface de compétence personnalisée.

Prérequis

Création d’une fonction Azure

Cet exemple utilise une fonction Azure pour illustrer le concept d’hébergement d’une API web. Toutefois, d’autres approches sont possibles. Pour autant que vous respectiez les exigences d’interface pour une compétence cognitive, l’approche que vous adoptez est sans importance. Toutefois, Azure Functions facilite la création d’une compétence personnalisée.

Créer un projet pour la fonction

Le modèle de projet Azure Functions dans Visual Studio Code crée un projet local qui peut être publié dans une application de fonction sur Azure. Une application de fonctions vous permet de regrouper les fonctions dans une unité logique pour la gestion, le déploiement et le partage des ressources.

  1. Dans Visual Studio Code, appuyez sur F1 pour ouvrir la palette de commandes. Dans la palette de commandes, recherchez et sélectionnez Azure Functions: Create new project....
  2. Choisissez un emplacement de répertoire pour votre espace de travail de projet et optez pour Sélectionner. N’utilisez pas de dossier de projet qui fait déjà partie d’un autre espace de travail.
  3. Sélectionnez un langage pour votre projet d’application de fonction. Pour ce tutoriel, sélectionnez Python.
  4. Sélectionnez la version de Python (la version 3.7.5 est prise en charge par Azure Functions).
  5. Sélectionnez un modèle pour la première fonction de votre projet. Sélectionnez un déclencheur HTTP pour créer une fonction déclenchée via HTTP dans la nouvelle application de fonction.
  6. Attribuez un nom à la fonction. Dans ce cas, nous allons utiliser Concatenator.
  7. Sélectionnez Fonction comme niveau d’autorisation. Nous allons utiliser une clé d’accès à une fonction pour appeler le point de terminaison HTTP de la fonction.
  8. Spécifiez la façon dont vous souhaitez ouvrir votre projet. Pour cette étape, sélectionnez Ajouter à l’espace de travail afin de créer l’application de fonction dans l’espace de travail actuel.

Visual Studio Code crée le projet d’application de fonction dans un nouvel espace de travail. Ce projet contient les fichiers host.json et local.settings.jsonconfiguration, ainsi que tous les fichiers projet spécifiques à la langue.

Une nouvelle fonction déclenchée via HTTP est également créée dans le dossier Concatenator du projet d’application de fonction. Vous trouverez dans celui-ci un fichier nommé « __init__.py », dont le contenu est le suivant :

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
        )

Nous allons maintenant modifier ce code pour suivre l’interface de compétence personnalisée. Remplacez le code par défaut par le contenu suivant :

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
                    }
            })

La méthode transform_value effectue une opération sur un seul enregistrement. Vous pouvez modifier la méthode en fonction de vos besoins. N’oubliez pas d’effectuer les validations d’entrée nécessaires, et de retourner une erreur ou un avertissement si l’opération ne peut pas être effectuée.

Déboguer votre code localement

Visual Studio Code facilite le débogage de votre code. Appuyez sur F5 ou accédez au menu Déboguer pour sélectionner Démarrer le débogage.

Vous pouvez définir des points d’arrêt dans le code en appuyant sur F9 sur la ligne qui vous intéresse.

Une fois que vous avez démarré le débogage, votre fonction s’exécute localement. Vous pouvez utiliser un outil tel que Postman ou Fiddler pour envoyer la requête à localhost. Notez l’emplacement de votre point de terminaison local dans la fenêtre de terminal.

Créer une application de fonction dans Azure

Lorsque vous êtes satisfait du comportement de la fonction, vous pouvez la publier. Jusqu’à présent, vous avez travaillé localement. Dans cette section, vous allez créer une application de fonction dans Azure, puis y déployer le projet local.

Créer l’application à partir de Visual Studio Code

  1. Dans Visual Studio Code, appuyez sur F1 pour ouvrir la palette de commandes. Dans la palette de commandes, recherchez et sélectionnez Créer une application de fonction dans Azure.

  2. Si vous avez plusieurs abonnements actifs, sélectionnez l’abonnement pour cette application.

  3. Entrez un nom global unique pour l’application de fonction. Tapez un nom qui soit valide pour une URL.

  4. Sélectionnez une pile d’exécution et choisissez la version du langage que vous avez exécutée localement.

  5. Sélectionnez l’emplacement de votre application. Si possible, choisissez la même région que celle qui héberge votre service de recherche.

La création de l’application ne nécessite que quelques minutes. Quand elle est prête, la nouvelle application apparaît sous Ressources et Application de fonction pour l’abonnement actif.

Déployer sur Azure

  1. Toujours dans Visual Studio Code, appuyez sur F1 pour ouvrir la palette de commandes. Dans la palette de commandes, recherchez et sélectionnez Déployer dans l’application de fonction....

  2. Sélectionnez l’application de fonction que vous avez créée.

  3. Confirmez que vous souhaitez continuer, puis sélectionnez Déployer. Vous pouvez superviser l’état du déploiement dans la fenêtre de sortie.

  4. Accédez au portail Azure, puis à Toutes les ressources. Recherchez l’application de fonction que vous avez déployée en utilisant le nom global unique que vous avez fourni à l’étape précédente.

    Conseil

    Vous pouvez également cliquer avec le bouton droit sur l’application de fonction dans Visual Studio Code et sélectionner Ouvrir dans le portail.

  5. Dans le portail, à gauche, sélectionnez Fonctions, puis sélectionnez la fonction que vous avez créée.

  6. Dans la page de présentation de la fonction, sélectionnez Obtenir l’URL de la fonction dans la barre de commandes supérieure. Cela vous permettra de copier l’URL pour appeler la fonction.

    Capture d’écran de la commande Obtenir l’URL de la fonction dans le portail Azure.

Tester la fonction dans Azure

En utilisant l’URL et la clé d’hôte par défaut que vous avez copiées, testez votre fonction à partir du portail Azure.

  1. Sur la gauche, sous Développeur, sélectionnez Code + test.

  2. Sélectionnez Test/exécution dans la barre de commandes.

  3. En guise d’entrée, utilisez Post, la clé par défaut, puis collez le corps de la demande :

    {
        "values": [
            {
                "recordId": "e1",
                "data":
                {
                    "text1":  "Hello",
                    "text2":  "World"
                }
            },
            {
                "recordId": "e2",
                "data": "This is an invalid input"
            }
        ]
    }
    
  4. Sélectionnez Exécuter.

    Capture d’écran de la spécification de l’entrée.

Cet exemple devrait produire le même résultat que celui que vous avez obtenu précédemment lors de l’exécution de la fonction dans l’environnement local.

Ajouter à un ensemble de compétences

À présent que vous avez une nouvelle compétence personnalisée, vous pouvez l’ajouter à vos jeu de compétences. L’exemple ci-dessous montre comment appeler la compétence en vue de concaténer le titre et l’auteur du document dans un même champ unique, que nous appellerons merged_title_author.

Remplacez [your-function-url-here] par l’URL de votre nouvelle fonction 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"
            }
          ]
      }
  ]
}

N’oubliez pas d’ajouter un « outputFieldMapping » dans la définition de l’indexeur pour envoyer « merged_title_author » à un champ « fullname » dans l’index de recherche.

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