Source code for surf.rest

# Copyright (c) 2009, Digital Enterprise Research Institute (DERI),
# NUI Galway
# All rights reserved.

# author: Cosmin Basca
# email: cosmin.basca@gmail.com

# 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 DERI 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 DERI ''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 DERI 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.

# -*- coding: utf-8 -*-
import inspect
from surf.rdf import Namespace
from surf.resource import Resource

__author__ = 'Cosmin Basca'


# TODO lazy loading ... not implemented when setting the resource from the json_dict ...
[docs]class Rest(object): """ The :class:`Rest` class handles the generation of REST like methods to perform CRUD operations on a :class:`surf.resource.Resource` instance note: The REST api exposed is designed in accordance with the REST controller used in `pylons` applications, it adheres to the REST specification and offers extra features :param resources_namespace: the `uri` used by instances :type resources_namespace: :class:`rdflib.namespace.Namespace` or str :param concept_class: the class for which the REST interface is exposed :type concept_class: :class:`surf.resource.Resource` """ def __init__(self, resources_namespace, concept_class): assert issubclass(concept_class, Resource) and inspect.isclass(concept_class) self._Resource = concept_class # Make sure resources_namespace is an instance of Namespace if not isinstance(resources_namespace, Namespace): resources_namespace = Namespace(resources_namespace) self._namespace = resources_namespace
[docs] def index(self): """ **REST** : GET /: All items in the collection, :return: all instances for the current :class:`surf.resources.Resource` :rtype: list or :class:`surf.resources.ResultProxy` """ return self._Resource.all()
[docs] def create(self, json_params): """ **REST** : POST /: Create a new item, creates a new :class:`surf.resource.Resource` instance :param dict json_params: extra *JSON* parameters to set as instance attributes """ instance = self._Resource() for attr_name in json_params: setattr(instance, attr_name, json_params[attr_name]) instance.save()
[docs] def new(self, json_params): """ **REST** : GET /new: Form to create a new item. alias for :meth:`surf.rest.Rest.create` method :param dict json_params: extra *JSON* parameters to set as instance attributes """ self.create(json_params)
[docs] def update(self, id, json_params): """ **REST** : PUT /id: Update an existing item., update an instances attributes with the supplied parameters :param str id: the resources id :param dict json_params: extra *JSON* parameters to set as instance attributes """ instance = self._Resource(self._namespace[id]) for attr_name in json_params: setattr(instance, attr_name, json_params[attr_name]) instance.update()
[docs] def edit(self, id, json_params): """ **REST** : GET /id;edit: alias for :meth:`surf.rest.Rest.update` method :param str id: the resources id :param dict json_params: extra *JSON* parameters to set as instance attributes """ self.update(id, json_params)
[docs] def delete(self, id): """ **REST** : DELETE /id: Delete an existing item. removes an instance from the underlying :class:`surf.store.Store` store :param str id: the resources id """ instance = self._Resource(self._namespace[id]) instance.remove()
[docs] def show(self, id): """ **REST** : GET /id: Show a specific item. show / retrieve the specified resource :param str id: the resources id :return: the resource :rtype: :class:`surf.resources.Resource` """ instance = self._Resource(self._namespace[id]) instance.load() return instance
@classmethod
[docs] def resource(cls, session, resources_namespace, concept_class, id): """ convenience method to get a resource given the arguments :param session: the *SuRF* session :type session: :class:`surf.session.Session` :param resources_namespace: the `uri` used by instances :type resources_namespace: :class:`rdflib.namespace.Namespace` or str :param concept_class: the class for which the REST interface is exposed :type concept_class: :class:`surf.resource.Resource` :param str id: the resources id :return: the resource :rtype: :class:`surf.resources.Resource` """ # Make sure resources_namespace is an instance of Namespace if not isinstance(resources_namespace, Namespace): resources_namespace = Namespace(resources_namespace) _Resource = session.get_class(concept_class) return _Resource(resources_namespace[id])