Command Syntax
firestone generate [COMMON_OPTIONS] cli [CLI_OPTIONS]
Basic Usage
Single File Output
Generate a single Python file containing the entire CLI:
firestone generate \
--title "My API" \
--description "My API description" \
--version 1.0 \
--resources resource.yaml \
cli \
--pkg myapi \
--client-pkg myapi.client \
--output cli.py
This creates cli.py - a standalone CLI script.
Module Output
Generate separate module files for each resource:
firestone generate \
--title "My API" \
--description "My API description" \
--version 1.0 \
--resources persons.yaml addressbook.yaml \
cli \
--pkg myapi \
--client-pkg myapi.client \
--as-modules \
--output-dir myapi/cli/
This creates:
myapi/cli/
├── persons.py
└── addressbook.py
Common Options
These options apply to all firestone generate commands:
--title (required)
The title of your API/CLI:
--title "Task Manager API"
Used in:
- CLI help text
- Main command docstring
- Generated code comments
--description (required)
Description of your API/CLI:
--description "Manage tasks and projects"
Appears in the main CLI help page.
--version (required)
Version number for your API:
--version 1.0
# or
--version 2.1.3
--resources (required)
One or more resource YAML files:
# Single resource
--resources tasks.yaml
# Multiple resources
--resources tasks.yaml projects.yaml users.yaml
Firestone processes each resource and generates CLI commands for all of them.
--summary (optional)
Short summary (defaults to description if not provided):
--summary "Task management"
CLI-Specific Options
--pkg (required)
The Python package name where your application code lives:
--pkg taskmanager
This determines import statements in the generated code:
from taskmanager import ...
--client-pkg (required)
The package where OpenAPI-generated client code is located:
--client-pkg taskmanager.client
Used for importing API client classes:
from taskmanager.client import api_client
from taskmanager.client import configuration
from taskmanager.client.api import tasks_api
Important: This should point to code generated by openapi-generator or a similar tool.
--output (optional)
Output file path (defaults to stdout):
# Write to file
--output mycli.py
# Write to stdout (default)
--output -
# Redirect stdout to file
firestone generate ... cli ... > mycli.py
--output-dir (required with --as-modules)
Directory for generated module files:
--as-modules \
--output-dir myapi/cli/
Creates one .py file per resource in the specified directory.
--as-modules (flag)
Generate separate module files instead of one monolithic file:
--as-modules
Without --as-modules (default):
cli.py # All resources in one file
With --as-modules:
cli/
├── tasks.py
├── projects.py
└── users.py
When to use:
- Single file: Simple APIs with 1-3 resources
- Modules: Complex APIs with many resources, better organization
--template (optional)
Path to custom Jinja2 template:
--template custom_cli.jinja2
See Customization for details on custom templates.
Complete Examples
Simple CLI
firestone generate \
--title "Todo API" \
--description "Manage your todos" \
--version 1.0 \
--resources todos.yaml \
cli \
--pkg todoapi \
--client-pkg todoapi.client \
--output todo_cli.py
Multi-Resource CLI
firestone generate \
--title "CRM API" \
--description "Customer relationship management" \
--version 2.0 \
--resources \
customers.yaml \
orders.yaml \
products.yaml \
cli \
--pkg crm \
--client-pkg crm.client \
--output crm_cli.py
Modular CLI Structure
firestone generate \
--title "E-commerce API" \
--description "Complete e-commerce platform" \
--version 1.5.0 \
--resources \
users.yaml \
products.yaml \
orders.yaml \
payments.yaml \
cli \
--pkg ecommerce \
--client-pkg ecommerce.client \
--as-modules \
--output-dir ecommerce/cli/
With Custom Template
firestone generate \
--title "Custom CLI" \
--description "CLI with custom formatting" \
--version 1.0 \
--resources resource.yaml \
cli \
--pkg myapp \
--client-pkg myapp.client \
--template templates/custom_cli.jinja2 \
--output custom_cli.py
Generated Output
Single File Structure
#!/usr/bin/env python
"""
Main entry point for a click based CLI.
"""
import click
from myapi.client import api_client
from myapi.client.api import tasks_api
@click.group()
@click.option("--api-url", envvar="API_URL")
def main(api_url):
"""My API
My API description
"""
# Setup configuration
pass
@main.group()
async def tasks(ctx_obj):
"""High level command for tasks."""
# Initialize API client
pass
@tasks.command("list")
async def tasks_get(ctx_obj):
"""List all tasks"""
# API call
pass
# ... more commands ...
if __name__ == "__main__":
main()
Module Structure
Each module (tasks.py, projects.py, etc.) exports an init() function:
# tasks.py
def init():
"""Initialize tasks resource CLI."""
@click.group()
async def tasks(ctx_obj):
"""High level command for tasks."""
pass
@tasks.command("list")
async def tasks_list(ctx_obj):
"""List all tasks"""
pass
return tasks
You then import and register these in your main CLI:
# main.py
import click
from myapi.cli import tasks
from myapi.cli import projects
@click.group()
def main():
pass
tasks_cli = tasks.init()
projects_cli = projects.init()
main.add_command(tasks_cli)
main.add_command(projects_cli)
Using the Generated CLI
Make It Executable
chmod +x cli.py
Run Directly
# Using python
python cli.py --help
# As executable
./cli.py --help
Install as Console Script
Add to your pyproject.toml:
[tool.poetry.scripts]
mycli = "myapi.cli:main"
Or setup.py:
setup(
entry_points={
'console_scripts': [
'mycli=myapi.cli:main',
],
}
)
Then install:
poetry install
# Now 'mycli' is available in your PATH
mycli --help
Workflow Integration
1. Define Resources
# tasks.yaml
kind: tasks
apiVersion: v1
# ... schema ...
2. Generate OpenAPI Spec
firestone generate \
--title "Task API" \
--description "Manage tasks" \
--version 1.0 \
--resources tasks.yaml \
openapi \
--output openapi.yaml
3. Generate Client Library
openapi-generator generate \
-i openapi.yaml \
-g python \
-o taskapi/client/
4. Generate CLI
firestone generate \
--title "Task API" \
--description "Manage tasks" \
--version 1.0 \
--resources tasks.yaml \
cli \
--pkg taskapi \
--client-pkg taskapi.client \
--output taskapi/cli.py
5. Use CLI
python taskapi/cli.py --api-url https://api.example.com tasks list
Common Patterns
Development vs Production
# Development - stdout for quick testing
firestone generate ... cli ... --output -
# Production - file output
firestone generate ... cli ... --output production_cli.py
Makefile Integration
.PHONY: gen-cli
gen-cli:
firestone generate \
--title "$(APP_TITLE)" \
--description "$(APP_DESC)" \
--version $(APP_VERSION) \
--resources $(RESOURCES) \
cli \
--pkg $(PKG_NAME) \
--client-pkg $(PKG_NAME).client \
--output $(OUTPUT_FILE)
Usage:
make gen-cli \
APP_TITLE="My API" \
APP_DESC="Description" \
APP_VERSION=1.0 \
RESOURCES="tasks.yaml" \
PKG_NAME="myapi" \
OUTPUT_FILE="cli.py"
Next Steps
- Command Options - Detailed option reference
- Generated Structure - Understanding the generated code
- CRUD Operations - Using the generated CLI
- Integration - Connecting with OpenAPI clients