def create_community_user(session: orm.Session, app: Optional[sanic.Sanic] = None) -> None: from rasax.community.services.role_service import RoleService from rasax.community.services.settings_service import SettingsService role_service = RoleService(session) role_service.init_roles(project_id=constants.COMMUNITY_PROJECT_NAME) settings_service = SettingsService(session) password = settings_service.get_community_user_password() is_password_generated = False # only re-assign password in local mode or if it doesn't exist if config.LOCAL_MODE or not password: password = os.environ.get(constants.ENV_RASA_X_PASSWORD) if not password: password = random_password() is_password_generated = True settings_service.save_community_user_password(password) user_service = UserService(session) user_service.insert_or_update_user(constants.COMMUNITY_USERNAME, password, constants.COMMUNITY_TEAM_NAME) if app: run_operation_in_single_sanic_worker( app, AppStartedCallable(password, is_password_generated))
async def get_model_config(request, project_id, user=None): settings_service = SettingsService(request[REQUEST_DB_SESSION_KEY]) stack_config = settings_service.get_config(user["team"], project_id) if not stack_config: return rasa_x_utils.error(http.HTTPStatus.NOT_FOUND, "SettingsFailed", "Could not find settings.") yaml_config = rasa_x_utils.dump_yaml(stack_config) return response.text(yaml_config)
def _create_initial_project(session) -> None: if not session.query(Project).first(): settings_service = SettingsService(session) settings_service.init_project( rasa_x_config.team_name, rasa_x_config.project_name ) session.commit() logger.debug( f"No projects present. Created initial default project '{rasa_x_config.project_name}'." )
def _stack_service(request: Request, default_environment: Text) -> StackService: settings_service = SettingsService(request[REQUEST_DB_SESSION_KEY]) environment = rasa_x_utils.deployment_environment_from_request( request, default_environment) service = settings_service.get_stack_service(environment) if not service: raise ValueError( f"Service for requested environment '{environment}' not found") return service
async def save_model_config(request, project_id, user=None): settings_service = SettingsService(request[REQUEST_DB_SESSION_KEY]) try: config_yaml = settings_service.inspect_and_save_yaml_config_from_request( request.body, user["team"], project_id) return response.text(config_yaml) except YAMLError as e: return rasa_x_utils.error( 400, "InvalidConfig", f"Failed to read configuration file. Error: {e}") except InvalidConfigError as e: return rasa_x_utils.error(http.HTTPStatus.UNPROCESSABLE_ENTITY, "ConfigMissingKeys", f"Error: {e}")
async def create_project(request: Request, project_id: Text, user: Dict) -> HTTPResponse: settings_service = SettingsService(request[REQUEST_DB_SESSION_KEY]) try: project = settings_service.init_project(user["team"], project_id) except ProjectException as e: return rasa_x_utils.error(404, "ProjectCreationError", details=e) user_service = UserService(request[REQUEST_DB_SESSION_KEY]) user_service.assign_project_to_user(user, project_id) return response.json(project)
def _update_community_user_password(self, username: Text, password: Text) -> None: if username == COMMUNITY_USERNAME: from rasax.community.services.settings_service import SettingsService SettingsService( self.session).save_community_user_password(password)
def initialise_services(_session): return ( UserService(_session), SettingsService(_session), DomainService(_session), RoleService(_session), )
async def get_environment_config(request: Request) -> HTTPResponse: settings_service = SettingsService(request[REQUEST_DB_SESSION_KEY]) environments = settings_service.get_environments_config( config.project_name) if not environments: return rasa_x_utils.error( 400, "EnvironmentSettingsNotFound", "could not find environment settings", ) return response.json({ "environments": utils.dump_yaml(environments.get("environments")) })
async def minimum_compatible_version(self) -> Optional[Text]: from rasax.community.services.settings_service import SettingsService if config.LOCAL_MODE: # In local mode Rasa X and Rasa are in the same environment from rasa.constants import MINIMUM_COMPATIBLE_VERSION return MINIMUM_COMPATIBLE_VERSION settings_service = SettingsService(self.session) stack_service = settings_service.get_stack_service(self.environment) info = await stack_service.version() if info: return info.get("minimum_compatible_version") else: logger.debug("Couldn't get a minimum compatible model version.") return None
def _initialize_with_local_data( project_path: Text, data_path: Text, session: Session, rasa_port: Union[int, Text], config_path: Text, ) -> Tuple[Dict[Text, Any], List[Dict[Text, Any]], TrainingData]: settings_service = SettingsService(session) default_env = default_environments_config_local(rasa_port) settings_service.save_environments_config(COMMUNITY_PROJECT_NAME, default_env.get("environments")) loop = asyncio.get_event_loop() # inject data domain, story_blocks, nlu_data = loop.run_until_complete( rasax.community.initialise.inject_files_from_disk( project_path, data_path, session, config_path=config_path)) # dump domain once domain_service = DomainService(session) domain_service.dump_domain() return domain, story_blocks, nlu_data
async def inject_files_from_disk( project_path: Union[Path, Text], data_path: Text, session: orm.Session, username: Optional[Text] = constants.COMMUNITY_USERNAME, config_path: Optional[Text] = config.default_config_path, ) -> Tuple[Dict[Text, Any], List[Dict[Text, Any]], "NluTrainingData"]: """Injects local files into database. Args: project_path: Path to the project of which the data should be injected. data_path: Path to the data within this project. session: Database session. username: The username which is used to inject the data. config_path: Path to the config file within the project Returns: Tuple of domain, stories, and NLU training data. """ import rasa.data from rasax.community.local import LOCAL_DOMAIN_PATH from rasax.community.services.data_service import DataService from rasax.community.services.settings_service import SettingsService utils.set_project_directory(project_path) domain_service = DomainService(session) domain = inject_domain( os.path.join(project_path, LOCAL_DOMAIN_PATH), domain_service, constants.COMMUNITY_PROJECT_NAME, username, ) settings_service = SettingsService(session) inject_config(os.path.join(project_path, config_path), settings_service) story_files, nlu_files = rasa.data.get_core_nlu_files([data_path]) story_service = StoryService(session) story_blocks = await inject_stories(story_files, story_service, username, constants.COMMUNITY_TEAM_NAME) data_service = DataService(session) nlu_data = inject_nlu_data(nlu_files, constants.COMMUNITY_PROJECT_NAME, username, data_service) return domain, story_blocks, nlu_data
async def train_model(request, project_id): stack_services = SettingsService( request[REQUEST_DB_SESSION_KEY]).stack_services(project_id) environment = utils.deployment_environment_from_request( request, "worker") stack_service = stack_services[environment] try: training_start = time.time() content = await stack_service.start_training_process() telemetry.track(telemetry.MODEL_TRAINED_EVENT) model_name = await _model_service(request).save_trained_model( project_id, content) nlg_service = NlgService(request[REQUEST_DB_SESSION_KEY]) nlg_service.mark_responses_as_used(training_start) return response.json({ "info": "New model trained.", "model": model_name }) except FileExistsError as e: logger.error(e) return response.json( { "info": "Model already exists.", "path": str(e) }, http.HTTPStatus.CREATED, ) except ValueError as e: logger.error(e) return rasa_x_utils.error( http.HTTPStatus.BAD_REQUEST, "StackTrainingFailed", "Unable to train on data containing retrieval intents.", details=e, ) except ClientError as e: logger.error(e) return rasa_x_utils.error( http.HTTPStatus.INTERNAL_SERVER_ERROR, "StackTrainingFailed", "Failed to train a Rasa model.", details=e, )
async def _get_project_status_event( session: Session, project_id: Text = config.project_name) -> Dict[Text, Any]: """Collect data used in `status` event. Args: session: Database session. project_id: The project ID. Returns: A dictionary containing statistics describing the current project's status. """ from rasax.community.services.event_service import EventService from rasax.community.services.domain_service import DomainService from rasax.community.services.model_service import ModelService from rasax.community.services.data_service import DataService from rasax.community.services.story_service import StoryService from rasax.community.services.settings_service import SettingsService import rasax.community.services.test_service as test_service from rasax.community.services import stack_service event_service = EventService(session) domain_service = DomainService(session) model_service = ModelService(config.rasa_model_dir, session) data_service = DataService(session) story_service = StoryService(session) settings_service = SettingsService(session) domain = domain_service.get_domain(project_id) or {} nlu_data = data_service.get_nlu_training_data_object(project_id=project_id) stories = story_service.fetch_stories() num_conversations = event_service.get_conversation_metadata_for_all_clients( ).count num_events = event_service.get_events_count() num_models = model_service.get_model_count() lookup_tables = data_service.get_lookup_tables(project_id, include_filenames=True) num_lookup_table_files = len( {table["filename"] for table in lookup_tables}) num_lookup_table_entries = sum( table.get("number_of_elements", 0) for table in lookup_tables) synonyms = data_service.get_entity_synonyms(project_id) num_synonyms = sum(len(entry["synonyms"]) for entry in synonyms) num_regexes = data_service.get_regex_features(project_id).count rasa_services = settings_service.stack_services(project_id) version_responses = await stack_service.collect_version_calls( rasa_services, timeout_in_seconds=ENVIRONMENT_LIVE_TIMEOUT) environment_names = _environment_names(rasa_services) tags = event_service.get_all_conversation_tags() conversations_with_tags = set() for tag in tags: conversations_with_tags.update(tag["conversations"]) e2e_tests = test_service.get_tests_from_file() return { # Use the SHA256 of the project ID in case its value contains # information about the user's use of Rasa X. On the analytics side, # having the original value or the hash makes no difference. This # reasoning is also applied on other values sent in this module. "project": hashlib.sha256(project_id.encode("utf-8")).hexdigest(), "local_mode": config.LOCAL_MODE, "rasa_x": __version__, "rasa_open_source": _rasa_version(version_responses), "num_intent_examples": len(nlu_data.intent_examples), "num_entity_examples": len(nlu_data.entity_examples), "num_actions": len(domain.get("actions", [])), "num_templates": len( domain.get("responses", []) ), # Old nomenclature from when 'responses' were still called 'templates' in the domain "num_slots": len(domain.get("slots", [])), "num_forms": len(domain.get("forms", [])), "num_intents": len(domain.get("intents", [])), "num_entities": len(domain.get("entities", [])), "num_stories": len(stories), "num_conversations": num_conversations, "num_events": num_events, "num_models": num_models, "num_lookup_table_files": num_lookup_table_files, "num_lookup_table_entries": num_lookup_table_entries, "num_synonyms": num_synonyms, "num_regexes": num_regexes, "num_environments": len(environment_names), "environment_names": environment_names, "num_live_environments": _number_of_live_rasa_environments(version_responses), "uptime_seconds": utils.get_uptime(), "num_tags": len(tags), "num_conversations_with_tags": len(conversations_with_tags), "num_e2e_tests": len(e2e_tests), }
def _dump_config(self, configuration_change: Dict[Text, Text]) -> None: from rasax.community.services.settings_service import SettingsService settings_service = SettingsService(self.session) settings_service.dump_config(configuration_change["team"], configuration_change["project_id"])
def _rasa_services(request: Request) -> Dict[Text, StackService]: settings_service = SettingsService(request[REQUEST_DB_SESSION_KEY]) return settings_service.stack_services()