tcrudge.handlers module

Module contains basic handlers:

  • BaseHandler - to be used for custom handlers. For instance - RPC, if you wish.
  • ApiHandler - Abstract for API handlers above.
  • ApiListHandler - Create (POST), List view (GET).
  • ApiItemHandler - detailed view (GET), Update (PUT), Delete (DELETE).
class tcrudge.handlers.ApiHandler(application, request, **kwargs)

Bases: tcrudge.handlers.BaseHandler

Base helper class for API functions. model_cls MUST be defined.

exclude_fields = ()
get_base_queryset()
get_schema_output

Maybe you’d ask: “What’s a get-schema?”

The answer is that we wanted to check input of every request method in a homologous way. So we decided to describe any input and output using JSON schema.

Schema must be a dict.

max_depth = None
model_cls

Model class must be defined. Otherwise it’ll crash a little later even if nothing seems to be accessing a model class. If you think you don’t need a model class, consider the architecture. Maybe it doesn’t fit REST. In that case use BaseHandler.

https://github.com/CodeTeam/tcrudge/issues/6

recurse = False
serialize(model)

Method to serialize a model.

By default all fields are serialized by model_to_dict. The model can be any model instance to pass through this method. It MUST be a Model instance, it won’t work for basic types containing such instances.

User have to handle it by their own hands.

Parameters:model (Model instance.) – Model instance to serialize.
Returns:serialized model.
Return type:dict
class tcrudge.handlers.ApiItemHandler(*args, **kwargs)

Bases: tcrudge.handlers.ApiHandler

Base Item API Handler. Supports R, U, D from CRUDL.

delete(item_id)

Handles DELETE request.

_delete method must be defined to handle delete logic. If method is not defined, HTTP 405 is raised.

If deletion is finished, writes to response HTTP code 200 and a message ‘Item deleted’.

Raises:HTTPError 405 if model object is not deletable.
delete_schema_input

JSON Schema to validate DELETE request body.

Returns:JSON schema for DELETE.
Return type:dict
delete_schema_output

Returns DELETE Schema, empty be default.

Return type:dict
get(item_id)

Handles GET request.

  1. Validates request.
  2. Writes serialized object of ORM model instance to response.
get_item(item_id)

Fetches item from database by PK. Result is cached in self._instance for multiple calls

Raises:HTTP 404 if no item found.
Returns:raw object if exists.
Return type:ORM model instance.
get_queryset(item_id)
get_schema_input

JSON Schema to validate DELETE request body.

Returns:GET JSON schema
Return type:dict
put(item_id)

Handles PUT request. Validates data and updates given item.

Returns serialized model.

Raises 405 in case of not updatable model (there must be _update method implemented in model class).

Raises 400 in case of violated constraints, invalid parameters and other data and integrity errors.

Raises:HTTP 405, HTTP 400.
put_schema_input

JSON Schema to validate PUT request body.

Returns:JSON schema of PUT
Return type:dict
put_schema_output

Returns PUT Schema, empty be default.

Return type:dict
class tcrudge.handlers.ApiListHandler(*args, **kwargs)

Bases: tcrudge.handlers.ApiHandler

Base List API Handler. Supports C, L from CRUDL. Handles pagination,

  • default limit is defined
  • maximum limit is defined

One can redefine that in their code.

Other pagination parameters are:

  • limit - a positive number of items to show on a single page, int.
  • offset - a positive int to define the position in result set to start with.
  • total - A boolean to define total amount of items to be put in result set or not. 1 or 0.

Those parameters can be sent as either GET parameters or HTTP headers. HTTP headers are more significant during parameters processing, but GET parameters are preferable to use as conservative way of pagination. HTTP headers are:

  • X-Limit
  • X-Offset
  • X-Total

“exclude” filter args are for pagination, you must not redefine them ever. Otherwise you’d have to also redefine the prepare method.

Some fieldnames can be added to that list. Those are fields one wishes not to be included to filters.

default_filter

Default queryset WHERE clause. Used for list queries first. One must redefine it to customize filters.

Returns:dict
default_limit = 50
default_order_by

Default queryset ORDER BY clause. Used for list queries. Order by must contain a string with a model field name.

exclude_filter_args = ['limit', 'offset', 'total']
get()

Handles GET request.

  1. Validates GET parameters using GET input schema and validator.
  2. Executes query using given query parameters.
  3. Paginates.
  4. Serializes result.
  5. Writes to response, not finishing it.
Raises:In case of bad query parameters - HTTP 400.
get_queryset(paginate=True)

Get queryset for model. Override this method to change logic.

By default it uses qs_filter and qs_order_by. All arguments for WHERE clause are passed with AND condition.

get_schema_input

JSON Schema to validate GET Url parameters. By default it contains pagination parameters as required fields. If you wish to use query filters via GET parameters, you need to redefine get_schema_input so that request with filter parameters would be valid.

In schema you must define every possible way to filter a field, you wish to be filtered, in every manner it should be filtered. For example, if you wish to filter by a field “name” so that the query returns you every object with name like given string:

{
    "type": "object",
    "additionalProperties": False,
    "properties": {
      "name__like": {"type": "string"},
      "total": {"type": "string"},
      "limit": {"type": "string"},
      "offset": {"type": "string"},
      "order_by": {"type": "string"},
    },
}

If you wish to filter by a field “created_dt” by given range:

{
    "type": "object",
    "additionalProperties": False,
    "properties": {
      "created_dt__gte": {"type": "string"},
      "created_dt__lte": {"type": "string"},
      "total": {"type": "string"},
      "limit": {"type": "string"},
      "offset": {"type": "string"},
      "order_by": {"type": "string"},
    },
}

To cut it short, you need to add parameters like “field__operator” for every field you wish to be filtered and for every operator you wish to be used.

Every schema must be a dict.

Returns:returns schema.
Return type:dict
head()

Handles HEAD request.

  1. Validates GET parameters using GET input schema and validator.
  2. Fetches total amount of items and returns it in X-Total header.
  3. Finishes response.
Raises:In case of bad query parameters - HTTPError 400.
max_limit = 100
post()

Handles POST request. Validates data and creates new item. Returns serialized object written to response.

HTTPError 405 is raised in case of not creatable model (there must be _create method implemented in model class).

HTTPError 400 is raised in case of violated constraints, invalid parameters and other data and integrity errors.

Raises:HTTPError 405, 400
post_schema_input

JSON schema of our model is generated here. Basically it is used for Create method - list handler, method POST.

Hint: Modified version of this schema can be used for Update (PUT, detail view).

Returns:JSON schema of given model_cls Model.
Return type:dict
post_schema_output

JSON Schema to validate POST request body. Abstract.

Every schema must be a dict.

Returns:dict
prepare()

Method to get and validate offset and limit params for GET REST request. Total is boolean 1 or 0.

Works for GET method only.

classmethod qs_filter(qs, flt, value, process_value=True)

Private method to set WHERE part of query. If required, Django-style filter is available via qs.filter() and peewee.DQ - this method provides joins.

Filter relational operators are: * NOT - ‘-‘, not operator, should be user as prefix * < - ‘lt’, less than * > - ‘gt’, greater than * <= - ‘lte’, less than or equal * >= - ‘gte’, greater than or equal * != - ‘ne’, not equal * LIKE - ‘like’, classic like operator * ILIKE - ‘ilike’, case-insensitive like operator * IN - ‘in’, classic in. Values should be separated by comma * ISNULL - ‘isnull’, operator to know if smth is equal to null. Use -<fieldname>__isnull for IS NOT NULL

classmethod qs_order_by(qs, value, process_value=True)

Set ORDER BY part of response.

Fields are passed in a string with commas to separate values. ‘-‘ prefix means descending order, otherwise it is ascending order.

Returns:orderbyed queryset
Return type:queryset
class tcrudge.handlers.BaseHandler(application, request, **kwargs)

Bases: tornado.web.RequestHandler

Base helper class. Provides basic handy responses.

To be used for customized handlers that don’t fit REST API recommendations.

Defines response types in relation to Accept header. Response interface is described in corresponding module.

By default, inherited handlers have callback functions for JSON and MessagePack responses.

bad_permissions()

Returns answer of access denied.

Raises:HTTPError 401
static default_callback(handler, response)

Default JSON response.

Sets JSON content type to given handler.

Serializes result with JSON serializer and sends JSON as response body.

Returns:Bytes of JSONised response
Return type:bytes
get_query_argument(name, default=<object object>, strip=True)
get_response(result=None, errors=None, **kwargs)

Method returns conventional formatted byte answer.

It gets Accept header, returns answer processed by callback.

Parameters:
  • result – contains result if succeeded
  • errors – contains errors if any
  • kwargs – other answer attributes
Returns:

byte answer of appropriate content type

Return type:

bytes

get_roles()

Gets roles. Abstract. Auth logic is up to user.

is_auth()

Validate user authorized. Abstract. Auth logic is up to user.

response(result=None, errors=None, **kwargs)

Method writes the response and finishes the request.

Parameters:
  • result – contains result if succeeded
  • errors – contains errors if any
  • kwargs – other answer attributes
response_callbacks = {'application/x-msgpack': <function response_msgpack>, 'application/json': <function response_json>}
validate(data, schema, format_checker=None, **kwargs)

Method to validate parameters. Raises HTTPError(400) with error info for invalid data.

Parameters:
Returns:

None if data is not valid. Else dict(data)

write_error(status_code, **kwargs)

Method gets traceback, writes it into response, finishes response.

Parameters:
  • status_code (int) – tornado parameter to format html, we don’t use it.
  • kwargs (dict) – in debug mode must contain exc_info.