Python Library that builds a complete CLI given one or more functions using introspection
Project description
Freyja ⚡
No-dependency, zero-configuration CLI tool to build command-line interfaces purely from your code.
Transform your Python classes into powerful command-line applications in seconds! Freyja uses introspection and type annotations to automatically generate professional CLIs with zero configuration required.
⚠️ Important: All constructor parameters MUST have default values for CLI generation to work. Parameters without defaults will cause CLI creation to fail.
Table of Contents
- 🚀 Why Freyja?
- ⚡ Quick Start
- 🏗️ Class-based CLI
- ✨ Key Features
- 📚 Documentation
- 🛠️ Development
- ⚙️ Requirements
🚀 Why Freyja?
Build CLIs in under 5 minutes! No configuration files, no complex setup, no learning curve. Just add type annotations to your class methods and Freyja does the rest.
pip install freyja
# That's it! No dependencies, no configuration needed.
Before Freyja:
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:
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
pip install freyja
Step 2: Create a class with typed methods
from freyja import FreyjaCLI
class Greeter:
"""Simple greeting application."""
def __init__(self, default_name: str = "World"):
"""Initialize greeter with default name."""
self.default_name = default_name
def greet(self, name: str = None, excited: bool = False) -> None:
"""Greet someone by name."""
actual_name = name or self.default_name
greeting = f"Hello, {actual_name}!"
if excited:
greeting += " 🎉"
print(greeting)
Step 3: Add 3 lines of Freyja code
if __name__ == '__main__':
cli = FreyjaCLI(Greeter, title="My CLI")
cli.run()
Step 4: Use your new CLI!
python script.py greet --name Alice --excited
# Output: Hello, Alice! 🎉
python script.py --help
# Automatic help generation with beautiful formatting
🏗️ Class-based CLI
Freyja transforms your Python classes into powerful CLI applications. Supports two flexible patterns:
Direct Methods Pattern
Simple and clean - each method becomes a command:
# calculator.py
from freyja import FreyjaCLI
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 = FreyjaCLI(Calculator, title="Advanced Calculator")
cli.run()
Usage:
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 (e.g., inner-class--method):
# project_manager.py
from freyja import FreyjaCLI
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 = FreyjaCLI(ProjectManager, title="Project Management Suite")
cli.run()
Usage:
# Global + Sub-global + Command arguments (flat double-dash notation)
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 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 - Direct methods or inner class 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 - Everything you need to master Freyja
Quick Links
- 🚀 Getting Started - Installation and first steps
- 👤 User Guide - Comprehensive guides for class-based CLI patterns
- ⚙️ Features - Type annotations, themes, completion, and more
- 📋 Examples & Best Practices - Real-world examples and patterns
- ❓ FAQ - Frequently asked questions
- 🔧 API Reference - Complete API documentation
🛠️ Development
📖 Development Guide - Comprehensive guide for contributors
Quick Setup
# 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/dev-tools setup env
# Run tests and examples
./bin/dev-tools test run
poetry run python examples/cls_example --help
Development Commands
poetry install # Install dependencies
./bin/dev-tools test run # Run tests with coverage
./bin/dev-tools build lint # Run all linters and formatters
./bin/dev-tools build compile # Build package
./bin/dev-tools build publish # Publish to PyPI (maintainers)
./bin/dev-tools build tag-version # Create version tags
⚙️ 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?
pip install freyja
# Start building amazing command-line tools in minutes! ⚡
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file freyja-1.0.22.tar.gz.
File metadata
- Download URL: freyja-1.0.22.tar.gz
- Upload date:
- Size: 133.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.4 CPython/3.12.4 Darwin/24.6.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2d8fa303b7f3e1f816a77186af70398265ec360a2977689ab253abc7bf9c65cf
|
|
| MD5 |
64272b74a4c6008f1213cf9d3fbb0e40
|
|
| BLAKE2b-256 |
5a49e996c5bcb08291f05ac56460e4e6ab9e48e1316799f41e8c033e264582bd
|
File details
Details for the file freyja-1.0.22-py3-none-any.whl.
File metadata
- Download URL: freyja-1.0.22-py3-none-any.whl
- Upload date:
- Size: 164.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.4 CPython/3.12.4 Darwin/24.6.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
278ae62b3d88fe392da2d83ecd0203990772fcf7384fe91051e7e890ea48f456
|
|
| MD5 |
a77bc4a9d77e9c624486d5cf07f1d412
|
|
| BLAKE2b-256 |
a51fa145fdbfc637c2dc8fef046f11f99510149fd0ce286dd60473d899cf7807
|