def feed_cli_with_input(_type, message, text, **kwargs): """ Create a Prompt, feed it with the given user input and return the CLI object. This returns a (result, Application) tuple. """ inp = create_pipe_input() try: inp.send_text(text) prompter = prompt_by_name(_type) application = prompter(message, input=inp, output=DummyOutput(), **kwargs) result = application.unsafe_ask() return result, application finally: inp.close()
def feed_cli_with_input(_type, message, texts, sleep_time=1, **kwargs): """ Create a Prompt, feed it with the given user input and return the CLI object. You an provide multiple texts, the feeder will async sleep for `sleep_time` This returns a (result, Application) tuple. """ if not isinstance(texts, list): texts = [texts] inp = create_pipe_input() try: prompter = prompt_by_name(_type) application = prompter(message, input=inp, output=DummyOutput(), **kwargs) if is_prompt_toolkit_3(): loop = asyncio.new_event_loop() future_result = loop.create_task(application.unsafe_ask_async()) for i, text in enumerate(texts): # noinspection PyUnresolvedReferences inp.send_text(text) if i != len(texts) - 1: loop.run_until_complete(asyncio.sleep(sleep_time)) result = loop.run_until_complete(future_result) else: for text in texts: inp.send_text(text) result = application.unsafe_ask() return result, application finally: inp.close()
def prompt(questions: List[Dict[Text, Any]], answers: Optional[Dict[Text, Any]] = None, patch_stdout: bool = False, true_color: bool = False, kbi_msg: Text = DEFAULT_KBI_MESSAGE, **kwargs): """Prompt the user for input on all the questions.""" if isinstance(questions, dict): questions = [questions] answers = answers or {} for question_config in questions: # import the question if 'type' not in question_config: raise PromptParameterException('type') if 'name' not in question_config: raise PromptParameterException('name') choices = question_config.get('choices') if choices is not None and callable(choices): question_config['choices'] = choices(answers) _kwargs = kwargs.copy() _kwargs.update(question_config) _type = _kwargs.pop('type') _filter = _kwargs.pop('filter', None) name = _kwargs.pop('name') when = _kwargs.pop('when', None) if true_color: _kwargs["color_depth"] = ColorDepth.TRUE_COLOR try: if when: # at least a little sanity check! if callable(question_config['when']): try: if not question_config['when'](answers): continue except Exception as e: raise ValueError("Problem in 'when' check of {} " "question: {}".format(name, e)) else: raise ValueError("'when' needs to be function that " "accepts a dict argument") if _filter: # at least a little sanity check! if not callable(_filter): raise ValueError("'filter' needs to be function that " "accepts an argument") if callable(question_config.get('default')): _kwargs['default'] = question_config['default'](answers) create_question_func = prompt_by_name(_type) if not create_question_func: raise ValueError("No question type '{}' found. " "Known question types are {}." "".format(_type, ", ".join(AVAILABLE_PROMPTS))) missing_args = list( utils.missing_arguments(create_question_func, _kwargs)) if missing_args: raise PromptParameterException(missing_args[0]) question = create_question_func(**_kwargs) answer = question.unsafe_ask(patch_stdout) if answer is not None: if _filter: try: answer = _filter(answer) except Exception as e: raise ValueError("Problem processing 'filter' of {} " "question: {}".format(name, e)) answers[name] = answer except KeyboardInterrupt: print('') print(kbi_msg) print('') return {} return answers
def unsafe_prompt( questions: Iterable[Mapping[str, Any]], answers: Optional[Mapping[str, Any]] = None, patch_stdout: bool = False, true_color: bool = False, **kwargs: Any, ) -> Dict[str, Any]: """Prompt the user for input on all the questions. Won't catch keyboard interrupts. Raises: KeyboardInterrupt: raised on keyboard interrupt """ if isinstance(questions, dict): questions = [questions] answers = dict(answers or {}) for question_config in questions: question_config = dict(question_config) # import the question if "type" not in question_config: raise PromptParameterException("type") if "name" not in question_config: raise PromptParameterException("name") choices = question_config.get("choices") if choices is not None and callable(choices): question_config["choices"] = choices(answers) _kwargs = kwargs.copy() _kwargs.update(question_config) _type = _kwargs.pop("type") _filter = _kwargs.pop("filter", None) name = _kwargs.pop("name") when = _kwargs.pop("when", None) if true_color: _kwargs["color_depth"] = ColorDepth.TRUE_COLOR if when: # at least a little sanity check! if callable(question_config["when"]): try: if not question_config["when"](answers): continue except Exception as e: raise ValueError("Problem in 'when' check of {} " "question: {}".format(name, e)) else: raise ValueError( "'when' needs to be function that accepts a dict argument") if _filter: # at least a little sanity check! if not callable(_filter): raise ValueError( "'filter' needs to be function that accepts an argument") if callable(question_config.get("default")): _kwargs["default"] = question_config["default"](answers) create_question_func = prompt_by_name(_type) if not create_question_func: raise ValueError("No question type '{}' found. " "Known question types are {}." "".format(_type, ", ".join(AVAILABLE_PROMPTS))) missing_args = list( utils.missing_arguments(create_question_func, _kwargs)) if missing_args: raise PromptParameterException(missing_args[0]) question = create_question_func(**_kwargs) answer = question.unsafe_ask(patch_stdout) if answer is not None: if _filter: try: answer = _filter(answer) except Exception as e: raise ValueError("Problem processing 'filter' of {} " "question: {}".format(name, e)) answers[name] = answer return answers
def unsafe_prompt( questions: Iterable[Mapping[str, Any]], answers: Optional[Mapping[str, Any]] = None, patch_stdout: bool = False, true_color: bool = False, **kwargs: Any, ) -> Dict[str, Any]: """Prompt the user for input on all the questions. Won't catch keyboard interrupts. Args: questions: A list of question configs representing questions to ask. A question config may have the following options: * type - The type of question. * name - An ID for the question (to identify it in the answers :obj:`dict`). * when - Callable to conditionally show the question. This function takes a :obj:`dict` representing the current answers. * filter - Function that the answer is passed to. The return value of this function is saved as the answer. Additional options correspond to the parameter names for particular question types. answers: Default answers. patch_stdout: Ensure that the prompt renders correctly if other threads are printing to stdout. true_color: Use true color output. color_depth: Color depth to use. If ``true_color`` is set to true then this value is ignored. type: Default ``type`` value to use in question config. filter: Default ``filter`` value to use in question config. name: Default ``name`` value to use in question config. when: Default ``when`` value to use in question config. default: Default ``default`` value to use in question config. kwargs: Additional options passed to every question. Returns: Dictionary of question answers. Raises: KeyboardInterrupt: raised on keyboard interrupt """ if isinstance(questions, dict): questions = [questions] answers = dict(answers or {}) for question_config in questions: question_config = dict(question_config) # import the question if "type" not in question_config: raise PromptParameterException("type") if "name" not in question_config: raise PromptParameterException("name") choices = question_config.get("choices") if choices is not None and callable(choices): question_config["choices"] = choices(answers) _kwargs = kwargs.copy() _kwargs.update(question_config) _type = _kwargs.pop("type") _filter = _kwargs.pop("filter", None) name = _kwargs.pop("name") when = _kwargs.pop("when", None) if true_color: _kwargs["color_depth"] = ColorDepth.TRUE_COLOR if when: # at least a little sanity check! if callable(question_config["when"]): try: if not question_config["when"](answers): continue except Exception as e: raise ValueError( "Problem in 'when' check of {} " "question: {}".format(name, e) ) else: raise ValueError( "'when' needs to be function that accepts a dict argument" ) if _filter: # at least a little sanity check! if not callable(_filter): raise ValueError( "'filter' needs to be function that accepts an argument" ) if callable(question_config.get("default")): _kwargs["default"] = question_config["default"](answers) create_question_func = prompt_by_name(_type) if not create_question_func: raise ValueError( "No question type '{}' found. " "Known question types are {}." "".format(_type, ", ".join(AVAILABLE_PROMPTS)) ) missing_args = list(utils.missing_arguments(create_question_func, _kwargs)) if missing_args: raise PromptParameterException(missing_args[0]) question = create_question_func(**_kwargs) answer = question.unsafe_ask(patch_stdout) if answer is not None: if _filter: try: answer = _filter(answer) except Exception as e: raise ValueError( "Problem processing 'filter' of {} " "question: {}".format(name, e) ) answers[name] = answer return answers