- Restrict mkdocstrings generation to real Python packages (require __init__.py) - Add explicit documentation section for CLI scaffolding and templates - Generalize CLI to support multiple templates with dynamic discovery - Package templates correctly for importlib.resources access - Add fully documented health_app template (app entry point and handlers) - Fix setuptools package-data configuration for bundled templates These changes make documentation import-safe, clarify package boundaries, and provide a deterministic, OpenAPI-first scaffolding workflow via CLI.
89 lines
2.2 KiB
Python
89 lines
2.2 KiB
Python
"""
|
|
openapi_first.cli
|
|
========================
|
|
|
|
Command-line interface for FastAPI OpenAPI-first scaffolding utilities.
|
|
|
|
This CLI bootstraps OpenAPI-first FastAPI applications from versioned,
|
|
bundled templates packaged with the library.
|
|
"""
|
|
|
|
import argparse
|
|
import shutil
|
|
from pathlib import Path
|
|
from importlib import resources
|
|
|
|
|
|
DEFAULT_TEMPLATE = "health_app"
|
|
|
|
|
|
def available_templates() -> list[str]:
|
|
"""
|
|
Return a list of available application templates.
|
|
"""
|
|
root = resources.files("openapi_first.templates")
|
|
return sorted(
|
|
item.name
|
|
for item in root.iterdir()
|
|
if item.is_dir() and not item.name.startswith("_")
|
|
)
|
|
|
|
|
|
def copy_template(template: str, target_dir: Path) -> None:
|
|
"""
|
|
Copy a bundled OpenAPI-first application template into a directory.
|
|
"""
|
|
target_dir = target_dir.resolve()
|
|
target_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
root = resources.files("openapi_first.templates")
|
|
src = root / template
|
|
|
|
if not src.exists():
|
|
raise FileNotFoundError(
|
|
f"Template '{template}' not found. "
|
|
f"Available templates: {', '.join(available_templates())}"
|
|
)
|
|
|
|
with resources.as_file(src) as path:
|
|
shutil.copytree(path, target_dir, dirs_exist_ok=True)
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(
|
|
description="FastAPI OpenAPI-first scaffolding tools"
|
|
)
|
|
parser.add_argument(
|
|
"template",
|
|
nargs="?",
|
|
default=DEFAULT_TEMPLATE,
|
|
help=f"Template name (default: {DEFAULT_TEMPLATE})",
|
|
)
|
|
parser.add_argument(
|
|
"path",
|
|
nargs="?",
|
|
default=None,
|
|
help="Target directory (defaults to template name)",
|
|
)
|
|
parser.add_argument(
|
|
"--list",
|
|
action="store_true",
|
|
help="List available templates and exit",
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
if args.list:
|
|
for name in available_templates():
|
|
print(name)
|
|
return
|
|
|
|
target = Path(args.path or args.template.replace("_", "-"))
|
|
|
|
try:
|
|
copy_template(args.template, target)
|
|
except Exception as exc:
|
|
raise SystemExit(str(exc)) from exc
|
|
|
|
print(f"Template '{args.template}' created at {target}")
|