code gen
This commit is contained in:
@@ -66,38 +66,135 @@ def copy_template(template: str, target_dir: Path) -> None:
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="FastAPI OpenAPI-first scaffolding tools"
|
||||
description="FastAPI OpenAPI-first developer tools"
|
||||
)
|
||||
parser.add_argument(
|
||||
subparsers = parser.add_subparsers(dest="command", help="Command to execute")
|
||||
|
||||
# Scaffold command
|
||||
scaffold_parser = subparsers.add_parser(
|
||||
"scaffold", help="Scaffold a new OpenAPI-first FastAPI application"
|
||||
)
|
||||
scaffold_parser.add_argument(
|
||||
"template",
|
||||
nargs="?",
|
||||
default=DEFAULT_TEMPLATE,
|
||||
help=f"Template name (default: {DEFAULT_TEMPLATE})",
|
||||
)
|
||||
parser.add_argument(
|
||||
scaffold_parser.add_argument(
|
||||
"path",
|
||||
nargs="?",
|
||||
default=None,
|
||||
help="Target directory (defaults to template name)",
|
||||
)
|
||||
parser.add_argument(
|
||||
scaffold_parser.add_argument(
|
||||
"--list",
|
||||
action="store_true",
|
||||
help="List available templates and exit",
|
||||
)
|
||||
|
||||
# Models command
|
||||
models_parser = subparsers.add_parser(
|
||||
"models", help="Generate Pydantic models from an OpenAPI specification"
|
||||
)
|
||||
models_parser.add_argument(
|
||||
"spec",
|
||||
help="Path to the OpenAPI specification file",
|
||||
)
|
||||
models_parser.add_argument(
|
||||
"-o",
|
||||
"--output",
|
||||
required=True,
|
||||
help="Path to the output Python file",
|
||||
)
|
||||
|
||||
# Routes command
|
||||
routes_parser = subparsers.add_parser(
|
||||
"routes",
|
||||
help="Generate route handler stubs from an OpenAPI specification",
|
||||
)
|
||||
routes_parser.add_argument(
|
||||
"spec",
|
||||
help="Path to the OpenAPI specification file",
|
||||
)
|
||||
routes_parser.add_argument(
|
||||
"-o",
|
||||
"--output-dir",
|
||||
required=True,
|
||||
help="Directory where route files will be created",
|
||||
)
|
||||
routes_parser.add_argument(
|
||||
"--use-models",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Import Pydantic models for request bodies",
|
||||
)
|
||||
routes_parser.add_argument(
|
||||
"--models-module",
|
||||
default="models",
|
||||
help="Python module path for models (default: models)",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.list:
|
||||
for name in available_templates():
|
||||
print(name)
|
||||
if args.command == "models":
|
||||
from .codegen import generate_models
|
||||
|
||||
try:
|
||||
generate_models(Path(args.spec), Path(args.output))
|
||||
print(f"Models generated successfully at {args.output}")
|
||||
except Exception as exc:
|
||||
raise SystemExit(str(exc)) from exc
|
||||
return
|
||||
|
||||
target = Path(args.path or args.template.replace("_", "-"))
|
||||
if args.command == "routes":
|
||||
from .codegen import generate_routes
|
||||
|
||||
try:
|
||||
copy_template(args.template, target)
|
||||
except Exception as exc:
|
||||
raise SystemExit(str(exc)) from exc
|
||||
try:
|
||||
files = generate_routes(
|
||||
spec_path=Path(args.spec),
|
||||
output_dir=Path(args.output_dir),
|
||||
use_models=args.use_models,
|
||||
models_module=args.models_module,
|
||||
)
|
||||
print(f"Generated {len(files)} route file(s):")
|
||||
for f in files:
|
||||
print(f" {f}")
|
||||
except Exception as exc:
|
||||
raise SystemExit(str(exc)) from exc
|
||||
return
|
||||
|
||||
print(f"Template '{args.template}' created at {target}")
|
||||
# Default to scaffold if no command or scaffold command
|
||||
if args.command == "scaffold" or args.command is None:
|
||||
# Handle the case where someone uses the old CLI style (openapi-first template path)
|
||||
# argparse with subparsers might not automatically handle this if positional args are passed
|
||||
# but let's assume we want to encourage the new style.
|
||||
|
||||
# If no command was provided but positional args were, they might be for scaffolding
|
||||
# This is a bit tricky with argparse subparsers.
|
||||
# For simplicity, let's just support the new explicit commands.
|
||||
|
||||
if args.command is None and not any(vars(args).values()):
|
||||
parser.print_help()
|
||||
return
|
||||
|
||||
if getattr(args, "list", False):
|
||||
for name in available_templates():
|
||||
print(name)
|
||||
return
|
||||
|
||||
template = getattr(args, "template", DEFAULT_TEMPLATE)
|
||||
path_arg = getattr(args, "path", None)
|
||||
target = Path(path_arg or template.replace("_", "-"))
|
||||
|
||||
try:
|
||||
copy_template(template, target)
|
||||
print(f"Template '{template}' created at {target}")
|
||||
except Exception as exc:
|
||||
raise SystemExit(str(exc)) from exc
|
||||
return
|
||||
|
||||
parser.print_help()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user