Exemple #1
0
    def __init__(self, service):
        Resource.__init__(self)
        self.service = service
        self.resources = {
            '/capoeira/events/similar/artist':
            self.service.capoeiraSimilarByArtistQuery,
            '/capoeira/events/similar/track':
            self.service.capoeiraSimilarByTrackQuery
        }
        self.isLeaf = True

        # default_params is used in lieu of a defined Accept field in the header
        default_params = AcceptParameters(ContentType("text/html"),
                                          Language("en"))
        acceptable = [
            AcceptParameters(ContentType("text/html"), Language("en")),
            AcceptParameters(ContentType("text/json"), Language("en")),
            AcceptParameters(ContentType("application/json"), Language("en"))
        ]
        self.contentNegotiator = ContentNegotiator(default_params, acceptable)
        # function mapping for rendering response
        self.renderFns = {
            'text/html': formatHTMLResponse,
            'text/json': formatJSONResponse,
            'application/json': formatJSONResponse
        }
Exemple #2
0
 def do_conneg(self,node):
     """Specify the default parameters. These are the parameters which will be used in place of any HTTP Accept headers which are not present in the negotiation request. For example, if the Accept-Language header is not passed to the negotiator it will assume that the client request is for "en"
     """
     # Configure conneg and work out default from node config
     acceptable=[]
     default_content_type=None
     for content_type in node.conneg:
         (code,dst,default) = node.conneg[content_type]
         self.log_message("conneg: config %s (%d,%s,%s)" % (content_type,code,dst,default))
         acceptable.append(AcceptParameters(ContentType(content_type)))
         if (default):
             default_content_type=content_type
     # If there was no default, pick the last one we saw
     if (not default_content_type):
         default_content_type=content_type
     # Do we have an Accept header in the request? If not then default
     if ('Accept' not in self.headers):
         return(default_content_type)
     # else conneg...
     default_params = AcceptParameters(ContentType(default_content_type))
     cn = ContentNegotiator(default_params, acceptable)
     accept = self.headers["Accept"]
     self.log_message("conneg: request Accept: %s" % (accept))
     selected = cn.negotiate(accept)
     #self.log_message("conneg: match %s" % (str(selected)))
     if (selected is not None and
         str(selected.content_type) in node.conneg):
         self.log_message("conneg: selected %s" % (selected.content_type))
         (code,dst,default) = node.conneg[str(selected.content_type)]
     else:
         self.log_message("conneg: defaulting to %s" % (default_content_type))
         (code,dst,default) = node.conneg[default_content_type]
     self.code = code
     self.response_headers.append(['Location',self.full_uri(dst)])
     self.log_message("conneg: %d redirect to %s" % (code,dst))
 def build(self, resource, accept):
     adapters = HypermediaResource.adapters.all()
     acceptable = [AcceptParameters(ContentType(adapter.media_type)) for adapter in adapters]
     cn = ContentNegotiator(AcceptParameters(ContentType(self.default_type)), acceptable)
     negotiate = cn.negotiate(accept=accept)
     if negotiate:
         return HypermediaResponse(str(negotiate.content_type), resource)
     return HypermediaResponse(self.default_type, resource)
 def test_en_only(self):
     """
     en only
     """
     accept_language = "en"
     server = [AcceptParameters(language=Language("en"))]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(accept_language=accept_language)
     assert str(accept_parameters.language) == "en"
 def test_unsupported_by_server(self):
     """
     en only, unsupported by server
     """
     accept_language = "en"
     server = [AcceptParameters(language=Language("de"))]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(accept_language=accept_language)
     assert accept_parameters is None
 def test_unsupported_by_server(self):
     """
     text/plain only, unsupported by server
     """
     client_accept = "text/plain"
     server = [AcceptParameters(ContentType("text/html"))]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(accept=client_accept)
     assert accept_parameters is None
 def test_text_plain_only(self):
     """
     text/plain only
     """
     client_accept = "text/plain"
     server = [AcceptParameters(ContentType("text/plain"))]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(accept=client_accept)
     assert str(accept_parameters.content_type) == "text/plain"
 def test_partially_supported_by_server(self):
     """
     en, partially supported by server
     """
     accept_language = "en"
     server = [AcceptParameters(language=Language("en-gb"))]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(accept_language=accept_language)
     assert str(accept_parameters.language) == "en-gb"
    def _GET_container(self, path=None):
        """
        GET a representation of the container in the appropriate (content negotiated) format as identified by
        the supplied id
        Args:
        - id:   The ID of the container as supplied in the request URL
        Returns a representation of the container: SSS will return either the Atom Entry identical to the one supplied
        as a deposit receipt or the pure RDF/XML Statement depending on the Accept header
        """
        ssslog.debug(
            "GET on Container (retrieve deposit receipt or statement); Incoming HTTP headers: "
            + str(request.environ))

        # authenticate
        try:
            auth = self.authenticate()

            ss = SwordServer(config, auth)

            # first thing we need to do is check that there is an object to return, because otherwise we may throw a
            # 415 Unsupported Media Type without looking first to see if there is even any media to content negotiate for
            # which would be weird from a client perspective
            if not ss.container_exists(path):
                return self.manage_error(SwordError(status=404, empty=True))

            # get the content negotiation headers
            accept_header = request.environ.get("HTTP_ACCEPT")
            accept_packaging_header = request.environ.get(
                "HTTP_ACCEPT_PACKAGING")

            # do the negotiation
            default_accept_parameters, acceptable = config.get_container_formats(
            )
            cn = ContentNegotiator(default_accept_parameters, acceptable)
            accept_parameters = cn.negotiate(accept=accept_header)
            ssslog.info("Container requested in format: " +
                        str(accept_parameters))

            # did we successfully negotiate a content type?
            if accept_parameters is None:
                raise SwordError(error_uri=Error.content,
                                 status=415,
                                 empty=True)

            # now actually get hold of the representation of the container and send it to the client
            cont = ss.get_container(path, accept_parameters)
            ssslog.info("Returning " + response.status + " from request on " +
                        inspect.stack()[0][3])
            if cont is not None:
                response.headers["Content-Type"] = str(
                    accept_parameters.content_type.mimetype())
            return cont

        except SwordError as e:
            return self.manage_error(e)
 def test_supported_by_server_through_language_variants(self):
     """
     en-gb, supported by server through language variants
     """
     accept_language = "en-gb"
     server = [AcceptParameters(language=Language("en"))]
     cn = ContentNegotiator(
         acceptable=server, ignore_language_variants=True
     )
     accept_parameters = cn.negotiate(accept_language=accept_language)
     assert str(accept_parameters.language) == "en"
    def _GET_media_resource(self, path=None):
        """
        GET the media resource content in the requested format (web request will include content negotiation via
        Accept header)
        Args:
        - id:   the ID of the object in the store
        Returns the content in the requested format
        """
        ssslog.debug("GET on MediaResource; Incoming HTTP headers: " +
                     str(request.environ))

        # NOTE: this method is not authenticated - we imagine sharing this URL with end-users who will just want
        # to retrieve the content.
        ss = SwordServer(config, None)

        # first thing we need to do is check that there is an object to return, because otherwise we may throw a
        # 406 Not Acceptable without looking first to see if there is even any media to content negotiate for
        # which would be weird from a client perspective
        if not ss.media_resource_exists(path):
            return self.manage_error(SwordError(status=404, empty=True))

        # get the content negotiation headers
        accept_header = request.environ.get("HTTP_ACCEPT")
        accept_packaging_header = request.environ.get("HTTP_ACCEPT_PACKAGING")

        # do the negotiation
        default_accept_parameters, acceptable = config.get_media_resource_formats(
        )
        cn = ContentNegotiator(default_accept_parameters, acceptable)
        accept_parameters = cn.negotiate(
            accept=accept_header, accept_packaging=accept_packaging_header)

        ssslog.info("Conneg format: " + str(accept_parameters))

        try:
            # can get hold of the media resource
            media_resource = ss.get_media_resource(path, accept_parameters)
        except SwordError as e:
            return self.manage_error(e)

        # either send the client a redirect, or stream the content out
        if media_resource.redirect:
            redirect(media_resource.url, _code=302)  # FOUND (not SEE OTHER)
            return
        else:
            response.content_type = media_resource.content_type
            if media_resource.packaging is not None:
                response.headers["Packaging"] = str(media_resource.packaging)
            f = open(media_resource.filepath, "r")
            response.status_int = 200
            response.status = "200 OK"
            ssslog.info("Returning " + response.status + " from request on " +
                        inspect.stack()[0][3])
            return f.read()
 def test_unsupported_by_server(self):
     """
     en-gb, unsupported by server
     """
     accept_language = "en-gb"
     server = [AcceptParameters(language=Language("en"))]
     cn = ContentNegotiator(
         acceptable=server, ignore_language_variants=False
     )
     accept_parameters = cn.negotiate(accept_language=accept_language)
     assert accept_parameters is None
 def test_without_q_values(self):
     """
     en vs de without q values
     """
     accept_language = "en, de"
     server = [
         AcceptParameters(language=Language("en")),
         AcceptParameters(language=Language("de")),
     ]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(accept_language=accept_language)
     assert str(accept_parameters.language) == "en"
 def test_with_q_values(self):
     """
     application/atom+xml vs application/rdf+xml with q values
     """
     client_accept = "application/atom+xml;q=0.6, application/rdf+xml;q=0.9"
     server = [
         AcceptParameters(ContentType("application/rdf+xml")),
         AcceptParameters(ContentType("application/atom+xml")),
     ]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(accept=client_accept)
     assert str(accept_parameters.content_type) == "application/rdf+xml"
 def test_with_q_values(self):
     """
     fr vs no with q values
     """
     accept_language = "fr;q=0.7, no;q=0.8"
     server = [
         AcceptParameters(language=Language("fr")),
         AcceptParameters(language=Language("no")),
     ]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(accept_language=accept_language)
     assert str(accept_parameters.language) == "no"
 def test_wildcard_by_itself(self):
     """
     * by itself
     """
     accept_language = "*"
     server = [
         AcceptParameters(language=Language("no")),
         AcceptParameters(language=Language("de")),
     ]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(accept_language=accept_language)
     assert str(accept_parameters.language) == "no"
 def test_image_wildcard_supported_by_serverwith_other_options_primary_option_supported(self):
     """
     * with other options, primary option supported
     """
     accept_language = "en, *"
     server = [
         AcceptParameters(language=Language("en")),
         AcceptParameters(language=Language("de")),
     ]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(accept_language=accept_language)
     assert str(accept_parameters.language) == "en"
 def test_mixed_q_values_most_preferred_available(self):
     """
     en vs no vs de with mixed q values, most preferred available
     """
     accept_language = "en;q=0.6, no;q=0.9, de"
     server = [
         AcceptParameters(language=Language("no")),
         AcceptParameters(language=Language("de")),
     ]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(accept_language=accept_language)
     assert str(accept_parameters.language) == "de"
 def test_content_type_and_language_specified(self):
     """
     content type and language specified
     """
     accept = "text/html"
     accept_lang = "en"
     server = [AcceptParameters(ContentType("text/html"), Language("en"))]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(
         accept=accept, accept_language=accept_lang
     )
     assert str(accept_parameters.content_type) == "text/html"
     assert str(accept_parameters.language) == "en"
 def test_any_supported_by_server(self):
     """
     */* supported by server
     """
     client_accept = "*/*"
     server = [
         AcceptParameters(ContentType("text/plain")),
         AcceptParameters(ContentType("image/png")),
         AcceptParameters(ContentType("image/jpeg")),
     ]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(accept=client_accept)
     assert str(accept_parameters.content_type) == "text/plain"
 def test_with_mixed_q_values(self):
     """
     en vs de vs fr with mixed q values
     """
     accept_language = "en;q=0.6, de;q=0.9, fr"
     server = [
         AcceptParameters(language=Language("en")),
         AcceptParameters(language=Language("de")),
         AcceptParameters(language=Language("fr")),
     ]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(accept_language=accept_language)
     assert str(accept_parameters.language) == "fr"
 def test_atom_with_type_feed_supported_by_server(self):
     """
     application/atom+xml;type=feed supported by server
     """
     client_accept = "application/atom+xml;type=feed"
     server = [
         AcceptParameters(ContentType("application/atom+xml;type=feed"))
     ]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(accept=client_accept)
     assert (
         str(accept_parameters.content_type)
         == "application/atom+xml;type=feed"
     )
    def _GET_media_resource(self, path=None):
        """
        GET the media resource content in the requested format (web request will include content negotiation via
        Accept header)
        Args:
        - id:   the ID of the object in the store
        Returns the content in the requested format
        """
        ssslog.debug("GET on MediaResource; Incoming HTTP headers: " + str(request.environ))
        
        # NOTE: this method is not authenticated - we imagine sharing this URL with end-users who will just want
        # to retrieve the content.
        ss = SwordServer(config, None)

        # first thing we need to do is check that there is an object to return, because otherwise we may throw a
        # 406 Not Acceptable without looking first to see if there is even any media to content negotiate for
        # which would be weird from a client perspective
        if not ss.media_resource_exists(path):
            return self.manage_error(SwordError(status=404, empty=True))
        
        # get the content negotiation headers
        accept_header = request.environ.get("HTTP_ACCEPT")
        accept_packaging_header = request.environ.get("HTTP_ACCEPT_PACKAGING")
        
        # do the negotiation
        default_accept_parameters, acceptable = config.get_media_resource_formats()
        cn = ContentNegotiator(default_accept_parameters, acceptable)
        accept_parameters = cn.negotiate(accept=accept_header, accept_packaging=accept_packaging_header)
        
        ssslog.info("Conneg format: " + str(accept_parameters))

        try:
            # can get hold of the media resource
            media_resource = ss.get_media_resource(path, accept_parameters)
        except SwordError as e:
            return self.manage_error(e)

        # either send the client a redirect, or stream the content out
        if media_resource.redirect:
            redirect(media_resource.url, _code=302) # FOUND (not SEE OTHER)
            return
        else:
            response.content_type = media_resource.content_type
            if media_resource.packaging is not None:
                response.headers["Packaging"] = str(media_resource.packaging)
            f = open(media_resource.filepath, "r")
            response.status_int = 200
            response.status = "200 OK"
            ssslog.info("Returning " + response.status + " from request on " + inspect.stack()[0][3])
            return f.read()
Exemple #24
0
    def determine_content_type(self, request):
        acceptable = (
            AcceptParameters(ContentType('application/json')),
            AcceptParameters(ContentType('application/hal+json')),
            AcceptParameters(ContentType('application/vnd.siren+json')),
        )

        negotiator = ContentNegotiator(acceptable[0], acceptable)
        accept = request.META.get('HTTP_ACCEPT')
        negotiated_type = negotiator.negotiate(accept=request.META.get('HTTP_ACCEPT'))
        if negotiated_type:
            return negotiated_type.content_type

        return acceptable[0].content_type
 def test_mixed_q_values_most_preferred_available(self):
     """
     application/atom+xml vs application/rdf+xml vs text/html with mixed q
     values, most preferred available
     """
     client_accept = (
         "application/atom+xml;q=0.6, application/rdf+xml;q=0.9, text/html"
     )
     server = [
         AcceptParameters(ContentType("application/rdf+xml")),
         AcceptParameters(ContentType("text/html")),
     ]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(accept=client_accept)
     assert str(accept_parameters.content_type) == "text/html"
Exemple #26
0
    def GET(self, path):
        """
        GET the media resource content in the requested format (web request will include content negotiation via
        Accept header)
        Args:
        - id:   the ID of the object in the store
        Returns the content in the requested format
        """
        ssslog.debug("GET on MediaResourceContent; Incoming HTTP headers: " + str(web.ctx.environ))
        
        # NOTE: this method is not authenticated - we imagine sharing this URL with end-users who will just want
        # to retrieve the content.  It's only for the purposes of example, anyway
        ss = SwordServer(config, None)

        # first thing we need to do is check that there is an object to return, because otherwise we may throw a
        # 406 Not Acceptable without looking first to see if there is even any media to content negotiate for
        # which would be weird from a client perspective
        if not ss.media_resource_exists(path):
            return web.notfound()
        
        # get the content negotiation headers
        accept_header = web.ctx.environ.get("HTTP_ACCEPT")
        accept_packaging_header = web.ctx.environ.get("HTTP_ACCEPT_PACKAGING")
        
        # do the negotiation
        default_accept_parameters, acceptable = config.get_media_resource_formats()
        cn = ContentNegotiator(default_accept_parameters, acceptable)
        accept_parameters = cn.negotiate(accept=accept_header, accept_packaging=accept_packaging_header)
        
        ssslog.info("Conneg format: " + str(accept_parameters))

        try:
            # can get hold of the media resource
            media_resource = ss.get_media_resource(path, accept_parameters)
        except SwordError as e:
            ssslog.debug("Raised error")
            return self.manage_error(e)

        # either send the client a redirect, or stream the content out
        if media_resource.redirect:
            return web.found(media_resource.url)
        else:
            web.header("Content-Type", media_resource.content_type)
            if media_resource.packaging is not None:
                web.header("Packaging", media_resource.packaging)
            f = open(media_resource.filepath, "r")
            web.ctx.status = "200 OK"
            return f.read()
 def test_two_content_types_and_two_languages_specified(self):
     """
     Two content types and 2 languages specified
     """
     accept = "text/html, text/plain"
     accept_lang = "en, de"
     server = [
         AcceptParameters(ContentType("text/html"), Language("de")),
         AcceptParameters(ContentType("text/plain"), Language("en")),
     ]
     cn = ContentNegotiator(acceptable=server)
     accept_parameters = cn.negotiate(
         accept=accept, accept_language=accept_lang
     )
     assert str(accept_parameters.content_type) == "text/html"
     assert str(accept_parameters.language) == "de"
Exemple #28
0
    def getFormat(self, request):

        defaultOutput = AcceptParameters(
            ContentType(self.defaultOutputFormat, params='q=0'))

        acceptable = [defaultOutput] + [AcceptParameters(ContentType(x)) for x in self._outputFormatsPreference]

        cn = ContentNegotiator(defaultOutput, acceptable)
        if request.requestHeaders.hasHeader("Accept"):
            kwargs = {"accept": request.requestHeaders.getRawHeaders("Accept")[0]}
        else:
            kwargs = {}

        accp = cn.negotiate(**kwargs)

        return str(accp.content_type) if accp else None
 def _GET_container(self, path=None):
     """
     GET a representation of the container in the appropriate (content negotiated) format as identified by
     the supplied id
     Args:
     - id:   The ID of the container as supplied in the request URL
     Returns a representation of the container: SSS will return either the Atom Entry identical to the one supplied
     as a deposit receipt or the pure RDF/XML Statement depending on the Accept header
     """
     ssslog.debug("GET on Container (retrieve deposit receipt or statement); Incoming HTTP headers: " + str(request.environ))
     
     # authenticate
     try:
         auth = self.authenticate()
         
         ss = SwordServer(config, auth)
         
         # first thing we need to do is check that there is an object to return, because otherwise we may throw a
         # 415 Unsupported Media Type without looking first to see if there is even any media to content negotiate for
         # which would be weird from a client perspective
         if not ss.container_exists(path):
             return self.manage_error(SwordError(status=404, empty=True))
             
         # get the content negotiation headers
         accept_header = request.environ.get("HTTP_ACCEPT")
         accept_packaging_header = request.environ.get("HTTP_ACCEPT_PACKAGING")
         
         # do the negotiation
         default_accept_parameters, acceptable = config.get_container_formats()
         cn = ContentNegotiator(default_accept_parameters, acceptable)
         accept_parameters = cn.negotiate(accept=accept_header)
         ssslog.info("Container requested in format: " + str(accept_parameters))
         
         # did we successfully negotiate a content type?
         if accept_parameters is None:
             raise SwordError(error_uri=Error.content, status=415, empty=True)
         
         # now actually get hold of the representation of the container and send it to the client
         cont = ss.get_container(path, accept_parameters)
         ssslog.info("Returning " + response.status + " from request on " + inspect.stack()[0][3])
         if cont is not None:
             response.headers["Content-Type"] = str(accept_parameters.content_type.mimetype())
         return cont
         
     except SwordError as e:
         return self.manage_error(e)
Exemple #30
0
    def get(self, request):
        content_type_to_acceptable = lambda content_type: AcceptParameters(
            ContentType(content_type))
        acceptable = map(content_type_to_acceptable,
                         self.content_type_providers().keys())
        preferred_content_type = self.preferred_content_type

        accept = request.headers.get('ACCEPT')

        negotiator = ContentNegotiator(
            content_type_to_acceptable(preferred_content_type), acceptable)
        negotiated_type = negotiator.negotiate(accept=accept)
        content_type = negotiated_type.content_type or preferred_content_type

        provider = self.content_type_providers()[str(content_type)]

        return provider()
Exemple #31
0
class CapoeiraResource(Resource):
    def __init__(self, service):
        Resource.__init__(self)
        self.service = service
        self.resources = {
            '/capoeira/events/similar/artist':
            self.service.capoeiraSimilarByArtistQuery,
            '/capoeira/events/similar/track':
            self.service.capoeiraSimilarByTrackQuery
        }
        self.isLeaf = True

        # default_params is used in lieu of a defined Accept field in the header
        default_params = AcceptParameters(ContentType("text/html"),
                                          Language("en"))
        acceptable = [
            AcceptParameters(ContentType("text/html"), Language("en")),
            AcceptParameters(ContentType("text/json"), Language("en")),
            AcceptParameters(ContentType("application/json"), Language("en"))
        ]
        self.contentNegotiator = ContentNegotiator(default_params, acceptable)
        # function mapping for rendering response
        self.renderFns = {
            'text/html': formatHTMLResponse,
            'text/json': formatJSONResponse,
            'application/json': formatJSONResponse
        }

    def _delayedRender(self, request, deferred, renderFn):
        def d(_):
            request.write(renderFn(deferred.result))
            request.finish()

        return d

    def render_GET(self, request):
        # try to find acceptable response format, else fail with 406
        acceptable = self.contentNegotiator.negotiate(
            request.getHeader('Accept'))
        if not acceptable:
            request.setResponseCode(406)
            return ""

        # get acceptable content type and associated render function
        contentType = str(acceptable.content_type)
        renderFn = self.renderFns[contentType]
        request.setHeader("Content-Type", contentType)
        if request.path in self.resources:
            d = self.resources[request.path](request)
            d.addCallback(self._delayedRender(request, d, renderFn))
            return NOT_DONE_YET
        else:
            # TODO: better handling of path not found
            return "{}"
Exemple #32
0
    def getFormat(self, request):

        defaultOutput = AcceptParameters(
            ContentType(self.defaultOutputFormat, params='q=0'))

        acceptable = [defaultOutput] + [
            AcceptParameters(ContentType(x))
            for x in self._outputFormatsPreference
        ]

        cn = ContentNegotiator(defaultOutput, acceptable)
        if request.requestHeaders.hasHeader("Accept"):
            kwargs = {
                "accept": request.requestHeaders.getRawHeaders("Accept")[0]
            }
        else:
            kwargs = {}

        accp = cn.negotiate(**kwargs)

        return str(accp.content_type) if accp else None
 def test_two_content_types_and_one_language_specified_with_weights(self):
     """
     Two content types and one language specified, with weights
     """
     weights = {
         "content_type": 2.0,
         "language": 1.0,
         "charset": 1.0,
         "encoding": 1.0,
     }
     accept = "text/html, text/plain"
     accept_lang = "en"
     server = [
         AcceptParameters(ContentType("text/html"), Language("de")),
         AcceptParameters(ContentType("text/plain"), Language("en")),
     ]
     cn = ContentNegotiator(acceptable=server, weights=weights)
     accept_parameters = cn.negotiate(
         accept=accept, accept_language=accept_lang
     )
     assert str(accept_parameters.content_type) == "text/plain"
     assert str(accept_parameters.language) == "en"
Exemple #34
0
    def _init_content_negotiator(self):
        #TODO: use config instead
        default_content_type = "application/ld+json"
        default_accept_params = AcceptParameters(
            ContentType(default_content_type))
        # rdf types
        rdf_types = set([
            plugin.name for plugin in plugins(kind=Serializer)
            if "/" in plugin.name
        ])

        #Blacklisted because mapped to TriX that requires a context-aware store
        blacklisted_types = ["application/xml"]

        #TODO: consider other types
        accepted_types = list(
            rdf_types.difference(blacklisted_types)) + ["application/json"]
        self._logger.debug("Accepted types: %s" % accepted_types)
        acceptable_params = [default_accept_params] + [
            AcceptParameters(ContentType(ct)) for ct in accepted_types
        ]

        self._negotiator = ContentNegotiator(default_accept_params,
                                             acceptable_params)
Exemple #35
0
    def _init_content_negotiator(self):
        #TODO: use config instead
        default_content_type = "application/ld+json"
        default_accept_params = AcceptParameters(ContentType(default_content_type))
        # rdf types
        rdf_types = set([plugin.name for plugin in plugins(kind=Serializer) if "/" in plugin.name])

        #Blacklisted because mapped to TriX that requires a context-aware store
        blacklisted_types = ["application/xml"]

        #TODO: consider other types
        accepted_types = list(rdf_types.difference(blacklisted_types)) + ["application/json"]
        self._logger.debug("Accepted types: %s" % accepted_types)
        acceptable_params = [default_accept_params] + [AcceptParameters(ContentType(ct)) for ct in accepted_types]

        self._negotiator = ContentNegotiator(default_accept_params, acceptable_params)
Exemple #36
0
 def get_accept_parameters(self, accept, accept_language):
     # do the content negotiation
     cn = ContentNegotiator(default_accept_parameters=self.config.accepts_default, 
                             acceptable=self.config.accepts, weights=self.config.conneg_weights)
     ap = cn.negotiate(accept=accept, accept_language=accept_language)
     return ap
Exemple #37
0
class HTTPController(object):
    """
    HTTP.

    TODO: check declared methods (only GET and HEAD are implicit).
    """

    DEFAULT_CONFIG = {
        'allow_put_new_type_existing_resource': False,
        'allow_put_remove_type_existing_resource': False,
        'allow_put_new_resource': True
    }

    def __init__(self, manager, config={}):
        self._logger = getLogger(__name__)
        self._manager = manager

        # For operations except POST
        self._cruder = HashLessCRUDer(manager)

        self._config = self.DEFAULT_CONFIG.copy()
        self._config.update(config)

        self._negotiator = None
        self._init_content_negotiator()

    def _init_content_negotiator(self):
        #TODO: use config instead
        default_content_type = "application/ld+json"
        default_accept_params = AcceptParameters(
            ContentType(default_content_type))
        # rdf types
        rdf_types = set([
            plugin.name for plugin in plugins(kind=Serializer)
            if "/" in plugin.name
        ])

        #Blacklisted because mapped to TriX that requires a context-aware store
        blacklisted_types = ["application/xml"]

        #TODO: consider other types
        accepted_types = list(
            rdf_types.difference(blacklisted_types)) + ["application/json"]
        self._logger.debug("Accepted types: %s" % accepted_types)
        acceptable_params = [default_accept_params] + [
            AcceptParameters(ContentType(ct)) for ct in accepted_types
        ]

        self._negotiator = ContentNegotiator(default_accept_params,
                                             acceptable_params)

    def get(self, hashless_iri, accept_header="*/*", **kwargs):
        """
            TODO: describe.

            No support declaration required.
        """
        self._logger.debug("Accept header: %s" % accept_header)
        accepted_type = self._negotiator.negotiate(accept=accept_header)
        if accepted_type is None:
            raise OMNotAcceptableException()

        content_type = str(accepted_type.content_type)
        self._logger.debug("Selected content-type: %s" % content_type)

        try:
            return self._cruder.get(hashless_iri, content_type)
        except OMObjectNotFoundError:
            raise OMResourceNotFoundException()

    def head(self, hashless_iri, **kwargs):
        """
            TODO: describe.

            No support declaration required.
        """
        #TODO: consider a more efficient implementation
        try:
            self._cruder.get(hashless_iri, None)
        except OMObjectNotFoundError:
            raise OMResourceNotFoundException()

    def post(self, hashless_iri, content_type=None, payload=None, **kwargs):
        """
            TODO: categorize the resource to decide what to do.

            Support declaration and implementation are required.

        """
        if content_type is None:
            raise OMBadRequestException("Content type is required.")
        #if payload is None:
        #    raise BadRequestException("No payload given.")

        # Must be its ID (we do not consider resources with hash IRIs)
        resource = self._manager.get(id=hashless_iri)
        if resource is None:
            raise OMResourceNotFoundException()

        operation = resource.get_operation(HTTP_POST)
        if operation is not None:

            graph = Graph()
            try:
                if content_type in JSON_TYPES:
                    resource = self._manager.get(hashless_iri=hashless_iri)
                    graph.parse(data=payload,
                                format="json-ld",
                                publicID=hashless_iri,
                                context=resource.context)
                else:
                    graph.parse(data=payload,
                                format=content_type,
                                publicID=hashless_iri)
            except PluginException:
                raise OMNotAcceptableException()

            #TODO: add arguments
            return operation(resource, graph=graph, content_type=content_type)

        #TODO: When error code is 405, alternatives must be given.
        raise OMMethodNotAllowedException()

    def put(self, hashless_iri, content_type=None, payload=None, **kwargs):
        """
            TODO: describe.

            No support declaration required.
        """
        if content_type is None:
            raise OMBadRequestException("Content type is required.")
        if payload is None:
            raise OMBadRequestException("No payload given.")
        return self._cruder.update(self,
                                   hashless_iri,
                                   payload,
                                   content_type,
                                   allow_new_type=False,
                                   allow_type_removal=False,
                                   allow_put_new_resource=True)

    def delete(self, hashless_iri, **kwargs):
        """
            TODO: describe.

            No declaration required.
        """
        self._cruder.delete(hashless_iri)

    def options(self, hashless_iri, **kwargs):
        """ TODO: implement it """
        raise NotImplementedError("")

    def patch(self, hashless_iri, content_type=None, payload=None, **kwargs):
        """ TODO: implement it  """
        if content_type is None:
            raise OMBadRequestException("Content type is required.")
        if payload is None:
            raise OMBadRequestException("No payload given.")
        raise NotImplementedError("PATCH is not yet supported.")
Exemple #38
0
class HTTPController(object):
    """
    HTTP.

    TODO: check declared methods (only GET and HEAD are implicit).
    """

    DEFAULT_CONFIG = {'allow_put_new_type_existing_resource': False,
                      'allow_put_remove_type_existing_resource': False,
                      'allow_put_new_resource': True
                      }

    def __init__(self, manager, config={}):
        self._logger = getLogger(__name__)
        self._manager = manager

        # For operations except POST
        self._cruder = HashLessCRUDer(manager)

        self._config = self.DEFAULT_CONFIG.copy()
        self._config.update(config)

        self._negotiator = None
        self._init_content_negotiator()

    def _init_content_negotiator(self):
        #TODO: use config instead
        default_content_type = "application/ld+json"
        default_accept_params = AcceptParameters(ContentType(default_content_type))
        # rdf types
        rdf_types = set([plugin.name for plugin in plugins(kind=Serializer) if "/" in plugin.name])

        #Blacklisted because mapped to TriX that requires a context-aware store
        blacklisted_types = ["application/xml"]

        #TODO: consider other types
        accepted_types = list(rdf_types.difference(blacklisted_types)) + ["application/json"]
        self._logger.debug("Accepted types: %s" % accepted_types)
        acceptable_params = [default_accept_params] + [AcceptParameters(ContentType(ct)) for ct in accepted_types]

        self._negotiator = ContentNegotiator(default_accept_params, acceptable_params)

    def get(self, hashless_iri, accept_header="*/*", **kwargs):
        """
            TODO: describe.

            No support declaration required.
        """
        self._logger.debug("Accept header: %s" % accept_header)
        accepted_type = self._negotiator.negotiate(accept=accept_header)
        if accepted_type is None:
            raise OMNotAcceptableException()

        content_type = str(accepted_type.content_type)
        self._logger.debug("Selected content-type: %s" % content_type)

        try:
            return self._cruder.get(hashless_iri, content_type)
        except OMObjectNotFoundError:
            raise OMResourceNotFoundException()

    def head(self, hashless_iri, **kwargs):
        """
            TODO: describe.

            No support declaration required.
        """
        #TODO: consider a more efficient implementation
        try:
            self._cruder.get(hashless_iri, None)
        except OMObjectNotFoundError:
            raise OMResourceNotFoundException()

    def post(self, hashless_iri, content_type=None, payload=None, **kwargs):
        """
            TODO: categorize the resource to decide what to do.

            Support declaration and implementation are required.

        """
        if content_type is None:
            raise OMBadRequestException("Content type is required.")
        #if payload is None:
        #    raise BadRequestException("No payload given.")

        # Must be its ID (we do not consider resources with hash IRIs)
        resource = self._manager.get(id=hashless_iri)
        if resource is None:
            raise OMResourceNotFoundException()

        operation = resource.get_operation(HTTP_POST)
        if operation is not None:

            graph = Graph()
            try:
                if content_type in JSON_TYPES:
                    resource = self._manager.get(hashless_iri=hashless_iri)
                    graph.parse(data=payload, format="json-ld", publicID=hashless_iri,
                                context=resource.context)
                else:
                    graph.parse(data=payload, format=content_type, publicID=hashless_iri)
            except PluginException:
                raise OMNotAcceptableException()

            #TODO: add arguments
            return operation(resource, graph=graph, content_type=content_type)

        #TODO: When error code is 405, alternatives must be given.
        raise OMMethodNotAllowedException()

    def put(self, hashless_iri, content_type=None, payload=None, **kwargs):
        """
            TODO: describe.

            No support declaration required.
        """
        if content_type is None:
            raise OMBadRequestException("Content type is required.")
        if payload is None:
            raise OMBadRequestException("No payload given.")
        return self._cruder.update(self, hashless_iri, payload, content_type,
                                   allow_new_type=False, allow_type_removal=False,
                                   allow_put_new_resource=True)

    def delete(self, hashless_iri, **kwargs):
        """
            TODO: describe.

            No declaration required.
        """
        self._cruder.delete(hashless_iri)

    def options(self, hashless_iri, **kwargs):
        """ TODO: implement it """
        raise NotImplementedError("")

    def patch(self, hashless_iri, content_type=None, payload=None, **kwargs):
        """ TODO: implement it  """
        if content_type is None:
            raise OMBadRequestException("Content type is required.")
        if payload is None:
            raise OMBadRequestException("No payload given.")
        raise NotImplementedError("PATCH is not yet supported.")