async def edit_responses( utterance: str, id: str, request_data: TextData, current_user: User = Depends(auth.get_current_user_and_bot), ): """ Updates existing utterance value """ mongo_processor.edit_text_response( id, request_data.data, utterance.lower(), current_user.get_bot(), current_user.get_user(), ) return { "message": "Utterance updated!", }
async def search_training_examples(request_data: TextData, current_user: User = Depends( auth.get_current_user_and_bot)): """ Searches existing training examples """ search_items = list( mongo_processor.search_training_examples(request_data.data, current_user.get_bot())) return {"data": {"searched_items": search_items}}
async def remove_responses( request_data: TextData, delete_utterance: bool = Path(default=False, description="Deletes utterance if True"), current_user: User = Depends(auth.get_current_user_and_bot)): """ Deletes existing utterance completely along with its examples. """ if delete_utterance: mongo_processor.delete_utterance(request_data.data.lower(), current_user.get_bot(), current_user.get_user()) else: mongo_processor.delete_response(request_data.data, current_user.get_bot(), current_user.get_user()) return { "message": "Utterance removed!", }
async def add_training_data(request_data: BulkTrainingDataAddRequest, current_user: User = Depends( auth.get_current_user)): """ Adds intents, training examples and responses along with story against the responses """ try: TrainingDataGenerationProcessor.validate_history_id( request_data.history_id) status, training_data_added = mongo_processor.add_training_data( training_data=request_data.training_data, bot=current_user.get_bot(), user=current_user.get_user(), is_integration=current_user.get_integration_status()) TrainingDataGenerationProcessor.update_is_persisted_flag( request_data.history_id, training_data_added) except Exception as e: raise AppException(e) return {"message": "Training data added successfully!", "data": status}
async def get_story_from_intent(intent: str, current_user: User = Depends( auth.get_current_user)): """ Fetches the utterance or response that is mapped to a particular intent """ response = mongo_processor.get_utterance_from_intent( intent, current_user.get_bot()) return_data = {"name": response[0], "type": response[1]} return {"data": return_data}
async def predict_intent(request_data: TextData, current_user: User = Depends(auth.get_current_user)): """ Fetches the predicted intent of the entered text form the loaded agent """ model = AgentProcessor.get_agent(current_user.get_bot()) response = await model.parse_message_using_nlu_interpreter( request_data.data) intent = response.get("intent").get("name") if response else None confidence = response.get("intent").get("confidence") if response else None return {"data": {"intent": intent, "confidence": confidence}}
async def deployment_history(current_user: User = Depends(auth.get_current_user)): """ Fetches model deployment history, when and who deployed the model """ return { "data": { "deployment_history": list( mongo_processor.get_model_deployment_history(bot=current_user.get_bot()) ) } }
async def add_simple_story(request_data: SimpleStoryRequest, current_user: User = Depends( auth.get_current_user)): """ Adds a story (conversational flow) with just one intent and an http action against it. """ if Utility.check_empty_string( request_data.action) or Utility.check_empty_string( request_data.intent): raise AppException("Action and intent cannot be empty") return { "message": "Story added successfully", "data": { "_id": mongo_processor.prepare_and_add_story(story=request_data.action, intent=request_data.intent, bot=current_user.get_bot(), user=current_user.get_user()) }, }
async def upload_Files( background_tasks: BackgroundTasks, nlu: UploadFile = File(...), domain: UploadFile = File(...), stories: UploadFile = File(...), config: UploadFile = File(...), rules: UploadFile = File(None), http_action: UploadFile = File(None), overwrite: bool = True, current_user: User = Depends(auth.get_current_user), ): """ Uploads training data nlu.md, domain.yml, stories.md and config.yml files """ await mongo_processor.upload_and_save(nlu, domain, stories, config, rules, http_action, current_user.get_bot(), current_user.get_user(), overwrite) background_tasks.add_task(start_training, current_user.get_bot(), current_user.get_user()) return {"message": "Data uploaded successfully!"}
async def delete_intent( intent: str = Path(default=None, description="intent name", example="greet"), delete_dependencies: bool = Path( default=True, description= """if True delete bot data related to this intent otherwise only delete intent""", ), current_user: User = Depends(auth.get_current_user), ): """ deletes an intent including training examples and stories """ mongo_processor.delete_intent(intent, current_user.get_bot(), current_user.get_user(), current_user.get_integration_status(), delete_dependencies) return {"message": "Intent deleted!"}
async def get_training_examples( intent: str, current_user: User = Depends(auth.get_current_user) ): """ Fetches all training examples against intent """ return { "data": list( mongo_processor.get_training_examples(intent, current_user.get_bot()) ) }
async def get_responses(utterance: str, current_user: User = Depends(auth.get_current_user)): """ Fetches list of utterances against utterance name """ return { "data": list( mongo_processor.get_response(utterance.lower(), current_user.get_bot())) }
def wrapped(current_user: User, **kwargs): today = datetime.today() today_start = today.replace(hour=0, minute=0, second=0) account = Account.objects().get(id=current_user.account) limit = account.license[ 'training'] if "training" in account.license else Utility.environment[ 'model']['train']["limit_per_day"] count = ModelTraining.objects( bot=current_user.get_bot(), start_timestamp__gte=today_start).count() if count >= limit: raise AppException("Training limit exhausted!")
async def chat(request_data: TextData, current_user: User = Depends(auth.get_current_user)): """ Fetches a bot response for a given text/query. It is basically used to test the chat functionality of the agent """ if Utility.environment.get('model') and Utility.environment['model'][ 'train'].get('agent_url'): agent_url = Utility.environment['model']['train'].get('agent_url') token = auth.create_access_token(data={"sub": current_user.email}) response = Utility.http_request('post', urljoin(agent_url, "/api/bot/chat"), token.decode('utf8'), current_user.get_user(), json={'data': request_data.data}) else: model = AgentProcessor.get_agent(current_user.get_bot()) response = await model.handle_text(request_data.data, sender_id=current_user.get_user()) response = {"data": {"response": response}} return response
async def get_http_action(action: str = Path(default=None, description="action name", example="http_action"), current_user: User = Depends( auth.get_current_user_and_bot)): """ Returns configuration set for the HTTP action """ http_action_config = mongo_processor.get_http_action_config( action_name=action, bot=current_user.bot) action_config = Utility.build_http_response_object(http_action_config, current_user.get_user(), current_user.bot) return Response(data=action_config)
async def download_data( background_tasks: BackgroundTasks, current_user: User = Depends(auth.get_current_user), ): """ Downloads training data nlu.md, domain.yml, stories.md, config.yml files """ file = mongo_processor.download_files(current_user.get_bot()) response = FileResponse(file, filename=os.path.basename(file), background=background_tasks) response.headers[ "Content-Disposition"] = "attachment; filename=" + os.path.basename( file) return response
async def delete_http_action(action: str = Path(default=None, description="action name", example="http_action"), current_user: User = Depends( auth.get_current_user)): """ Deletes the http action config and story event """ try: mongo_processor.delete_http_action_config(action, user=current_user.get_user(), bot=current_user.bot) except Exception as e: raise AppException(e) message = "HTTP action deleted" return Response(message=message)
async def generate_integration_token( current_user: User = Depends(auth.get_current_user_and_bot), ): """ Generates an access token for api integration """ access_token = auth.generate_integration_token( bot=current_user.get_bot(), account=current_user.account) return { "data": { "access_token": access_token, "token_type": "bearer" }, "message": """It is your responsibility to keep the token secret. If leaked then other may have access to your system.""", }
async def download_model( background_tasks: BackgroundTasks, current_user: User = Depends(auth.get_current_user), ): """ Downloads latest trained model file """ try: model_path = AgentProcessor.get_latest_model(current_user.get_bot()) response = FileResponse( model_path, filename=os.path.basename(model_path), background=background_tasks, ) response.headers[ "Content-Disposition"] = "attachment; filename=" + os.path.basename( model_path) return response except Exception as e: raise AppException(str(e))
async def validate_training_data( background_tasks: BackgroundTasks, current_user: User = Depends(auth.get_current_user_and_bot), ): """ Validates bot training data. """ DataImporterLogProcessor.is_limit_exceeded(current_user.get_bot()) DataImporterLogProcessor.is_event_in_progress(current_user.get_bot()) Utility.make_dirs( os.path.join("training_data", current_user.get_bot(), str(datetime.utcnow()))) DataImporterLogProcessor.add_log(current_user.get_bot(), current_user.get_user(), is_data_uploaded=False) background_tasks.add_task(EventsTrigger.trigger_data_importer, current_user.get_bot(), current_user.get_user(), False, False) return {"message": "Event triggered! Check logs."}
async def train( background_tasks: BackgroundTasks, current_user: User = Depends(auth.get_current_user), ): """ Trains the chatbot """ ModelProcessor.is_training_inprogress(current_user.get_bot()) ModelProcessor.is_daily_training_limit_exceeded(current_user.get_bot()) ModelProcessor.set_training_status( bot=current_user.get_bot(), user=current_user.get_user(), status=MODEL_TRAINING_STATUS.INPROGRESS.value, ) token = auth.create_access_token(data={"sub": current_user.email}) background_tasks.add_task( start_training, current_user.get_bot(), current_user.get_user(), token.decode('utf8') ) return {"message": "Model training started."}
async def upload_file(background_tasks: BackgroundTasks, doc: UploadFile = File(...), current_user: User = Depends(auth.get_current_user)): """ Uploads document for training data generation and triggers event for intent creation """ TrainingDataGenerationProcessor.is_in_progress(current_user.get_bot()) TrainingDataGenerationProcessor.check_data_generation_limit( current_user.get_bot()) file_path = await Utility.upload_document(doc) TrainingDataGenerationProcessor.set_status( bot=current_user.get_bot(), user=current_user.get_user(), status=TRAINING_DATA_GENERATOR_STATUS.INITIATED.value, document_path=file_path) token = auth.create_access_token(data={"sub": current_user.email}) background_tasks.add_task(Utility.trigger_data_generation_event, current_user.get_bot(), current_user.get_user(), token.decode('utf8')) return { "message": "File uploaded successfully and training data generation has begun" }
async def conversation_time(month: HistoryMonth = 1,current_user: User = Depends(auth.get_current_user)): """ Fetches the duration of the chat that took place between the users and the agent""" conversation_time, message = ChatHistory.conversation_time(current_user.get_bot(), month) return {"data": conversation_time, "message": message}
async def get_stories(current_user: User = Depends(auth.get_current_user)): """ Fetches existing list of stories (conversation flows) """ return {"data": list(mongo_processor.get_stories(current_user.get_bot()))}
async def get_training_data_count(current_user: User = Depends( auth.get_current_user_and_bot)): count = mongo_processor.get_training_data_count(current_user.get_bot()) return Response(data=count)
async def get_config(current_user: User = Depends(auth.get_current_user), ): """ Fetches bot pipeline and polcies configurations """ config = mongo_processor.load_config(current_user.get_bot()) return {"data": {"config": config}}
async def conversation_steps(month: HistoryMonth = 1, current_user: User = Depends(auth.get_current_user)): """ Fetches the number of conversation steps that took place in the chat between the users and the agent """ conversation_steps, message = ChatHistory.conversation_steps(current_user.get_bot(), month) return {"data": conversation_steps, "message": message}
async def get_intents(current_user: User = Depends(auth.get_current_user)): """ Fetches list of existing intents for particular bot """ return Response( data=mongo_processor.get_intents(current_user.get_bot())).dict()