Поделиться через


Пример. Создание пользовательского навыка с помощью Python (архивный)

Этот пример архивирован и не поддерживается. В ней объясняется, как создать настраиваемый навык веб-API с помощью Python и Visual Studio Code. В примере использовалась функция Azure , реализующая пользовательский интерфейс навыка.

Предварительные требования

Создание функции Azure

В этом примере для демонстрации концепции размещения веб-API используется Функция Azure, однако возможны также и другие варианты. При условии соблюдения требований к интерфейсу для когнитивного навыка выбранный вами подход не имеет значения. Однако Функции Azure упрощают создание пользовательских навыков.

Создание проекта для функции

Шаблон проекта Функции Azure в Visual Studio Code создает локальный проект, который можно опубликовать в приложении-функции в Azure. Приложение-функция позволяет группировать функции в логические единицы для развертывания и совместного использования ресурсов, а также управления ими.

  1. В Visual Studio Code нажмите клавишу F1, чтобы открыть палитру команд. В палитре команд найдите и щелкните Azure Functions: Create new project....
  2. Выберите расположение для рабочей области проекта и нажмите кнопку Выбрать. Не используйте папку проекта, которая уже является частью другой рабочей области.
  3. Выберите язык для проекта приложения-функции. Для работы с этим учебником выберите Python.
  4. Выберите версию Python (версия 3.7.5 поддерживается Функции Azure).
  5. Выберите шаблон для первой функции проекта. Выберите Триггер HTTP, чтобы создать в новом приложении-функции функцию, запускаемую по протоколу HTTP.
  6. Укажите имя функции. В этом случае попробуем использовать Concatenator
  7. Выберите элемент Функция в качестве уровня авторизации. Вы будете использовать ключ доступа функции для вызова конечной точки HTTP функции.
  8. Укажите способ открытия проекта. На этом этапе выберите Добавить в рабочую область, чтобы создать приложение-функцию в текущей рабочей области.

Редактор Visual Studio Code создаст проект приложения-функции в новой рабочей области. Этот проект содержит файлы host.json и local.settings.jsonconfiguration, а также все языковые файлы проекта.

Новая функция, запускаемая по протоколу HTTP, также создается в папке Concatenator проекта приложения-функции. Внутри него будет файл с именем "__init__.py" со следующим содержимым:

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
        )

Теперь давайте изменим этот код, чтобы следовать пользовательскому интерфейсу навыка. Замените код по умолчанию следующим содержимым:

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

Метод transform_value выполняет операцию в одной записи. Вы можете изменить метод в соответствии с конкретными потребностями. Не забудьте выполнить необходимую проверку входных данных и возвращать ошибки и предупреждения, если операция не может быть завершена.

Отладка кода в локальной среде

Visual Studio Code упрощает отладку кода. Нажмите клавишу F5 или выберите команду Начать отладку в меню Отладка.

Вы можете задать любые точки останова в коде, нажав в соответствующей строке клавишу F9.

После начала отладки функция будет выполняться локально. Вы можете использовать такой инструмент, как Postman или Fiddler, чтобы отправить запрос в localhost. Обратите внимание на расположение локальной конечной точки в окне терминала.

Создание приложения-функции в Azure

Если вы удовлетворены поведением функции, ее можно опубликовать. До сих пор вы работали локально. В этом разделе вы создадите приложение-функцию в Azure, а затем развернете локальный проект в созданном приложении.

Создание приложения из Visual Studio Code

  1. В Visual Studio Code нажмите клавишу F1, чтобы открыть палитру команд. В палитре команд найдите и выберите Создать приложение-функцию в Azure.

  2. Если у вас несколько активных подписок, выберите подписку для этого приложения.

  3. Введите глобально уникальное имя приложения-функции. Введите имя, допустимое для URL-адреса.

  4. Выберите стек среды выполнения и версию языка, на котором вы работали локально.

  5. Выберите расположение для вашего приложения. По возможности выберите тот же регион, в котором также размещена служба поиска.

Создание приложения занимает несколько минут. Когда оно будет готово, вы увидите новое приложение в разделе Ресурсы и приложение-функция активной подписки.

Развернуть в Azure

  1. В Visual Studio Code нажмите клавишу F1, чтобы открыть палитру команд. В палитре команд найдите и щелкните Deploy to Function App... (Развернуть в приложение-функцию…).

  2. Выберите созданное приложение-функцию.

  3. Подтвердите, что вы хотите продолжить, а затем выберите Развернуть. Состояние развертывания можно отслеживать в окне вывода.

  4. Перейдите в портал Azure и выберите Все ресурсы. Найдите развернутое приложение-функцию, используя глобально уникальное имя, которое вы указали на предыдущем шаге.

    Совет

    Вы также можете щелкнуть правой кнопкой мыши приложение-функцию в Visual Studio Code и выбрать Открыть на портале.

  5. На портале слева выберите Функции, а затем выберите созданную функцию.

  6. На странице обзора функции выберите Получить URL-адрес функции на панели команд вверху. Это позволит скопировать URL-адрес для вызова функции.

    Снимок экрана: команда Get Function URL (Получить URL-адрес функции) в портал Azure.

Тестирование функции в Azure

Используя ключ узла по умолчанию и URL-адрес, которые вы скопировали, протестируйте функцию в портал Azure.

  1. Слева в разделе Разработчик выберите Код и тестирование.

  2. Выберите Тест/запуск на панели команд.

  3. Для ввода используйте Post, ключ по умолчанию, а затем вставьте в текст запроса:

    {
        "values": [
            {
                "recordId": "e1",
                "data":
                {
                    "text1":  "Hello",
                    "text2":  "World"
                }
            },
            {
                "recordId": "e2",
                "data": "This is an invalid input"
            }
        ]
    }
    
  4. Выберите Запуск.

    Снимок экрана: спецификация входных данных.

Этот пример должен дать тот же результат, как и при запуске функции в локальной среде.

Добавление в набор навыков

Теперь, когда у вас есть новый пользовательский навык, можно добавить его в ваш набор навыков. В приведенном ниже примере показано, как вызвать навык для объединения заголовка и автора документа в одно поле, которое мы называем merged_title_author.

Замените [your-function-url-here] URL-адресом новой Функции 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"
            }
          ]
      }
  ]
}

Не забудьте добавить "outputFieldMapping" в определение индексатора, чтобы отправить "merged_title_author" в поле "fullname" в индексе поиска.

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