def run(args: argparse.Namespace) -> None: import questionary print_success("Welcome to Rasa! 🤖\n") print("To get started quickly, I can assist you to create an " "initial project.\n" "If you need some help to get from this template to a " "bad ass contextual assistant, checkout our quickstart guide" "here: https://rasa.com/docs/core/quickstart \n\n" "Now let's start! 👇🏽\n") path = questionary.text( "Please enter a folder path where I should create " "the initial project [default: current directory]", default=".", ).ask() if not os.path.isdir(path): _ask_create_path(path) if path is None or not os.path.isdir(path): print_cancel() if len(os.listdir(path)) > 0: _ask_overwrite(path) init_project(args, path)
def run(args: argparse.Namespace) -> None: import questionary print_success("Welcome to Rasa! 🤖\n") if args.no_prompt: print("To get started quickly, an " "initial project will be created.\n" "If you need some help, check out " "the documentation at {}.\n".format(DOCS_BASE_URL)) else: print("To get started quickly, an " "initial project will be created.\n" "If you need some help, check out " "the documentation at {}.\n" "Now let's start! 👇🏽\n".format(DOCS_BASE_URL)) path = (questionary.text( "Please enter a path where the project will be " "created [default: current directory]", default=".", ).skip_if(args.no_prompt, default=".").ask()) if not os.path.isdir(path): _ask_create_path(path) if path is None or not os.path.isdir(path): print_cancel() if not args.no_prompt and len(os.listdir(path)) > 0: _ask_overwrite(path) init_project(args, path)
def print_run_or_instructions(args: argparse.Namespace, path: Text) -> None: from rasa.core import constants import questionary should_run = questionary.confirm( "Do you want to speak to the trained bot on the command line? 🤖").ask( ) if should_run: # provide defaults for command line arguments attributes = [ "endpoints", "credentials", "cors", "auth_token", "jwt_secret", "jwt_method", "enable_api", ] for a in attributes: setattr(args, a, None) args.port = constants.DEFAULT_SERVER_PORT shell(args) else: print_success("Ok 👍🏼. If you want to speak to the bot later, " "change into the project directory and run 'rasa shell'." "".format(path))
def package_model( fingerprint: Fingerprint, output_directory: Text, train_path: Text, fixed_model_name: Optional[Text] = None, model_prefix: Text = "", ): """ Compress a trained model. Args: fingerprint: fingerprint of the model output_directory: path to the directory in which the model should be stored train_path: path to uncompressed model fixed_model_name: name of the compressed model file model_prefix: prefix of the compressed model file Returns: path to 'tar.gz' model file """ output_directory = create_output_path( output_directory, prefix=model_prefix, fixed_name=fixed_model_name ) create_package_rasa(train_path, output_directory, fingerprint) print_success( "Your Rasa model is trained and saved at '{}'.".format( os.path.abspath(output_directory) ) ) return output_directory
async def record_messages( server_url=DEFAULT_SERVER_URL, auth_token=None, sender_id=UserMessage.DEFAULT_SENDER_ID, max_message_limit=None, use_response_stream=True, ): """Read messages from the command line and print bot responses.""" auth_token = auth_token if auth_token else "" exit_text = INTENT_MESSAGE_PREFIX + "stop" cliutils.print_success("Bot loaded. Type a message and press enter " "(use '{}' to exit): ".format(exit_text)) num_messages = 0 while not utils.is_limit_reached(num_messages, max_message_limit): text = get_cmd_input() if text == exit_text or text is None: break if use_response_stream: bot_responses = send_message_receive_stream( server_url, auth_token, sender_id, text) async for response in bot_responses: print_bot_output(response) else: bot_responses = await send_message_receive_block( server_url, auth_token, sender_id, text) for response in bot_responses: print_bot_output(response) num_messages += 1 return num_messages
def rasa_x(args: argparse.Namespace): from rasa.cli.utils import print_success, print_error, signal_handler from rasa.core.utils import AvailableEndpoints signal.signal(signal.SIGINT, signal_handler) _configure_logging(args) if args.production: print_success("Starting Rasa X in production mode... 🚀") args.endpoints = get_validated_path( args.endpoints, "endpoints", DEFAULT_ENDPOINTS_PATH, True ) endpoints = AvailableEndpoints.read_endpoints(args.endpoints) _rasa_service(args, endpoints) else: if not is_rasa_x_installed(): print_error( "Rasa X is not installed. The `rasa x` " "command requires an installation of Rasa X." ) sys.exit(1) # noinspection PyUnresolvedReferences from rasax.community import local rasa_x_token = generate_rasa_x_token() start_rasa_for_local_rasa_x(args, rasa_x_token=rasa_x_token) local.main(args, ".", args.data, token=rasa_x_token)
def run_build(cwd, output): if config.development_mode: build_cmd = "build-frontend-enterprise" else: build_cmd = "build-frontend" print_info("Building frontend (development mode)...") # this will always use the frontend enterprise build, as in this case we # have the source anyways (won't happen in packaged build) if subprocess.call(["make", "install-frontend"], cwd=cwd): print_error( "Failed to install frontend dependencies. Check logs for details." ) _write_index_html( frontend_directory, "Frontend install failed! Check the logs for details.", ) elif subprocess.call(["make", build_cmd], cwd=cwd): print_error("Failed to build frontend code. Check logs for details.") _write_index_html( frontend_directory, "Frontend build failed! Check the logs for details." ) else: print_success( "Finished building frontend, serving from {}." "".format(os.path.abspath(output)) )
def train_nlu(config: Text, nlu_data: Text, output: Text, train_path: Optional[Text]) -> Optional["Interpreter"]: """Trains a NLU model. Args: config: Path to the config file for NLU. nlu_data: Path to the NLU training data. output: Output path. train_path: If `None` the model will be trained in a temporary directory, otherwise in the provided directory. Returns: If `train_path` is given it returns the path to the model archive, otherwise the path to the directory with the trained model files. """ import rasa_nlu _train_path = train_path or tempfile.mkdtemp() _, nlu_model, _ = rasa_nlu.train(config, nlu_data, _train_path, project="", fixed_model_name="nlu") if not train_path: nlu_data = data.get_nlu_directory(nlu_data) output_path = create_output_path(output, prefix="nlu-") new_fingerprint = model.model_fingerprint(config, nlu_data=nlu_data) model.create_package_rasa(_train_path, output_path, new_fingerprint) print_success("Your Rasa NLU model is trained and saved at '{}'." "".format(output_path)) return nlu_model
def is_metrics_collection_enabled(args: argparse.Namespace) -> bool: """Make sure the user consents to any metrics collection.""" try: allow_metrics = read_global_config_value("metrics", unavailable_ok=False) return allow_metrics.get("enabled", False) except ValueError: pass # swallow the error and ask the user allow_metrics = (questionary.confirm( "Rasa will track a minimal amount of anonymized usage information " "(like how often you use the 'train' button) to help us improve Rasa X. " "None of your training data or conversations will ever be sent to Rasa. " "Are you OK with Rasa collecting anonymized usage data?").skip_if( args.no_prompt, default=True).ask()) print_success("Your decision has been stored into {}. " "".format(GLOBAL_USER_CONFIG_PATH)) if not args.no_prompt: date = datetime.datetime.now() write_global_config_value("metrics", { "enabled": allow_metrics, "date": date }) return allow_metrics
def convert_and_write(cls, source_path: Path, output_path: Path) -> None: """Converts the given training data file and saves it to the output directory. Args: source_path: Path to the training data file. output_path: Path to the output directory. """ from rasa.shared.core.training_data.story_reader.yaml_story_reader import ( KEY_ACTIVE_LOOP, ) output_core_path = cls.generate_path_for_converted_training_data_file( source_path, output_path) reader = MarkdownStoryReader(unfold_or_utterances=False) writer = YAMLStoryWriter() loop = asyncio.get_event_loop() steps = loop.run_until_complete(reader.read_from_file(source_path)) if YAMLStoryWriter.stories_contain_loops(steps): print_warning( f"Training data file '{source_path}' contains forms. " f"Any 'form' events will be converted to '{KEY_ACTIVE_LOOP}' events. " f"Please note that in order for these stories to work you still " f"need the 'FormPolicy' to be active. However the 'FormPolicy' is " f"deprecated, please consider switching to the new 'RulePolicy', " f"for which you can find the documentation here: {DOCS_URL_RULES}." ) writer.dump(output_core_path, steps) print_success( f"Converted Core file: '{source_path}' >> '{output_core_path}'.")
def _read_telemetry_consent(no_prompt: bool) -> bool: """Check if the user wants to enable telemetry or not. Args: no_prompt: If `True`, do not prompt the user for input (but inform about any decision taken). Returns: Boolean indicating if the user wants to enable telemetry. """ import questionary allow_telemetry = (questionary.confirm( "Rasa will track a minimal amount of anonymized usage information " "(like how often the 'train' button is used) to help us improve Rasa X. " "None of your training data or conversations will ever be sent to Rasa. " "Are you OK with Rasa collecting anonymized usage data?").skip_if( no_prompt, default=True).ask()) if not no_prompt: rasa_cli_utils.print_success( f"Your decision has been stored into '{GLOBAL_USER_CONFIG_PATH}'.") else: rasa_cli_utils.print_info( "By adding the '--no_prompt' parameter you agreed to allow Rasa to track " "and send anonymized usage information.") return allow_telemetry
def _write_nlu_yaml(training_data_path: Path, output_path: Path, source_path: Path) -> None: reader = MarkdownReader() writer = RasaYAMLWriter() training_data = reader.read(training_data_path) writer.dump(output_path, training_data) print_success(f"Converted NLU file: '{source_path}' >> '{output_path}'.")
def train_project(path: Text) -> Optional[Text]: print_success("Training an initial model...") config = os.path.join(path, DEFAULT_CONFIG_PATH) training_files = os.path.join(path, DEFAULT_DATA_PATH) domain = os.path.join(path, DEFAULT_DOMAIN_PATH) output = os.path.join(path, create_output_path()) model = rasa.train(domain, config, training_files, output) return model
def run_in_production(args: argparse.Namespace): from rasa.cli.utils import print_success from rasa.core.utils import AvailableEndpoints print_success("Starting Rasa X in production mode... 🚀") args.endpoints = get_validated_path(args.endpoints, "endpoints", DEFAULT_ENDPOINTS_PATH, True) endpoints = AvailableEndpoints.read_endpoints(args.endpoints) _rasa_service(args, endpoints)
def run_in_production(args: argparse.Namespace): from rasa.cli.utils import print_success print_success("Starting Rasa X in production mode... 🚀") credentials_path, endpoints_path = _get_credentials_and_endpoints_paths(args) endpoints = AvailableEndpoints.read_endpoints(endpoints_path) _rasa_service(args, endpoints, None, credentials_path)
def _display_bot_response(response: Dict): from IPython.display import Image, display for response_type, value in response.items(): if response_type == 'text': print_success(value) if response_type == 'image': image = Image(url=value) display(image, )
def run_cmdline(model_path, component_builder=None): interpreter = Interpreter.load(model_path, component_builder) print_success( "NLU model loaded. Type a message and press enter to parse it.") while True: text = input().strip() r = interpreter.parse(text) print(json.dumps(r, indent=2)) print_success("Next message:")
def _display_bot_response(response: Dict): from IPython.display import Image, display # pytype: disable=import-error for response_type, value in response.items(): if response_type == "text": print_success(value) if response_type == "image": image = Image(url=value) display(image)
def rasa_x(args: argparse.Namespace): from rasa.cli.utils import print_success, print_error, signal_handler from rasa.core.utils import AvailableEndpoints signal.signal(signal.SIGINT, signal_handler) _configure_logging(args) if args.production: print_success("Starting Rasa X in production mode... 🚀") args.endpoints = get_validated_path(args.endpoints, "endpoints", DEFAULT_ENDPOINTS_PATH, True) endpoints = AvailableEndpoints.read_endpoints(args.endpoints) _rasa_service(args, endpoints) else: if not is_rasa_x_installed(): print_error("Rasa X is not installed. The `rasa x` " "command requires an installation of Rasa X.") sys.exit(1) project_path = "." if not is_rasa_project_setup(project_path): print_error( "This directory is not a valid Rasa project. Use 'rasa init' " "to create a new Rasa project or switch to a valid Rasa project " "directory.") sys.exit(1) _validate_domain(os.path.join(project_path, DEFAULT_DOMAIN_PATH)) if args.data and not os.path.exists(args.data): print_warning( "The provided data path ('{}') does not exists. Rasa X will start " "without any training data.".format(args.data)) # noinspection PyUnresolvedReferences from rasax.community import local local.check_license_and_metrics(args) rasa_x_token = generate_rasa_x_token() process = start_rasa_for_local_rasa_x(args, rasa_x_token=rasa_x_token) try: local.main(args, project_path, args.data, token=rasa_x_token) except Exception: print(traceback.format_exc()) print_error( "Sorry, something went wrong (see error above). Make sure to start " "Rasa X with valid data and valid domain and config files. Please, " "also check any warnings that popped up.\nIf you need help fixing " "the issue visit our forum: https://forum.rasa.com/.") finally: process.terminate()
def train_nlu(config: Text, nlu_data: Text, output: Text, train_path: Optional[Text]) -> Optional[Text]: """Trains a NLU model. Args: config: Path to the config file for NLU. nlu_data: Path to the NLU training data. output: Output path. train_path: If `None` the model will be trained in a temporary directory, otherwise in the provided directory. Returns: If `train_path` is given it returns the path to the model archive, otherwise the path to the directory with the trained model files. """ import rasa.nlu.train config = get_valid_config(config, CONFIG_MANDATORY_KEYS_NLU) if not train_path: # training NLU only hence the training files still have to be selected skill_imports = SkillSelector.load(config) nlu_data_directory = data.get_nlu_directory(nlu_data, skill_imports) else: nlu_data_directory = nlu_data if not os.listdir(nlu_data_directory): print_error( "No NLU data given. Please provide NLU data in order to train " "a Rasa NLU model.") return _train_path = train_path or tempfile.mkdtemp() print_color("Start training NLU model ...", color=bcolors.OKBLUE) _, nlu_model, _ = rasa.nlu.train(config, nlu_data_directory, _train_path, fixed_model_name="nlu") print_color("Done.", color=bcolors.OKBLUE) if not train_path: output_path = create_output_path(output, prefix="nlu-") new_fingerprint = model.model_fingerprint(config, nlu_data=nlu_data_directory) model.create_package_rasa(_train_path, output_path, new_fingerprint) print_success( "Your Rasa NLU model is trained and saved at '{}'.".format( output_path)) return output_path return _train_path
def _ask_create_path(path: Text) -> None: import questionary should_create = questionary.confirm( "Path '{}' does not exist 🧐. Create path?".format(path)).ask() if should_create: os.makedirs(path) else: print_success("Ok. You can continue setting up by running " "'rasa init' 🙋🏽♀️") exit(0)
def _write_core_yaml(training_data_path: Path, output_path: Path, source_path: Path) -> None: reader = MarkdownStoryReader() writer = YAMLStoryWriter() loop = asyncio.get_event_loop() steps = loop.run_until_complete(reader.read_from_file(training_data_path)) writer.dump(output_path, steps) print_success(f"Converted Core file: '{source_path}' >> '{output_path}'.")
async def _train_core_with_validated_data( domain: Domain, config: Text, story_directory: Text, output: Text, train_path: Optional[Text] = None, fixed_model_name: Optional[Text] = None, uncompress: bool = False, kwargs: Optional[Dict] = None, ) -> Optional[Text]: """Train Core with validated training and config data.""" import rasa.core.train if not os.listdir(story_directory): print_error( "No dialogue data given. Please provide dialogue data in order to " "train a Rasa Core model.") return _train_path = train_path or tempfile.mkdtemp() # normal (not compare) training print_color("Start training dialogue model ...", color=bcolors.OKBLUE) await rasa.core.train( domain_file=domain, stories_file=story_directory, output_path=os.path.join(_train_path, "core"), policy_config=config, kwargs=kwargs, ) print_color("Done.", color=bcolors.OKBLUE) if not train_path: # Only Core was trained. output_path = create_output_path(output, prefix="core-", fixed_name=fixed_model_name) new_fingerprint = model.model_fingerprint(config, domain, stories=story_directory) model.create_package_rasa(_train_path, output_path, new_fingerprint) if uncompress: output_path = decompress(output_path) print_success( "Your Rasa Core model is trained and saved at '{}'.".format( output_path)) return output_path return _train_path
def _ask_create_path(path: Text) -> None: import questionary should_create = questionary.confirm( "Path '{}' does not exist 🧐. Should I create it?".format(path)).ask() if should_create: os.makedirs(path) else: print_success( "Ok. Then I stop here. If you need me again, simply type " "'rasa init' 🙋🏽♀️") exit(0)
async def train_core_async( domain: Text, config: Text, stories: Text, output: Text, train_path: Optional[Text] = None, kwargs: Optional[Dict] = None, ) -> Optional[Text]: """Trains a Core model. Args: domain: Path to the domain file. config: Path to the config file for Core. stories: Path to the Core training data. output: Output path. train_path: If `None` the model will be trained in a temporary directory, otherwise in the provided directory. kwargs: Additional training parameters. Returns: If `train_path` is given it returns the path to the model archive, otherwise the path to the directory with the trained model files. """ import rasa.core.train config = get_valid_config(config, CONFIG_MANDATORY_KEYS_CORE) _train_path = train_path or tempfile.mkdtemp() # normal (not compare) training core_model = await rasa.core.train( domain_file=domain, stories_file=data.get_core_directory(stories), output_path=os.path.join(_train_path, "core"), policy_config=config, kwargs=kwargs, ) if not train_path: # Only Core was trained. stories = data.get_core_directory(stories) output_path = create_output_path(output, prefix="core-") new_fingerprint = model.model_fingerprint(config, domain, stories=stories) model.create_package_rasa(_train_path, output_path, new_fingerprint) print_success( "Your Rasa Core model is trained and saved at '{}'.".format( output_path)) return core_model
def rasa_x(args: argparse.Namespace): from rasa.cli.utils import print_success, print_error, signal_handler from rasa.core.utils import configure_file_logging signal.signal(signal.SIGINT, signal_handler) args.log_level = args.loglevel or os.environ.get(ENV_LOG_LEVEL, DEFAULT_LOG_LEVEL) configure_file_logging(args.log_level, args.log_file) logging.getLogger("werkzeug").setLevel(logging.WARNING) logging.getLogger("engineio").setLevel(logging.WARNING) logging.getLogger("pika").setLevel(logging.WARNING) logging.getLogger("socketio").setLevel(logging.ERROR) if not args.loglevel == logging.DEBUG: logging.getLogger().setLevel(logging.WARNING) logging.getLogger("py.warnings").setLevel(logging.ERROR) if args.production: print_success("Starting Rasa X in production mode... 🚀") _rasa_service(args) else: if not is_rasa_x_installed(): print_error("Rasa X is not installed. The `rasa x` " "command requires an installation of Rasa X.") sys.exit(1) # noinspection PyUnresolvedReferences import rasax.community.utils as rasa_x_utils if not rasa_x_utils.are_terms_accepted(): rasa_x_utils.accept_terms_or_quit(args) metrics = rasa_x_utils.is_metrics_collection_enabled(args) print_success("Starting Rasa X in local mode... 🚀") start_event_service() rasa_x_token = generate_rasa_x_token() start_rasa_for_local_platform(args, rasa_x_token=rasa_x_token) # noinspection PyUnresolvedReferences from rasax.community.api.local import main_local main_local(args.project_path, args.data, token=rasa_x_token, metrics=metrics)
def rasa_x(args: argparse.Namespace): from rasa.cli.utils import print_success, print_error, signal_handler from rasa.core.utils import AvailableEndpoints signal.signal(signal.SIGINT, signal_handler) _configure_logging(args) if args.production: print_success("Starting Rasa X in production mode... 🚀") args.endpoints = get_validated_path( args.endpoints, "endpoints", DEFAULT_ENDPOINTS_PATH, True ) endpoints = AvailableEndpoints.read_endpoints(args.endpoints) _rasa_service(args, endpoints) else: if not is_rasa_x_installed(): print_error( "Rasa X is not installed. The `rasa x` " "command requires an installation of Rasa X." ) sys.exit(1) project_path = "." if not is_rasa_project_setup(project_path): print_error( "This directory is not a valid Rasa project. Use 'rasa init' " "to create a new Rasa project or switch to a valid Rasa project " "directory." ) sys.exit(1) if args.data and not os.path.exists(args.data): print_warning( "The provided data path ('{}') does not exists. Rasa X will start " "without any training data.".format(args.data) ) # noinspection PyUnresolvedReferences from rasax.community import local local.check_license_and_metrics(args) rasa_x_token = generate_rasa_x_token() process = start_rasa_for_local_rasa_x(args, rasa_x_token=rasa_x_token) try: local.main(args, project_path, args.data, token=rasa_x_token) finally: process.terminate()
def accept_terms_or_quit(args: argparse.Namespace) -> None: """Prompt the user to accept the Rasa terms.""" import webbrowser import questionary from rasax.community.constants import RASA_TERMS_URL show_prompt = not hasattr(args, "no_prompt") or not args.no_prompt if not show_prompt: print( f"By adding the '--no_prompt' parameter you agreed to the Rasa " f"X license agreement ({RASA_TERMS_URL})" ) return rasa_cli_utils.print_success( "Before you can use Rasa X, you have to agree to its " "license agreement (you will only have to do this " "once)." ) should_open_in_browser = questionary.confirm( "Would you like to view the license agreement in your web browser?" ).ask() if should_open_in_browser: webbrowser.open(RASA_TERMS_URL) accepted_terms = questionary.confirm( "\nRasa X License Agreement\n" "===========================\n\n" "Do you agree to the Rasa X license agreement ({})?\n" "By typing 'y', you agree to the terms. " "If you are using this software for a company, by confirming, " "you acknowledge you have the authority to do so.\n" "If you do not agree, type 'n' to stop Rasa X." "".format(RASA_TERMS_URL), default=False, qmark="", ).ask() if accepted_terms: rasa_utils.write_global_config_value(CONFIG_FILE_TERMS_KEY, True) else: rasa_cli_utils.print_error_and_exit( "Sorry, without accepting the terms, you cannot use Rasa X. " "You can of course still use the (Apache 2 licensed) Rasa framework: " "https://github.com/RasaHQ/rasa", exit_code=0, )
def _migrate_tracker_store_to_rasa_x( endpoints_file: Text, max_number_of_trackers: Optional[int]) -> None: old_tracker_store = _get_old_tracker_store(endpoints_file) rasa_x_tracker_store = _get_rasa_x_tracker_store() # Disable warnings regarding not existing slots logging.getLogger("rasa.core.trackers").setLevel(logging.CRITICAL) if rasa_x_tracker_store.keys(): should_migrate = questionary.confirm( "Found existing trackers in your Rasa X tracker store. Do you " "still want to migrate the new trackers?") if not should_migrate: exit(1) db_session = db_utils.get_database_session(True, create_tables=True) sql_migrations.run_migrations(db_session) event_service = EventService(db_session) sender_ids = old_tracker_store.keys() if max_number_of_trackers: sender_ids = sender_ids[:max_number_of_trackers] print_success("Start migrating {} trackers.".format(len(sender_ids))) nr_skipped_trackers = 0 for sender_id in tqdm(sender_ids): if rasa_x_tracker_store.retrieve(sender_id): nr_skipped_trackers += 1 logging.debug( "Tracker for sender '{}' already exists. Skipping the " "migration for it.".format(sender_id)) else: tracker = old_tracker_store.retrieve(sender_id) # Migrate tracker store to new tracker store format rasa_x_tracker_store.save(tracker) # Replay events of tracker _replay_tracker_events(tracker, event_service) # Set latest event id so that the `SQLiteEventConsumer` only consumes not already # migrated events set_latest_event_id(db_session, rasa_x_tracker_store) print_success( "Finished migrating trackers ({} were skipped since they were " "already migrated).".format(nr_skipped_trackers))
def rasa_x(args: argparse.Namespace): from rasa.cli.utils import print_success, print_error, signal_handler from rasa.core.utils import configure_file_logging from rasa.utils.io import configure_colored_logging signal.signal(signal.SIGINT, signal_handler) logging.getLogger("werkzeug").setLevel(logging.WARNING) logging.getLogger("engineio").setLevel(logging.WARNING) logging.getLogger("pika").setLevel(logging.WARNING) logging.getLogger("socketio").setLevel(logging.ERROR) if not args.loglevel == logging.DEBUG: logging.getLogger().setLevel(logging.WARNING) logging.getLogger("py.warnings").setLevel(logging.ERROR) logging.getLogger("apscheduler").setLevel(logging.ERROR) logging.getLogger("rasa").setLevel(logging.WARNING) logging.getLogger("sanic.root").setLevel(logging.ERROR) log_level = args.loglevel or DEFAULT_LOG_LEVEL configure_colored_logging(log_level) configure_file_logging(log_level, args.log_file) metrics = is_metrics_collection_enabled(args) if args.production: print_success("Starting Rasa X in production mode... 🚀") _core_service(args) else: print_success("Starting Rasa X in local mode... 🚀") if not is_rasa_x_installed(): print_error( "Rasa X is not installed. The `rasa x` " "command requires an installation of Rasa X." ) sys.exit(1) # noinspection PyUnresolvedReferences from rasax.community.api.local import main_local start_event_service() rasa_x_token = generate_rasa_x_token() start_core_for_local_platform(args, rasa_x_token=rasa_x_token) main_local( args.project_path, args.data_path, token=rasa_x_token, metrics=metrics )