def fulfill(self, convo, tx, slot_data): if not self.fulfillment: dbg('Nothing to fulfill for intent %s' % self.name) return dbg('Handling fulfillment for intent %s: %s' % (self.name, self.fulfillment)) url = self.fulfillment['url'] status_code = None fulfillment_data = self.get_fulfillment_data(convo, tx, slot_data) try: resp = requests.post(url, json=fulfillment_data) status_code = resp.status_code content = resp.content resp.raise_for_status() return FulfillmentResponse('%s_fulfillment' % self.name, **resp.json()) except Exception as e: content = str(e) raise finally: ff = Fulfillments(conversation_id=convo.id, url=url, status_code=status_code, response=content, data=json.dumps(fulfillment_data)) db.session.merge(ff) db.session.commit()
def run(self, result=None): if self.DEBUG and (result.failures or result.errors): if result.failures: dbg(result.failures) if result.errors: dbg(result.errors) st() super(TestBase, self).run(result)
def train(self, asynchronous=True, app_version=None): app_version = app_version or self.app_version dbg('Training app, asynchronous:%s' % asynchronous) result = self.authoring_client.train.train_version(self.app_id, app_version) if asynchronous: return LUISNLU.to_application_training_result(result) result = poll_call(self.get_application_training_status, 'status', 'Trained', 1, 100, app_version=app_version) return LUISNLU.to_application_training_result(result)
def main(f, bot, version, train, publish, dry_run, force): schema = IntentConfigFileSchema() parse_schema_file(f, schema) bot_config = get_bot_config(bot) nlu = get_nlu(bot_config) versions = {x['version']: x for x in nlu.get_application_versions()} if version not in versions: print( 'Version "%s" is not in current versions. A new version will be created' % version) if not force: answer = prompt_user( 'Are you sure you want to create a new app version?', ['y', 'n']) if answer == 'n': print('Exiting.') return nlu.clone_current_version(version) else: if not force: answer = prompt_user( 'Are you sure you want to add intents to existing version "%s"?' % version, ['y', 'n']) if answer == 'n': print('Exiting.') return current_intents = { x['name']: x for x in nlu.get_intents(app_version=version) } for intent_name, intent_data in bot_config.intent_configs.items(): dbg('---- Processing intent "%s"' % intent_name) intent = current_intents.get(intent_name, None) if not intent: intent = nlu.add_intent(intent_name, app_version=version) if intent_data.utterances: current_utterances = { x['text'].lower(): x for x in nlu.get_utterances(intent, app_version=version) } for utterance in intent_data.utterances: if utterance.lower() not in current_utterances: nlu.add_utterance(intent, utterance, app_version=version) if train or publish: nlu.train(app_version=version) if publish: nlu.publish(app_version=version, is_staging=True) nlu.publish(app_version=version, is_staging=False)
def get_convo_cache(app_config): # TODO: in production, replace with something multi-process friendly global CONVO_CACHE if CONVO_CACHE is not None: return CONVO_CACHE dbg('Initializing TTLCache for conversations', config=app_config) cache_size = app_config.get('CONVO_CACHE_SIZE', DEFAULT_CONVO_CACHE_SIZE) cache_ttl = app_config.get('CONVO_CACHE_TTL', DEFAULT_CONVO_CACHE_TTL) CONVO_CACHE = TTLCache(cache_size, cache_ttl) return CONVO_CACHE
def luis_predict(client, query, config=None, staging=True, verbose=True): if not config: config = current_app.config key = (query, staging, verbose) nlu_cache = get_nlu_cache(config) if nlu_cache is not None: nlu_result = nlu_cache.get(key, None) if nlu_result: dbg('Using cached NLU result for key %s' % str(key)) return nlu_result luis_result = client.prediction.resolve(config['luis_app_id'], query, verbose=verbose, staging=staging, timezone_offset='-300') result = luis_result.as_dict() if nlu_cache is not None: nlu_cache[key] = result return result
def get_nlu_cache(app_config): # TODO: in production, replace with something multi-process friendly global NLU_CACHE if NLU_CACHE is not None: return NLU_CACHE if not app_config.get('NLU_CACHE', False): return None if app_config['DEBUG']: dbg('Initializing DiskCache for NLU', config=app_config) cache_dir = app_config.get('NLU_DISK_CACHE_DIR', '/tmp') ttl = app_config.get('NLU_DISK_CACHE_TTL', DEFAULT_NLU_DISK_CACHE_TTL) NLU_CACHE = DiskCache(cache_dir, ttl=ttl) return NLU_CACHE dbg('Initializing LRUCache for NLU', config=app_config) nlu_size = app_config.get('NLU_CACHE_SIZE', DEFAULT_NLU_CACHE_SIZE) NLU_CACHE = LRUCache(nlu_size) return NLU_CACHE
def load_bot_configs_from_directory(self, load_tests=False, load_utterances=False): """Load bot configs from app config directory""" directory = self.app_config['BOT_CONFIG_DIRECTORY'].rstrip('/') files = glob.glob("%s/*.json" % directory) bot_file_schema = BotConfigFileSchema() intent_file_schema = IntentConfigFileSchema() smalltalk_intent_configs = None count = 0 for filename in files: bot_config = parse_schema_file(filename, bot_file_schema) bot_name = os.path.basename(filename).split('.json')[0] entity_handlers = copy.deepcopy(COMMON_ENTITY_HANDLERS) bot_entity_handlers = bot_config.get('entity_handlers', {}) entity_handlers.update(bot_entity_handlers) common_interactions = copy.deepcopy(COMMON_INTERACTIONS) bot_common_interactions = bot_config.get('common_interactions', {}) common_interactions.update(bot_common_interactions) common_interactions = InteractionMap(common_interactions) intent_configs = copy.deepcopy(COMMON_INTENT_CONFIGS) bot_intent_configs = bot_config.get('intent_configs', {}) check_bot_intent_configs(bot_intent_configs) intent_configs.update(bot_intent_configs) # We always add the smalltalk configs whether it is enabled or not so the bot # can recognize which intents are smalltalk even if it doesnt support them if not smalltalk_intent_configs: result = parse_schema_file(SMALLTALK_INTENT_FILE, intent_file_schema) smalltalk_intent_configs = result['intent_configs'] update = {'is_smalltalk': True, 'is_repeatable': True, 'is_preemptive': True} update_intents(smalltalk_intent_configs, update) intent_configs.update(smalltalk_intent_configs) if not load_utterances: clear_utterances(intent_configs) convert_to_intent_objects(intent_configs, entity_handlers) self.configs[bot_name] = BotConfig( bot_name, intent_configs, entity_handlers, common_interactions, bot_config.get('nlu_class', self.app_config.get('NLU_CLASS', DEFAULT_NLU_CLASS)), bot_config.get('nlu_config', self.app_config['NLU_CONFIG']), new_intent_limit=bot_config.get('new_intent_limit', self.app_config.get('NEW_INTENT_LIMIT', DEFAULT_NEW_INTENT_LIMIT)), intent_filter_threshold=bot_config.get('intent_filter_threshold', DEFAULT_INTENT_FILTER_THRESHOLD), entity_filter_threshold=bot_config.get('entity_filter_threshold', DEFAULT_ENTITY_FILTER_THRESHOLD), max_question_attempts=bot_config.get('max_question_attempts', DEFAULT_MAX_QUESTION_ATTEMPTS), max_consecutive_interaction_attempts=bot_config.get('max_consecutive_interaction_attempts', DEFAULT_MAX_CONSECUTIVE_INTERACTION_ATTEMPTS), max_consecutive_repeat_attempts=bot_config.get('max_consecutive_repeat_attempts', DEFAULT_MAX_CONSECUTIVE_REPEAT_ATTEMPTS), smalltalk=bot_config.get('smalltalk', False), tests=bot_config.get('tests', {}) if load_tests else {} ) count += 1 dbg('Loaded %d bot configs' % count)
def add_utterance(self, intent, utterance, app_version=None): app_version = app_version or self.app_version dbg('Adding utterance "%s" to intent %s' % (utterance, intent['name'])) example = ExampleLabelObject(text=utterance, intent_name=intent['name']) result = self.authoring_client.examples.add(self.app_id, app_version, example) return LUISNLU.to_utterance(result)
def add_intent(self, name, app_version=None): app_version = app_version or self.app_version dbg('Adding intent %s to LUIS app %s/%s' % (name, self.app_id, app_version)) # This just returns the intent ID as a string currently. intent_id = self.authoring_client.model.add_intent(self.app_id, app_version, name) return Intent(name, api_id=intent_id)
def publish(self, is_staging=True, region='westus', app_version=None): app_version = app_version or self.app_version dbg('Publishing app version %s, is_staging:%s region:%s' % (app_version, is_staging, region)) publish_obj = ApplicationPublishObject(version_id=app_version, is_staging=is_staging, region=region) result = self.authoring_client.apps.publish(self.app_id, publish_obj) return LUISNLU.to_application_publish_result(result)
def clone_version(self, old_version, new_version): dbg('Cloning version %s to %s' % (old_version, new_version)) version = self.authoring_client.versions.clone(self.app_id, old_version, version=new_version) return version