From f81ca786427db40b648b5bcc0e67044163215457 Mon Sep 17 00:00:00 2001 From: Thorsten <51322849+tfranzel-cashlink@users.noreply.github.com> Date: Wed, 12 Feb 2020 20:35:54 +0100 Subject: [PATCH] Add file option to generateschema (#7130) --- docs/api-guide/schemas.md | 2 +- .../management/commands/generateschema.py | 8 +++++++- tests/schemas/test_managementcommand.py | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/docs/api-guide/schemas.md b/docs/api-guide/schemas.md index e33a2a611..e63fd83e6 100644 --- a/docs/api-guide/schemas.md +++ b/docs/api-guide/schemas.md @@ -30,7 +30,7 @@ into the commonly used YAML-based OpenAPI format. If your schema is static, you can use the `generateschema` management command: ```bash -./manage.py generateschema > openapi-schema.yml +./manage.py generateschema --file openapi-schema.yml ``` Once you've generated a schema in this way you can annotate it with any diff --git a/rest_framework/management/commands/generateschema.py b/rest_framework/management/commands/generateschema.py index a7763492c..024306b65 100644 --- a/rest_framework/management/commands/generateschema.py +++ b/rest_framework/management/commands/generateschema.py @@ -25,6 +25,7 @@ class Command(BaseCommand): parser.add_argument('--format', dest="format", choices=['openapi', 'openapi-json'], default='openapi', type=str) parser.add_argument('--urlconf', dest="urlconf", default=None, type=str) parser.add_argument('--generator_class', dest="generator_class", default=None, type=str) + parser.add_argument('--file', dest="file", default=None, type=str) def handle(self, *args, **options): if options['generator_class']: @@ -40,7 +41,12 @@ class Command(BaseCommand): schema = generator.get_schema(request=None, public=True) renderer = self.get_renderer(options['format']) output = renderer.render(schema, renderer_context={}) - self.stdout.write(output.decode()) + + if options['file']: + with open(options['file'], 'wb') as f: + f.write(output) + else: + self.stdout.write(output.decode()) def get_renderer(self, format): if self.get_mode() == COREAPI_MODE: diff --git a/tests/schemas/test_managementcommand.py b/tests/schemas/test_managementcommand.py index 6cdf7f8b1..115f871e5 100644 --- a/tests/schemas/test_managementcommand.py +++ b/tests/schemas/test_managementcommand.py @@ -1,4 +1,6 @@ import io +import os +import tempfile import pytest from django.conf.urls import url @@ -73,6 +75,21 @@ class GenerateSchemaTests(TestCase): out_json = yaml.safe_load(self.out.getvalue()) assert out_json == CustomSchemaGenerator.SCHEMA + def test_writes_schema_to_file_on_parameter(self): + fd, path = tempfile.mkstemp() + try: + call_command('generateschema', '--file={}'.format(path), stdout=self.out) + # nothing on stdout + assert not self.out.getvalue() + + call_command('generateschema', stdout=self.out) + expected_out = self.out.getvalue() + # file output identical to stdout output + with os.fdopen(fd) as fh: + assert expected_out and fh.read() == expected_out + finally: + os.remove(path) + @pytest.mark.skipif(yaml is None, reason='PyYAML is required.') @override_settings(REST_FRAMEWORK={'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.AutoSchema'}) def test_coreapi_renders_default_schema_with_custom_title_url_and_description(self):