Types

Doctor types validate request parameters passed to logic functions. Every request parameter that gets passed to your logic function should define a type from one of those below. See quick type creation for functions that allow you to create types easily on the fly.

String

A String type represents a str and allows you to define several attributes for validation.

Attributes

  • description - A human readable description of what the type represents. This will be used when generating documentation.

  • example - An example value to send to the endpoint when generating API documentation. This is optional and a default example value will be generated for you.

  • format - An identifier indicating a complex datatype with a string representation. For example date, to represent an ISO 8601 formatted date string. The following formats are supported:

    • date - Will parse the string as a datetime.datetime instance. Expects the format ‘%Y-%m-%d’
    • date-time - Will parse the string as a datetime.datetime instance. Expects a valid ISO8601 string. e.g. ‘2018-02-21T16:09:02Z’
    • email - Does basic validation that the string is an email by checking for an ‘@’ character in the string.
    • time - Will parse the string as a datetime.datetime instance. Expects the format ‘%H:%M:%S’
    • uri - Will validate the string is a valid URI.
  • max_length - The maximum length of the string.

  • min_length - The minimum length of the string.

  • pattern - A regex pattern the string should match anywhere whitin it. Uses re.search.

  • trim_whitespace - If True the string will be trimmed of whitespace.

Example

from doctor.types import String

class FirstName(String):
    description = "A user's first name."
    min_length = 1
    max_length = 255
    trim_whitespace = True

Number

A Number type represents a float and allows you to define several attributes for validation.

Attributes

  • description - A human readable description of what the type represents. This will be used when generating documentation.
  • example - An example value to send to the endpoint when generating API documentation. This is optional and a default example value will be generated for you.
  • exclusive_maximum- If True and maximum is set, the maximum value should be treated as exclusive (value can not be equal to maximum).
  • exclusive_minimum- If True and minimum is set, the minimum value should be treated as exclusive (value can not be equal to minimum).
  • maximum - The maximum value allowed.
  • minimum - The minimum value allowed.
  • multiple_of - The value is required to be a multiple of this value.

Example

from doctor.types import Number

class AverageRating(Number):
    description = 'The average rating.'
    exclusive_maximum = False
    exclusive_minimum = True
    minimum = 0.00
    maximum = 10.0

Integer

An Integer type represents an int and allows you to define several attributes for validation.

Attributes

  • description - A human readable description of what the type represents. This will be used when generating documentation.
  • example - An example value to send to the endpoint when generating API documentation. This is optional and a default example value will be generated for you.
  • exclusive_maximum- If True and the maximum is set, the maximum value should be treated as exclusive (value can not be equal to maximum).
  • exclusive_minimum- If True and the minimum is set, the minimum value should be treated as exclusive (value can not be equal to minimum).
  • maximum - The maximum value allowed.
  • minimum - The minimum value allowed.
  • multiple_of - The value is required to be a multiple of this value.

Example

from doctor.types import Integer

class Age(Integer):
    description = 'The age of the user.'
    exclusive_maximum = False
    exclusive_minimum = True
    minimum = 1
    maximum = 120

Boolean

A Boolean type represents a bool. This type will convert several common strings used as booleans to a boolean type when instaniated. The following str values (case-insensitve) will be converted to a boolean:

  • ‘true’/’false’
  • ‘on’/’off’
  • ‘1’/‘0’

It also accepts typical truthy inputs e.g. True, False, 1, 0.

Attributes

  • description - A human readable description of what the type represents. This will be used when generating documentation.
  • example - An example value to send to the endpoint when generating API documentation. This is optional and a default example value will be generated for you.

Example

from doctor.types import Boolean

class Accept(Boolean):
    description = 'Indicates if the user accepted the agreement or not.'

Enum

An Enum type represents a str that should be one of any defined values and allows you to define several attributes for validation.

Attributes

  • description - A human readable description of what the type represents. This will be used when generating documentation.
  • enum - A list of str containing valid values.
  • example - An example value to send to the endpoint when generating API documentation. This is optional and a default example value will be generated for you.

Example

from doctor.types import Enum

class Color(Enum):
    description = 'A color.'
    enum = ['blue', 'green', 'purple', 'yellow']

Object

An Object type represents a dict and allows you to define properties and required properties.

Attributes

  • additional_properties - If True, additional properties (that is, ones not defined in properties) will be allowed.
  • description - A human readable description of what the type represents. This will be used when generating documentation.
  • example - An example value to send to the endpoint when generating API documentation. This is optional and a default example value will be generated for you.
  • properties - A dict containing a mapping of property name to expected type.
  • required - A list of required properties.

Example

from doctor.types import Object, boolean, string

class Contact(Object):
    description = 'An address book contact.'
    additional_properties = True
    properties = {
        'name': string('The contact name', min_length=1, max_length=200),
        'is_primary', boolean('Indicates if this is a primary contact.'),
    }
    required = ['name']

Array

An Array type represents a list and allows you to define properties and required properties.

Attributes

  • additional_items - If items is a list and this is True then additional items whose types aren’t defined are allowed in the list.
  • description - A human readable description of what the type represents. This will be used when generating documentation.
  • example - An example value to send to the endpoint when generating API documentation. This is optional and a default example value will be generated for you.
  • items - The type each item should be, or a list of types where the position of the type in the list represents the type at that position in the array the item should be.
  • min_items - The minimum number of items allowed in the list.
  • max_items - The maximum number of items allowed in the list.
  • unique_items - If True, items in the array should be unique from one another.

Example

from doctor.types import Array, string

class Countries(Array):
    description = 'An array of countries.'
    items = string('A country')
    min_items = 0
    max_items = 5
    unique_items = True

JsonSchema

A JsonSchema type is primarily meant to ease the transition from doctor 2.x.x to 3.0.0. It allows you to specify an already defined schema file to represent a type. You can use a definition within the schema as your type or the root type of the schema.

This type will use the json schema to set the description, example and native type attributes of the class. This type should not be used directly, instead you should use json_schema_type() to create your class.

Attributes

  • definition_key - The key of the definition within your schema that should be used for the type.
  • description - A human readable description of what the type represents. This will be used when generating documentation. This value will automatically get loaded from your schema definition.
  • example - An example value to send to the endpoint when generating API documentation. This value will automatically get loaded from your schema definition.
  • schema_file - The full path to the schema file. This attribute is required to be defined on your class.

Example

annotation.yaml

---
$schema: 'http://json-schema.org/draft-04/schema#'
description: An annotation.
definitions:
  annotation_id:
    description: Auto-increment ID.
    example: 1
    type: integer
  name:
    description: The name of the annotation.
    example: Example Annotation.
    type: string
type: object
properties:
  annotation_id:
    $ref: '#/definitions/annotation_id'
  name:
    $ref: '#/definitions/name'
additionalProperties: false

Using `definition_key`

from doctor.types import json_schema_type

AnnotationId = json_schema_type(
    '/full/path/to/annoation.yaml', definition_key='annotation_id')

Without `definition_key`

from doctor.types import json_schema_type

Annotation = json_schema_type('/full/path/to/annotation.yaml')

Quick Type Creation

Each type also has a function that can be used to quickly create a new type without having to define large classes. Each of these functions takes the description of the type as the first positional argument and any attributes the type accepts can be passed as keyword arguments. The following functions are provided:

Examples

from doctor.errors import TypeSystemError
from doctor.types import (
    array, boolean, enum, integer, json_schema_type, new_type, number,
    string, String)

# Create a new array type of countries
Countries = array('List of countries', items=string('Country'), min_items=1)

# Create a new boolean type
Agreed = boolean('Indicates if user agreed or not')

# Create a new enum type
Color = enum('A color', enum=['blue', 'green', 'red'])

# Create a new integer type
AnnotationId = integer('Annotation PK', minimum=1)

# Create a new jsonschema type
Annotation = json_schema_type(schema_file='/path/to/annotation.yaml')

# Create a new type based on a String
class FooString(String):
    must_start_with_foo = True

    def __new__(cls, *args, **kwargs):
        value = super().__new__(cls, *args, **kwargs)
        if cls.must_start_with_foo:
            if not value.lower().startswith('foo'):
                raise TypeSystemError('Must start with foo', cls=cls)

MyFooString = new_type(FooString, 'My foo string')

# Create a new number type
ProductRating = number('Product rating', maximum=10, minimum=1)

# Create a new string type
FirstName = string('First name', min_length=2, max_length=255)

Module Documentation

Copyright © 2017, Encode OSS Ltd. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This file is a modified version of the typingsystem.py module in apistar. https://github.com/encode/apistar/blob/973c6485d8297c1bcef35a42221ac5107dce25d5/apistar/typesystem.py

class doctor.types.Array(*args, **kwargs)[source]

Bases: doctor.types.SuperType, list

Represents a list type.

additional_items = False

If items is a list and this is True then additional items whose types aren’t defined are allowed in the list.

classmethod get_example()[source]

Returns an example value for the Array type.

If an example isn’t a defined attribute on the class we return a list of 1 item containing the example value of the items attribute. If items is None we simply return a [1].

Return type:list
items = None

The type each item should be, or a list of types where the position of the type in the list represents the type at that position in the array the item should be.

max_items = None

The maxiimum number of items allowed in the list.

min_items = 0

The minimum number of items allowed in the list.

native_type

alias of builtins.list

unique_items = False

If True items in the array should be unique from one another.

class doctor.types.Boolean(*args, **kwargs)[source]

Bases: doctor.types.SuperType

Represents a bool type.

classmethod get_example()[source]

Returns an example value for the Boolean type.

Return type:bool
native_type

alias of builtins.bool

class doctor.types.Enum(*args, **kwargs)[source]

Bases: doctor.types.SuperType, str

Represents a str type that must be one of any defined allowed values.

enum = []

A list of valid values.

classmethod get_example()[source]

Returns an example value for the Enum type.

Return type:str
native_type

alias of builtins.str

class doctor.types.Integer(*args, **kwargs)[source]

Bases: doctor.types._NumericType, int

Represents an int type.

classmethod get_example()[source]

Returns an example value for the Integer type.

Return type:int
native_type

alias of builtins.int

doctor.types.JSON_TYPES_TO_NATIVE = {'array': <class 'list'>, 'boolean': <class 'bool'>, 'integer': <class 'int'>, 'number': <class 'float'>, 'object': <class 'dict'>, 'string': <class 'str'>}

A mapping of json types to native python types.

class doctor.types.JsonSchema(*args, **kwargs)[source]

Bases: doctor.types.SuperType

Represents a type loaded from a json schema.

NOTE: This class should not be used directly. Instead use json_schema_type() to create a new class based on this one.

definition_key = None

The key from the definitions in the schema file that the type should come from.

classmethod get_example()[source]

Returns an example value for the JsonSchema type.

Return type:Any
schema = None

The loaded ResourceSchema

schema_file = None

The full path to the schema file.

exception doctor.types.MissingDescriptionError[source]

Bases: ValueError

An exception raised when a type is missing a description.

class doctor.types.Number(*args, **kwargs)[source]

Bases: doctor.types._NumericType, float

Represents a float type.

classmethod get_example()[source]

Returns an example value for the Number type.

Return type:float
native_type

alias of builtins.float

class doctor.types.Object(*args, **kwargs)[source]

Bases: doctor.types.SuperType, dict

Represents a dict type.

additional_properties = True

If True additional properties will be allowed, otherwise they will not.

classmethod get_example()[source]

Returns an example value for the Dict type.

If an example isn’t a defined attribute on the class we return a dict of example values based on each property’s annotation.

Return type:dict
native_type

alias of builtins.dict

properties = {}

A mapping of property name to expected type.

required = []

A list of required properties.

class doctor.types.String(*args, **kwargs)[source]

Bases: doctor.types.SuperType, str

Represents a str type.

format = None

Will check format of the string for date, date-time, email, time and uri.

classmethod get_example()[source]

Returns an example value for the String type.

Return type:str
max_length = None

The maximum length of the string.

min_length = None

The minimum length of the string.

native_type

alias of builtins.str

pattern = None

A regex pattern that the string should match.

trim_whitespace = True

Whether to trim whitespace on a string. Defaults to True.

class doctor.types.SuperType(*args, **kwargs)[source]

Bases: object

A super type all custom types must extend from.

This super type requires all subclasses define a description attribute that describes what the type represents. A ValueError will be raised if the subclass does not define a description attribute.

description = None

The description of what the type represents.

example = None

An example value for the type.

class doctor.types._NumericType(*args, **kwargs)[source]

Bases: doctor.types.SuperType

Base class for both Number and Integer.

exclusive_maximum = False

The maximum value should be treated as exclusive or not.

exclusive_minimum = False

The minimum value should be treated as exclusive or not.

maximum = None

The maximum value allowed.

minimum = None

The minimum value allowed.

multiple_of = None

The value is required to be a multiple of this value.

doctor.types.array(description, **kwargs)[source]

Create a Array type.

Parameters:
  • description – A description of the type.
  • kwargs – Can include any attribute defined in Array
Return type:

Type[+CT]

doctor.types.boolean(description, **kwargs)[source]

Create a Boolean type.

Parameters:
  • description – A description of the type.
  • kwargs – Can include any attribute defined in Boolean
Return type:

Type[+CT]

doctor.types.enum(description, **kwargs)[source]

Create a Enum type.

Parameters:
  • description – A description of the type.
  • kwargs – Can include any attribute defined in Enum
Return type:

Type[+CT]

doctor.types.get_value_from_schema(schema, definition, key, definition_key, resolve=False)[source]

Gets a value from a schema and definition.

Parameters:
  • schema (ResourceSchema) – The resource schema.
  • definition (dict) – The definition dict from the schema.
  • key (str) – The key to use to get the value from the schema.
  • definition_key (str) – The name of the definition.
  • resolve (bool) – If True we will attempt to resolve the definition from the schema.
Returns:

The value.

Raises:

TypeSystemError – If the key can’t be found in the schema/definition or we can’t resolve the definition.

doctor.types.integer(description, **kwargs)[source]

Create a Integer type.

Parameters:
  • description – A description of the type.
  • kwargs – Can include any attribute defined in Integer
Return type:

Type[+CT]

doctor.types.json_schema_type(schema_file, **kwargs)[source]

Create a JsonSchema type.

This function will automatically load the schema and set it as an attribute of the class along with the description and example.

Parameters:
  • schema_file (str) – The full path to the json schema file to load.
  • kwargs – Can include any attribute defined in JsonSchema
Return type:

Type[+CT]

doctor.types.new_type(cls, description, **kwargs)[source]

Create a user defined type.

Parameters:
  • description – A description of the type.
  • kwargs – Can include any attribute defined in the provided user defined type.
Return type:

Type[+CT]

doctor.types.number(description, **kwargs)[source]

Create a Number type.

Parameters:
  • description – A description of the type.
  • kwargs – Can include any attribute defined in Number
Return type:

Type[+CT]

doctor.types.string(description, **kwargs)[source]

Create a String type.

Parameters:
  • description (str) – A description of the type.
  • kwargs – Can include any attribute defined in String
Return type:

Type[+CT]