Codebase list python-faraday / master doc / recipes.rst
master

Tree @master (Download .tar.gz)

recipes.rst @masterview markup · raw · history · blame

Extending your views

This will cover common recipes used to make more advanced views.

Customizing the list endpoint

Enabling pagination and sorting

By default all views inherit from SortableMixin so they allow the user to set the order field with the sort GET parameter, and the direction with the sort_dir parameter (it's value should be either "asc" or "desc").

To define the default field that will be used if this parameter is not set, you should set the order_field attribute of your class. For example, the Hosts view uses the IP field to sort the returned data by default:

class HostsView(PaginatedMixin,
                FilterAlchemyMixin,
                ReadWriteWorkspacedView):
    route_base = 'hosts'
    model_class = Host
    order_field = Host.ip.asc()
    # ...

Note that you have to indicate both the field and the direction, like in the example.

If you want to enable pagination you should explicitly inherit from PaginatedMixin. Then, when the users specify both page and page_number GET parameters the view will paginate the results.

By default it won't show the pagination metadata (like the total number of pages or elements), so you will have to follow the steps below to do it.

Changing returned JSON format

Since the new views were designed to fit the Web UI, the format of the list endpoints of different models should be distinct in some cases.

To do this, you can override the _envelope_list method of your view. It takes a list of serialized objects and a None-able pagination_metadata object with details of the pagination. If you don't use pagination, you won't have to worry about this last one. In the case you are inheriting from PaginatedMixin, it will be an instance of flask_sqlalchemy.Pagination.

For example, lets see the code of the vulns API:

class VulnerabilityView(PaginatedMixin,
                        FilterAlchemyMixin,
                        ReadWriteWorkspacedView):
    # ...
    def _envelope_list(self, objects, pagination_metadata=None):
        vulns = []
        for vuln in objects:
            vulns.append({
                'id': vuln['_id'],
                'key': vuln['_id'],
                'value': vuln
            })
        return {
            'vulnerabilities': vulns,
            'count': (pagination_metadata.total
                    if pagination_metadata is not None else len(vulns))
    }

Warning

Ensure that you correctly handle the case of pagination_metadata being None. This happens when the user doesn't specify the page number or size, so all the objects will be shown.

Adding filters

If you want to enable the API clients to filter by a specific field, you should inherit from the FilterAlchemyMixin (this isn't done by default like with SortableMixin). Then you define a filterset_class attribute in your class indicating the filteralchemy filterset to use:

from filteralchemy import FilterSet, operators

class HostFilterSet(FilterSet):
    class Meta(FilterSetMeta):
        model = Host
        fields = ('os',)
        operators = (operators.Equal, operators.Like, operators.ILike)

class HostsView(PaginatedMixin,
                FilterAlchemyMixin,
                ReadWriteWorkspacedView):
    route_base = 'hosts'
    model_class = Host
    filterset_class = HostFilterSet

Then the user will be able to use GET parameters like os (exact match) and os__like (SQL like) to filter the query.

Trigerring some actions when creating/updating

Using different schemas depending on the method

Docutils System Messages

System Message: INFO/1 (<string>, line 11)

Hyperlink target "pagination-and-sorting-recipe" is not referenced.

System Message: INFO/1 (<string>, line 42)

Hyperlink target "envelope-list-example" is not referenced.