Metadata-Version: 2.4
Name: yapp-prompt
Version: 0.1.3
Summary: YAPP (Yet Another Prompt Package) is a lightweight Python library that provides a robust, typed, and configurable way to handle interactive user input.
Author-email: BonjourBenjamin <contact@benjapied.com>
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: rich
Dynamic: license-file

# 🧩 YAPP — Yet Another Prompt Package

**YAPP** is a lightweight Python library that provides a robust, typed, and configurable way to handle interactive user input.

It provides a unique `prompt` function capable of handling:
* default value
* custom validation
* type conversion (`cast`)
* predefined choices
* attempt limit management
* masked input (e.g., passwords, tokens, etc.) [`secret`]
* advanced typing via `typing.overload`

---

## 🚀 Installation

```bash
pip install yapp-prompt
```

---

## ✨ Features
* ✅ Default value management
* ✅ Support for nullable inputs
* ✅ Custom validation
* ✅ Automatic type conversion
* ✅ Support for user selections
* ✅ Secure input (`getpass`)
* ✅ Limit on the number of attempts
* ✅ Explicit typing with `typing.overload`

---

## 📦 Base usage

```python
from yapp_prompt import prompt
name = prompt("What is your name?")
print(name)
```

---

## 🎯 Default value

```python
age = prompt("Your age", default=18, cast=int)
print(age, type(age))
```

👉 If the user presses `Enter`, `18` will be returned.

---

## 🔁 Nullable

```python
value = prompt("Optional value", nullable=True)
```
👉 Return `None` if the user presses `Enter`.

---

## 🔒 Hidden input (passwords, tokens, etc.)

```python
password = prompt("Password", secret=True)
```

---

## 🔢 Type conversion (`cast`)

```python
age = prompt("Your age", cast=int)
```

---

## ✔️ Custom validation

```python
def is_valid(value: str) -> bool:
    return value.isdigit()

age = prompt("Age", verification=is_valid, cast=int)
```

---

## 📋 Preset options

```python
def verify(choices, value):
    return value in choices

color = prompt(
    "Choose a color",
    choices=["red", "blue", "green"],
    verification=verify
)
```

---

## 🎨 Custom formatter

```python
def formatter(choices):
    return "\nAvailable: " + ", ".join(choices)

color = prompt(
    "Color",
    choices=["red", "blue"],
    formatter=formatter
)
```

---

## 🔁 Number of attempts

```python
value = prompt("Enter value", max_attempt=3)
```

### Infinite mode

```python
value = prompt("Enter value", max_attempt="infinite")
```

---

## ⚙️ Paramètres
| Parameters     | Type                   | Description            | Special value |
| -------------- | ---------------------- | ---------------------- | ------------- |
| `message`      | `str`                  | Message displayed      |               |
| `choices`      | `Choices \| None`      | List of option         |               |
| `default`      | `T \| None`            | Default value          |               |
| `nullable`     | `bool`                 | Allows `None`          |               |
| `formatter`    | `Callable`             | Format of the options  |               |
| `verification` | `Callable`             | Validation function    |               |
| `cast`         | `Callable`             | Type conversion        |               |
| `secret`       | `bool`                 | Masque la saisie       |               |
| `max_attempt`  | `int`                  | Max number of attempts | `"infinite"`  |
| `console`      | `rich.console.Console` | Console used           |               |

---

## 🧠 Advanced typing
YAPP uses `typing.overload` to provide accurate typing based on:
* `default`
* `nullable`
* `max_attempt`
👉 Example :

```python
value: int = prompt("Number", cast=int, default=0)
```

```python
value: int | None = prompt("Number", cast=int, nullable=True)
```

---

## ⚠️ Important information
### Empty value (`""`)
* If `default` exist -> return `default`
* Else if `nullable=True` -> return `None`
* Else -> requests another seizure until attempt maximum attempt.

---

## 🐞 Error Handling
* If `verification` fails -> try again
* If `cast` fails -> try again
* If `max_attempts` is reaching -> return `default` if exist else `None`

---

## 🧪 Tests
Use `pytest` with `monkeypatch` to mock `input` :
```bash
pytest -v
```

---

## ⚠️ Dependencies
* [`rich`](https://pypi.org/project/rich/) for console output
---

## 💡 Use cases
* Interactive CLIs
* Automation scripts
* Command-line tools

---

## 📄 License
[MIT](LICENSE)

---

## 👨‍💻 Auteur
BonjourBenjamin
