8000 Merge pull request #153 from Microsoft/cysu/recog · rsliang/botbuilder-python@c56d828 · GitHub
[go: up one dir, main page]

Skip to content

Commit c56d828

Browse files
authored
Merge pull request microsoft#153 from Microsoft/cysu/recog
serialization: py json interop
2 parents 20fd85b + d92de1a commit c56d828

File tree

7 files changed

+475
-41
lines changed

7 files changed

+475
-41
lines changed

libraries/botbuilder-ai/botbuilder/ai/luis/luis_prediction_options.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,29 @@ class LuisPredictionOptions(object):
99
Optional parameters for a LUIS prediction request.
1010
"""
1111

12-
def __init__(self, timeout: float = 100000):
13-
self._bing_spell_check_subscription_key: str = None
14-
self._include_all_intents: bool = None
15-
self._include_instance_data: bool = None
16-
self._log: bool = None
17-
self._spell_check: bool = None
18-
self._staging: bool = None
12+
def __init__(
13+
self,
14+
bing_spell_check_subscription_key: str = None,
15+
include_all_intents: bool = None,
16+
include_instance_data: bool = None,
17+
log: bool = None,
18+
spell_check: bool = None,
19+
staging: bool = None,
20+
timeout: float = 100000,
21+
timezone_offset: float = None,
22+
telemetry_client: BotTelemetryClient = NullTelemetryClient(),
23+
log_personal_information: bool = False,
24+
):
25+
self._bing_spell_check_subscription_key: str = bing_spell_check_subscription_key
26+
self._include_all_intents: bool = include_all_intents
27+
self._include_instance_data: bool = include_instance_data
28+
self._log: bool = log
29+
self._spell_check: bool = spell_check
30+
self._staging: bool = staging
1931
self._timeout: float = timeout
20-
self._timezone_offset: float = None
21-
self._telemetry_client: BotTelemetryClient = NullTelemetryClient()
22-
self._log_personal_information: bool = False
32+
self._timezone_offset: float = timezone_offset
33+
self._telemetry_client: BotTelemetryClient = telemetry_client
34+
self._log_personal_information: bool = log_personal_information
2335

2436
@property
2537
def bing_spell_check_subscription_key(self) -> str:

libraries/botbuilder-ai/botbuilder/ai/luis/luis_recognizer.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -336,11 +336,21 @@ async def _recognize_internal(
336336
recognizer_result, turn_context, telemetry_properties, telemetry_metrics
337337
)
338338

339+
await self._emit_trace_info(turn_context, luis_result, recognizer_result)
340+
341+
return recognizer_result
342+
343+
async def _emit_trace_info(
344+
self,
345+
turn_context: TurnContext,
346+
luis_result: LuisResult,
347+
recognizer_result: RecognizerResult,
348+
) -> None:
339349
trace_info: Dict[str, object] = {
340-
"recognizerResult": recognizer_result,
350+
"recognizerResult": LuisUtil.recognizer_result_as_dict(recognizer_result),
341351
"luisModel": {"ModelID": self._application.application_id},
342-
"luisOptions": self._options,
343-
"luisResult": luis_result,
352+
"luisOptions": {"Staging": self._options.staging},
353+
"luisResult": LuisUtil.luis_result_as_dict(luis_result),
344354
}
345355

346356
trace_activity = ActivityUtil.create_trace(
@@ -352,5 +362,3 @@ async def _recognize_internal(
352362
)
353363

354364
await turn_context.send_activity(trace_activity)
355-
356-
return recognizer_result

libraries/botbuilder-ai/botbuilder/ai/luis/luis_util.py

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
from collections import OrderedDict
66
from typing import Dict, List, Set, Union
77

8+
import azure.cognitiveservices.language.luis.runtime.models as runtime_models
89
from azure.cognitiveservices.language.luis.runtime.models import (
910
CompositeEntityModel,
1011
EntityModel,
1112
LuisResult,
1213
)
14+
from msrest import Serializer
1315

1416
from .. import __title__, __version__
1517
from . import IntentScore, RecognizerResult
@@ -28,7 +30,7 @@ def normalized_intent(intent: str) -> str:
2830

2931
@staticmethod
3032
def get_intents(luis_result: LuisResult) -> Dict[str, IntentScore]:
31-
if luis_result.intents:
33+
if luis_result.intents is not None:
3234
return {
3335
LuisUtil.normalized_intent(i.intent): IntentScore(i.score or 0)
3436
for i in luis_result.intents
@@ -45,7 +47,7 @@ def extract_entities_and_metadata(
4547
entities: List[EntityModel],
4648
composite_entities: List[CompositeEntityModel],
4749
verbose: bool,
48-
) -> Dict:
50+
) -> Dict[str, object]:
4951
entities_and_metadata = {}
5052
if verbose:
5153
entities_and_metadata[LuisUtil._metadata_key] = {}
@@ -130,7 +132,7 @@ def extract_entity_value(entity: EntityModel) -> object:
130132
"builtin.currency",
131133
"builtin.temperature",
132134
}:
133-
units = str(resolution.unit)
135+
units = resolution["unit"]
134136
val = LuisUtil.number(resolution["value"])
135137
obj = {}
136138
if val is not None:
@@ -139,7 +141,8 @@ def extract_entity_value(entity: EntityModel) -> object:
139141
obj["units"] = units
140142
return obj
141143
else:
142-
return resolution.get("value") or resolution.get("values")
144+
value = resolution.get("value")
145+
return value if value is not None else resolution.get("values")
143146

144147
@staticmethod
145148
def extract_entity_metadata(entity: EntityModel) -> Dict:
@@ -295,3 +298,50 @@ def get_user_agent():
295298
platform_user_agent = f"({os_version}; {py_version})"
296299
user_agent = f"{package_user_agent} {platform_user_agent}"
297300
return user_agent
301+
302+
@staticmethod
303+
def recognizer_result_as_dict(
304+
recognizer_result: RecognizerResult
305+
) -> Dict[str, object]:
306+
# an internal method that returns a dict for json serialization.
307+
308+
intents: Dict[str, Dict[str, float]] = {
309+
name: LuisUtil.intent_score_as_dict(intent_score)
310+
for name, intent_score in recognizer_result.intents.items()
311+
} if recognizer_result.intents is not None else None
312+
313+
d: Dict[str, object] = {
314+
"text": recognizer_result.text,
315+
"alteredText": recognizer_result.altered_text,
316+
"intents": intents,
317+
"entities": recognizer_result.entities,
318+
}
319+
320+
if recognizer_result.properties is not None:
321+
for key, value in recognizer_result.properties.items():
322+
if key not in d:
323+
if isinstance(value, LuisResult):
324+
d[key] = LuisUtil.luis_result_as_dict(value)
325+
else:
326+
d[key] = value
327+
328+
return d
329+
330+
@staticmethod
331+
def intent_score_as_dict(intent_score: IntentScore) -> Dict[str, float]:
332+
if intent_score is None:
333+
return None
334+
335+
return {"score": intent_score.score}
336+
337+
@staticmethod
338+
def luis_result_as_dict(luis_result: LuisResult) -> Dict[str, object]:
339+
if luis_result is None:
340+
return None
341+
342+
client_models = {
343+
k: v for k, v in runtime_models.__dict__.items() if isinstance(v, type)
344+
}
345+
serializer = Serializer(client_models)
346+
d = serializer.body(luis_result, "LuisResult")
347+
return d

libraries/botbuilder-ai/botbuilder/ai/luis/recognizer_result.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,21 +99,21 @@ def intents(self, value: Dict[str, IntentScore]) -> None:
9999
self._intents = value
100100

101101
@property
102-
def entities(self) -> Dict:
102+
def entities(self) -> Dict[str, object]:
103103
"""Gets the recognized top-level entities.
104104
105105
:return: Object with each top-level recognized entity as a key.
106-
:rtype: Dict
106+
:rtype: Dict[str, object]
107107
"""
108108

109109
return self._entities
110110

111111
@entities.setter
112-
def entities(self, value: Dict) -> None:
112+
def entities(self, value: Dict[str, object]) -> None:
113113
"""Sets the recognized top-level entities.
114114
115115
:param value: Object with each top-level recognized entity as a key.
116-
:type value: Dict
116+
:type value: Dict[str, object]
117117
:return:
118118
:rtype: None
119119
"""

0 commit comments

Comments
 (0)
0