authentik.api.management.commands.build_schema
1from json import dumps 2 3from django.core.management.base import BaseCommand, no_translations 4from drf_spectacular.drainage import GENERATOR_STATS 5from drf_spectacular.generators import SchemaGenerator 6from drf_spectacular.renderers import OpenApiYamlRenderer 7from drf_spectacular.validation import validate_schema 8from structlog.stdlib import get_logger 9 10from authentik.blueprints.v1.schema import SchemaBuilder 11 12 13class Command(BaseCommand): 14 15 def __init__(self, *args, **kwargs): 16 super().__init__(*args, **kwargs) 17 self.logger = get_logger() 18 19 def add_arguments(self, parser): 20 parser.add_argument("--blueprint-file", type=str, default="blueprints/schema.json") 21 parser.add_argument("--api-file", type=str, default="schema.yml") 22 23 @no_translations 24 def handle(self, *args, blueprint_file: str, api_file: str, **options): 25 self.build_blueprint(blueprint_file) 26 self.build_api(api_file) 27 28 def build_blueprint(self, file: str): 29 self.logger.debug("Building blueprint schema...", file=file) 30 blueprint_builder = SchemaBuilder() 31 blueprint_builder.build() 32 with open(file, "w") as _schema: 33 _schema.write( 34 dumps(blueprint_builder.schema, indent=4, default=SchemaBuilder.json_default) 35 ) 36 37 def build_api(self, file: str): 38 self.logger.debug("Building API schema...", file=file) 39 generator = SchemaGenerator() 40 schema = generator.get_schema(request=None, public=True) 41 GENERATOR_STATS.emit_summary() 42 validate_schema(schema) 43 output = OpenApiYamlRenderer().render(schema, renderer_context={}) 44 with open(file, "wb") as f: 45 f.write(output)
14class Command(BaseCommand): 15 16 def __init__(self, *args, **kwargs): 17 super().__init__(*args, **kwargs) 18 self.logger = get_logger() 19 20 def add_arguments(self, parser): 21 parser.add_argument("--blueprint-file", type=str, default="blueprints/schema.json") 22 parser.add_argument("--api-file", type=str, default="schema.yml") 23 24 @no_translations 25 def handle(self, *args, blueprint_file: str, api_file: str, **options): 26 self.build_blueprint(blueprint_file) 27 self.build_api(api_file) 28 29 def build_blueprint(self, file: str): 30 self.logger.debug("Building blueprint schema...", file=file) 31 blueprint_builder = SchemaBuilder() 32 blueprint_builder.build() 33 with open(file, "w") as _schema: 34 _schema.write( 35 dumps(blueprint_builder.schema, indent=4, default=SchemaBuilder.json_default) 36 ) 37 38 def build_api(self, file: str): 39 self.logger.debug("Building API schema...", file=file) 40 generator = SchemaGenerator() 41 schema = generator.get_schema(request=None, public=True) 42 GENERATOR_STATS.emit_summary() 43 validate_schema(schema) 44 output = OpenApiYamlRenderer().render(schema, renderer_context={}) 45 with open(file, "wb") as f: 46 f.write(output)
The base class from which all management commands ultimately derive.
Use this class if you want access to all of the mechanisms which parse the command-line arguments and work out what code to call in response; if you don't need to change any of that behavior, consider using one of the subclasses defined in this file.
If you are interested in overriding/customizing various aspects of the command-parsing and -execution behavior, the normal flow works as follows:
django-adminormanage.pyloads the command class and calls itsrun_from_argv()method.The
run_from_argv()method callscreate_parser()to get anArgumentParserfor the arguments, parses them, performs any environment changes requested by options likepythonpath, and then calls theexecute()method, passing the parsed arguments.The
execute()method attempts to carry out the command by calling thehandle()method with the parsed arguments; any output produced byhandle()will be printed to standard output and, if the command is intended to produce a block of SQL statements, will be wrapped inBEGINandCOMMIT.If
handle()orexecute()raised any exception (e.g.CommandError),run_from_argv()will instead print an error message tostderr.
Thus, the handle() method is typically the starting point for
subclasses; many built-in commands and command types either place
all of their logic in handle(), or perform some additional
parsing work in handle() and then delegate from it to more
specialized methods as needed.
Several attributes affect behavior at various steps along the way:
help
A short description of the command, which will be printed in
help messages.
output_transaction
A boolean indicating whether the command outputs SQL
statements; if True, the output will automatically be
wrapped with BEGIN; and COMMIT;. Default value is
False.
requires_migrations_checks
A boolean; if True, the command prints a warning if the set of
migrations on disk don't match the migrations in the database.
requires_system_checks
A list or tuple of tags, e.g. [Tags.staticfiles, Tags.models]. System
checks registered in the chosen tags will be checked for errors prior
to executing the command. The value '__all__' can be used to specify
that all system checks should be performed. Default value is '__all__'.
To validate an individual application's models
rather than all applications' models, call
``self.check(app_configs)`` from ``handle()``, where ``app_configs``
is the list of application's configuration provided by the
app registry.
stealth_options
A tuple of any options the command uses which aren't defined by the
argument parser.
20 def add_arguments(self, parser): 21 parser.add_argument("--blueprint-file", type=str, default="blueprints/schema.json") 22 parser.add_argument("--api-file", type=str, default="schema.yml")
Entry point for subclassed commands to add custom arguments.
106 def wrapper(*args, **kwargs): 107 from django.utils import translation 108 109 saved_locale = translation.get_language() 110 translation.deactivate_all() 111 try: 112 res = handle_func(*args, **kwargs) 113 finally: 114 if saved_locale is not None: 115 translation.activate(saved_locale) 116 return res
The type of the None singleton.
29 def build_blueprint(self, file: str): 30 self.logger.debug("Building blueprint schema...", file=file) 31 blueprint_builder = SchemaBuilder() 32 blueprint_builder.build() 33 with open(file, "w") as _schema: 34 _schema.write( 35 dumps(blueprint_builder.schema, indent=4, default=SchemaBuilder.json_default) 36 )
38 def build_api(self, file: str): 39 self.logger.debug("Building API schema...", file=file) 40 generator = SchemaGenerator() 41 schema = generator.get_schema(request=None, public=True) 42 GENERATOR_STATS.emit_summary() 43 validate_schema(schema) 44 output = OpenApiYamlRenderer().render(schema, renderer_context={}) 45 with open(file, "wb") as f: 46 f.write(output)