
# Freyja ⚡
**No-dependency, zero-configuration CLI tool to build command-line interfaces purely from your code.**
Transform your Python functions and classes into powerful command-line applications in seconds! Freyja uses introspection and type annotations to automatically generate professional CLIs with zero configuration required.
## Table of Contents
* [🚀 Why Freyja?](#-why-freyja)
* [⚡ Quick Start](#-quick-start)
* [🗂️ Module-based CLI](#️-module-based-cli)
* [🏗️ Class-based CLI](#️-class-based-cli)
* [Direct Methods Pattern](#direct-methods-pattern)
* [Inner Classes Pattern](#inner-classes-pattern)
* [✨ Key Features](#-key-features)
* [📚 Documentation](#-documentation)
* [🛠️ Development](#️-development)
* [⚙️ Requirements](#️-requirements)
## 🚀 Why Freyja?
**Build CLIs in under 5 minutes!** No configuration files, no complex setup, no learning curve. Just add type annotations to your functions and Freyja does the rest.
```bash
pip install freyja
# That's it! No dependencies, no configuration needed.
```
**Before Freyja:**
```bash
python script.py --config-file /path/to/config --database-host localhost --database-port 5432 --username admin --password secret --table-name users --action create --data '{"name": "Alice", "email": "alice@example.com"}'
```
**After Freyja:**
```bash
python script.py database--create-user --name Alice --email alice@example.com
# Global config handled automatically, clean syntax, built-in help
```
## ⚡ Quick Start
**Step 1:** Install Freyja
```bash
pip install freyja
```
**Step 2:** Add type annotations to your functions
```python
def greet(name: str = "World", excited: bool = False) -> None:
"""Greet someone by name."""
greeting = f"Hello, {name}!"
if excited:
greeting += " 🎉"
print(greeting)
```
**Step 3:** Add 3 lines of Freyja code
```python
from freyja import CLI
import sys
if __name__ == '__main__':
cli = CLI(sys.modules[__name__], title="My CLI")
cli.display()
```
**Step 4:** Use your new CLI!
```bash
python script.py greet --name Alice --excited
# Output: Hello, Alice! 🎉
python script.py --help
# Automatic help generation with beautiful formatting
```
## 🗂️ Module-based CLI
Perfect for functional programming styles and simple utilities. Every function becomes a command:
```python
# data_processor.py
from freyja import CLI
import sys
def process_csv(input_file: str, output_format: str = "json", verbose: bool = False) -> None:
"""Process CSV file and convert to specified format."""
print(f"Processing {input_file} -> {output_format}")
if verbose:
print("Verbose mode enabled")
def analyze_logs(log_file: str, pattern: str, max_lines: int = 1000) -> None:
"""Analyze log files for specific patterns."""
print(f"Analyzing {log_file} for pattern: {pattern} (max {max_lines} lines)")
if __name__ == '__main__':
cli = CLI(sys.modules[__name__], title="Data Processing Tools")
cli.display()
```
**Usage:**
```bash
python data_processor.py process-csv --input-file data.csv --output-format xml --verbose
python data_processor.py analyze-logs --log-file app.log --pattern "ERROR" --max-lines 500
python data_processor.py --help # Beautiful auto-generated help
```
## 🏗️ Class-based CLI
Ideal for stateful applications and complex workflows. Supports two powerful patterns:
### Direct Methods Pattern
Simple and clean - each method becomes a command:
```python
# calculator.py
from freyja import CLI
class Calculator:
"""Advanced calculator with memory and history."""
def __init__(self, precision: int = 2, memory_enabled: bool = True):
"""Initialize calculator with global settings."""
self.precision = precision
self.memory = 0 if memory_enabled else None
def add(self, a: float, b: float, store_result: bool = False) -> None:
"""Add two numbers together."""
result = round(a + b, self.precision)
print(f"{a} + {b} = {result}")
if store_result and self.memory is not None:
self.memory = result
print(f"Result stored in memory: {result}")
def multiply(self, a: float, b: float) -> None:
"""Multiply two numbers."""
result = round(a * b, self.precision)
print(f"{a} × {b} = {result}")
if __name__ == '__main__':
cli = CLI(Calculator, title="Advanced Calculator")
cli.display()
```
**Usage:**
```bash
python calculator.py --precision 4 add --a 3.14159 --b 2.71828 --store-result
# Output: 3.14159 + 2.71828 = 5.8599
# Result stored in memory: 5.8599
```
### Inner Classes Pattern
Organize complex applications with flat double-dash commands:
```python
# project_manager.py
from freyja import CLI
from pathlib import Path
class ProjectManager:
"""Complete project management suite with organized command structure."""
def __init__(self, config_file: str = "config.json", debug: bool = False):
"""Initialize with global settings."""
self.config_file = config_file
self.debug = debug
class Database:
"""Database operations and management."""
def __init__(self, connection_string: str = "sqlite:///projects.db", timeout: int = 30):
"""Initialize database connection."""
self.connection_string = connection_string
self.timeout = timeout
def migrate(self, version: str = "latest", dry_run: bool = False) -> None:
"""Run database migrations."""
action = "Would run" if dry_run else "Running"
print(f"{action} migration to version: {version}")
print(f"Connection: {self.connection_string}")
def backup(self, output_path: Path, compress: bool = True) -> None:
"""Create database backup."""
compression = "compressed" if compress else "uncompressed"
print(f"Creating {compression} backup at: {output_path}")
class Projects:
"""Project creation and management operations."""
def __init__(self, workspace: str = "./projects", auto_save: bool = True):
"""Initialize project operations."""
self.workspace = workspace
self.auto_save = auto_save
def create(self, name: str, template: str = "basic", description: str = "") -> None:
"""Create a new project from template."""
print(f"Creating project '{name}' using '{template}' template")
print(f"Workspace: {self.workspace}")
print(f"Description: {description}")
print(f"Auto-save: {'enabled' if self.auto_save else 'disabled'}")
def deploy(self, project_name: str, environment: str = "staging", force: bool = False) -> None:
"""Deploy project to specified environment."""
action = "Force deploying" if force else "Deploying"
print(f"{action} {project_name} to {environment}")
if __name__ == '__main__':
cli = CLI(ProjectManager, title="Project Management Suite")
cli.display()
```
**Usage:**
```bash
# Global + Sub-global + Command arguments (all flat)
python project_manager.py --config-file prod.json --debug \
database--migrate --connection-string postgres://prod --version 2.1.0 --dry-run
# Create new project with custom workspace
python project_manager.py projects--create --workspace /prod/projects --auto-save \
--name "web-app" --template "react" --description "Production web application"
# Deploy with force flag
python project_manager.py projects--deploy --project-name web-app --environment production --force
# Beautiful help shows all flat commands organized by group
python project_manager.py --help
```
## ✨ Key Features
🚀 **Zero Configuration** - Works out of the box with just type annotations
⚡ **Lightning Fast** - No runtime dependencies, minimal overhead
🎯 **Type Safe** - Automatic validation from your type hints
📚 **Auto Documentation** - Help text generated from your docstrings
🎨 **Beautiful Output** - Professional themes and formatting
🔧 **Flexible Architecture** - Module-based or class-based patterns
📦 **No Dependencies** - Uses only Python standard library
🌈 **Shell Completion** - Bash, Zsh, Fish, and PowerShell support
✅ **Production Ready** - Battle-tested in enterprise applications
## 📚 Documentation
**[📖 Complete Documentation Hub](docs/README.md)** - Everything you need to master Freyja
### Quick Links
* **[🚀 Getting Started](docs/getting-started/README.md)** - Installation and first steps
* **[👤 User Guide](docs/user-guide/README.md)** - Comprehensive guides for both CLI modes
* **[⚙️ Features](docs/features/README.md)** - Type annotations, themes, completion, and more
* **[📋 Examples & Best Practices](docs/guides/README.md)** - Real-world examples and patterns
* **[❓ FAQ](docs/faq.md)** - Frequently asked questions
* **[🔧 API Reference](docs/reference/README.md)** - Complete API documentation
## 🛠️ Development
**[📖 Development Guide](CLAUDE.md)** - Comprehensive guide for contributors
### Quick Setup
```bash
# Clone and setup
git clone https://github.com/terracoil/freyja.git
cd freyja
# Install Poetry and setup environment
curl -sSL https://install.python-poetry.org | python3 -
./bin/setup-dev.sh
# Run tests and examples
./bin/test.sh
poetry run python examples/mod_example.py --help
poetry run python examples/cls_example.py --help
```
### Development Commands
```bash
poetry install # Install dependencies
./bin/test.sh # Run tests with coverage
./bin/lint.sh # Run all linters and formatters
poetry build # Build package
./bin/publish.sh # Publish to PyPI (maintainers)
```
## ⚙️ Requirements
* **Python 3.13.5+** (recommended) or Python 3.8+
* **Zero runtime dependencies** - uses only Python standard library
* **Type annotations required** - for automatic CLI generation
* **Docstrings recommended** - for automatic help text generation
---
**Ready to transform your Python code into powerful CLIs?**
```bash
pip install freyja
# Start building amazing command-line tools in minutes! ⚡
```
**[📚 Get Started Now →](docs/getting-started/README.md)**
Raw data
{
"_id": null,
"home_page": "https://pypi.org/project/freyja/",
"name": "freyja",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0.0,>=3.13.7",
"maintainer_email": null,
"keywords": "cli, auto, introspection, argparse, command-line",
"author": "Steven Miers",
"author_email": "steven.miers@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/ca/62/22e5123871133d3f31aebdba2953abb60b9408e8733ab19d4b4b7e720e32/freyja-1.0.4.tar.gz",
"platform": null,
"description": "\n\n# Freyja \u26a1\n**No-dependency, zero-configuration CLI tool to build command-line interfaces purely from your code.**\n\nTransform your Python functions and classes into powerful command-line applications in seconds! Freyja uses introspection and type annotations to automatically generate professional CLIs with zero configuration required.\n\n## Table of Contents\n* [\ud83d\ude80 Why Freyja?](#-why-freyja)\n* [\u26a1 Quick Start](#-quick-start)\n* [\ud83d\uddc2\ufe0f Module-based CLI](#\ufe0f-module-based-cli)\n* [\ud83c\udfd7\ufe0f Class-based CLI](#\ufe0f-class-based-cli)\n * [Direct Methods Pattern](#direct-methods-pattern)\n * [Inner Classes Pattern](#inner-classes-pattern)\n* [\u2728 Key Features](#-key-features)\n* [\ud83d\udcda Documentation](#-documentation)\n* [\ud83d\udee0\ufe0f Development](#\ufe0f-development)\n* [\u2699\ufe0f Requirements](#\ufe0f-requirements)\n\n## \ud83d\ude80 Why Freyja?\n\n**Build CLIs in under 5 minutes!** No configuration files, no complex setup, no learning curve. Just add type annotations to your functions and Freyja does the rest.\n\n```bash\npip install freyja\n# That's it! No dependencies, no configuration needed.\n```\n\n**Before Freyja:**\n```bash\npython script.py --config-file /path/to/config --database-host localhost --database-port 5432 --username admin --password secret --table-name users --action create --data '{\"name\": \"Alice\", \"email\": \"alice@example.com\"}'\n```\n\n**After Freyja:**\n```bash\npython script.py database--create-user --name Alice --email alice@example.com\n# Global config handled automatically, clean syntax, built-in help\n```\n\n## \u26a1 Quick Start\n\n**Step 1:** Install Freyja\n```bash\npip install freyja\n```\n\n**Step 2:** Add type annotations to your functions\n```python\ndef greet(name: str = \"World\", excited: bool = False) -> None:\n \"\"\"Greet someone by name.\"\"\"\n greeting = f\"Hello, {name}!\"\n if excited:\n greeting += \" \ud83c\udf89\"\n print(greeting)\n```\n\n**Step 3:** Add 3 lines of Freyja code\n```python\nfrom freyja import CLI\nimport sys\n\nif __name__ == '__main__':\n cli = CLI(sys.modules[__name__], title=\"My CLI\")\n cli.display()\n```\n\n**Step 4:** Use your new CLI!\n```bash\npython script.py greet --name Alice --excited\n# Output: Hello, Alice! \ud83c\udf89\n\npython script.py --help\n# Automatic help generation with beautiful formatting\n```\n\n## \ud83d\uddc2\ufe0f Module-based CLI\n\nPerfect for functional programming styles and simple utilities. Every function becomes a command:\n\n```python\n# data_processor.py\nfrom freyja import CLI\nimport sys\n\n\ndef process_csv(input_file: str, output_format: str = \"json\", verbose: bool = False) -> None:\n \"\"\"Process CSV file and convert to specified format.\"\"\"\n print(f\"Processing {input_file} -> {output_format}\")\n if verbose:\n print(\"Verbose mode enabled\")\n\n\ndef analyze_logs(log_file: str, pattern: str, max_lines: int = 1000) -> None:\n \"\"\"Analyze log files for specific patterns.\"\"\"\n print(f\"Analyzing {log_file} for pattern: {pattern} (max {max_lines} lines)\")\n\n\nif __name__ == '__main__':\n cli = CLI(sys.modules[__name__], title=\"Data Processing Tools\")\n cli.display()\n```\n\n**Usage:**\n```bash\npython data_processor.py process-csv --input-file data.csv --output-format xml --verbose\npython data_processor.py analyze-logs --log-file app.log --pattern \"ERROR\" --max-lines 500\npython data_processor.py --help # Beautiful auto-generated help\n```\n\n## \ud83c\udfd7\ufe0f Class-based CLI\n\nIdeal for stateful applications and complex workflows. Supports two powerful patterns:\n\n### Direct Methods Pattern\n\nSimple and clean - each method becomes a command:\n\n```python\n# calculator.py\nfrom freyja import CLI\n\n\nclass Calculator:\n \"\"\"Advanced calculator with memory and history.\"\"\"\n\n def __init__(self, precision: int = 2, memory_enabled: bool = True):\n \"\"\"Initialize calculator with global settings.\"\"\"\n self.precision = precision\n self.memory = 0 if memory_enabled else None\n\n def add(self, a: float, b: float, store_result: bool = False) -> None:\n \"\"\"Add two numbers together.\"\"\"\n result = round(a + b, self.precision)\n print(f\"{a} + {b} = {result}\")\n \n if store_result and self.memory is not None:\n self.memory = result\n print(f\"Result stored in memory: {result}\")\n\n def multiply(self, a: float, b: float) -> None:\n \"\"\"Multiply two numbers.\"\"\"\n result = round(a * b, self.precision)\n print(f\"{a} \u00d7 {b} = {result}\")\n\n\nif __name__ == '__main__':\n cli = CLI(Calculator, title=\"Advanced Calculator\")\n cli.display()\n```\n\n**Usage:**\n```bash\npython calculator.py --precision 4 add --a 3.14159 --b 2.71828 --store-result\n# Output: 3.14159 + 2.71828 = 5.8599\n# Result stored in memory: 5.8599\n```\n\n### Inner Classes Pattern\n\nOrganize complex applications with flat double-dash commands:\n\n```python\n# project_manager.py\nfrom freyja import CLI\nfrom pathlib import Path\n\n\nclass ProjectManager:\n \"\"\"Complete project management suite with organized command structure.\"\"\"\n\n def __init__(self, config_file: str = \"config.json\", debug: bool = False):\n \"\"\"Initialize with global settings.\"\"\"\n self.config_file = config_file\n self.debug = debug\n\n class Database:\n \"\"\"Database operations and management.\"\"\"\n\n def __init__(self, connection_string: str = \"sqlite:///projects.db\", timeout: int = 30):\n \"\"\"Initialize database connection.\"\"\"\n self.connection_string = connection_string\n self.timeout = timeout\n\n def migrate(self, version: str = \"latest\", dry_run: bool = False) -> None:\n \"\"\"Run database migrations.\"\"\"\n action = \"Would run\" if dry_run else \"Running\"\n print(f\"{action} migration to version: {version}\")\n print(f\"Connection: {self.connection_string}\")\n\n def backup(self, output_path: Path, compress: bool = True) -> None:\n \"\"\"Create database backup.\"\"\"\n compression = \"compressed\" if compress else \"uncompressed\"\n print(f\"Creating {compression} backup at: {output_path}\")\n\n class Projects:\n \"\"\"Project creation and management operations.\"\"\"\n\n def __init__(self, workspace: str = \"./projects\", auto_save: bool = True):\n \"\"\"Initialize project operations.\"\"\"\n self.workspace = workspace\n self.auto_save = auto_save\n\n def create(self, name: str, template: str = \"basic\", description: str = \"\") -> None:\n \"\"\"Create a new project from template.\"\"\"\n print(f\"Creating project '{name}' using '{template}' template\")\n print(f\"Workspace: {self.workspace}\")\n print(f\"Description: {description}\")\n print(f\"Auto-save: {'enabled' if self.auto_save else 'disabled'}\")\n\n def deploy(self, project_name: str, environment: str = \"staging\", force: bool = False) -> None:\n \"\"\"Deploy project to specified environment.\"\"\"\n action = \"Force deploying\" if force else \"Deploying\"\n print(f\"{action} {project_name} to {environment}\")\n\n\nif __name__ == '__main__':\n cli = CLI(ProjectManager, title=\"Project Management Suite\")\n cli.display()\n```\n\n**Usage:**\n```bash\n# Global + Sub-global + Command arguments (all flat)\npython project_manager.py --config-file prod.json --debug \\\n database--migrate --connection-string postgres://prod --version 2.1.0 --dry-run\n\n# Create new project with custom workspace\npython project_manager.py projects--create --workspace /prod/projects --auto-save \\\n --name \"web-app\" --template \"react\" --description \"Production web application\"\n\n# Deploy with force flag\npython project_manager.py projects--deploy --project-name web-app --environment production --force\n\n# Beautiful help shows all flat commands organized by group\npython project_manager.py --help\n```\n\n## \u2728 Key Features\n\n\ud83d\ude80 **Zero Configuration** - Works out of the box with just type annotations \n\u26a1 **Lightning Fast** - No runtime dependencies, minimal overhead \n\ud83c\udfaf **Type Safe** - Automatic validation from your type hints \n\ud83d\udcda **Auto Documentation** - Help text generated from your docstrings \n\ud83c\udfa8 **Beautiful Output** - Professional themes and formatting \n\ud83d\udd27 **Flexible Architecture** - Module-based or class-based patterns \n\ud83d\udce6 **No Dependencies** - Uses only Python standard library \n\ud83c\udf08 **Shell Completion** - Bash, Zsh, Fish, and PowerShell support \n\u2705 **Production Ready** - Battle-tested in enterprise applications \n\n## \ud83d\udcda Documentation\n\n**[\ud83d\udcd6 Complete Documentation Hub](docs/README.md)** - Everything you need to master Freyja\n\n### Quick Links\n* **[\ud83d\ude80 Getting Started](docs/getting-started/README.md)** - Installation and first steps\n* **[\ud83d\udc64 User Guide](docs/user-guide/README.md)** - Comprehensive guides for both CLI modes \n* **[\u2699\ufe0f Features](docs/features/README.md)** - Type annotations, themes, completion, and more\n* **[\ud83d\udccb Examples & Best Practices](docs/guides/README.md)** - Real-world examples and patterns\n* **[\u2753 FAQ](docs/faq.md)** - Frequently asked questions\n* **[\ud83d\udd27 API Reference](docs/reference/README.md)** - Complete API documentation\n\n## \ud83d\udee0\ufe0f Development\n\n**[\ud83d\udcd6 Development Guide](CLAUDE.md)** - Comprehensive guide for contributors\n\n### Quick Setup\n\n```bash\n# Clone and setup\ngit clone https://github.com/terracoil/freyja.git\ncd freyja\n\n# Install Poetry and setup environment \ncurl -sSL https://install.python-poetry.org | python3 -\n./bin/setup-dev.sh\n\n# Run tests and examples\n./bin/test.sh\npoetry run python examples/mod_example.py --help\npoetry run python examples/cls_example.py --help\n```\n\n### Development Commands\n\n```bash\npoetry install # Install dependencies\n./bin/test.sh # Run tests with coverage\n./bin/lint.sh # Run all linters and formatters\npoetry build # Build package\n./bin/publish.sh # Publish to PyPI (maintainers)\n```\n\n## \u2699\ufe0f Requirements\n\n* **Python 3.13.5+** (recommended) or Python 3.8+\n* **Zero runtime dependencies** - uses only Python standard library\n* **Type annotations required** - for automatic CLI generation\n* **Docstrings recommended** - for automatic help text generation\n\n---\n\n**Ready to transform your Python code into powerful CLIs?**\n\n```bash\npip install freyja\n# Start building amazing command-line tools in minutes! \u26a1\n```\n\n**[\ud83d\udcda Get Started Now \u2192](docs/getting-started/README.md)**",
"bugtrack_url": null,
"license": "MIT",
"summary": "Python Library that builds a complete CLI given one or more functions using introspection",
"version": "1.0.4",
"project_urls": {
"Documentation": "https://github.com/tangledpath/freyja/docs",
"Homepage": "https://pypi.org/project/freyja/",
"Repository": "https://github.com/tangledpath/freyja"
},
"split_keywords": [
"cli",
" auto",
" introspection",
" argparse",
" command-line"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "75d3033306f94abbaf555b156220c2468aebdde37733ab4620b2d16421baac02",
"md5": "7f976c626316f91ea534f020b64c9286",
"sha256": "268770ad85f1101afa0df4debcdc18529412ed2cac6b91029eeaff2ebf97d111"
},
"downloads": -1,
"filename": "freyja-1.0.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "7f976c626316f91ea534f020b64c9286",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0.0,>=3.13.7",
"size": 124324,
"upload_time": "2025-09-03T16:33:28",
"upload_time_iso_8601": "2025-09-03T16:33:28.474110Z",
"url": "https://files.pythonhosted.org/packages/75/d3/033306f94abbaf555b156220c2468aebdde37733ab4620b2d16421baac02/freyja-1.0.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "ca6222e5123871133d3f31aebdba2953abb60b9408e8733ab19d4b4b7e720e32",
"md5": "fedff4d9cbebcccc8ba817814deb1943",
"sha256": "f710cd1d87117873a7fc6e3902138f0602439be042a0294d6781507741e8a013"
},
"downloads": -1,
"filename": "freyja-1.0.4.tar.gz",
"has_sig": false,
"md5_digest": "fedff4d9cbebcccc8ba817814deb1943",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0.0,>=3.13.7",
"size": 102698,
"upload_time": "2025-09-03T16:33:29",
"upload_time_iso_8601": "2025-09-03T16:33:29.543805Z",
"url": "https://files.pythonhosted.org/packages/ca/62/22e5123871133d3f31aebdba2953abb60b9408e8733ab19d4b4b7e720e32/freyja-1.0.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-03 16:33:29",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "tangledpath",
"github_project": "freyja",
"github_not_found": true,
"lcname": "freyja"
}