def get_param( response: session_pb2.DetectIntentResponse, param_name: str, context_name: str, ) -> Any: logger_console.info({ "message": "getting param", "content": context_name, "tags": ["parameters"] }) context = ParameterMethods.get_context(response=response, context_name=context_name) if context is None: return None params = list(context.parameters) if param_name in params: returned_param = context.parameters[param_name] else: returned_param = "None" try: returned_param = MessageToJson(returned_param) except AttributeError: pass logger_console.info({ "message": "found param", "content": returned_param }) return context.parameters[param_name] if param_name in params else None
def delete_param_from_cai_context( client: Client, response: session_pb2.DetectIntentResponse, param_name: str, context: str ) -> None: logger_console.info( { "message": "deleting parameter from cai", "paramter": param_name, "context": context, "tags": ["parameters", "contexts"], } ) session = get_session_from_response(response) context_name = f"{session}/contexts/{context}" existing_context = client.services.contexts.get_context(request=context_pb2.GetContextRequest(name=context_name)) try: del existing_context.parameters[param_name] client.services.contexts.delete_context(request=context_pb2.DeleteContextRequest(name=context_name)) client.services.contexts.create_context( request=context_pb2.CreateContextRequest(parent=session, context=existing_context) ) except KeyError: logger_console.exception( { "message": "tried to delete param that didnt exist", "parameter": param_name, "context": context, "tags": ["parameters", "contexts"], } )
def strip_seconds( response: session_pb2.DetectIntentResponse, ) -> session_pb2.DetectIntentResponse: logger_console.info("strip seconds from text in response") for message in response.query_result.fulfillment_messages: if not len(message.text.text): continue SingleMessageHandler.strip_seconds_in_message(message) return response
def reformat_date( response: session_pb2.DetectIntentResponse, ) -> session_pb2.DetectIntentResponse: logger_console.info("reformatting date in response") for message in response.query_result.fulfillment_messages: if not len(message.text.text): continue SingleMessageHandler.reformat_date_in_message(message) return response
def test_log(log_store): CONSOLE_TEXT = "console log" logger_console.addHandler(log_store) logger_console.debug(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["debug"] logger_console.info(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["info"] logger_console.warning(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["warning"] logger_console.error(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["error"] logger_console.critical(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["critical"] CONSOLE_TEXT = "debug log" logger_debug.addHandler(log_store) logger_debug.debug(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["debug"] logger_debug.info(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["info"] logger_debug.warning(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["warning"] logger_debug.error(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["error"] logger_debug.critical(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["critical"] CONSOLE_TEXT = "root log" logger_root.addHandler(log_store) logger_root.debug(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["debug"] logger_root.info(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["info"] logger_root.warning(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["warning"] logger_root.error(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["error"] logger_root.critical(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["critical"] assert len(log_store.messages["critical"]) == 3 log_store.reset() assert len(log_store.messages["critical"]) == 0 CONSOLE_TEXT = "root log 2" logger.addHandler(log_store) logger.debug(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["debug"] logger.info(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["info"] logger.warning(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["warning"] logger.error(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["error"] logger.critical(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["critical"]
def delete_param_from_response(response: session_pb2.DetectIntentResponse, param_name: str) -> None: logger_console.info({ "message": "deleting parameter from response", "parameter": param_name, "tags": ["parameters"] }) for context in response.query_result.output_contexts: if param_name in context.parameters: del context.parameters[param_name]
def add_weekday( response: session_pb2.DetectIntentResponse, days: Union[EnglishDays, GermanDays] = GermanDays ) -> session_pb2.DetectIntentResponse: logger_console.info("add weekday to date in response") for message in response.query_result.fulfillment_messages: if not len(message.text.text): continue SingleMessageHandler.add_weekday_in_message(message, days) return response
def detect_intent( client: Client, response: session_pb2.DetectIntentResponse, text: str ) -> session_pb2.DetectIntentResponse: logger_console.info({"message": "detect intent triggered in bpi helpers", "tags": ["timing"]}) request = get_detect_intent_request(text=text, session=get_session_from_response(response=response),) logger_console.info({"message": "detect intent returned in bpi helpers", "tags": ["timing"]}) result = client.services.sessions.detect_intent(request) logger_console.warning(f"wrote {text}, received {result.query_result.fulfillment_messages}") return result
def _log_default_config(self) -> None: client_configuration_str = ( "\nnlu-client configuration:\n" + f" Secure: {SECURE}\n" + f" Host: {CAI_HOST}\n" + f" Port: {CAI_PORT}\n" + f" Http_token: {HTTP_AUTH_TOKEN}\n" + f" User_name: {USER_NAME}\n" + f" Password: {USER_PASS}\n" ) logger_console.info(client_configuration_str)
def substitute_pattern( pattern: str, replace: str, response: session_pb2.DetectIntentResponse, ) -> session_pb2.DetectIntentResponse: logger_console.info({ "message": "replacing text in response", "pattern": pattern, "replace": replace }) for j, message in enumerate( response.query_result.fulfillment_messages): SingleMessageHandler.substitute_pattern_in_message( message, pattern, replace) return response
def test_handler_level_manipulation(log_store): CONSOLE_TEXT = "console log" logger_console.setLevel(logging.DEBUG) logger_console.addHandler(log_store) logger_console.debug(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["debug"] for handler in logger_console.handlers: handler.setLevel(logging.INFO) log_store.reset() assert len(log_store.messages["debug"]) == 0 logger_console.debug(CONSOLE_TEXT) assert CONSOLE_TEXT not in log_store.messages["debug"] logger_console.info(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["info"]
def _strip_seconds_text( message: intent_pb2.Intent.Message) -> intent_pb2.Intent.Message: match: Union[bool, re.Match] = True # type: ignore while match: match = re.match(r"(.*)(\d\d:\d\d:\d\d)(.*)", message.text.text[0]) # type: ignore if match: time = match.groups()[1] new_response = "".join( [match.groups()[0], time[:-3], match.groups()[2]] # type: ignore ) message.text.text[0] = new_response logger_console.info( f"DATE: {time} formatted to DATE: {time[:-2]}") return message
def add_params_to_response( response: session_pb2.DetectIntentResponse, params: Dict[str, Any], context_name: str, ) -> session_pb2.DetectIntentResponse: logger_console.info({ "message": "adding parameter to response", "paramter": params, "context": context_name, "tags": ["parameters", "contexts"], }) parameters = create_parameter_dict(params) for j, i in enumerate(response.query_result.output_contexts): if i.name == context_name: for k, v in parameters.items(): i.parameters[k].CopyFrom(v) return response
def get_context(response: session_pb2.DetectIntentResponse, context_name: str) -> Optional[context_pb2.Context]: logger_console.info({ "message": "searching for context", "content": context_name, "tags": ["contexts"] }) context = [ c for c in response.query_result.output_contexts if c.name == context_name ] logger_console.info({ "message": "found context", "content": MessageToJson(context[0]) if len(context) else "None" }) return context[0] if len(context) else None
def _reformat_date_text( message: intent_pb2.Intent.Message) -> intent_pb2.Intent.Message: match: Union[bool, re.Match] = True # type: ignore while match: match = re.match(r"(.*)(\d{4}.*T\d\d:\d\d:\d\d)(.*)", message.text.text[0]) # type: ignore if match: date = datetime.datetime.fromisoformat( match.groups()[1]) # type: ignore new_response = "".join([ match.groups()[0], date.strftime(DATE_FORMAT), match.groups()[2] ] # type: ignore ) message.text.text[0] = new_response logger_console.info( f"DATE: {date} formatted to DATE: {date.strftime(DATE_FORMAT)}" ) return message
def process_intent_handler( self, cai_response: session_pb2.DetectIntentResponse ) -> session_pb2.DetectIntentResponse: # Create an ordered dictionary by key value length intent_name = cai_response.query_result.intent.display_name handlers: List[Callable] = self._get_handlers_for_intent( intent_name, self.intent_handlers) for handler in handlers: cai_response = handler(cai_response, self.client) text = [ i.text.text for i in cai_response.query_result.fulfillment_messages ] logger_console.info({ "message": f"BPI-DetectIntentResponse from BPI with text: {text}", "content": text, "text": text, "tags": ["text", "clean"], }) return cai_response
def get_triggers(message: intent_pb2.Intent.Message, session_id: Optional[str] = None) -> Dict[str, List[str]]: found_triggers: Dict[str, List[str]] = {} for trigger in SipTriggers: if SingleMessageHandler.check_message_for_pattern( message, trigger.value): content = SingleMessageHandler.get_pattern_from_message( message, trigger.value) found_triggers[trigger.value] = content for qtrigger in QueryTriggers: if SingleMessageHandler.check_message_for_pattern( message, qtrigger.value): content = SingleMessageHandler.get_pattern_from_message( message, qtrigger.value) found_triggers[qtrigger.value] = content if len(found_triggers): logger_console.info({ "message": f"Found triggers: {found_triggers}", "found_triggers": found_triggers, "session_id": session_id }) return found_triggers
def _add_params_to_cai_context( client: Client, session: str, params: Dict[str, Any], context: str, ) -> None: logger_console.info( { "message": "adding parameter to cai", "paramter": params, "context": context, "tags": ["parameters", "contexts"], } ) parameters = create_parameter_dict(params) try: request = context_pb2.GetContextRequest(name=f"{session}/contexts/{context}") existing_context = client.services.contexts.get_context(request) for k, v in parameters.items(): existing_context.parameters[k].CopyFrom(v) client.services.contexts.update_context( request=context_pb2.UpdateContextRequest( context=existing_context ) ) except _InactiveRpcError: context = context_pb2.Context( name=f"{session}/contexts/{context}", lifespan_count=100, parameters=parameters, lifespan_time=1000 ) client.services.contexts.create_context( request=context_pb2.CreateContextRequest( parent=f'{session}', context=context, ) )
def _add_weekday_text( message: intent_pb2.Intent.Message, days: Union[EnglishDays, GermanDays]) -> intent_pb2.Intent.Message: date_regex = r"\d\d\D\d\d\D\d\d\d\d" matches = len(re.findall(date_regex, message.text.text[0])) if matches > 1: print( "Multiple date subtitutions on one line! Not supported. Will only substitute the first" ) match = re.match(fr"(.*)({date_regex})(.*)", message.text.text[0]) # type: ignore if match: time = match.groups()[1] day_of_the_week_index = int( datetime.datetime.strptime(time, DATE_FORMAT_BACK).strftime("%w")) day = list(iter(days))[day_of_the_week_index].value new_response = "".join( [match.groups()[0], day, time, match.groups()[2]] # type: ignore ) message.text.text[0] = new_response logger_console.info(f"DATE: {time} formatted to DATE: {time[:-2]}") return message
def serve(self) -> None: logger_console.info(f"attempting to start server on port {PORT}") self._setup_server() logger_console.warning({"message": f"Server started on port {PORT}", "content": PORT}) logger_console.warning( { "message": f"using intent handlers list: {self.intent_handlers}", "content": self.intent_handlers, } ) try: while True: time.sleep(10) except KeyboardInterrupt: logger_console.info("Keyboard interrupt, shutting down") logger_console.info({"message": "server shut down", "tags": ["timing"]})
QA_THRESHOLD_RETRIEVER: float = float(os.getenv("QA_THRESHOLD_RETRIEVER", "0.5")) QA_ACTIVE: bool = True if os.getenv("QA_ACTIVE", "False") == "True" else False QA_SECURE: Optional[str] = os.getenv("QA_SECURE", "False") client_configuration_str = ( "\nqa-client configuration:\n" + f" Secure: {QA_SECURE}\n" + f" Host: {QA_HOST}\n" + f" Port: {QA_PORT}\n" + f" Language: {QA_LANG}\n" + f" Number of answers per query: {QA_MAX_ANSWERS}\n" + f" Reader threshold: {QA_THRESHOLD_READER}\n" + f" Retriever threshold: {QA_THRESHOLD_RETRIEVER}\n" + f" Is active?: {QA_ACTIVE}\n" ) logger_console.info(client_configuration_str) class QAClientProvider: """ provide a central qa-client instance to the bpi server without building it on import """ def __init__(self) -> None: self.config = None self.client = None self._built = False def instantiate_client(self, qa_port: str = "") -> Tuple[ClientConfig, Client]: if qa_port == "": qa_port = QA_PORT
def CreateContext(self, request: context_pb2.CreateContextRequest, context: grpc.ServicerContext) -> context_pb2.Context: logger_console.info("passing create context request on to CAI") return self.client.services.contexts.create_context(request=request)
def Login(self, request: user_pb2.LoginRequest, context: grpc.ServicerContext) -> user_pb2.LoginResponse: logger_console.info(f'Login request handled by bpi\n' f'Login user: {request.user_email}') return super().Login(request, context)
def test_level_manipulation(log_store): CONSOLE_TEXT = "console log" logger_console.addHandler(log_store) logger_console.debug(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["debug"] logger_console.setLevel(logging.INFO) log_store.reset() assert len(log_store.messages["debug"]) == 0 logger_console.debug(CONSOLE_TEXT) assert CONSOLE_TEXT not in log_store.messages["debug"] logger_console.info(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["info"] logger_console.setLevel(logging.WARN) log_store.reset() assert len(log_store.messages["info"]) == 0 logger_console.debug(CONSOLE_TEXT) assert CONSOLE_TEXT not in log_store.messages["debug"] logger_console.info(CONSOLE_TEXT) assert CONSOLE_TEXT not in log_store.messages["info"] logger_console.warning(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["warning"] logger_console.setLevel(logging.ERROR) log_store.reset() assert len(log_store.messages["warning"]) == 0 logger_console.debug(CONSOLE_TEXT) assert CONSOLE_TEXT not in log_store.messages["debug"] logger_console.info(CONSOLE_TEXT) assert CONSOLE_TEXT not in log_store.messages["info"] logger_console.warning(CONSOLE_TEXT) assert CONSOLE_TEXT not in log_store.messages["warning"] logger_console.error(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["error"] logger_console.setLevel(logging.CRITICAL) log_store.reset() assert len(log_store.messages["error"]) == 0 logger_console.debug(CONSOLE_TEXT) assert CONSOLE_TEXT not in log_store.messages["debug"] logger_console.info(CONSOLE_TEXT) assert CONSOLE_TEXT not in log_store.messages["info"] logger_console.warning(CONSOLE_TEXT) assert CONSOLE_TEXT not in log_store.messages["warning"] logger_console.error(CONSOLE_TEXT) assert CONSOLE_TEXT not in log_store.messages["error"] logger_console.critical(CONSOLE_TEXT) assert CONSOLE_TEXT in log_store.messages["critical"] logger_console.setLevel(logging.CRITICAL + 1) log_store.reset() assert len(log_store.messages["error"]) == 0 logger_console.debug(CONSOLE_TEXT) assert CONSOLE_TEXT not in log_store.messages["debug"] logger_console.info(CONSOLE_TEXT) assert CONSOLE_TEXT not in log_store.messages["info"] logger_console.warning(CONSOLE_TEXT) assert CONSOLE_TEXT not in log_store.messages["warning"] logger_console.error(CONSOLE_TEXT) assert CONSOLE_TEXT not in log_store.messages["error"] logger_console.critical(CONSOLE_TEXT) assert CONSOLE_TEXT not in log_store.messages["critical"]