File: common_decorators.py

package info (click to toggle)
python-flask-rdf 0.2.1-1%2Bdeb10u1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 132 kB
  • sloc: python: 323; makefile: 14
file content (86 lines) | stat: -rw-r--r-- 2,636 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
from __future__ import absolute_import
from .format import decide, FormatSelector
from rdflib.graph import Graph


class ViewDecorator(object):
	def __init__(self, format_selector=None):
		self.format_selector = format_selector
		if self.format_selector is None:
			self.format_selector = FormatSelector()

	@classmethod
	def is_graph(cls, obj):
		""" Check whether this object is an rdflib Graph """
		return isinstance(obj, Graph)

	@classmethod
	def get_graph(cls, response):
		""" Given a view response, find the rdflib Graph, or None """
		if cls.is_graph(response):	# single graph object
			return response

	@classmethod
	def replace_graph(cls, response, serialized):
		""" Replace the rdflib Graph in a view response """
		if cls.is_graph(response):	# single graph object
			return serialized
		return response

	@classmethod
	def make_new_response(cls, old_response, mimetype, serialized):
		""" Return a new framework-specific response with the seralized data """
		raise NotImplementedError

	@classmethod
	def make_406_response(cls):
		""" Return the framework-specific HTTP 406 error """
		raise NotImplementedError

	@classmethod
	def get_accept(cls):
		""" Load the framework-specific Accept header """
		raise NotImplementedError

	def output(self, response, accepts):
		""" Formats a response from a view to handle any RDF graphs
		    If a view function returns an RDF graph, serialize it based on Accept header
		    If it's not an RDF graph, return it without any special handling
		"""
		graph = self.get_graph(response)
		if graph is not None:
			# decide the format
			mimetype, format = self.format_selector.decide(accepts, graph.context_aware)

			# requested content couldn't find anything
			if mimetype is None:
				return self.make_406_response()

			# explicitly mark text mimetypes as utf-8
			if 'text' in mimetype:
				mimetype = mimetype + '; charset=utf-8'

			# format the new response
			serialized = graph.serialize(format=format)
			response = self.make_new_response(response, mimetype, serialized)
			return response
		else:
			return response

	def decorate(self, view):
		""" Wraps a view function to return formatted RDF graphs
		    Uses content negotiation to serialize the graph to the client-preferred format
		    Passes other content through unmodified
		"""
		from functools import wraps

		@wraps(view)
		def decorated(*args, **kwargs):
			response = view(*args, **kwargs)
			accept = self.get_accept()
			return self.output(response, accept)
		return decorated

	def __call__(self, view):
		""" Enables this class to be used as the decorator directly """
		return self.decorate(view)