1import sys
2
3import click
4
5from plain.cli import register_cli
6from plain.runtime import settings
7from plain.utils.module_loading import import_string
8
9from .openapi.generator import OpenAPISchemaGenerator
10from .openapi.validation import OpenAPIValidationError, validate_openapi_schema
11
12
13@register_cli("api")
14@click.group()
15def cli() -> None:
16 """API commands"""
17
18
19@cli.command()
20@click.option(
21 "--validate",
22 is_flag=True,
23 help="Validate the OpenAPI schema (requires openapi-spec-validator).",
24)
25@click.option("--indent", default=2, help="Indentation level for JSON and YAML output.")
26@click.option(
27 "--format",
28 default="json",
29 help="Output format (json or yaml).",
30 type=click.Choice(["json", "yaml"]),
31)
32def generate_openapi(validate: bool, indent: int, format: str) -> None:
33 if not settings.API_OPENAPI_ROUTER:
34 click.secho("No OpenAPI URL router configured.", fg="red", err=True)
35 sys.exit(1)
36
37 url_router_class = import_string(settings.API_OPENAPI_ROUTER)
38
39 schema = OpenAPISchemaGenerator(url_router_class)
40
41 if format == "json":
42 print(schema.as_json(indent=indent))
43 elif format == "yaml":
44 print(schema.as_yaml(indent=indent))
45
46 if validate:
47 click.secho("\nOpenAPI schema validation: ", err=True, nl=False)
48 try:
49 validate_openapi_schema(schema.schema)
50 except OpenAPIValidationError as exc:
51 click.secho("Failed", fg="red", err=True)
52 click.secho(str(exc), fg="yellow", err=True)
53 sys.exit(1)
54 click.secho("Success", fg="green", err=True)