Skip to content

Commit

Permalink
docs: improve documentation
Browse files Browse the repository at this point in the history
* Improves documentation. (addresses inveniosoftware#99)

Signed-off-by: Leonardo Rossi <[email protected]>
  • Loading branch information
Leonardo Rossi committed Jul 20, 2016
1 parent 97ac2ef commit 36b98a9
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 25 deletions.
185 changes: 175 additions & 10 deletions invenio_records_rest/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,156 @@ def _(x):
max_result_window=10000,
),
)
"""Default REST endpoints loaded.
This option can be overwritten to describe the endpoints of the different
record types. Each endpoint is in charge of managing all its CRUD operations
(GET, POST, PUT, DELETE, ...).
The structure of the dictionary is as follows:
.. code-block:: python
from invenio_records_rest.query import es_search_factory
def search_factory(*args, **kwargs):
if not current_user.is_authenticated:
abort(401)
return es_search_factory(*args, **kwargs)
def permission_check_factory():
def check_title(record, *args, **kwargs):
def can(self):
if record['title'] == 'Hello World':
return True
return type('Check', (), {'can': can})()
RECORDS_REST_ENDPOINTS = {
"record-pid-type": {
"create_permission_factory_imp": permission_check_factory(),
"default_media_type": "application/json",
"delete_permission_factory_imp": permission_check_factory(),
"item_route": ""/recods/<pid(recid):pid_value>"",
"links_factory_imp": ("invenio_records_rest.links:"
"default_links_factory"),
"list_route": "/records/",
"max_result_window": 10000,
"pid_fetcher": "<registered-pid-fetcher>",
"pid_minter": "<registered-minter-name>",
"pid_type": "<record-pid-type>",
"read_permission_factory_imp": permission_check_factory(),
"record_class": "mypackage.api:MyRecord",
"record_loaders": {
"application/json": "mypackage.loaders:json_loader"
},
"record_serializers": {
"application/json": "mypackage.utils:my_json_serializer"
},
"search_class": "mypackage.utils:mysearchclass",
"search_factory_imp": search_factory(),
"search_index": "elasticsearch-index-name",
"search_serializers": {
"application/json": "mypackage.utils:my_json_search_serializer"
},
"search_type": "elasticsearch-doc-type",
"suggesters": {
"my_url_param_to_complete": {
"completion": {
"field": "suggest_byyear_elasticsearch_field",
"size": 10,
"context": "year"
}
},
},
"update_permission_factory_imp": permission_check_factory(),
"use_options_view": True,
},
}
:param create_permission_factory_imp: Import path to factory that crcreate
permission object for a given record.
:param default_media_type: Default media type for both records and search.
:param delete_permission_factory_imp: Import path to factory that creates a
delete permission object for a given record.
:param item_route: URL template for a single record.
:param links_factory_imp: Factory for record links generation.
:param list_route: Base URL for the records endpoint.
:param max_result_window: Maximum total number of records retrieved from a
query.
:param pid_type: It specifies the record pid type. It's used also to build the
endpoint name. Required.
E.g. ``url_for('record-pid-type_list')`` to point to the records list.
:param pid_fetcher: It identifies the registered fetcher name
(see class:`invenio_pidstore:_PIDStoreState`). Required.
:param pid_minter: It identifies the registered minter name
(see class:`invenio_pidstore:_PIDStoreState`). Required.
:param read_permission_factory_imp: Import path to factory that creates a
read permission object for a given record.
:param record_class: Name of the record API class.
:param record_loaders: It contains the list of record deserializers for
supperted formats.
:param record_serializers: It contains the list of record serializers for
supported formats.
:param search_class: Import path or class object for the object in charge of
execute the search queries. The default search class is
class:`invenio_search.api.RecordsSearch`.
For more information about resource loading, see
class:`elasticsearch_dsl.Search`.
:param search_factory_imp: Factory that parse query that returns a tuple with
search instance and URL arguments.
:param search_index: Name of the search index used when searching records.
:param search_serializers: It contains the list of records serializers for all
supported format. This configuration differ from the previous because in
this case it handle a list of records resulted by a search query instead of
a single record.
:param search_type: Name of the search type used when searching records.
:param suggesters: Suggester fields configuration. Any element of the
dictionary represents a suggestion field. The key is used as url query
parameter.
To have more information about suggestion configuration, you can read
suggesters section on ElasticSearch documentation.
Note: only completion suggessters are supported.
:param update_permission_factory_imp: Import path to factory that creates a
update permission object for a given record.
:param use_options_view: Determines if a special option view should be
installed.
"""

RECORDS_REST_DEFAULT_LOADERS = {
'application/json': lambda: request.get_json(),
'application/json-patch+json': lambda: request.get_json(force=True),
}
"""Default data loaders per request mime type.
This option can be overritten in each REST endpoint as follows::
This option can be overritten in each REST endpoint as follows:
.. code-block:: python
{
RECORDS_REST_ENDPOINTS = {
"recid": {
...
"record_loaders": {
Expand Down Expand Up @@ -97,13 +237,17 @@ def _(x):
)
"""Sort options for default sorter factory.
The structure of the dictionary is as follows::
The structure of the dictionary is as follows:
{
.. code-block:: python
RECORDS_REST_SORT_OPTIONS = {
"<index or index alias>": {
"fields": ["<search_field>", "<search_field>", ...],
"title": "<title displayed to end user in search-ui>",
"default_order": "<default sort order in search-ui>",
"<sort-field-name>": {
"fields": ["<search_field>", "<search_field>", ...],
"title": "<title displayed to end user in search-ui>",
"default_order": "<default sort order in search-ui>",
}
}
}
Expand All @@ -124,7 +268,19 @@ def _(x):
noquery='mostrecent',
)
)
"""Default sort option per index with/without query string."""
"""Default sort option per index with/without query string.
The structure of the dictionary is as follows:
.. code-block:: python
RECORDS_REST_DEFAULT_SORT = {
"<index or index alias>": {
"query": "<default-sort-if-a-query-is-passed-from-url>",
"noquery": "<default-sort-if-no-query-in-passed-from-url>"
}
}
"""

RECORDS_REST_FACETS = dict(
records=dict(
Expand All @@ -138,9 +294,11 @@ def _(x):
)
"""Facets per index for the default facets factory.
The structure of the dictionary is as follows::
The structure of the dictionary is as follows:
.. code-block:: python
{
RECORDS_REST_FACETS = {
"<index or index alias>": {
"aggs": {
"<key>": <aggregation definition>,
Expand All @@ -159,6 +317,13 @@ def _(x):
"""

RECORDS_REST_DEFAULT_CREATE_PERMISSION_FACTORY = deny_all
"""Default crete permission factory: reject any request."""

RECORDS_REST_DEFAULT_READ_PERMISSION_FACTORY = check_elasticsearch
"""Default read permission factory: check if the record exists."""

RECORDS_REST_DEFAULT_UPDATE_PERMISSION_FACTORY = deny_all
"""Default update permission factory: reject any request."""

RECORDS_REST_DEFAULT_DELETE_PERMISSION_FACTORY = deny_all
"""Default delete permission factory: reject any request."""
2 changes: 1 addition & 1 deletion invenio_records_rest/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
# Search
#
class MaxResultWindowRESTError(RESTException):
"""Maximum number of results passed."""
"""Maximum number of passed results have been reached."""

code = 400
description = 'Maximum number of results have been reached.'
Expand Down
23 changes: 20 additions & 3 deletions invenio_records_rest/facets.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,25 @@


def terms_filter(field):
"""Create a term filter."""
"""Create a term filter.
:param field: field name.
:returns: function that returns the Terms query.
"""
def inner(values):
return Q('terms', **{field: values})
return inner


def range_filter(field, start_date_math=None, end_date_math=None, **kwargs):
"""Create a range filter."""
"""Create a range filter.
:param field: field name
:param start_date_math: starting date
:param end_date_math: ending date
:param kwargs: addition arguments passed to the Range query.
:returns: function that returns the Range query.
"""
def inner(values):
if len(values) != 1 or values[0].count('--') != 1 or values[0] == '--':
raise RESTValidationError(
Expand Down Expand Up @@ -121,7 +132,13 @@ def _aggregations(search, definitions):


def default_facets_factory(search, index):
"""Add facets to query."""
"""Add a default facets to query.
:param search: basic search object
:param index: index name
:returns: a tuple containing the new search object and a dictionary with
all fields and values used.
"""
urlkwargs = MultiDict()

facets = current_app.config['RECORDS_REST_FACETS'].get(index)
Expand Down
6 changes: 4 additions & 2 deletions invenio_records_rest/sorter.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def geolocation_sort(field_name, argument, unit, mode=None,
:param unit: Distance unit (e.g. km).
:param mode: Sort mode (avg, min, max).
:param distance_type: Distance calculation mode.
:returns: Function that returns geolocation sort field.
"""
def inner(asc):
locations = request.values.getlist(argument, type=str)
Expand All @@ -73,7 +74,7 @@ def parse_sort_field(field_value):
"""Parse a URL field.
:param field_value: Field value (e.g. 'key' or '-key').
:returns: Tuple of (field, ascending).
:returns: Tuple of (field, ascending) as string and boolean.
"""
if field_value.startswith("-"):
return (field_value[1:], False)
Expand All @@ -98,6 +99,7 @@ def eval_field(field, asc):
:param field: Field definition (string, dict or callable).
:param asc: ``True`` if order is ascending, ``False`` if descending.
:returns: Dictionary with the sort field query.
"""
if isinstance(field, dict):
if asc:
Expand All @@ -118,7 +120,7 @@ def eval_field(field, asc):


def default_sorter_factory(search, index):
"""Sort a query.
"""Default sort query factory.
:param query: Search query.
:param index: Index to search in.
Expand Down
31 changes: 22 additions & 9 deletions invenio_records_rest/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,14 @@ def create_url_rules(endpoint, list_route=None, item_route=None,
"""Create Werkzeug URL rules.
:param endpoint: Name of endpoint.
:param list_route: record listing URL route . Required.
:param item_route: record URL route (must include ``<pid_value>`` pattern).
:param list_route: Record listing URL route. Required.
:param item_route: Record URL route (must include ``<pid_value>`` pattern).
Required.
:param pid_type: Persistent identifier type for endpoint. Required.
:param template: Template to render. Defaults to
``invenio_records_ui/detail.html``.
:param pid_minter: It identifies the registered minter name.
(see class:`invenio_pidstore:_PIDStoreState`). Required.
:param pid_fetcher: It identifies the registered fetcher name
(see class:`invenio_pidstore:_PIDStoreState`). Required.
:param read_permission_factory_imp: Import path to factory that creates a
read permission object for a given record.
:param create_permission_factory_imp: Import path to factory that creates a
Expand All @@ -142,18 +144,29 @@ def create_url_rules(endpoint, list_route=None, item_route=None,
update permission object for a given record.
:param delete_permission_factory_imp: Import path to factory that creates a
delete permission object for a given record.
:param record_class: Name of the record API class.
:param record_serializers: Serializers used for records.
:param record_loaders: It contains the list of record deserializers for
supperted formats.
:param search_class: Import path or class object for the object in charge
of execute the search queries. The default search class is
class:`invenio_search.api.RecordsSearch`.
For more information about resource loading, see
class:`elasticsearch_dsl.Search`.
:param search_serializers: Serializers used for search results.
:param search_index: Name of the search index used when searching records.
:param search_type: Name of the search type used when searching records.
:param record_class: Name of the record API class.
:param record_serializers: serializers used for records.
:param search_serializers: serializers used for search results.
:param default_media_type: default media type for both records and search.
:param max_result_window: maximum number of results that Elasticsearch can
:param default_media_type: Default media type for both records and search.
:param max_result_window: Maximum number of results that Elasticsearch can
provide for the given search index without use of scroll. This value
should correspond to Elasticsearch ``index.max_result_window`` value
for the index.
:param use_options_view: Determines if a special option view should be
installed.
:param search_factory_imp: Factory that parse query that returns a tuple
with search instance and URL arguments.
:param links_factory_imp: Factory for record links generation.
:param suggesters: Suggester fields configuration.
:returns: a list of dictionaries with can each be passed as keywords
arguments to ``Blueprint.add_url_rule``.
Expand Down

0 comments on commit 36b98a9

Please sign in to comment.