def main(): args = CmdlineParser().parse_args() # Parse environment variables from Dockerfile. # If an environment variable is not empty and it's not defined in the arguments, then we'll use the environment # variable. if args.config_file_name is None and len( os.environ.get("CONFIG_FILE_NAME", "")) > 0: args.config_file_name = os.environ["CONFIG_FILE_NAME"] if args.config_password is None and len( os.environ.get("CONFIG_PASSWORD", "")) > 0: args.config_password = os.environ["CONFIG_PASSWORD"] # If no password is given from the command line, prompt for one. secrets_manager_cls = ETHKeyFileSecretManger client_config_map = load_client_config_map_from_file() if args.config_password is None: secrets_manager = login_prompt(secrets_manager_cls, style=load_style(client_config_map)) if not secrets_manager: return else: secrets_manager = secrets_manager_cls(args.config_password) asyncio.get_event_loop().run_until_complete( quick_start(args, secrets_manager))
def __init__(self, input_handler: Callable, bindings: KeyBindings, completer: Completer): self.search_field = create_search_field() self.input_field = create_input_field(completer=completer) self.output_field = create_output_field() self.log_field = create_log_field(self.search_field) self.layout = generate_layout(self.input_field, self.output_field, self.log_field, self.search_field) # add self.to_stop_config to know if cancel is triggered self.to_stop_config: bool = False self.bindings = bindings self.input_handler = input_handler self.input_field.accept_handler = self.accept self.app = Application(layout=self.layout, full_screen=True, key_bindings=self.bindings, style=load_style(), mouse_support=True, clipboard=PyperclipClipboard()) # settings self.prompt_text = ">>> " self.pending_input = None self.input_event = None self.hide_input = False
def test_load_style_windows(self, is_windows_mock): is_windows_mock.return_value = True global_config_map = {} global_config_map["top-pane"] = self.ConfigVar("#FAFAFA") global_config_map["bottom-pane"] = self.ConfigVar("#FAFAFA") global_config_map["output-pane"] = self.ConfigVar("#FAFAFA") global_config_map["input-pane"] = self.ConfigVar("#FAFAFA") global_config_map["logs-pane"] = self.ConfigVar("#FAFAFA") global_config_map["terminal-primary"] = self.ConfigVar("#FCFCFC") style = Style.from_dict({ "output-field": "bg:#ansigray #ansigray", "input-field": "bg:#ansigray #ansiwhite", "log-field": "bg:#ansigray #ansiwhite", "header": "bg:#ansigray #ansiwhite", "footer": "bg:#ansigray #ansiwhite", "search": "#ansigray", "search.current": "#ansigray", "primary": "#ansigray", "warning": "#ansibrightyellow", "error": "#ansired" }) self.assertEqual(style.class_names_and_attrs, load_style(global_config_map).class_names_and_attrs)
def __init__(self, input_handler: Callable, bindings: KeyBindings, completer: Completer): use_asyncio_event_loop() self.input_field = create_input_field(completer=completer) self.output_field = create_output_field() self.log_field = create_log_field() self.layout = generate_layout(self.input_field, self.output_field, self.log_field) self.bindings = bindings self.input_handler = input_handler self.input_field.accept_handler = self.accept self.app = Application(layout=self.layout, full_screen=True, key_bindings=self.bindings, style=load_style(), mouse_support=True, clipboard=PyperclipClipboard()) self.log_lines: Deque[str] = deque() self.log(HEADER) # settings self.prompt_text = ">>> " self.pending_input = None self.input_event = None self.hide_input = False
def test_load_style_unix(self, is_windows_mock): is_windows_mock.return_value = False global_config_map = {} global_config_map["top-pane"] = self.ConfigVar("#FAFAFA") global_config_map["bottom-pane"] = self.ConfigVar("#FAFAFA") global_config_map["output-pane"] = self.ConfigVar("#FAFAFA") global_config_map["input-pane"] = self.ConfigVar("#FAFAFA") global_config_map["logs-pane"] = self.ConfigVar("#FAFAFA") global_config_map["terminal-primary"] = self.ConfigVar("#FCFCFC") style = Style.from_dict({ "output-field": "bg:#FAFAFA #FCFCFC", "input-field": "bg:#FAFAFA #FFFFFF", "log-field": "bg:#FAFAFA #FFFFFF", "header": "bg:#FAFAFA #AAAAAA", "footer": "bg:#FAFAFA #AAAAAA", "search": "bg:#000000 #93C36D", "search.current": "bg:#000000 #1CD085", "primary": "#FCFCFC", "warning": "#93C36D", "error": "#F5634A" }) self.assertEqual(style.class_names_and_attrs, load_style(global_config_map).class_names_and_attrs)
def main(): chdir_to_data_directory() secrets_manager_cls = ETHKeyFileSecretManger ev_loop: asyncio.AbstractEventLoop = asyncio.get_event_loop() client_config_map = load_client_config_map_from_file() if login_prompt(secrets_manager_cls, style=load_style(client_config_map)): ev_loop.run_until_complete(main_async(client_config_map))
async def run(self): self.app = Application(layout=self.layout, full_screen=True, key_bindings=self.bindings, style=load_style(), mouse_support=True, clipboard=PyperclipClipboard()) await self.app.run_async()
async def run(self): self.app = Application(layout=self.layout, full_screen=True, key_bindings=self.bindings, style=load_style(), mouse_support=True, clipboard=PyperclipClipboard()) await self.app.run_async(pre_run=self.did_start_ui) self._stdout_redirect_context.close()
def __init__(self) -> None: super().__init__() self.html_tag_css_style_map: Dict[str, str] = {style: css for style, css in load_style().style_rules} self.html_tag_css_style_map.update({ style: config.value for style, config in color_config_map.items() if style not in self.html_tag_css_style_map.keys() }) # Maps specific text to its corresponding UI styles self.text_style_tag_map: Dict[str, str] = text_ui_style
def __init__(self, client_config_map: ClientConfigAdapter) -> None: super().__init__() self.html_tag_css_style_map: Dict[str, str] = { style: css for style, css in load_style(client_config_map).style_rules } self.html_tag_css_style_map.update({ ti.attr: ti.value for ti in client_config_map.color.traverse() if ti.attr not in self.html_tag_css_style_map }) # Maps specific text to its corresponding UI styles self.text_style_tag_map: Dict[str, str] = text_ui_style
def test_load_style_unix(self, is_windows_mock): is_windows_mock.return_value = False global_config_map = ClientConfigMap() global_config_map.color.top_pane = "#FAFAFA" global_config_map.color.bottom_pane = "#FAFAFA" global_config_map.color.output_pane = "#FAFAFA" global_config_map.color.input_pane = "#FAFAFA" global_config_map.color.logs_pane = "#FAFAFA" global_config_map.color.terminal_primary = "#FCFCFC" global_config_map.color.primary_label = "#5FFFD7" global_config_map.color.secondary_label = "#FFFFFF" global_config_map.color.success_label = "#5FFFD7" global_config_map.color.warning_label = "#FFFF00" global_config_map.color.info_label = "#5FD7FF" global_config_map.color.error_label = "#FF0000" adapter = ClientConfigAdapter(global_config_map) style = Style.from_dict({ "output_field": "bg:#FAFAFA #FCFCFC", "input_field": "bg:#FAFAFA #FFFFFF", "log_field": "bg:#FAFAFA #FFFFFF", "header": "bg:#FAFAFA #AAAAAA", "footer": "bg:#FAFAFA #AAAAAA", "search": "bg:#000000 #93C36D", "search.current": "bg:#000000 #1CD085", "primary": "#FCFCFC", "warning": "#93C36D", "error": "#F5634A", "tab_button.focused": "bg:#FCFCFC #FAFAFA", "tab_button": "bg:#FFFFFF #FAFAFA", "dialog": "bg:#171E2B", "dialog frame.label": "bg:#FCFCFC #000000", "dialog.body": "bg:#000000 #FCFCFC", "dialog shadow": "bg:#171E2B", "button": "bg:#000000", "text-area": "bg:#000000 #FCFCFC", # Label bg and font color "primary_label": "bg:#5FFFD7 #FAFAFA", "secondary_label": "bg:#FFFFFF #FAFAFA", "success_label": "bg:#5FFFD7 #FAFAFA", "warning_label": "bg:#FFFF00 #FAFAFA", "info_label": "bg:#5FD7FF #FAFAFA", "error_label": "bg:#FF0000 #FAFAFA", }) self.assertEqual(style.class_names_and_attrs, load_style(adapter).class_names_and_attrs)
def test_load_style_windows(self, is_windows_mock): is_windows_mock.return_value = True global_config_map = ClientConfigMap() global_config_map.color.top_pane = "#FAFAFA" global_config_map.color.bottom_pane = "#FAFAFA" global_config_map.color.output_pane = "#FAFAFA" global_config_map.color.input_pane = "#FAFAFA" global_config_map.color.logs_pane = "#FAFAFA" global_config_map.color.terminal_primary = "#FCFCFC" global_config_map.color.primary_label = "#5FFFD7" global_config_map.color.secondary_label = "#FFFFFF" global_config_map.color.success_label = "#5FFFD7" global_config_map.color.warning_label = "#FFFF00" global_config_map.color.info_label = "#5FD7FF" global_config_map.color.error_label = "#FF0000" adapter = ClientConfigAdapter(global_config_map) style = Style.from_dict({ "output_field": "bg:#ansiwhite #ansiwhite", "input_field": "bg:#ansiwhite #ansiwhite", "log_field": "bg:#ansiwhite #ansiwhite", "header": "bg:#ansiwhite #ansiwhite", "footer": "bg:#ansiwhite #ansiwhite", "search": "#ansiwhite", "search.current": "#ansiwhite", "primary": "#ansiwhite", "warning": "#ansibrightyellow", "error": "#ansired", "tab_button.focused": "bg:#ansiwhite #ansiwhite", "tab_button": "bg:#ansiwhite #ansiwhite", "dialog": "bg:#ansigreen", "dialog frame.label": "bg:#ansiwhite #ansiblack", "dialog.body": "bg:#ansiblack #ansiwhite", "dialog shadow": "bg:#ansigreen", "button": "bg:#ansigreen", "text-area": "bg:#ansiblack #ansiwhite", # Label bg and font color "primary_label": "bg:#ansicyan #ansiwhite", "secondary_label": "bg:#ansiwhite #ansiwhite", "success_label": "bg:#ansicyan #ansiwhite", "warning_label": "bg:#ansiyellow #ansiwhite", "info_label": "bg:#ansicyan #ansiwhite", "error_label": "bg:#ansired #ansiwhite", }) self.assertEqual(style.class_names_and_attrs, load_style(adapter).class_names_and_attrs)
def test_login_success( self, new_password_required_mock: MagicMock, login_mock: MagicMock, input_dialog_mock: MagicMock, message_dialog_mock: MagicMock, ): new_password_required_mock.return_value = False run_mock = MagicMock() run_mock.run.return_value = self.password input_dialog_mock.return_value = run_mock login_mock.return_value = True self.assertTrue(login_prompt(ETHKeyFileSecretManger, style=load_style(self.client_config_map))) self.assertEqual(1, len(login_mock.mock_calls)) message_dialog_mock.assert_not_called()
def test_login_error_retries( self, new_password_required_mock: MagicMock, login_mock: MagicMock, input_dialog_mock: MagicMock, message_dialog_mock: MagicMock, ): new_password_required_mock.return_value = False run_mock = MagicMock() run_mock.run.return_value = "somePassword" input_dialog_mock.return_value = run_mock message_dialog_mock.return_value = run_mock login_mock.side_effect = [False, True] self.assertTrue(login_prompt(ETHKeyFileSecretManger, style=load_style(self.client_config_map))) self.assertEqual(2, len(login_mock.mock_calls)) message_dialog_mock.assert_called()
async def _config_single_key_legacy( self, # type: HummingbotApplication key: str, input_value: Any, ): # pragma: no cover config_var, config_map, file_path = None, None, None if self.strategy_config_map is not None and key in self.strategy_config_map: config_map = self.strategy_config_map file_path = STRATEGIES_CONF_DIR_PATH / self.strategy_file_name config_var = config_map[key] if input_value is None: self.notify( "Please follow the prompt to complete configurations: ") if config_var.key == "inventory_target_base_pct": await self.asset_ratio_maintenance_prompt_legacy( config_map, input_value) elif config_var.key == "inventory_price": await self.inventory_price_prompt_legacy(config_map, input_value) else: await self.prompt_a_config_legacy(config_var, input_value=input_value, assign_default=False) if self.app.to_stop_config: self.app.to_stop_config = False return missings = missing_required_configs_legacy(config_map) if missings: self.notify( "\nThere are other configuration required, please follow the prompt to complete them." ) missings = await self._prompt_missing_configs(config_map) save_to_yml_legacy(str(file_path), config_map) self.notify("\nNew configuration saved:") self.notify(f"{key}: {str(config_var.value)}") self.app.app.style = load_style(self.client_config_map) for config in missings: self.notify(f"{config.key}: {str(config.value)}") if (isinstance(self.strategy, PureMarketMakingStrategy) or isinstance(self.strategy, PerpetualMarketMakingStrategy)): updated = ConfigCommand.update_running_mm(self.strategy, key, config_var.value) if updated: self.notify( f"\nThe current {self.strategy_name} strategy has been updated " f"to reflect the new configuration.")
def test_load_style_windows(self, is_windows_mock): is_windows_mock.return_value = True global_config_map = {} global_config_map["top-pane"] = self.ConfigVar("#FAFAFA") global_config_map["bottom-pane"] = self.ConfigVar("#FAFAFA") global_config_map["output-pane"] = self.ConfigVar("#FAFAFA") global_config_map["input-pane"] = self.ConfigVar("#FAFAFA") global_config_map["logs-pane"] = self.ConfigVar("#FAFAFA") global_config_map["terminal-primary"] = self.ConfigVar("#FCFCFC") global_config_map["primary-label"] = self.ConfigVar("#5FFFD7") global_config_map["secondary-label"] = self.ConfigVar("#FFFFFF") global_config_map["success-label"] = self.ConfigVar("#5FFFD7") global_config_map["warning-label"] = self.ConfigVar("#FFFF00") global_config_map["info-label"] = self.ConfigVar("#5FD7FF") global_config_map["error-label"] = self.ConfigVar("#FF0000") style = Style.from_dict({ "output-field": "bg:#ansiwhite #ansiwhite", "input-field": "bg:#ansiwhite #ansiwhite", "log-field": "bg:#ansiwhite #ansiwhite", "header": "bg:#ansiwhite #ansiwhite", "footer": "bg:#ansiwhite #ansiwhite", "search": "#ansiwhite", "search.current": "#ansiwhite", "primary": "#ansiwhite", "warning": "#ansibrightyellow", "error": "#ansired", "tab_button.focused": "bg:#ansiwhite #ansiwhite", "tab_button": "bg:#ansiwhite #ansiwhite", # Label bg and font color "primary-label": "bg:#ansicyan #ansiwhite", "secondary-label": "bg:#ansiwhite #ansiwhite", "success-label": "bg:#ansicyan #ansiwhite", "warning-label": "bg:#ansiyellow #ansiwhite", "info-label": "bg:#ansicyan #ansiwhite", "error-label": "bg:#ansired #ansiwhite", }) self.assertEqual(style.class_names_and_attrs, load_style(global_config_map).class_names_and_attrs)
def test_load_style_unix(self, is_windows_mock): is_windows_mock.return_value = False global_config_map = {} global_config_map["top-pane"] = self.ConfigVar("#FAFAFA") global_config_map["bottom-pane"] = self.ConfigVar("#FAFAFA") global_config_map["output-pane"] = self.ConfigVar("#FAFAFA") global_config_map["input-pane"] = self.ConfigVar("#FAFAFA") global_config_map["logs-pane"] = self.ConfigVar("#FAFAFA") global_config_map["terminal-primary"] = self.ConfigVar("#FCFCFC") global_config_map["primary-label"] = self.ConfigVar("#5FFFD7") global_config_map["secondary-label"] = self.ConfigVar("#FFFFFF") global_config_map["success-label"] = self.ConfigVar("#5FFFD7") global_config_map["warning-label"] = self.ConfigVar("#FFFF00") global_config_map["info-label"] = self.ConfigVar("#5FD7FF") global_config_map["error-label"] = self.ConfigVar("#FF0000") style = Style.from_dict({ "output-field": "bg:#FAFAFA #FCFCFC", "input-field": "bg:#FAFAFA #FFFFFF", "log-field": "bg:#FAFAFA #FFFFFF", "header": "bg:#FAFAFA #AAAAAA", "footer": "bg:#FAFAFA #AAAAAA", "search": "bg:#000000 #93C36D", "search.current": "bg:#000000 #1CD085", "primary": "#FCFCFC", "warning": "#93C36D", "error": "#F5634A", "tab_button.focused": "bg:#FCFCFC #FAFAFA", "tab_button": "bg:#FFFFFF #FAFAFA", # Label bg and font color "primary-label": "bg:#5FFFD7 #FAFAFA", "secondary-label": "bg:#FFFFFF #FAFAFA", "success-label": "bg:#5FFFD7 #FAFAFA", "warning-label": "bg:#FFFF00 #FAFAFA", "info-label": "bg:#5FD7FF #FAFAFA", "error-label": "bg:#FF0000 #FAFAFA", }) self.assertEqual(style.class_names_and_attrs, load_style(global_config_map).class_names_and_attrs)
def __init__(self, input_handler: Callable, bindings: KeyBindings, completer: Completer): self.search_field = create_search_field() self.input_field = create_input_field(completer=completer) self.output_field = create_output_field() self.log_field = create_log_field(self.search_field) self.timer = create_timer() self.process_usage = create_process_monitor() self.trade_monitor = create_trade_monitor() self.layout = generate_layout(self.input_field, self.output_field, self.log_field, self.search_field, self.timer, self.process_usage, self.trade_monitor) # add self.to_stop_config to know if cancel is triggered self.to_stop_config: bool = False self.live_updates = False self.bindings = bindings self.input_handler = input_handler self.input_field.accept_handler = self.accept self.app = Application(layout=self.layout, full_screen=True, key_bindings=self.bindings, style=load_style(), mouse_support=True, clipboard=PyperclipClipboard()) # settings self.prompt_text = ">>> " self.pending_input = None self.input_event = None self.hide_input = False # start ui tasks loop = asyncio.get_event_loop() loop.create_task(start_timer(self.timer)) loop.create_task(start_process_monitor(self.process_usage)) loop.create_task(start_trade_monitor(self.trade_monitor))
async def _config_single_key( self, # type: HummingbotApplication key: str, input_value): """ Configure a single variable only. Prompt the user to finish all configurations if there are remaining empty configs at the end. """ self.placeholder_mode = True self.app.hide_input = True try: if (not isinstance(self.strategy_config_map, (type(None), ClientConfigAdapter)) and key in self.strategy_config_map): await self._config_single_key_legacy(key, input_value) else: client_config_key = key in self.client_config_map.config_paths( ) if client_config_key: config_map = self.client_config_map file_path = CLIENT_CONFIG_PATH elif self.strategy is not None: self.notify( "Configuring the strategy while it is running is not currently supported." ) return else: config_map = self.strategy_config_map file_path = STRATEGIES_CONF_DIR_PATH / self.strategy_file_name if input_value is None: self.notify( "Please follow the prompt to complete configurations: " ) if key == "inventory_target_base_pct": await self.asset_ratio_maintenance_prompt( config_map, input_value) elif key == "inventory_price": await self.inventory_price_prompt(config_map, input_value) else: await self.prompt_a_config(config_map, key, input_value, assign_default=False) if self.app.to_stop_config: self.app.to_stop_config = False return save_to_yml(file_path, config_map) self.notify("\nNew configuration saved.") if client_config_key: self.list_client_configs() else: self.list_strategy_configs() self.app.app.style = load_style(self.client_config_map) except asyncio.TimeoutError: self.logger().error("Prompt timeout") except Exception as err: self.logger().error(str(err), exc_info=True) finally: self.app.hide_input = False self.placeholder_mode = False self.app.change_prompt(prompt=">>> ")
async def _config_single_key( self, # type: HummingbotApplication key: str, input_value): """ Configure a single variable only. Prompt the user to finish all configurations if there are remaining empty configs at the end. """ self.placeholder_mode = True self.app.hide_input = True try: config_var, config_map, file_path = None, None, None if key in global_config_map: config_map = global_config_map file_path = GLOBAL_CONFIG_PATH elif self.strategy_config_map is not None and key in self.strategy_config_map: config_map = self.strategy_config_map file_path = join(CONF_FILE_PATH, self.strategy_file_name) config_var = config_map[key] if input_value is None: self._notify( "Please follow the prompt to complete configurations: ") if config_var.key == "inventory_target_base_pct": await self.asset_ratio_maintenance_prompt( config_map, input_value) elif config_var.key == "inventory_price": await self.inventory_price_prompt(config_map, input_value) else: await self.prompt_a_config(config_var, input_value=input_value, assign_default=False) if self.app.to_stop_config: self.app.to_stop_config = False return await self.update_all_secure_configs() missings = missing_required_configs(config_map) if missings: self._notify( "\nThere are other configuration required, please follow the prompt to complete them." ) missings = await self._prompt_missing_configs(config_map) save_to_yml(file_path, config_map) self._notify("\nNew configuration saved:") self._notify(f"{key}: {str(config_var.value)}") self.app.app.style = load_style() for config in missings: self._notify(f"{config.key}: {str(config.value)}") if isinstance(self.strategy, PureMarketMakingStrategy) or \ isinstance(self.strategy, PerpetualMarketMakingStrategy): updated = ConfigCommand.update_running_mm( self.strategy, key, config_var.value) if updated: self._notify( f"\nThe current {self.strategy_name} strategy has been updated " f"to reflect the new configuration.") except asyncio.TimeoutError: self.logger().error("Prompt timeout") except Exception as err: self.logger().error(str(err), exc_info=True) finally: self.app.hide_input = False self.placeholder_mode = False self.app.change_prompt(prompt=">>> ")