Exemplo n.º 1
0
    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()
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
 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)
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
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
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
 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)
Exemplo n.º 10
0
 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)
Exemplo n.º 11
0
 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)
Exemplo n.º 12
0
 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