Skip to content

praekelt/swagger-django-generator

Repository files navigation

Build Status

swagger-(django)-generator

Convert Swagger specifications into Django or aiohttp server code

Table of Contents generated with DocToc

Introduction

This utility parses a Swagger specification and generates Django- or aiohttp-specific definitions, which allows for easy integration into Django projects or creating aiohttp daemons. In particular, the following files are currently generated:

  • urls.py, for routing requests,
  • views.py, for handling requests, performing validation, etc.,
  • schemas.py, containing the JSONSchema definitions of parameters and request body arguments,
  • utils.py, containing utility functions that can be tweaked, if necessary, and
  • stubs.py, containing the abstract base class for the API functions, as well as a class containing mocked implementations of the functions.

Getting started

A virtual environment can be set up by running

make virtualenv
./ve/bin/python setup.py develop  # Installs package so that templates can be found

This utility is self-documenting. To get an idea of what is supported, simply run the utility with the --help flag:

└─▪ ./ve/bin/python swagger_django_generator/generator.py --help
Usage: generator.py [OPTIONS] SPECIFICATION

Options:
  --spec-format [json|yaml]
  --backend [django|aiohttp]
  --verbose / --no-verbose
  --output-dir DIRECTORY
  --module-name TEXT         The name of the module where the generated code
                             will be used, e.g. myproject.some_application
  --urls-file TEXT           Use an alternative filename for the urls.
  --views-file TEXT          Use an alternative filename for the views.
  --schemas-file TEXT        Use an alternative filename for the schemas.
  --utils-file TEXT          Use an alternative filename for the utilities.
  --stubs-file TEXT          Use an alternative filename for the utilities.
  --help                     Show this message and exit.

By default the generated views.py will call a generated mock implementation, which is defined in stubs.py along with the abstract base class. You have create your own class derived from AbstractStubClass. Typically you can define this class in a file called implementation.py and then edit your settings.py to contain the following definition:

STUBS_CLASS = "myproject.implementation.Implementation"

The code generated for aiohttp uses a STUBS_CLASS environment variable.

Examples

A demo application

For a quick demonstration of how to get started, run make demo. This will create a demo Django application that uses files generated by this application. The command does the following in the back:

# Create a new Django project
./ve/bin/django-admin startproject demo
# Generate files for the petstore API (including stubs) straight into the project
./ve/bin/python swagger_django_generator/generator.py tests/resources/petstore.json --output-dir demo/demo/ --module-name demo

You can then start the server:

./ve/bin/python demo/manage.py runserver

Generated files

The following links references files that were generated using this utility based on the popular PetStore Swagger definition.

  • the schemas file contains global schema definitions
  • the stubs file is where the abstract base class for your code will live, along with a mocked implementation
  • the urls file is where the routing takes place
  • the utils file contains utility functions
  • the views handles security and validation
  • the stubs contains the abstract base class with the API functions, as well as a class containing mocked implentations.

Notes

  • All generated API calls are CSRF exempt (Django backend)
  • API calls that have any form of security defined on them will require a logged in user or basic HTTP auth (Django backend)
  • At this stage there are limited tests.

Todo

  • We can look at using the swagger-tester library.
  • Investigate using warlock or python-jsonschema-objects to generate models for ease of use.
  • Look at using some of the Python libs here

Why?

Using the Swagger/OpenAPI specification enables the use of a tremendous amount of tooling:

  • the generation of documentation
  • creating a UI to play around with the API
  • importing into Runscope for automated test creation
  • client code generation for various languages
  • server code generation for various application servers

When we have to write applications that provide APIs, it will typically have to form part of a Django application. Unfortunately the "official" code generation tool only supports code generation for Tornado and Flask when it comes to the Python language.

This tool is intended to plug the gap for Django. We can focus on getting the spec right, quickly generate server code and integrate with testing frameworks like Runscope. The generated code takes care of the routing, input and output validation and common error handling.

At a minimum it allows us to get some working code up and running in very little time.