Basic Usage

To use Spectastic in a project:

import spectastic

First, it’s important to know that spectastic assumes that it’s working with a valid Open API / Swagger schema to reduce it’s dependency footprint. If you need to validate your schema, consider bravado-core.

Warning

You’ll want to make sure you’ve specified operation id's for all paths. These aren’t mandatory in an Open API specification, but are mandatory for spectastic.

Validating Incoming Requests

Spectastic offers two strategies for validation:

Most of spectastic’s utility is contained within Operation instances. Lets make one using our test schema:

from spectastic.schema import Schema
from spectastic import Operation

schema = Spec(SPEC)
op = Operation.from_schema(schema, 'GetItem')

Once instantiated, you can validate an incoming BasicRequest:

op.validate_request(request)

Note

BasicRequest is probably not what you’re using in your app. If you’re using flask, check out convert_request() to make the conversion.

If there are validation errors, we’ll raise a ValidationErrors exception, which contains an errors property consisting of a list of FieldError:

from spectastic.request import BasicRequest

request = BasicRequest(
    {"hello": "world"},
    {"Authorization": "basic beefbabaabbabeef"},
    {"query": "created:yesterday"},
    "/things/are/great",
)

try:
  op.validate_request(request)
except ValidationErrors as e:
  print e.errors[0].field

Note

Though it works out of the box, strictly speaking the request doesn’t need to be a werkzeug Request. See BasicRequest for an example.

Spectastic is MultiDict and Headers aware. These data structures facilitate query parameters / headers that occur multiple times in a request e.g. a query such as “http://example.com?search=foo&search=bar”.

Flask Integration

Spectastic’s flask_utils module has some additional tools to automatically validate incoming requests for a given route against your schema:

from spectastic.contrib.flask_utils import validate_route

...

@validate_route(schema, 'GetItems')
@app.route('/items/')
def get_items(*args, **kwargs):
  return 'Success'

The validate_route() function has a few bonuses. The first argument may be a Schema instance or a callable that returns a Schema. An optional responder callable receives any ValidationErrors that may have occured and returns an appropriate flask-compatible response. You can use this to customize your error output.

The default_responder() simply outputs the general structure shown below along with a 400 status code:

{
  "errors": [
    {
      "msg": "Required path parameter is missing",
      "location": "path",
      "field": "query",
    },
    {
      ...
    }
  ]
}