Проблема парсинга ответа Alexa json в python для получения имени значения - PullRequest
1 голос
/ 03 апреля 2019

Моему обработчику передано следующее намерение:

"request": {
    "type": "IntentRequest",
    "requestId": "amzn1.echo-api.request.3af5c8c3-1d1f-4169-8ce8-fde1a99a7c8d",
    "timestamp": "2019-04-03T04:08:06Z",
    "locale": "en-US",
    "intent": {
        "name": "get_speeds",
        "confirmationStatus": "NONE",
        "slots": {
            "direction": {
                "name": "direction",
                "value": "inbound",
                "resolutions": {
                    "resolutionsPerAuthority": [
                        {
                            "authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.e76bf13b-71ac-4a90-94d4-597aa597ae87.direction",
                            "status": {
                                "code": "ER_SUCCESS_MATCH"
                            },
                            "values": [
                                {
                                    "value": {
                                        "name": "inbound",
                                        "id": "a8e6fe5b9e68f30a146cefebaa7edcc3"
                                    }
                                }
                            ]
                        }
                    ]
                },
                "confirmationStatus": "NONE",
                "source": "USER"
            }
        }
    },
    "dialogState": "COMPLETED"
}

Я хочу извлечь фактическое значение, а не высказывание, например, имя значения, в данном случае «входящее». Я пробовал это и различные подобные итерации (отпечатки для отладки):

    slots = handler_input.request_envelope.request.intent.slots
    resolutions = slots["direction"].resolutions
    print(resolutions)
    print(resolutions["resolutions_per_authority"])
    direction = resolutions["resolutions_per_authority"][0]["values"][0]["value"]["name"]
    session_attr = handler_input.attributes_manager.session_attributes

Я также пытался сделать то же самое с «olutionsPerAuthority », который передает JSON, но, очевидно, не то, что выходит в мою программу, как в журнале:

04:08:07
{'resolutions_per_authority': [{'authority': 'amzn1.er-authority.echo-sdk.amzn1.ask.skill.e76bf13b-71ac-4a90-94d4-597aa597ae87.direction',

04:08:07
'status': {'code': 'ER_SUCCESS_MATCH'},

04:08:07
'values': [{'value': {'id': 'a8e6fe5b9e68f30a146cefebaa7edcc3',

04:08:07
'name': 'inbound'}}]}]}

04:08:07
'Resolutions' object is not subscriptable

Это ошибка, которую я постоянно получаю со всеми моими подходами: объект 'Resolutions' не подходит для подписки. Может кто-нибудь помочь мне с тем, как извлечь значения канонических слотов? Мне нужно сделать то же самое для нескольких других целей, но я думаю, что если я смогу заставить это работать, это станет моделью для других.

Ответы [ 2 ]

1 голос
/ 04 апреля 2019

Как вы уже указали, ваша проблема заключалась в том, что вы обрабатывали объект разрешения как доступный для подписки, обращаясь к нему через

resolutions.resolutions_per_authority[0].values[0].value

- верный способ получить его.

Может быть полезно указать, что в случае нескольких совпадений Alexa будет возвращать разрешения в порядке наиболее вероятного совпадения намерений пользователя.

Этот фрагмент кода выполняет итерации слотов и возвращает словарь python, содержащий только ключи, чтобы узнать, была ли она проверена, и идентификатор соответствующего значения:

from ask_sdk_model.slu.entityresolution import StatusCode

@staticmethod
def get_slot_values(filled_slots):
    """Return slot values with additional info."""
    slot_values = {}
    logger.info("Filled slots: {}".format(filled_slots).replace("\n", "\r"))

    for key, slot_item in six.iteritems(filled_slots):
        name = slot_item.name
        try:
            status_code = slot_item.resolutions.resolutions_per_authority[0].status.code

            if status_code == StatusCode.ER_SUCCESS_MATCH:
                slot_values[name] = {
                    "synonym": slot_item.value,
                    "resolved": slot_item.resolutions.resolutions_per_authority[0].values[0].value.__dict__,  # to make it JSON serializable
                    "is_validated": True,
                }
            elif status_code == StatusCode.ER_SUCCESS_NO_MATCH:
                slot_values[name] = {
                    "synonym": slot_item.value,
                    "resolved": slot_item.value,
                    "is_validated": False,
                }
            else:
                pass
        except (AttributeError, ValueError, KeyError, IndexError, TypeError) as e:
            # for BUILT-IN intents, there are no resolutions, but the value is specified
            if slot_item.value is not None and slot_item.value != 'NONE':
                slot_values[name] = {
                    "synonym": slot_item.value,
                    "resolved": slot_item.value,
                    "is_validated": True,
                }
            else:
                logger.info("SLOT {} UNRESOLVED".format(name))
                slot_values[name] = {
                    "synonym": slot_item.value,
                    "resolved": slot_item.value,
                    "is_validated": False,
                }
    return slot_values

, где filled_slots = handler_input.request_envelope.request.intent.slots

0 голосов
/ 03 апреля 2019

ОК, я наконец-то нашел пример на python, который использует объектно-ориентированную версию относительно нового SDK, как и я.Примером является Python-версия примера Amazon PetMatch .

Исходя из этого, работает следующее:

slots = handler_input.request_envelope.request.intent.slots
direction = slots["direction"].resolutions.resolutions_per_authority[0].values[0].value.name

Я все еще стремлюсь лучше понять, КАК это работает, но, по крайней мере, это работает, и может также помочь кому-то еще.Я нахожу, что с примерами Alexa и документацией, есть тонна, но она не очень хорошо организована, и API постоянно меняется, поэтому некоторые из того, что вы находите, оказываются устаревшими.

...