def validate(self, clean=True): if clean: self.clean() if Utility.check_empty_string(self.name) or Utility.check_empty_string( self.type): raise ValueError( "Slot name and type cannot be empty or blank spaces") error = "" if self.type == FloatSlot.type_name: if not self.min_value and not self.max_value: self.min_value = 0.0 self.max_value = 1.0 if self.min_value < self.max_value: error = "FloatSlot must have min_value < max_value" if not isinstance(self.initial_value, int): if error: error += "\n" error = "FloatSlot initial_value must be numeric value" ValidationError(error) elif self.type == CategoricalSlot.type_name: if not self.values: raise ValidationError( "CategoricalSlot must have list of categories in values field" )
def validate(self, clean=True): if clean: self.clean() if Utility.check_empty_string( self.value) or Utility.check_empty_string(self.entity): raise ValidationError( "Entity name and value cannot be empty or blank spaces")
def validate(self, clean=True): if clean: self.clean() if not Utility.check_empty_string(self.value) and self.type != 'slot': raise ValidationError("Value is allowed only for slot") if Utility.check_empty_string( self.name) and self.type != 'active_loop': raise ValidationError("Empty name is allowed only for active_loop")
def validate(self, clean=True): if not self.title or not self.payload: raise ValidationError("title and payload must be present!") elif Utility.check_empty_string( self.title) or Utility.check_empty_string( self.payload.strip()): raise ValidationError( "Response title and payload cannot be empty or blank spaces")
def validate(self, clean=True): if (Utility.check_empty_string(self.email) or Utility.check_empty_string(self.first_name) or Utility.check_empty_string(self.last_name) or Utility.check_empty_string(self.password)): raise ValidationError( "Email, FirstName, LastName and password cannot be empty or blank space" ) elif isinstance(email(self.email), ValidationFailure): raise ValidationError("Please enter valid email address")
def check(cls, values): from kairon.shared.utils import Utility if Utility.check_empty_string(values.get('key')): raise ValueError("key cannot be empty") if values.get('parameter_type' ) == ParameterChoice.slot and Utility.check_empty_string( values.get('value')): raise ValueError("Provide name of the slot as value") return values
def validate(self, clean=True): if clean: self.clean() if Utility.check_empty_string(self.name) or Utility.check_empty_string( self.pattern): raise ValidationError( "Regex name and pattern cannot be empty or blank spaces") else: try: re.compile(self.pattern) except Exception: raise AppException("invalid regular expression " + self.pattern)
def validate(self, clean=True): if clean: self.clean() if Utility.check_empty_string(self.name): raise ValidationError( "Utterance Name cannot be empty or blank spaces")
async def get_current_user_and_bot(security_scopes: SecurityScopes, request: Request, token: str = Depends(DataUtility.oauth2_scheme)): if security_scopes.scopes: authenticate_value = f'Bearer scope="{security_scopes.scope_str}"' else: authenticate_value = "Bearer" user = await Authentication.get_current_user(request, token) bot_id = request.path_params.get('bot') if Utility.check_empty_string(bot_id): raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail='Bot is required', ) if user.is_integration_user: user_role = user.role else: user_role = AccountProcessor.fetch_role_for_user(user.email, bot_id) user_role = user_role['role'] if security_scopes.scopes and user_role not in security_scopes.scopes: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail=f"{security_scopes.scopes} access is required to perform this operation on the bot", headers={"WWW-Authenticate": authenticate_value}, ) AccountProcessor.get_bot_and_validate_status(bot_id) user.active_bot = bot_id return user
def generate_integration_token( bot: Text, user: Text, role: ACCESS_ROLES = ACCESS_ROLES.CHAT.value, expiry: int = 0, access_limit: list = None, name: Text = None, token_type: TOKEN_TYPE = TOKEN_TYPE.INTEGRATION.value ): """ Generates an access token for secure integration of the bot with an external service/architecture """ if token_type == TOKEN_TYPE.LOGIN.value: raise NotImplementedError iat: datetime = datetime.now(tz=timezone.utc) iat = iat.replace(microsecond=0) data = {'bot': bot, "sub": user, 'iat': iat, 'type': token_type, 'role': role} if not Utility.check_empty_string(name): data.update({"name": name}) if expiry > 0: expiry = iat + timedelta(minutes=expiry) expiry = expiry.replace(microsecond=0) data.update({"exp": expiry}) else: expiry = None if access_limit: data['access-limit'] = access_limit access_token = Authentication.create_access_token(data=data, token_type=token_type) if token_type == TOKEN_TYPE.INTEGRATION.value: IntegrationProcessor.add_integration(name, bot, user, role, iat, expiry, access_limit) return access_token
def add_account(name: str, user: str): """ adds a new account :param name: account name :param user: user id :return: account id """ if Utility.check_empty_string(name): raise AppException("Account Name cannot be empty or blank spaces") Utility.is_exist( Account, exp_message="Account name already exists!", name__iexact=name, status=True, ) license = { "bots": 2, "intents": 3, "examples": 20, "training": 3, "augmentation": 5 } return Account(name=name.strip(), user=user, license=license).save().to_mongo().to_dict()
def validate_request_method(cls, v, values, **kwargs): from kairon.shared.utils import Utility if not v: raise ValueError("Steps are required to form Flow") if v[0].type != StoryStepType.intent: raise ValueError("First step should be an intent") if v[len(v) - 1].type == StoryStepType.intent: raise ValueError( "Intent should be followed by utterance or action") intents = 0 for i, j in enumerate(range(1, len(v))): if v[i].type == StoryStepType.intent: intents = intents + 1 if v[i].type == StoryStepType.intent and v[ j].type == StoryStepType.intent: raise ValueError("Found 2 consecutive intents") if Utility.check_empty_string( v[i].name) and v[i].type != StoryStepType.form_end: raise ValueError( f"Only {StoryStepType.form_end} step type can have empty name" ) if 'type' in values: if values['type'] == StoryType.rule and intents > 1: raise ValueError( f"""Found rules '{values['name']}' that contain more than intent.\nPlease use stories for this case""" ) return v
def clean(self): self.name = self.name.strip().lower() if Utility.check_empty_string(self.failure_response): self.failure_response = 'I have failed to process your request.' try: self.num_results = int(self.num_results) except ValueError: self.num_results = 1
def validate_value(cls, v, values, **kwargs): from kairon.shared.utils import Utility if len(v) <= 0: raise ValueError("value field cannot be empty") for ele in v: if Utility.check_empty_string(ele): raise ValueError("value cannot be an empty string") return v
def update_bot(name: Text, bot: Text): if Utility.check_empty_string(name): raise AppException('Name cannot be empty') try: bot_info = Bot.objects(id=bot, status=True).get() bot_info.name = name bot_info.save() except DoesNotExist: raise AppException('Bot not found')
def validate(self, clean=True): if clean: self.clean() from .utils import DataUtility if Utility.check_empty_string(self.block_name): raise ValidationError("rule name cannot be empty or blank spaces") elif not self.events: raise ValidationError("events cannot be empty") DataUtility.validate_flow_events(self.events, "RULE", self.block_name)
def validate_bot_request(bot_in_request_path: str, bot_in_token: str): """ Validates the bot which is being accessed is the same bot for which the integration was generated. :param bot_in_request_path: bot for which the request was made. :param bot_in_token: bot which is present in auth token claims. """ if not Utility.check_empty_string( bot_in_request_path) and bot_in_request_path != bot_in_token: raise ServiceHandlerException('Access to bot is denied', 401)
def add_bot(name: str, account: int, user: str, is_new_account: bool = False): """ add a bot to account :param name: bot name :param account: account id :param user: user id :param is_new_account: True if it is a new account :return: bot id """ from kairon.shared.data.processor import MongoProcessor from kairon.shared.data.data_objects import BotSettings if Utility.check_empty_string(name): raise AppException("Bot Name cannot be empty or blank spaces") if Utility.check_empty_string(user): raise AppException("user cannot be empty or blank spaces") Utility.is_exist( Bot, exp_message="Bot already exists!", name__iexact=name, account=account, status=True, ) bot = Bot(name=name, account=account, user=user).save().to_mongo().to_dict() bot_id = bot['_id'].__str__() if not is_new_account: AccountProcessor.__allow_access_to_bot( bot_id, user, user, account, ACCESS_ROLES.OWNER.value, ACTIVITY_STATUS.ACTIVE.value) BotSettings(bot=bot_id, user=user).save() processor = MongoProcessor() config = processor.load_config(bot_id) processor.add_or_overwrite_config(config, bot_id, user) processor.add_default_fallback_data(bot_id, user, True, True) processor.add_system_required_slots(bot_id, user) return bot
def validate(self, clean=True): if clean: self.clean() if self.entities: for ent in self.entities: ent.validate() extracted_ent = self.text[ent.start:ent.end] if extracted_ent != ent.value: raise ValidationError( "Invalid entity: " + ent.entity + ", value: " + ent.value + " does not match with the position in the text " + extracted_ent) elif Utility.check_empty_string( self.text) or Utility.check_empty_string(self.intent): raise ValidationError( "Training Example name and text cannot be empty or blank spaces" )
def validate_responses(cls, v, values, **kwargs): from kairon.shared.utils import Utility err_msg = "Questions cannot be empty or contain spaces" if not v: raise ValueError(err_msg) for response in v: if Utility.check_empty_string(response): raise ValueError(err_msg) return v
def validate_pattern(cls, f, values, **kwargs): from kairon.shared.utils import Utility import re if Utility.check_empty_string(f): raise ValueError("Regex pattern cannot be empty or a blank space") try: re.compile(f) except Exception: raise AppException("invalid regular expression") return f
def validate(self, clean=True): from kairon.shared.actions.utils import ActionUtility if clean: self.clean() try: ActionUtility.validate_pipedrive_credentials(self.domain, self.api_token) if Utility.check_empty_string(self.metadata.get('name')): raise ValidationError("metadata: name is required") except Exception as e: raise ValidationError(e)
def validate_bot_request(bot_in_request_path: str, bot_in_token: str): """ Validates the bot which is being accessed is the same bot for which the integration was generated. :param bot_in_request_path: bot for which the request was made. :param bot_in_token: bot which is present in auth token claims. """ if not Utility.check_empty_string(bot_in_request_path) and bot_in_request_path != bot_in_token: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail='Access to bot is denied', )
def add_user( email: str, password: str, first_name: str, last_name: str, account: int, user: str, ): """ adds new user to the account :param email: user login id :param password: user password :param first_name: user firstname :param last_name: user lastname :param account: account id :param user: user id :return: user details """ if (Utility.check_empty_string(email) or Utility.check_empty_string(last_name) or Utility.check_empty_string(first_name) or Utility.check_empty_string(password)): raise AppException( "Email, FirstName, LastName and password cannot be empty or blank spaces" ) Utility.is_exist( User, exp_message= "User already exists! try with different email address.", email__iexact=email.strip(), status=True, ) return (User(email=email.strip(), password=Utility.get_password_hash(password.strip()), first_name=first_name.strip(), last_name=last_name.strip(), account=account, user=user.strip()).save().to_mongo().to_dict())
def get_current_user_and_bot_for_channel(token: Text, bot: Text, request: HTTPServerRequest): user = TornadoAuthenticate.get_user_from_token(token, request) if Utility.check_empty_string(bot): raise ServiceHandlerException("Bot is required", 422, {"WWW-Authenticate": "Bearer"}) AccountProcessor.fetch_role_for_user(user.email, bot) bot = AccountProcessor.get_bot(bot) if not bot["status"]: raise ServiceHandlerException( "Inactive Bot Please contact system admin!", 422, {"WWW-Authenticate": "Bearer"}) user.active_bot = bot return user
async def authenticate_and_get_collection(request: Request, token: str = Depends(DataUtility.oauth2_scheme_non_strict)): token_configured = Utility.environment['authentication']['token'] if token_configured != token: raise HTTPException( status_code=HTTP_401_UNAUTHORIZED, detail="Could not validate credentials", headers={"WWW-Authenticate": "Bearer"}, ) if 'bot' == Utility.environment['tracker']['type']: bot_id = request.path_params.get('bot') if Utility.check_empty_string(bot_id): raise HTTPException( status_code=422, detail="Bot id is required", ) return bot_id else: collection = Utility.environment['tracker']['collection'] if Utility.check_empty_string(collection): raise HTTPException( status_code=422, detail="Collection not configured", ) return collection
def get_current_user_and_bot(request: HTTPServerRequest, **kwargs): user = TornadoAuthenticate.get_current_user(request, **kwargs) bot_id = kwargs.get('bot') if Utility.check_empty_string(bot_id): raise ServiceHandlerException("Bot is required", 422, {"WWW-Authenticate": "Bearer"}) if not user.is_integration_user: AccountProcessor.fetch_role_for_user(user.email, bot_id) bot = AccountProcessor.get_bot(bot_id) if not bot["status"]: raise ServiceHandlerException( "Inactive Bot Please contact system admin!", 422, {"WWW-Authenticate": "Bearer"}) user.active_bot = bot_id return user
def validate(self, clean=True): from rasa.shared.core.domain import _validate_slot_mappings if not self.mapping or self.mapping == [{}]: raise ValueError("At least one mapping is required") if Utility.check_empty_string(self.slot): raise ValueError("Slot name cannot be empty or blank spaces") if clean: self.clean() try: _validate_slot_mappings({'form_name': {self.slot: self.mapping}}) except Exception as e: raise ValidationError(e)
def validate(self, clean=True): if clean: self.clean() if Utility.check_empty_string(self.name): raise ValidationError( "Response name cannot be empty or blank spaces") elif not self.text and not self.custom: raise ValidationError( "Either Text or Custom response must be present!") else: if self.text: self.text.validate() elif self.custom: self.custom.validate()
def trigger_model_testing(bot: Text, user: Text, run_e2e: bool = False): """ Triggers model testing event. @param bot: bot id. @param user: kairon username. @param run_e2e: if true, tests are run on test stories. e2e test run in case of rasa is when intent predictions are also done as part of core model testing. @return: """ try: event_url = Utility.get_event_url("TESTING") if not Utility.check_empty_string(event_url): env_var = {'BOT': bot, 'USER': user} event_request = Utility.build_event_request(env_var) Utility.http_request("POST", event_url, None, user, event_request) ModelTestingLogProcessor.log_test_result( bot, user, event_status=EVENT_STATUS.TASKSPAWNED.value) else: ModelTestingLogProcessor.log_test_result( bot, user, event_status=EVENT_STATUS.INPROGRESS.value) nlu_results, stories_results = ModelTester.run_tests_on_model( bot, run_e2e) ModelTestingLogProcessor.log_test_result( bot, user, stories_result=stories_results, nlu_result=nlu_results, event_status=EVENT_STATUS.COMPLETED.value) except exceptions.ConnectionError as e: logger.error(str(e)) ModelTestingLogProcessor.log_test_result( bot, user, exception=f'Failed to trigger the event. {e}', event_status=EVENT_STATUS.FAIL.value) except Exception as e: logger.error(str(e)) ModelTestingLogProcessor.log_test_result( bot, user, exception=str(e), event_status=EVENT_STATUS.FAIL.value)