Skip to content

Commit

Permalink
feat: added support for Paths, Email and Passwords
Browse files Browse the repository at this point in the history
  • Loading branch information
Chandra Irugalbandara committed Jul 29, 2024
1 parent 91d64a1 commit fb20d16
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 0 deletions.
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Argonauts is a Python library that transforms your functions into interactive co

- Transform functions into interactive CLIs with a single decorator
- Automatic type inference and validation
- Email, Password Support with validation
- Path Support with Autosuggestion
- Chainable interactive functions

## 📦 Installation
Expand Down Expand Up @@ -114,6 +116,35 @@ movie_night()

![Argonauts Demo](public/demo_1.gif)

### Email, Password, and Path Support

Argonauts provides built-in support for email, password, and path inputs with validation:

```python
from argonauts import argonaut
from argonauts.inputs import Email, Password, Path

@argonaut(process_name="Please wait...")
def login(email: Email, password: Password):
"""Login with email and password."""
...

@argonaut(process_name="Loading Configurations...")
def configure(config_path: Path):
"""Load configurations from a file."""
...
```

You can customize these Input types by inhereting them and overriding the `validate` method:

```python
from argonauts.inputs import Path

class JSONFile(Path):
def validate(self, value: str) -> bool:
return super().validate(value) and value.endswith(".json")
```

## 🤝 Contributing

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for more details.
Expand Down
30 changes: 30 additions & 0 deletions argonauts/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from functools import wraps
from typing import Any, Callable, get_args, get_origin

from argonauts.inputs import Email, Password, Path

import questionary

from rich.console import Console
Expand Down Expand Up @@ -131,6 +133,34 @@ def create_prompt(name: str, param: inspect.Parameter) -> Any: # noqa
validate=lambda text: text.replace(".", "", 1).isdigit()
or "Please enter a valid float.",
).ask()
if annotation == list:
return (
questionary.text(
f"Enter {name} (comma separated):",
default=", ".join(default) if default is not None else "",
validate=lambda text: len(text) > 0 or f"Please enter a valid {name}.",
)
.ask()
.split(", ")
)
if annotation == Path:
return questionary.path(
f"Enter {name}:",
default=default if default is not None else "",
validate=lambda path: Path.validate(path)
or f"Please enter a valid {name}.",
).ask()
if annotation == Password:
return questionary.password(
f"Enter {name}:",
validate=lambda text: len(text) > 0 or f"Please enter a valid {name}.",
).ask()
if annotation == Email:
return questionary.text(
f"Enter {name}:",
validate=lambda text: Email.validate(text)
or f"Please enter a valid {name}.",
).ask()

raise ValueError(f"Unsupported type: {annotation}")

Expand Down
38 changes: 38 additions & 0 deletions argonauts/inputs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""Different Types of Inputs to use with argonauts."""

import os
import re


class Path:
"""Path input with autocompletion."""

def __init__(self) -> None:
"""Initialize Path input."""
pass

@staticmethod
def validate(path: str) -> bool:
"""Validate the given path."""
return os.path.exists(path)


class Password:
"""Password input with masking."""

def __init__(self) -> None:
"""Initialize Password input."""
pass


class Email:
"""Email input with validation."""

def __init__(self) -> None:
"""Initialize Email input."""
pass

@staticmethod
def validate(email: str) -> bool:
"""Validate the given email."""
return bool(re.match(r"[^@]+@[^@]+\.[^@]+", email))
25 changes: 25 additions & 0 deletions examples/new_stuff.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""Example of using the new argonauts API."""

import time

from argonauts import argonaut
from argonauts.inputs import Email, Password, Path


@argonaut(process_name="Please wait...")
def login(email: Email, password: Password) -> None:
"""Login with email and password."""
time.sleep(3)
print(f"Logged in with {email}.")


@argonaut(process_name="Loading Configurations...")
def configure(config_path: Path) -> None:
"""Configure with the given path."""
time.sleep(3)
print(f"Configured with {config_path}.")


if __name__ == "__main__":
login()
configure()

0 comments on commit fb20d16

Please sign in to comment.