Skip to content

[Bug]: adaptie cards search results causes AttributeError: 'dict' object has no attribute 'is_xml_model' #2547

@ameijer552

Description

@ameijer552

Language

Python

Version

latest (1.8.1)

Description

while following the guide 03.adaptiveCards.a.typeAheadBot i encounterd the following error:
Traceback (most recent call last):
File "/usr/src/app/.venv/lib/python3.12/site-packages/msrest/serialization.py", line 494, in _serialize
is_xml_model_serialization = kwargs["is_xml"]
~~~~~~^^^^^^^^^^
KeyError: 'is_xml'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/src/app/.venv/lib/python3.12/site-packages/botbuilder/core/integration/aiohttp_channel_service_exception_middleware.py", line 21, in aiohttp_error_middleware
response = await handler(request)
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/app/src/main.py", line 508, in on_messages
res = await app.process(req)
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/app/.venv/lib/python3.12/site-packages/teams/app.py", line 742, in process
return await self._adapter.process(request, self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/app/.venv/lib/python3.12/site-packages/teams/teams_adapter.py", line 101, in process
res = await super().process(
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/app/.venv/lib/python3.12/site-packages/botbuilder/integration/aiohttp/cloud_adapter.py", line 108, in process
data=serializer_helper(invoke_response.body),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/app/.venv/lib/python3.12/site-packages/botbuilder/core/serializer_helper.py", line 40, in serializer_helper
return serializer._serialize(object_to_serialize)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/app/.venv/lib/python3.12/site-packages/msrest/serialization.py", line 496, in _serialize
is_xml_model_serialization = kwargs.setdefault("is_xml", target_obj.is_xml_model())
^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'dict' object has no attribute 'is_xml_model'

===============================
The output is an list of AdaptiveCardsSearchResult, what ever i do nothing work. eventualy i found an temporary workaround, its not pretty but it works, unless someone else has a beter alternative.

from botbuilder.schema import Activity
from botbuilder.core import InvokeResponse, TurnContext

from msrest.serialization import Model

class SearchResponseValue(Model):
    _attribute_map = {"results": {"key": "results", "type": "[object]"}}
    def __init__(self, results: list[dict]):
        self.results = results

class SearchResponse(Model):
    _attribute_map = {
        "type": {"key": "type", "type": "str"},
        "value": {"key": "value", "type": "SearchResponseValue"},
    }
    def __init__(self, results: list[dict]):
        self.type = "application/vnd.microsoft.search.searchResponse"
        self.value = SearchResponseValue(results)

# inside the def....
    invoke_response = InvokeResponse(status=200, body=SearchResponse(results))

    context.turn_state[context._INVOKE_RESPONSE_KEY] = invoke_response

    await context.send_activity(
        Activity(
            type="invokeResponse", value=invoke_response
        )
    )
    # Return an empty list to bypass the internal working of the adaptive card search thus avoiding the serialisation bug.
    return []

Reproduction Steps

1. follow the example (03.adaptiveCards.a.typeAheadBot) [https://github.com/microsoft/teams-ai/tree/main/python/samples/03.adaptiveCards.a.typeAheadBot/src]

2. use the following code:

@app.adaptive_cards.search("npmpackages")
async def search_npm_package(
    _context: TurnContext, _state: AppTurnState, query: Query[AdaptiveCardsSearchParams]
):
    search_query = query.parameters.query_text
    count = query.count
    async with aiohttp.ClientSession() as session:
        async with session.get(
            f"http://registry.npmjs.com/-/v1/search?text={search_query}&size={count})"
        ) as response:
            data = await response.json()
            npm_packages = []
            for obj in data["objects"]:
                result = AdaptiveCardsSearchResult(
                    title= obj["package"]["name"],
                    value= f"{obj['package']['name']} - {obj['package'].get('description','')}",
                )
                npm_packages.append(result)
            return npm_packages

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions