Skip to content

Commit

Permalink
✨ feat: interactive cli input (#947)
Browse files Browse the repository at this point in the history
Co-authored-by: rahul <raxhvl@users.noreply.github.com>
Co-authored-by: danceratopz <danceratopz@gmail.com>
  • Loading branch information
3 people authored Nov 7, 2024
1 parent 61aad9e commit e69aae5
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 2 deletions.
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ dependencies = [
"solc-select>=1.0.4,<2",
"filelock>=3.15.1,<4",
"ethereum-types>=0.2.1,<0.3",
"pyyaml>=6.0.2",
"types-pyyaml>=6.0.12.20240917",
"pyyaml>=6.0.2,<7",
"types-pyyaml>=6.0.12.20240917,<7",
"pytest-json-report>=1.5.0,<2",
"questionary>=2.0.1,<3",
]

[project.urls]
Expand Down
75 changes: 75 additions & 0 deletions src/cli/input/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""
A standard interface for interactive CLI inputs.
"""

from .questionary_input_repository import QuestionaryInputRepository

# Instantiate the input repository
input_repository = QuestionaryInputRepository()


def input_text(question: str) -> str:
"""
Ask a simple text input question.
Args:
question (str): The question to ask.
Returns:
str: The user's response.
"""
return input_repository.input_text(question)


def input_password(question: str) -> str:
"""
Ask a password input question (hidden text).
Args:
question (str): The question to ask.
Returns:
str: The user's response (password).
"""
return input_repository.input_password(question)


def input_select(question: str, choices: list) -> str:
"""
Ask a single-choice question from a list of options.
Args:
question (str): The question to ask.
choices (list): A list of options for the user to choose from.
Returns:
str: The selected choice.
"""
return input_repository.input_select(question, choices)


def input_checkbox(question: str, choices: list) -> list:
"""
Ask a multi-choice question and return a list of selected choices.
Args:
question (str): The question to ask.
choices (list): A list of options for the user to choose from.
Returns:
list: The list of selected choices.
"""
return input_repository.input_checkbox(question, choices)


def input_confirm(question: str) -> bool:
"""
Ask a yes/no confirmation question.
Args:
question (str): The question to ask.
Returns:
bool: True for 'yes', False for 'no'.
"""
return input_repository.input_confirm(question)
38 changes: 38 additions & 0 deletions src/cli/input/input_repository.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""
An abstract base class for handling interactive CLI inputs.
"""

from abc import ABC, abstractmethod
from typing import List


class InputRepository(ABC):
"""
Abstract base class for input handling.
This class defines the interface for different input types that can be swapped out.
"""

@abstractmethod
def input_text(self, question: str) -> str:
"""Ask a text input question."""
pass

@abstractmethod
def input_password(self, question: str) -> str:
"""Ask a password input question (hidden)."""
pass

@abstractmethod
def input_select(self, question: str, choices: List[str]) -> str:
"""Ask a single-choice selection question."""
pass

@abstractmethod
def input_checkbox(self, question: str, choices: List[str]) -> List[str]:
"""Ask a multi-choice question."""
pass

@abstractmethod
def input_confirm(self, question: str) -> bool:
"""Ask a yes/no confirmation question."""
pass
42 changes: 42 additions & 0 deletions src/cli/input/questionary_input_repository.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""
Interactive CLI inputs using questionary library.
See: https://questionary.readthedocs.io/
"""

from questionary import checkbox, confirm, password, select, text

from .input_repository import InputRepository


class QuestionaryInputRepository(InputRepository):
"""Repository for handling various types of user inputs using the Questionary library."""

def input_text(self, question: str) -> str:
"""Ask a text input question.
See: https://questionary.readthedocs.io/en/stable/api.html#questionary.text
"""
return text(message=question).ask()

def input_password(self, question: str) -> str:
"""Ask a password input question (hidden).
See: https://questionary.readthedocs.io/en/stable/api.html#questionary.password
"""
return password(message=question).ask()

def input_select(self, question: str, choices: list) -> str:
"""Ask a single-choice selection question.
See: https://questionary.readthedocs.io/en/stable/api.html#questionary.select
"""
return select(message=question, choices=choices).ask()

def input_checkbox(self, question: str, choices: list) -> list:
"""Ask a multi-choice question.
See: https://questionary.readthedocs.io/en/stable/api.html#questionary.checkbox
"""
return checkbox(message=question, choices=choices).ask()

def input_confirm(self, question: str) -> bool:
"""Ask a yes/no confirmation question.
See: https://questionary.readthedocs.io/en/stable/api.html#questionary.confirm
"""
return confirm(message=question).ask()
35 changes: 35 additions & 0 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions whitelist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ Pytest
pytest's
pytestArgs
qGpsxSA
questionary
quickstart
radd
randao
Expand Down

0 comments on commit e69aae5

Please sign in to comment.