Plain is headed towards 1.0! Subscribe for development updates →

 1import json
 2import sys
 3
 4import click
 5import requests
 6
 7from plain.cli import register_cli
 8from plain.runtime import settings
 9from plain.utils.module_loading import import_string
10
11from .openapi.generator import OpenAPISchemaGenerator
12
13
14@register_cli("api")
15@click.group()
16def cli() -> None:
17    """API commands"""
18
19
20@cli.command()
21@click.option("--validate", is_flag=True, help="Validate the OpenAPI schema.")
22@click.option("--indent", default=2, help="Indentation level for JSON and YAML output.")
23@click.option(
24    "--format",
25    default="json",
26    help="Output format (json or yaml).",
27    type=click.Choice(["json", "yaml"]),
28)
29def generate_openapi(validate: bool, indent: int, format: str) -> None:
30    if not settings.API_OPENAPI_ROUTER:
31        click.secho("No OpenAPI URL router configured.", fg="red", err=True)
32        sys.exit(1)
33
34    url_router_class = import_string(settings.API_OPENAPI_ROUTER)
35
36    schema = OpenAPISchemaGenerator(url_router_class)
37
38    if format == "json":
39        print(schema.as_json(indent=indent))
40    elif format == "yaml":
41        print(schema.as_yaml(indent=indent))
42
43    if validate:
44        click.secho("\nOpenAPI schema validation: ", err=True, nl=False)
45        response = requests.post(
46            "https://validator.swagger.io/validator/debug",
47            headers={"Content-Type": "application/json"},
48            json=schema.schema,
49        )
50        response.raise_for_status()
51        failed = response.json().get(
52            "schemaValidationMessages", []
53        ) or response.json().get("messages", [])
54        if failed:
55            click.secho("Failed", fg="red", err=True)
56            click.secho(
57                json.dumps(response.json(), indent=2, sort_keys=True),
58                fg="yellow",
59                err=True,
60            )
61            sys.exit(1)
62        else:
63            click.secho("Success", fg="green", err=True)