Utilities Various utility functions shipped with Werkzeug.  HTML Helpers
class werkzeug.utils.HTMLBuilder(dialect)
Helper object for HTML generation. Per default there are two instances of that class. The html one, and the xhtml one for those two dialects. The class uses keyword parameters and positional parameters to generate small snippets of HTML. Keyword parameters are converted to XML/SGML attributes, positional arguments are used as children. Because Python accepts positional arguments before keyword arguments it’s a good idea to use a list with the star-syntax for some children: >>> html.p(class_='foo', *[html.a('foo', href='foo.html'), ' ',
...                        html.a('bar', href='bar.html')])
'
foo bar
'
 This class works around some browser limitations and can not be used for arbitrary SGML/XML generation. For that purpose lxml and similar libraries exist. Calling the builder escapes the string passed: >>> html.p(html("<foo>"))
'
<foo>
'
  Deprecated since version 2.0: Will be removed in Werkzeug 2.1.

werkzeug.utils.escape(s)
Replace &, <, >, ", and ' with HTML-safe sequences. None is escaped to an empty string.  Deprecated since version 2.0: Will be removed in Werkzeug 2.1. Use MarkupSafe instead.   Parameters
s (Any) –   Return type
str

werkzeug.utils.unescape(s)
The reverse of escape(). This unescapes all the HTML entities, not only those inserted by escape.  Deprecated since version 2.0: Will be removed in Werkzeug 2.1. Use MarkupSafe instead.   Parameters
s (str) –   Return type
str
   General Helpers
class werkzeug.utils.cached_property(fget, name=None, doc=None)
A property() that is only evaluated once. Subsequent access returns the cached value. Setting the property sets the cached value. Deleting the property clears the cached value, accessing it again will evaluate it again. class Example:
    @cached_property
    def value(self):
        # calculate something important here
        return 42

e = Example()
e.value  # evaluates
e.value  # uses cache
e.value = 16  # sets cache
del e.value  # clears cache
 The class must have a __dict__ for this to work.  Changed in version 2.0: del obj.name clears the cached value.   Parameters

fget (Callable[[Any], Any]) –
name (Optional[str]) –
doc (Optional[str]) –    Return type
None

werkzeug.utils.invalidate_cached_property(obj, name)
Invalidates the cache for a cached_property: >>> class Test(object):
...     @cached_property
...     def magic_number(self):
...         print("recalculating...")
...         return 42
...
>>> var = Test()
>>> var.magic_number
recalculating...
42
>>> var.magic_number
42
>>> invalidate_cached_property(var, "magic_number")
>>> var.magic_number
recalculating...
42
 You must pass the name of the cached property as the second argument.  Deprecated since version 2.0: Will be removed in Werkzeug 2.1. Use del obj.name instead.   Parameters

obj (object) –
name (str) –    Return type
None

class werkzeug.utils.environ_property(name, default=None, load_func=None, dump_func=None, read_only=None, doc=None)
Maps request attributes to environment variables. This works not only for the Werkzeug request object, but also any other class with an environ attribute: >>> class Test(object):
...     environ = {'key': 'value'}
...     test = environ_property('key')
>>> var = Test()
>>> var.test
'value'
 If you pass it a second value it’s used as default if the key does not exist, the third one can be a converter that takes a value and converts it. If it raises ValueError or TypeError the default value is used. If no default value is provided None is used. Per default the property is read only. You have to explicitly enable it by passing read_only=False to the constructor.

class werkzeug.utils.header_property(name, default=None, load_func=None, dump_func=None, read_only=None, doc=None)
Like environ_property but for headers.

werkzeug.utils.redirect(location, code=302, Response=None)
Returns a response object (a WSGI application) that, if called, redirects the client to the target location. Supported codes are 301, 302, 303, 305, 307, and 308. 300 is not supported because it’s not a real redirect and 304 because it’s the answer for a request with a request with defined If-Modified-Since headers.  Changelog New in version 0.10: The class used for the Response object can now be passed in.   New in version 0.6: The location can now be a unicode string that is encoded using the iri_to_uri() function.   Parameters

location (str) – the location the response should redirect to.
code (int) – the redirect status code. defaults to 302.
Response (class) – a Response class to use when instantiating a response. The default is werkzeug.wrappers.Response if unspecified.   Return type
Response

werkzeug.utils.append_slash_redirect(environ, code=301)
Redirects to the same URL but with a slash appended. The behavior of this function is undefined if the path ends with a slash already.  Parameters

environ (WSGIEnvironment) – the WSGI environment for the request that triggers the redirect.
code (int) – the status code for the redirect.   Return type
Response

werkzeug.utils.send_file(path_or_file, environ, mimetype=None, as_attachment=False, download_name=None, conditional=True, etag=True, last_modified=None, max_age=None, use_x_sendfile=False, response_class=None, _root_path=None)
Send the contents of a file to the client. The first argument can be a file path or a file-like object. Paths are preferred in most cases because Werkzeug can manage the file and get extra information from the path. Passing a file-like object requires that the file is opened in binary mode, and is mostly useful when building a file in memory with io.BytesIO. Never pass file paths provided by a user. The path is assumed to be trusted, so a user could craft a path to access a file you didn’t intend. If the WSGI server sets a file_wrapper in environ, it is used, otherwise Werkzeug’s built-in wrapper is used. Alternatively, if the HTTP server supports X-Sendfile, use_x_sendfile=True will tell the server to send the given path, which is much more efficient than reading it in Python.  Parameters

path_or_file (Union[os.PathLike, str, BinaryIO]) – The path to the file to send, relative to the current working directory if a relative path is given. Alternatively, a file-like object opened in binary mode. Make sure the file pointer is seeked to the start of the data.
environ (WSGIEnvironment) – The WSGI environ for the current request.
mimetype (Optional[str]) – The MIME type to send for the file. If not provided, it will try to detect it from the file name.
as_attachment (bool) – Indicate to a browser that it should offer to save the file instead of displaying it.
download_name (Optional[str]) – The default name browsers will use when saving the file. Defaults to the passed file name.
conditional (bool) – Enable conditional and range responses based on request headers. Requires passing a file path and environ.
etag (Union[bool, str]) – Calculate an ETag for the file, which requires passing a file path. Can also be a string to use instead.
last_modified (Optional[Union[datetime.datetime, int, float]]) – The last modified time to send for the file, in seconds. If not provided, it will try to detect it from the file path.
max_age (Optional[Union[int, Callable[[Optional[Union[os.PathLike, str]]], int]]]) – How long the client should cache the file, in seconds. If set, Cache-Control will be public, otherwise it will be no-cache to prefer conditional caching.
use_x_sendfile (bool) – Set the X-Sendfile header to let the server to efficiently send the file. Requires support from the HTTP server. Requires passing a file path.
response_class (Optional[Type[Response]]) – Build the response using this class. Defaults to Response.
_root_path (Optional[Union[os.PathLike, str]]) – Do not use. For internal use only. Use send_from_directory() to safely send files under a path.   Return type
Response    New in version 2.0: Adapted from Flask’s implementation.   Changed in version 2.0: download_name replaces Flask’s attachment_filename parameter. If as_attachment=False, it is passed with Content-Disposition: inline instead.   Changed in version 2.0: max_age replaces Flask’s cache_timeout parameter. conditional is enabled and max_age is not set by default.   Changed in version 2.0: etag replaces Flask’s add_etags parameter. It can be a string to use instead of generating one.   Changed in version 2.0: If an encoding is returned when guessing mimetype from download_name, set the Content-Encoding header.

werkzeug.utils.import_string(import_name, silent=False)
Imports an object based on a string. This is useful if you want to use import paths as endpoints or something similar. An import path can be specified either in dotted notation (xml.sax.saxutils.escape) or with a colon as object delimiter (xml.sax.saxutils:escape). If silent is True the return value will be None if the import fails.  Parameters

import_name (str) – the dotted name for the object to import.
silent (bool) – if set to True import errors are ignored and None is returned instead.   Returns
imported object  Return type
Any

werkzeug.utils.find_modules(import_path, include_packages=False, recursive=False)
Finds all the modules below a package. This can be useful to automatically import all views / controllers so that their metaclasses / function decorators have a chance to register themselves on the application. Packages are not returned unless include_packages is True. This can also recursively list modules but in that case it will import all the packages to get the correct load path of that module.  Parameters

import_path (str) – the dotted name for the package to find child modules.
include_packages (bool) – set to True if packages should be returned, too.
recursive (bool) – set to True if recursion should happen.   Returns
generator  Return type
Iterator[str]

werkzeug.utils.validate_arguments(func, args, kwargs, drop_extra=True)
Checks if the function accepts the arguments and keyword arguments. Returns a new (args, kwargs) tuple that can safely be passed to the function without causing a TypeError because the function signature is incompatible. If drop_extra is set to True (which is the default) any extra positional or keyword arguments are dropped automatically. The exception raised provides three attributes:
missing

A set of argument names that the function expected but where missing.
extra

A dict of keyword arguments that the function can not handle but where provided.
extra_positional

A list of values that where given by positional argument but the function cannot accept.   This can be useful for decorators that forward user submitted data to a view function: from werkzeug.utils import ArgumentValidationError, validate_arguments

def sanitize(f):
    def proxy(request):
        data = request.values.to_dict()
        try:
            args, kwargs = validate_arguments(f, (request,), data)
        except ArgumentValidationError:
            raise BadRequest('The browser failed to transmit all '
                             'the data expected.')
        return f(*args, **kwargs)
    return proxy
  Parameters

func – the function the validation is performed against.
args – a tuple of positional arguments.
kwargs – a dict of keyword arguments.
drop_extra – set to False if you don’t want extra arguments to be silently dropped.   Returns
tuple in the form (args, kwargs).    Deprecated since version 2.0: Will be removed in Werkzeug 2.1. Use inspect.signature() instead.

werkzeug.utils.secure_filename(filename)
Pass it a filename and it will return a secure version of it. This filename can then safely be stored on a regular file system and passed to os.path.join(). The filename returned is an ASCII only string for maximum portability. On windows systems the function also makes sure that the file is not named after one of the special device files. >>> secure_filename("My cool movie.mov")
'My_cool_movie.mov'
>>> secure_filename("../../../etc/passwd")
'etc_passwd'
>>> secure_filename('i contain cool \xfcml\xe4uts.txt')
'i_contain_cool_umlauts.txt'
 The function might return an empty filename. It’s your responsibility to ensure that the filename is unique and that you abort or generate a random filename if the function returned an empty one.  Changelog New in version 0.5.   Parameters
filename (str) – the filename to secure  Return type
str

werkzeug.utils.bind_arguments(func, args, kwargs)
Bind the arguments provided into a dict. When passed a function, a tuple of arguments and a dict of keyword arguments bind_arguments returns a dict of names as the function would see it. This can be useful to implement a cache decorator that uses the function arguments to build the cache key based on the values of the arguments.  Parameters

func – the function the arguments should be bound for.
args – tuple of positional arguments.
kwargs – a dict of keyword arguments.   Returns
a dict of bound keyword arguments.    Deprecated since version 2.0: Will be removed in Werkzeug 2.1. Use Signature.bind() instead.
   URL Helpers Please refer to URL Helpers.   User Agent API
class werkzeug.user_agent.UserAgent(string)
Represents a parsed user agent header value. The default implementation does no parsing, only the string attribute is set. A subclass may parse the string to set the common attributes or expose other information. Set werkzeug.wrappers.Request.user_agent_class to use a subclass.  Parameters
string (str) – The header value to parse.  Return type
None    New in version 2.0: This replaces the previous useragents module, but does not provide a built-in parser.
platform: Optional[str] = None
The OS name, if it could be parsed from the string.

browser: Optional[str] = None
The browser name, if it could be parsed from the string.

version: Optional[str] = None
The browser version, if it could be parsed from the string.

language: Optional[str] = None
The browser language, if it could be parsed from the string.

string: str
The original header value.

to_header()
Convert to a header value.  Return type
str

   UserAgent Parsing (deprecated)  Deprecated since version 2.0: This module will be removed in Werkzeug 2.1. Subclass werkzeug.user_agent.UserAgent to use a dedicated parser instead.
class werkzeug.useragents.UserAgent(environ_or_string)
Represents a parsed user agent header value. This uses a basic parser to try to extract some information from the header.  Parameters
environ_or_string (t.Union[str, WSGIEnvironment]) – The header value to parse, or a WSGI environ containing the header.  Return type
None    Deprecated since version 2.0: Will be removed in Werkzeug 2.1. Subclass werkzeug.user_agent.UserAgent (note the new module name) to use a dedicated parser instead.   Changed in version 2.0: Passing a WSGI environ is deprecated and will be removed in 2.1.
to_header()
Convert to a header value.  Return type
str

   Security Helpers  Changelog New in version 0.6.1.
werkzeug.security.generate_password_hash(password, method='pbkdf2:sha256', salt_length=16)
Hash a password with the given method and salt with a string of the given length. The format of the string returned includes the method that was used so that check_password_hash() can check the hash. The format for the hashed string looks like this: method$salt$hash
 This method can not generate unsalted passwords but it is possible to set param method=’plain’ in order to enforce plaintext passwords. If a salt is used, hmac is used internally to salt the password. If PBKDF2 is wanted it can be enabled by setting the method to pbkdf2:method:iterations where iterations is optional: pbkdf2:sha256:80000$salt$hash
pbkdf2:sha256$salt$hash
  Parameters

password (str) – the password to hash.
method (str) – the hash method to use (one that hashlib supports). Can optionally be in the format pbkdf2:method:iterations to enable PBKDF2.
salt_length (int) – the length of the salt in letters.   Return type
str

werkzeug.security.check_password_hash(pwhash, password)
Check a password against a given salted and hashed password value. In order to support unsalted legacy passwords this method supports plain text passwords, md5 and sha1 hashes (both salted and unsalted). Returns True if the password matched, False otherwise.  Parameters

pwhash (str) – a hashed string like returned by generate_password_hash().
password (str) – the plaintext password to compare against the hash.   Return type
bool

werkzeug.security.safe_str_cmp(a, b)
This function compares strings in somewhat constant time. This requires that the length of at least one string is known in advance. Returns True if the two strings are equal, or False if they are not.  Deprecated since version 2.0: Will be removed in Werkzeug 2.1. Use hmac.compare_digest() instead.   Changelog New in version 0.7.   Parameters

a (str) –
b (str) –    Return type
bool

werkzeug.security.safe_join(directory, *pathnames)
Safely join zero or more untrusted path components to a base directory to avoid escaping the base directory.  Parameters

directory (str) – The trusted base directory.
pathnames (str) – The untrusted path components relative to the base directory.   Returns
A safe path, otherwise None.  Return type
Optional[str]

werkzeug.security.pbkdf2_hex(data, salt, iterations=260000, keylen=None, hashfunc=None)
Like pbkdf2_bin(), but returns a hex-encoded string.  Parameters

data (Union[str, bytes]) – the data to derive.
salt (Union[str, bytes]) – the salt for the derivation.
iterations (int) – the number of iterations.
keylen (Optional[int]) – the length of the resulting key. If not provided, the digest size will be used.
hashfunc (Optional[Union[str, Callable]]) – the hash function to use. This can either be the string name of a known hash function, or a function from the hashlib module. Defaults to sha256.   Return type
str    Deprecated since version 2.0: Will be removed in Werkzeug 2.1. Use hashlib.pbkdf2_hmac() instead.   Changelog New in version 0.9.

werkzeug.security.pbkdf2_bin(data, salt, iterations=260000, keylen=None, hashfunc=None)
Returns a binary digest for the PBKDF2 hash algorithm of data with the given salt. It iterates iterations times and produces a key of keylen bytes. By default, SHA-256 is used as hash function; a different hashlib hashfunc can be provided.  Parameters

data (Union[str, bytes]) – the data to derive.
salt (Union[str, bytes]) – the salt for the derivation.
iterations (int) – the number of iterations.
keylen (Optional[int]) – the length of the resulting key. If not provided the digest size will be used.
hashfunc (Optional[Union[str, Callable]]) – the hash function to use. This can either be the string name of a known hash function or a function from the hashlib module. Defaults to sha256.   Return type
bytes    Deprecated since version 2.0: Will be removed in Werkzeug 2.1. Use hashlib.pbkdf2_hmac() instead.   Changelog New in version 0.9.

   Logging Werkzeug uses standard Python logging. The logger is named "werkzeug". import logging
logger = logging.getLogger("werkzeug")
 If the logger level is not set, it will be set to INFO on first use. If there is no handler for that level, a StreamHandler is added.


class werkzeug.routing.UUIDConverter(map, *args, **kwargs)
This converter only accepts UUID strings: Rule('/object/<uuid:identifier>')
  Changelog New in version 0.10.   Parameters

map (Map) – the Map.
args (Any) –
kwargs (Any) –    Return type
None


werkzeug.utils.validate_arguments(func, args, kwargs, drop_extra=True)
Checks if the function accepts the arguments and keyword arguments. Returns a new (args, kwargs) tuple that can safely be passed to the function without causing a TypeError because the function signature is incompatible. If drop_extra is set to True (which is the default) any extra positional or keyword arguments are dropped automatically. The exception raised provides three attributes:
missing

A set of argument names that the function expected but where missing.
extra

A dict of keyword arguments that the function can not handle but where provided.
extra_positional

A list of values that where given by positional argument but the function cannot accept.   This can be useful for decorators that forward user submitted data to a view function: from werkzeug.utils import ArgumentValidationError, validate_arguments

def sanitize(f):
    def proxy(request):
        data = request.values.to_dict()
        try:
            args, kwargs = validate_arguments(f, (request,), data)
        except ArgumentValidationError:
            raise BadRequest('The browser failed to transmit all '
                             'the data expected.')
        return f(*args, **kwargs)
    return proxy
  Parameters

func – the function the validation is performed against.
args – a tuple of positional arguments.
kwargs – a dict of keyword arguments.
drop_extra – set to False if you don’t want extra arguments to be silently dropped.   Returns
tuple in the form (args, kwargs).    Deprecated since version 2.0: Will be removed in Werkzeug 2.1. Use inspect.signature() instead.


werkzeug.wsgi.wrap_file(environ, file, buffer_size=8192)
Wraps a file. This uses the WSGI server’s file wrapper if available or otherwise the generic FileWrapper.  Changelog New in version 0.5.  If the file wrapper from the WSGI server is used it’s important to not iterate over it from inside the application but to pass it through unchanged. If you want to pass out a file wrapper inside a response object you have to set Response.direct_passthrough to True. More information about file wrappers are available in PEP 333.  Parameters

file (BinaryIO) – a file-like object with a read() method.
buffer_size (int) – number of bytes for one iteration.
environ (WSGIEnvironment) –    Return type
Iterable[bytes]


class werkzeug.datastructures.WWWAuthenticate(auth_type=None, values=None, on_update=None)
Provides simple access to WWW-Authenticate headers.
property algorithm
A string indicating a pair of algorithms used to produce the digest and a checksum. If this is not present it is assumed to be “MD5”. If the algorithm is not understood, the challenge should be ignored (and a different one used, if there is more than one).

static auth_property(name, doc=None)
A static helper function for Authentication subclasses to add extra authentication system properties onto a class: class FooAuthenticate(WWWAuthenticate):
    special_realm = auth_property('special_realm')
 For more information have a look at the sourcecode to see how the regular properties (realm etc.) are implemented.

property domain
A list of URIs that define the protection space. If a URI is an absolute path, it is relative to the canonical root URL of the server being accessed.

property nonce
A server-specified data string which should be uniquely generated each time a 401 response is made. It is recommended that this string be base64 or hexadecimal data.

property opaque
A string of data, specified by the server, which should be returned by the client unchanged in the Authorization header of subsequent requests with URIs in the same protection space. It is recommended that this string be base64 or hexadecimal data.

property qop
A set of quality-of-privacy directives such as auth and auth-int.

property realm
A string to be displayed to users so they know which username and password to use. This string should contain at least the name of the host performing the authentication and might additionally indicate the collection of users who might have access.

set_basic(realm='authentication required')
Clear the auth info and enable basic auth.

set_digest(realm, nonce, qop=('auth'), opaque=None, algorithm=None, stale=False)
Clear the auth info and enable digest auth.

property stale
A flag, indicating that the previous request from the client was rejected because the nonce value was stale.

to_header()
Convert the stored values into a WWW-Authenticate header.

property type
The type of the auth mechanism. HTTP currently specifies Basic and Digest.


static auth_property(name, doc=None)
A static helper function for Authentication subclasses to add extra authentication system properties onto a class: class FooAuthenticate(WWWAuthenticate):
    special_realm = auth_property('special_realm')
 For more information have a look at the sourcecode to see how the regular properties (realm etc.) are implemented.


set_basic(realm='authentication required')
Clear the auth info and enable basic auth.


set_digest(realm, nonce, qop=('auth'), opaque=None, algorithm=None, stale=False)
Clear the auth info and enable digest auth.


to_header()
Convert the stored values into a WWW-Authenticate header.


Versioning  Versioning an interface is just a "polite" way to kill deployed clients. — Roy Fielding.  API versioning allows you to alter behavior between different clients. REST framework provides for a number of different versioning schemes. Versioning is determined by the incoming client request, and may either be based on the request URL, or based on the request headers. There are a number of valid approaches to approaching versioning. Non-versioned systems can also be appropriate, particularly if you're engineering for very long-term systems with multiple clients outside of your control. Versioning with REST framework When API versioning is enabled, the request.version attribute will contain a string that corresponds to the version requested in the incoming client request. By default, versioning is not enabled, and request.version will always return None. Varying behavior based on the version How you vary the API behavior is up to you, but one example you might typically want is to switch to a different serialization style in a newer version. For example: def get_serializer_class(self):
    if self.request.version == 'v1':
        return AccountSerializerVersion1
    return AccountSerializer
 Reversing URLs for versioned APIs The reverse function included by REST framework ties in with the versioning scheme. You need to make sure to include the current request as a keyword argument, like so. from rest_framework.reverse import reverse

reverse('bookings-list', request=request)
 The above function will apply any URL transformations appropriate to the request version. For example:  If NamespaceVersioning was being used, and the API version was 'v1', then the URL lookup used would be 'v1:bookings-list', which might resolve to a URL like http://example.org/v1/bookings/. If QueryParameterVersioning was being used, and the API version was 1.0, then the returned URL might be something like http://example.org/bookings/?version=1.0
  Versioned APIs and hyperlinked serializers When using hyperlinked serialization styles together with a URL based versioning scheme make sure to include the request as context to the serializer. def get(self, request):
    queryset = Booking.objects.all()
    serializer = BookingsSerializer(queryset, many=True, context={'request': request})
    return Response({'all_bookings': serializer.data})
 Doing so will allow any returned URLs to include the appropriate versioning. Configuring the versioning scheme The versioning scheme is defined by the DEFAULT_VERSIONING_CLASS settings key. REST_FRAMEWORK = {
    'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning'
}
 Unless it is explicitly set, the value for DEFAULT_VERSIONING_CLASS will be None. In this case the request.version attribute will always return None. You can also set the versioning scheme on an individual view. Typically you won't need to do this, as it makes more sense to have a single versioning scheme used globally. If you do need to do so, use the versioning_class attribute. class ProfileList(APIView):
    versioning_class = versioning.QueryParameterVersioning
 Other versioning settings The following settings keys are also used to control versioning:
DEFAULT_VERSION. The value that should be used for request.version when no versioning information is present. Defaults to None.
ALLOWED_VERSIONS. If set, this value will restrict the set of versions that may be returned by the versioning scheme, and will raise an error if the provided version is not in this set. Note that the value used for the DEFAULT_VERSION setting is always considered to be part of the ALLOWED_VERSIONS set (unless it is None). Defaults to None.
VERSION_PARAM. The string that should be used for any versioning parameters, such as in the media type or URL query parameters. Defaults to 'version'.  You can also set your versioning class plus those three values on a per-view or a per-viewset basis by defining your own versioning scheme and using the default_version, allowed_versions and version_param class variables. For example, if you want to use URLPathVersioning: from rest_framework.versioning import URLPathVersioning
from rest_framework.views import APIView

class ExampleVersioning(URLPathVersioning):
    default_version = ...
    allowed_versions = ...
    version_param = ...

class ExampleView(APIVIew):
    versioning_class = ExampleVersioning
 API Reference AcceptHeaderVersioning This scheme requires the client to specify the version as part of the media type in the Accept header. The version is included as a media type parameter, that supplements the main media type. Here's an example HTTP request using the accept header versioning style. GET /bookings/ HTTP/1.1
Host: example.com
Accept: application/json; version=1.0
 In the example request above request.version attribute would return the string '1.0'. Versioning based on accept headers is generally considered as best practice, although other styles may be suitable depending on your client requirements. Using accept headers with vendor media types Strictly speaking the json media type is not specified as including additional parameters. If you are building a well-specified public API you might consider using a vendor media type. To do so, configure your renderers to use a JSON based renderer with a custom media type: class BookingsAPIRenderer(JSONRenderer):
    media_type = 'application/vnd.megacorp.bookings+json'
 Your client requests would now look like this: GET /bookings/ HTTP/1.1
Host: example.com
Accept: application/vnd.megacorp.bookings+json; version=1.0
 URLPathVersioning This scheme requires the client to specify the version as part of the URL path. GET /v1/bookings/ HTTP/1.1
Host: example.com
Accept: application/json
 Your URL conf must include a pattern that matches the version with a 'version' keyword argument, so that this information is available to the versioning scheme. urlpatterns = [
    re_path(
        r'^(?P<version>(v1|v2))/bookings/$',
        bookings_list,
        name='bookings-list'
    ),
    re_path(
        r'^(?P<version>(v1|v2))/bookings/(?P<pk>[0-9]+)/$',
        bookings_detail,
        name='bookings-detail'
    )
]
 NamespaceVersioning To the client, this scheme is the same as URLPathVersioning. The only difference is how it is configured in your Django application, as it uses URL namespacing, instead of URL keyword arguments. GET /v1/something/ HTTP/1.1
Host: example.com
Accept: application/json
 With this scheme the request.version attribute is determined based on the namespace that matches the incoming request path. In the following example we're giving a set of views two different possible URL prefixes, each under a different namespace: # bookings/urls.py
urlpatterns = [
    re_path(r'^$', bookings_list, name='bookings-list'),
    re_path(r'^(?P<pk>[0-9]+)/$', bookings_detail, name='bookings-detail')
]

# urls.py
urlpatterns = [
    re_path(r'^v1/bookings/', include('bookings.urls', namespace='v1')),
    re_path(r'^v2/bookings/', include('bookings.urls', namespace='v2'))
]
 Both URLPathVersioning and NamespaceVersioning are reasonable if you just need a simple versioning scheme. The URLPathVersioning approach might be better suitable for small ad-hoc projects, and the NamespaceVersioning is probably easier to manage for larger projects. HostNameVersioning The hostname versioning scheme requires the client to specify the requested version as part of the hostname in the URL. For example the following is an HTTP request to the http://v1.example.com/bookings/ URL: GET /bookings/ HTTP/1.1
Host: v1.example.com
Accept: application/json
 By default this implementation expects the hostname to match this simple regular expression: ^([a-zA-Z0-9]+)\.[a-zA-Z0-9]+\.[a-zA-Z0-9]+$
 Note that the first group is enclosed in brackets, indicating that this is the matched portion of the hostname. The HostNameVersioning scheme can be awkward to use in debug mode as you will typically be accessing a raw IP address such as 127.0.0.1. There are various online tutorials on how to access localhost with a custom subdomain which you may find helpful in this case. Hostname based versioning can be particularly useful if you have requirements to route incoming requests to different servers based on the version, as you can configure different DNS records for different API versions. QueryParameterVersioning This scheme is a simple style that includes the version as a query parameter in the URL. For example: GET /something/?version=0.1 HTTP/1.1
Host: example.com
Accept: application/json
 Custom versioning schemes To implement a custom versioning scheme, subclass BaseVersioning and override the .determine_version method. Example The following example uses a custom X-API-Version header to determine the requested version. class XAPIVersionScheme(versioning.BaseVersioning):
    def determine_version(self, request, *args, **kwargs):
        return request.META.get('HTTP_X_API_VERSION', None)
 If your versioning scheme is based on the request URL, you will also want to alter how versioned URLs are determined. In order to do so you should override the .reverse() method on the class. See the source code for examples. versioning.py


Renderers  Before a TemplateResponse instance can be returned to the client, it must be rendered. The rendering process takes the intermediate representation of template and context, and turns it into the final byte stream that can be served to the client. — Django documentation  REST framework includes a number of built in Renderer classes, that allow you to return responses with various media types. There is also support for defining your own custom renderers, which gives you the flexibility to design your own media types. How the renderer is determined The set of valid renderers for a view is always defined as a list of classes. When a view is entered REST framework will perform content negotiation on the incoming request, and determine the most appropriate renderer to satisfy the request. The basic process of content negotiation involves examining the request's Accept header, to determine which media types it expects in the response. Optionally, format suffixes on the URL may be used to explicitly request a particular representation. For example the URL http://example.com/api/users_count.json might be an endpoint that always returns JSON data. For more information see the documentation on content negotiation. Setting the renderers The default set of renderers may be set globally, using the DEFAULT_RENDERER_CLASSES setting. For example, the following settings would use JSON as the main media type and also include the self describing API. REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ]
}
 You can also set the renderers used for an individual view, or viewset, using the APIView class-based views. from django.contrib.auth.models import User
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response
from rest_framework.views import APIView

class UserCountView(APIView):
    """
    A view that returns the count of active users in JSON.
    """
    renderer_classes = [JSONRenderer]

    def get(self, request, format=None):
        user_count = User.objects.filter(active=True).count()
        content = {'user_count': user_count}
        return Response(content)
 Or, if you're using the @api_view decorator with function based views. @api_view(['GET'])
@renderer_classes([JSONRenderer])
def user_count_view(request, format=None):
    """
    A view that returns the count of active users in JSON.
    """
    user_count = User.objects.filter(active=True).count()
    content = {'user_count': user_count}
    return Response(content)
 Ordering of renderer classes It's important when specifying the renderer classes for your API to think about what priority you want to assign to each media type. If a client underspecifies the representations it can accept, such as sending an Accept: */* header, or not including an Accept header at all, then REST framework will select the first renderer in the list to use for the response. For example if your API serves JSON responses and the HTML browsable API, you might want to make JSONRenderer your default renderer, in order to send JSON responses to clients that do not specify an Accept header. If your API includes views that can serve both regular webpages and API responses depending on the request, then you might consider making TemplateHTMLRenderer your default renderer, in order to play nicely with older browsers that send broken accept headers. API Reference JSONRenderer Renders the request data into JSON, using utf-8 encoding. Note that the default style is to include unicode characters, and render the response using a compact style with no unnecessary whitespace: {"unicode black star":"★","value":999}
 The client may additionally include an 'indent' media type parameter, in which case the returned JSON will be indented. For example Accept: application/json; indent=4. {
    "unicode black star": "★",
    "value": 999
}
 The default JSON encoding style can be altered using the UNICODE_JSON and COMPACT_JSON settings keys. .media_type: application/json .format: 'json' .charset: None TemplateHTMLRenderer Renders data to HTML, using Django's standard template rendering. Unlike other renderers, the data passed to the Response does not need to be serialized. Also, unlike other renderers, you may want to include a template_name argument when creating the Response. The TemplateHTMLRenderer will create a RequestContext, using the response.data as the context dict, and determine a template name to use to render the context. Note: When used with a view that makes use of a serializer the Response sent for rendering may not be a dictionary and will need to be wrapped in a dict before returning to allow the TemplateHTMLRenderer to render it. For example: response.data = {'results': response.data}
 The template name is determined by (in order of preference):  An explicit template_name argument passed to the response. An explicit .template_name attribute set on this class. The return result of calling view.get_template_names().  An example of a view that uses TemplateHTMLRenderer: class UserDetail(generics.RetrieveAPIView):
    """
    A view that returns a templated HTML representation of a given user.
    """
    queryset = User.objects.all()
    renderer_classes = [TemplateHTMLRenderer]

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        return Response({'user': self.object}, template_name='user_detail.html')
 You can use TemplateHTMLRenderer either to return regular HTML pages using REST framework, or to return both HTML and API responses from a single endpoint. If you're building websites that use TemplateHTMLRenderer along with other renderer classes, you should consider listing TemplateHTMLRenderer as the first class in the renderer_classes list, so that it will be prioritised first even for browsers that send poorly formed ACCEPT: headers. See the HTML & Forms Topic Page for further examples of TemplateHTMLRenderer usage. .media_type: text/html .format: 'html' .charset: utf-8 See also: StaticHTMLRenderer StaticHTMLRenderer A simple renderer that simply returns pre-rendered HTML. Unlike other renderers, the data passed to the response object should be a string representing the content to be returned. An example of a view that uses StaticHTMLRenderer: @api_view(['GET'])
@renderer_classes([StaticHTMLRenderer])
def simple_html_view(request):
    data = '
Hello, world
'
    return Response(data)
 You can use StaticHTMLRenderer either to return regular HTML pages using REST framework, or to return both HTML and API responses from a single endpoint. .media_type: text/html .format: 'html' .charset: utf-8 See also: TemplateHTMLRenderer BrowsableAPIRenderer Renders data into HTML for the Browsable API:  This renderer will determine which other renderer would have been given highest priority, and use that to display an API style response within the HTML page. .media_type: text/html .format: 'api' .charset: utf-8 .template: 'rest_framework/api.html' Customizing BrowsableAPIRenderer By default the response content will be rendered with the highest priority renderer apart from BrowsableAPIRenderer. If you need to customize this behavior, for example to use HTML as the default return format, but use JSON in the browsable API, you can do so by overriding the get_default_renderer() method. For example: class CustomBrowsableAPIRenderer(BrowsableAPIRenderer):
    def get_default_renderer(self, view):
        return JSONRenderer()
 AdminRenderer Renders data into HTML for an admin-like display:  This renderer is suitable for CRUD-style web APIs that should also present a user-friendly interface for managing the data. Note that views that have nested or list serializers for their input won't work well with the AdminRenderer, as the HTML forms are unable to properly support them. Note: The AdminRenderer is only able to include links to detail pages when a properly configured URL_FIELD_NAME (url by default) attribute is present in the data. For HyperlinkedModelSerializer this will be the case, but for ModelSerializer or plain Serializer classes you'll need to make sure to include the field explicitly. For example here we use models get_absolute_url method: class AccountSerializer(serializers.ModelSerializer):
    url = serializers.CharField(source='get_absolute_url', read_only=True)

    class Meta:
        model = Account
 .media_type: text/html .format: 'admin' .charset: utf-8 .template: 'rest_framework/admin.html' HTMLFormRenderer Renders data returned by a serializer into an HTML form. The output of this renderer does not include the enclosing <form> tags, a hidden CSRF input or any submit buttons. This renderer is not intended to be used directly, but can instead be used in templates by passing a serializer instance to the render_form template tag. {% load rest_framework %}

<form action="/submit-report/" method="post">
    {% csrf_token %}
    {% render_form serializer %}
    <input type="submit" value="Save" />
</form>
 For more information see the HTML & Forms documentation. .media_type: text/html .format: 'form' .charset: utf-8 .template: 'rest_framework/horizontal/form.html' MultiPartRenderer This renderer is used for rendering HTML multipart form data. It is not suitable as a response renderer, but is instead used for creating test requests, using REST framework's test client and test request factory. .media_type: multipart/form-data; boundary=BoUnDaRyStRiNg .format: 'multipart' .charset: utf-8 Custom renderers To implement a custom renderer, you should override BaseRenderer, set the .media_type and .format properties, and implement the .render(self, data, media_type=None, renderer_context=None) method. The method should return a bytestring, which will be used as the body of the HTTP response. The arguments passed to the .render() method are: data The request data, as set by the Response() instantiation. media_type=None Optional. If provided, this is the accepted media type, as determined by the content negotiation stage. Depending on the client's Accept: header, this may be more specific than the renderer's media_type attribute, and may include media type parameters. For example "application/json; nested=true". renderer_context=None Optional. If provided, this is a dictionary of contextual information provided by the view. By default this will include the following keys: view, request, response, args, kwargs. Example The following is an example plaintext renderer that will return a response with the data parameter as the content of the response. from django.utils.encoding import smart_text
from rest_framework import renderers

class PlainTextRenderer(renderers.BaseRenderer):
    media_type = 'text/plain'
    format = 'txt'

    def render(self, data, media_type=None, renderer_context=None):
        return smart_text(data, encoding=self.charset)
 Setting the character set By default renderer classes are assumed to be using the UTF-8 encoding. To use a different encoding, set the charset attribute on the renderer. class PlainTextRenderer(renderers.BaseRenderer):
    media_type = 'text/plain'
    format = 'txt'
    charset = 'iso-8859-1'

    def render(self, data, media_type=None, renderer_context=None):
        return data.encode(self.charset)
 Note that if a renderer class returns a unicode string, then the response content will be coerced into a bytestring by the Response class, with the charset attribute set on the renderer used to determine the encoding. If the renderer returns a bytestring representing raw binary content, you should set a charset value of None, which will ensure the Content-Type header of the response will not have a charset value set. In some cases you may also want to set the render_style attribute to 'binary'. Doing so will also ensure that the browsable API will not attempt to display the binary content as a string. class JPEGRenderer(renderers.BaseRenderer):
    media_type = 'image/jpeg'
    format = 'jpg'
    charset = None
    render_style = 'binary'

    def render(self, data, media_type=None, renderer_context=None):
        return data
 Advanced renderer usage You can do some pretty flexible things using REST framework's renderers. Some examples...  Provide either flat or nested representations from the same endpoint, depending on the requested media type. Serve both regular HTML webpages, and JSON based API responses from the same endpoints. Specify multiple types of HTML representation for API clients to use. Underspecify a renderer's media type, such as using media_type = 'image/*', and use the Accept header to vary the encoding of the response.  Varying behaviour by media type In some cases you might want your view to use different serialization styles depending on the accepted media type. If you need to do this you can access request.accepted_renderer to determine the negotiated renderer that will be used for the response. For example: @api_view(['GET'])
@renderer_classes([TemplateHTMLRenderer, JSONRenderer])
def list_users(request):
    """
    A view that can return JSON or HTML representations
    of the users in the system.
    """
    queryset = Users.objects.filter(active=True)

    if request.accepted_renderer.format == 'html':
        # TemplateHTMLRenderer takes a context dict,
        # and additionally requires a 'template_name'.
        # It does not require serialization.
        data = {'users': queryset}
        return Response(data, template_name='list_users.html')

    # JSONRenderer requires serialized data as normal.
    serializer = UserSerializer(instance=queryset)
    data = serializer.data
    return Response(data)
 Underspecifying the media type In some cases you might want a renderer to serve a range of media types. In this case you can underspecify the media types it should respond to, by using a media_type value such as image/*, or */*. If you underspecify the renderer's media type, you should make sure to specify the media type explicitly when you return the response, using the content_type attribute. For example: return Response(data, content_type='image/png')
 Designing your media types For the purposes of many Web APIs, simple JSON responses with hyperlinked relations may be sufficient. If you want to fully embrace RESTful design and HATEOAS you'll need to consider the design and usage of your media types in more detail. In the words of Roy Fielding, "A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types.". For good examples of custom media types, see GitHub's use of a custom application/vnd.github+json media type, and Mike Amundsen's IANA approved application/vnd.collection+json JSON-based hypermedia. HTML error views Typically a renderer will behave the same regardless of if it's dealing with a regular response, or with a response caused by an exception being raised, such as an Http404 or PermissionDenied exception, or a subclass of APIException. If you're using either the TemplateHTMLRenderer or the StaticHTMLRenderer and an exception is raised, the behavior is slightly different, and mirrors Django's default handling of error views. Exceptions raised and handled by an HTML renderer will attempt to render using one of the following methods, by order of precedence.  Load and render a template named {status_code}.html. Load and render a template named api_exception.html. Render the HTTP status code and text, for example "404 Not Found".  Templates will render with a RequestContext which includes the status_code and details keys. Note: If DEBUG=True, Django's standard traceback error page will be displayed instead of rendering the HTTP status code and text. Third party packages The following third party packages are also available. YAML REST framework YAML provides YAML parsing and rendering support. It was previously included directly in the REST framework package, and is now instead supported as a third-party package. Installation & configuration Install using pip. $ pip install djangorestframework-yaml
 Modify your REST framework settings. REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework_yaml.parsers.YAMLParser',
    ],
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework_yaml.renderers.YAMLRenderer',
    ],
}
 XML REST Framework XML provides a simple informal XML format. It was previously included directly in the REST framework package, and is now instead supported as a third-party package. Installation & configuration Install using pip. $ pip install djangorestframework-xml
 Modify your REST framework settings. REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework_xml.parsers.XMLParser',
    ],
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework_xml.renderers.XMLRenderer',
    ],
}
 JSONP REST framework JSONP provides JSONP rendering support. It was previously included directly in the REST framework package, and is now instead supported as a third-party package. Warning: If you require cross-domain AJAX requests, you should generally be using the more modern approach of CORS as an alternative to JSONP. See the CORS documentation for more details. The jsonp approach is essentially a browser hack, and is only appropriate for globally readable API endpoints, where GET requests are unauthenticated and do not require any user permissions. Installation & configuration Install using pip. $ pip install djangorestframework-jsonp
 Modify your REST framework settings. REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework_jsonp.renderers.JSONPRenderer',
    ],
}
 MessagePack MessagePack is a fast, efficient binary serialization format. Juan Riaza maintains the djangorestframework-msgpack package which provides MessagePack renderer and parser support for REST framework. XLSX (Binary Spreadsheet Endpoints) XLSX is the world's most popular binary spreadsheet format. Tim Allen of The Wharton School maintains drf-renderer-xlsx, which renders an endpoint as an XLSX spreadsheet using OpenPyXL, and allows the client to download it. Spreadsheets can be styled on a per-view basis. Installation & configuration Install using pip. $ pip install drf-renderer-xlsx
 Modify your REST framework settings. REST_FRAMEWORK = {
    ...

    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
        'drf_renderer_xlsx.renderers.XLSXRenderer',
    ],
}
 To avoid having a file streamed without a filename (which the browser will often default to the filename "download", with no extension), we need to use a mixin to override the Content-Disposition header. If no filename is provided, it will default to export.xlsx. For example: from rest_framework.viewsets import ReadOnlyModelViewSet
from drf_renderer_xlsx.mixins import XLSXFileMixin
from drf_renderer_xlsx.renderers import XLSXRenderer

from .models import MyExampleModel
from .serializers import MyExampleSerializer

class MyExampleViewSet(XLSXFileMixin, ReadOnlyModelViewSet):
    queryset = MyExampleModel.objects.all()
    serializer_class = MyExampleSerializer
    renderer_classes = [XLSXRenderer]
    filename = 'my_export.xlsx'
 CSV Comma-separated values are a plain-text tabular data format, that can be easily imported into spreadsheet applications. Mjumbe Poe maintains the djangorestframework-csv package which provides CSV renderer support for REST framework. UltraJSON UltraJSON is an optimized C JSON encoder which can give significantly faster JSON rendering. Adam Mertz maintains drf_ujson2, a fork of the now unmaintained drf-ujson-renderer, which implements JSON rendering using the UJSON package. CamelCase JSON djangorestframework-camel-case provides camel case JSON renderers and parsers for REST framework. This allows serializers to use Python-style underscored field names, but be exposed in the API as Javascript-style camel case field names. It is maintained by Vitaly Babiy. Pandas (CSV, Excel, PNG) Django REST Pandas provides a serializer and renderers that support additional data processing and output via the Pandas DataFrame API. Django REST Pandas includes renderers for Pandas-style CSV files, Excel workbooks (both .xls and .xlsx), and a number of other formats. It is maintained by S. Andrew Sheppard as part of the wq Project. LaTeX Rest Framework Latex provides a renderer that outputs PDFs using Laulatex. It is maintained by Pebble (S/F Software). renderers.py


Permissions  Authentication or identification by itself is not usually sufficient to gain access to information or code. For that, the entity requesting access must have authorization. — Apple Developer Documentation  Together with authentication and throttling, permissions determine whether a request should be granted or denied access. Permission checks are always run at the very start of the view, before any other code is allowed to proceed. Permission checks will typically use the authentication information in the request.user and request.auth properties to determine if the incoming request should be permitted. Permissions are used to grant or deny access for different classes of users to different parts of the API. The simplest style of permission would be to allow access to any authenticated user, and deny access to any unauthenticated user. This corresponds to the IsAuthenticated class in REST framework. A slightly less strict style of permission would be to allow full access to authenticated users, but allow read-only access to unauthenticated users. This corresponds to the IsAuthenticatedOrReadOnly class in REST framework. How permissions are determined Permissions in REST framework are always defined as a list of permission classes. Before running the main body of the view each permission in the list is checked. If any permission check fails an exceptions.PermissionDenied or exceptions.NotAuthenticated exception will be raised, and the main body of the view will not run. When the permissions checks fail either a "403 Forbidden" or a "401 Unauthorized" response will be returned, according to the following rules:  The request was successfully authenticated, but permission was denied. — An HTTP 403 Forbidden response will be returned.
 The request was not successfully authenticated, and the highest priority authentication class does not use WWW-Authenticate headers. — An HTTP 403 Forbidden response will be returned.
 The request was not successfully authenticated, and the highest priority authentication class does use WWW-Authenticate headers. — An HTTP 401 Unauthorized response, with an appropriate WWW-Authenticate header will be returned.
  Object level permissions REST framework permissions also support object-level permissioning. Object level permissions are used to determine if a user should be allowed to act on a particular object, which will typically be a model instance. Object level permissions are run by REST framework's generic views when .get_object() is called. As with view level permissions, an exceptions.PermissionDenied exception will be raised if the user is not allowed to act on the given object. If you're writing your own views and want to enforce object level permissions, or if you override the get_object method on a generic view, then you'll need to explicitly call the .check_object_permissions(request, obj) method on the view at the point at which you've retrieved the object. This will either raise a PermissionDenied or NotAuthenticated exception, or simply return if the view has the appropriate permissions. For example: def get_object(self):
    obj = get_object_or_404(self.get_queryset(), pk=self.kwargs["pk"])
    self.check_object_permissions(self.request, obj)
    return obj
 Note: With the exception of DjangoObjectPermissions, the provided permission classes in rest_framework.permissions do not implement the methods necessary to check object permissions. If you wish to use the provided permission classes in order to check object permissions, you must subclass them and implement the has_object_permission() method described in the Custom permissions section (below). Limitations of object level permissions For performance reasons the generic views will not automatically apply object level permissions to each instance in a queryset when returning a list of objects. Often when you're using object level permissions you'll also want to filter the queryset appropriately, to ensure that users only have visibility onto instances that they are permitted to view. Because the get_object() method is not called, object level permissions from the has_object_permission() method are not applied when creating objects. In order to restrict object creation you need to implement the permission check either in your Serializer class or override the perform_create() method of your ViewSet class. Setting the permission policy The default permission policy may be set globally, using the DEFAULT_PERMISSION_CLASSES setting. For example. REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ]
}
 If not specified, this setting defaults to allowing unrestricted access: 'DEFAULT_PERMISSION_CLASSES': [
   'rest_framework.permissions.AllowAny',
]
 You can also set the authentication policy on a per-view, or per-viewset basis, using the APIView class-based views. from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request, format=None):
        content = {
            'status': 'request was permitted'
        }
        return Response(content)
 Or, if you're using the @api_view decorator with function based views. from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def example_view(request, format=None):
    content = {
        'status': 'request was permitted'
    }
    return Response(content)
 Note: when you set new permission classes via the class attribute or decorators you're telling the view to ignore the default list set in the settings.py file. Provided they inherit from rest_framework.permissions.BasePermission, permissions can be composed using standard Python bitwise operators. For example, IsAuthenticatedOrReadOnly could be written: from rest_framework.permissions import BasePermission, IsAuthenticated, SAFE_METHODS
from rest_framework.response import Response
from rest_framework.views import APIView

class ReadOnly(BasePermission):
    def has_permission(self, request, view):
        return request.method in SAFE_METHODS

class ExampleView(APIView):
    permission_classes = [IsAuthenticated|ReadOnly]

    def get(self, request, format=None):
        content = {
            'status': 'request was permitted'
        }
        return Response(content)
 Note: it supports & (and), | (or) and ~ (not). API Reference AllowAny The AllowAny permission class will allow unrestricted access, regardless of if the request was authenticated or unauthenticated. This permission is not strictly required, since you can achieve the same result by using an empty list or tuple for the permissions setting, but you may find it useful to specify this class because it makes the intention explicit. IsAuthenticated The IsAuthenticated permission class will deny permission to any unauthenticated user, and allow permission otherwise. This permission is suitable if you want your API to only be accessible to registered users. IsAdminUser The IsAdminUser permission class will deny permission to any user, unless user.is_staff is True in which case permission will be allowed. This permission is suitable if you want your API to only be accessible to a subset of trusted administrators. IsAuthenticatedOrReadOnly The IsAuthenticatedOrReadOnly will allow authenticated users to perform any request. Requests for unauthorised users will only be permitted if the request method is one of the "safe" methods; GET, HEAD or OPTIONS. This permission is suitable if you want to your API to allow read permissions to anonymous users, and only allow write permissions to authenticated users. DjangoModelPermissions This permission class ties into Django's standard django.contrib.auth model permissions. This permission must only be applied to views that have a .queryset property or get_queryset() method. Authorization will only be granted if the user is authenticated and has the relevant model permissions assigned.
POST requests require the user to have the add permission on the model.
PUT and PATCH requests require the user to have the change permission on the model.
DELETE requests require the user to have the delete permission on the model.  The default behaviour can also be overridden to support custom model permissions. For example, you might want to include a view model permission for GET requests. To use custom model permissions, override DjangoModelPermissions and set the .perms_map property. Refer to the source code for details. DjangoModelPermissionsOrAnonReadOnly Similar to DjangoModelPermissions, but also allows unauthenticated users to have read-only access to the API. DjangoObjectPermissions This permission class ties into Django's standard object permissions framework that allows per-object permissions on models. In order to use this permission class, you'll also need to add a permission backend that supports object-level permissions, such as django-guardian. As with DjangoModelPermissions, this permission must only be applied to views that have a .queryset property or .get_queryset() method. Authorization will only be granted if the user is authenticated and has the relevant per-object permissions and relevant model permissions assigned.
POST requests require the user to have the add permission on the model instance.
PUT and PATCH requests require the user to have the change permission on the model instance.
DELETE requests require the user to have the delete permission on the model instance.  Note that DjangoObjectPermissions does not require the django-guardian package, and should support other object-level backends equally well. As with DjangoModelPermissions you can use custom model permissions by overriding DjangoObjectPermissions and setting the .perms_map property. Refer to the source code for details. Note: If you need object level view permissions for GET, HEAD and OPTIONS requests and are using django-guardian for your object-level permissions backend, you'll want to consider using the DjangoObjectPermissionsFilter class provided by the djangorestframework-guardian package. It ensures that list endpoints only return results including objects for which the user has appropriate view permissions. Custom permissions To implement a custom permission, override BasePermission and implement either, or both, of the following methods:  .has_permission(self, request, view) .has_object_permission(self, request, view, obj)  The methods should return True if the request should be granted access, and False otherwise. If you need to test if a request is a read operation or a write operation, you should check the request method against the constant SAFE_METHODS, which is a tuple containing 'GET', 'OPTIONS' and 'HEAD'. For example: if request.method in permissions.SAFE_METHODS:
    # Check permissions for read-only request
else:
    # Check permissions for write request
 Note: The instance-level has_object_permission method will only be called if the view-level has_permission checks have already passed. Also note that in order for the instance-level checks to run, the view code should explicitly call .check_object_permissions(request, obj). If you are using the generic views then this will be handled for you by default. (Function-based views will need to check object permissions explicitly, raising PermissionDenied on failure.) Custom permissions will raise a PermissionDenied exception if the test fails. To change the error message associated with the exception, implement a message attribute directly on your custom permission. Otherwise the default_detail attribute from PermissionDenied will be used. Similarly, to change the code identifier associated with the exception, implement a code attribute directly on your custom permission - otherwise the default_code attribute from PermissionDenied will be used. from rest_framework import permissions

class CustomerAccessPermission(permissions.BasePermission):
    message = 'Adding customers not allowed.'

    def has_permission(self, request, view):
         ...
 Examples The following is an example of a permission class that checks the incoming request's IP address against a blocklist, and denies the request if the IP has been blocked. from rest_framework import permissions

class BlocklistPermission(permissions.BasePermission):
    """
    Global permission check for blocked IPs.
    """

    def has_permission(self, request, view):
        ip_addr = request.META['REMOTE_ADDR']
        blocked = Blocklist.objects.filter(ip_addr=ip_addr).exists()
        return not blocked
 As well as global permissions, that are run against all incoming requests, you can also create object-level permissions, that are only run against operations that affect a particular object instance. For example: class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    Object-level permission to only allow owners of an object to edit it.
    Assumes the model instance has an `owner` attribute.
    """

    def has_object_permission(self, request, view, obj):
        # Read permissions are allowed to any request,
        # so we'll always allow GET, HEAD or OPTIONS requests.
        if request.method in permissions.SAFE_METHODS:
            return True

        # Instance must have an attribute named `owner`.
        return obj.owner == request.user
 Note that the generic views will check the appropriate object level permissions, but if you're writing your own custom views, you'll need to make sure you check the object level permission checks yourself. You can do so by calling self.check_object_permissions(request, obj) from the view once you have the object instance. This call will raise an appropriate APIException if any object-level permission checks fail, and will otherwise simply return. Also note that the generic views will only check the object-level permissions for views that retrieve a single model instance. If you require object-level filtering of list views, you'll need to filter the queryset separately. See the filtering documentation for more details. Overview of access restriction methods REST framework offers three different methods to customize access restrictions on a case-by-case basis. These apply in different scenarios and have different effects and limitations.
queryset/get_queryset(): Limits the general visibility of existing objects from the database. The queryset limits which objects will be listed and which objects can be modified or deleted. The get_queryset() method can apply different querysets based on the current action.
permission_classes/get_permissions(): General permission checks based on the current action, request and targeted object. Object level permissions can only be applied to retrieve, modify and deletion actions. Permission checks for list and create will be applied to the entire object type. (In case of list: subject to restrictions in the queryset.)
serializer_class/get_serializer(): Instance level restrictions that apply to all objects on input and output. The serializer may have access to the request context. The get_serializer() method can apply different serializers based on the current action.  The following table lists the access restriction methods and the level of control they offer over which actions.     queryset permission_classes serializer_class     Action: list global no object-level*   Action: create no global object-level   Action: retrieve global object-level object-level   Action: update global object-level object-level   Action: partial_update global object-level object-level   Action: destroy global object-level no   Can reference action in decision no** yes no**   Can reference request in decision no** yes yes    * A Serializer class should not raise PermissionDenied in a list action, or the entire list would not be returned.  ** The get_*() methods have access to the current view and can return different Serializer or QuerySet instances based on the request or action. Third party packages The following third party packages are also available. DRF - Access Policy The Django REST - Access Policy package provides a way to define complex access rules in declarative policy classes that are attached to view sets or function-based views. The policies are defined in JSON in a format similar to AWS' Identity & Access Management policies.  Composed Permissions The Composed Permissions package provides a simple way to define complex and multi-depth (with logic operators) permission objects, using small and reusable components. REST Condition The REST Condition package is another extension for building complex permissions in a simple and convenient way. The extension allows you to combine permissions with logical operators. DRY Rest Permissions The DRY Rest Permissions package provides the ability to define different permissions for individual default and custom actions. This package is made for apps with permissions that are derived from relationships defined in the app's data model. It also supports permission checks being returned to a client app through the API's serializer. Additionally it supports adding permissions to the default and custom list actions to restrict the data they retrieve per user. Django Rest Framework Roles The Django Rest Framework Roles package makes it easier to parameterize your API over multiple types of users. Django REST Framework API Key The Django REST Framework API Key package provides permissions classes, models and helpers to add API key authorization to your API. It can be used to authorize internal or third-party backends and services (i.e. machines) which do not have a user account. API keys are stored securely using Django's password hashing infrastructure, and they can be viewed, edited and revoked at anytime in the Django admin. Django Rest Framework Role Filters The Django Rest Framework Role Filters package provides simple filtering over multiple types of roles. Django Rest Framework PSQ The Django Rest Framework PSQ package is an extension that gives support for having action-based permission_classes, serializer_class, and queryset dependent on permission-based rules. permissions.py


Throttling  HTTP/1.1 420 Enhance Your Calm Twitter API rate limiting response  Throttling is similar to permissions, in that it determines if a request should be authorized. Throttles indicate a temporary state, and are used to control the rate of requests that clients can make to an API. As with permissions, multiple throttles may be used. Your API might have a restrictive throttle for unauthenticated requests, and a less restrictive throttle for authenticated requests. Another scenario where you might want to use multiple throttles would be if you need to impose different constraints on different parts of the API, due to some services being particularly resource-intensive. Multiple throttles can also be used if you want to impose both burst throttling rates, and sustained throttling rates. For example, you might want to limit a user to a maximum of 60 requests per minute, and 1000 requests per day. Throttles do not necessarily only refer to rate-limiting requests. For example a storage service might also need to throttle against bandwidth, and a paid data service might want to throttle against a certain number of a records being accessed. How throttling is determined As with permissions and authentication, throttling in REST framework is always defined as a list of classes. Before running the main body of the view each throttle in the list is checked. If any throttle check fails an exceptions.Throttled exception will be raised, and the main body of the view will not run. Setting the throttling policy The default throttling policy may be set globally, using the DEFAULT_THROTTLE_CLASSES and DEFAULT_THROTTLE_RATES settings. For example. REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/day',
        'user': '1000/day'
    }
}
 The rate descriptions used in DEFAULT_THROTTLE_RATES may include second, minute, hour or day as the throttle period. You can also set the throttling policy on a per-view or per-viewset basis, using the APIView class-based views. from rest_framework.response import Response
from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView

class ExampleView(APIView):
    throttle_classes = [UserRateThrottle]

    def get(self, request, format=None):
        content = {
            'status': 'request was permitted'
        }
        return Response(content)
 If you're using the @api_view decorator with function based views you can use the following decorator. @api_view(['GET'])
@throttle_classes([UserRateThrottle])
def example_view(request, format=None):
    content = {
        'status': 'request was permitted'
    }
    return Response(content)
 It's also possible to set throttle classes for routes that are created using the @action decorator. Throttle classes set in this way will override any viewset level class settings. @action(detail=True, methods=["post"], throttle_classes=[UserRateThrottle])
def example_adhoc_method(request, pk=None):
    content = {
        'status': 'request was permitted'
    }
    return Response(content)
 How clients are identified The X-Forwarded-For HTTP header and REMOTE_ADDR WSGI variable are used to uniquely identify client IP addresses for throttling. If the X-Forwarded-For header is present then it will be used, otherwise the value of the REMOTE_ADDR variable from the WSGI environment will be used. If you need to strictly identify unique client IP addresses, you'll need to first configure the number of application proxies that the API runs behind by setting the NUM_PROXIES setting. This setting should be an integer of zero or more. If set to non-zero then the client IP will be identified as being the last IP address in the X-Forwarded-For header, once any application proxy IP addresses have first been excluded. If set to zero, then the REMOTE_ADDR value will always be used as the identifying IP address. It is important to understand that if you configure the NUM_PROXIES setting, then all clients behind a unique NAT'd gateway will be treated as a single client. Further context on how the X-Forwarded-For header works, and identifying a remote client IP can be found here. Setting up the cache The throttle classes provided by REST framework use Django's cache backend. You should make sure that you've set appropriate cache settings. The default value of LocMemCache backend should be okay for simple setups. See Django's cache documentation for more details. If you need to use a cache other than 'default', you can do so by creating a custom throttle class and setting the cache attribute. For example: from django.core.cache import caches

class CustomAnonRateThrottle(AnonRateThrottle):
    cache = caches['alternate']
 You'll need to remember to also set your custom throttle class in the 'DEFAULT_THROTTLE_CLASSES' settings key, or using the throttle_classes view attribute. API Reference AnonRateThrottle The AnonRateThrottle will only ever throttle unauthenticated users. The IP address of the incoming request is used to generate a unique key to throttle against. The allowed request rate is determined from one of the following (in order of preference).  The rate property on the class, which may be provided by overriding AnonRateThrottle and setting the property. The DEFAULT_THROTTLE_RATES['anon'] setting.  AnonRateThrottle is suitable if you want to restrict the rate of requests from unknown sources. UserRateThrottle The UserRateThrottle will throttle users to a given rate of requests across the API. The user id is used to generate a unique key to throttle against. Unauthenticated requests will fall back to using the IP address of the incoming request to generate a unique key to throttle against. The allowed request rate is determined from one of the following (in order of preference).  The rate property on the class, which may be provided by overriding UserRateThrottle and setting the property. The DEFAULT_THROTTLE_RATES['user'] setting.  An API may have multiple UserRateThrottles in place at the same time. To do so, override UserRateThrottle and set a unique "scope" for each class. For example, multiple user throttle rates could be implemented by using the following classes... class BurstRateThrottle(UserRateThrottle):
    scope = 'burst'

class SustainedRateThrottle(UserRateThrottle):
    scope = 'sustained'
 ...and the following settings. REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'example.throttles.BurstRateThrottle',
        'example.throttles.SustainedRateThrottle'
    ],
    'DEFAULT_THROTTLE_RATES': {
        'burst': '60/min',
        'sustained': '1000/day'
    }
}
 UserRateThrottle is suitable if you want simple global rate restrictions per-user. ScopedRateThrottle The ScopedRateThrottle class can be used to restrict access to specific parts of the API. This throttle will only be applied if the view that is being accessed includes a .throttle_scope property. The unique throttle key will then be formed by concatenating the "scope" of the request with the unique user id or IP address. The allowed request rate is determined by the DEFAULT_THROTTLE_RATES setting using a key from the request "scope". For example, given the following views... class ContactListView(APIView):
    throttle_scope = 'contacts'
    ...

class ContactDetailView(APIView):
    throttle_scope = 'contacts'
    ...

class UploadView(APIView):
    throttle_scope = 'uploads'
    ...
 ...and the following settings. REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.ScopedRateThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        'contacts': '1000/day',
        'uploads': '20/day'
    }
}
 User requests to either ContactListView or ContactDetailView would be restricted to a total of 1000 requests per-day. User requests to UploadView would be restricted to 20 requests per day. Custom throttles To create a custom throttle, override BaseThrottle and implement .allow_request(self, request, view). The method should return True if the request should be allowed, and False otherwise. Optionally you may also override the .wait() method. If implemented, .wait() should return a recommended number of seconds to wait before attempting the next request, or None. The .wait() method will only be called if .allow_request() has previously returned False. If the .wait() method is implemented and the request is throttled, then a Retry-After header will be included in the response. Example The following is an example of a rate throttle, that will randomly throttle 1 in every 10 requests. import random

class RandomRateThrottle(throttling.BaseThrottle):
    def allow_request(self, request, view):
        return random.randint(1, 10) != 1
 throttling.py


Exceptions  Exceptions… allow error handling to be organized cleanly in a central or high-level place within the program structure. — Doug Hellmann, Python Exception Handling Techniques  Exception handling in REST framework views REST framework's views handle various exceptions, and deal with returning appropriate error responses. The handled exceptions are:  Subclasses of APIException raised inside REST framework. Django's Http404 exception. Django's PermissionDenied exception.  In each case, REST framework will return a response with an appropriate status code and content-type. The body of the response will include any additional details regarding the nature of the error. Most error responses will include a key detail in the body of the response. For example, the following request: DELETE http://api.example.com/foo/bar HTTP/1.1
Accept: application/json
 Might receive an error response indicating that the DELETE method is not allowed on that resource: HTTP/1.1 405 Method Not Allowed
Content-Type: application/json
Content-Length: 42

{"detail": "Method 'DELETE' not allowed."}
 Validation errors are handled slightly differently, and will include the field names as the keys in the response. If the validation error was not specific to a particular field then it will use the "non_field_errors" key, or whatever string value has been set for the NON_FIELD_ERRORS_KEY setting. An example validation error might look like this: HTTP/1.1 400 Bad Request
Content-Type: application/json
Content-Length: 94

{"amount": ["A valid integer is required."], "description": ["This field may not be blank."]}
 Custom exception handling You can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API. The function must take a pair of arguments, the first is the exception to be handled, and the second is a dictionary containing any extra context such as the view currently being handled. The exception handler function should either return a Response object, or return None if the exception cannot be handled. If the handler returns None then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response. For example, you might want to ensure that all error responses include the HTTP status code in the body of the response, like so: HTTP/1.1 405 Method Not Allowed
Content-Type: application/json
Content-Length: 62

{"status_code": 405, "detail": "Method 'DELETE' not allowed."}
 In order to alter the style of the response, you could write the following custom exception handler: from rest_framework.views import exception_handler

def custom_exception_handler(exc, context):
    # Call REST framework's default exception handler first,
    # to get the standard error response.
    response = exception_handler(exc, context)

    # Now add the HTTP status code to the response.
    if response is not None:
        response.data['status_code'] = response.status_code

    return response
 The context argument is not used by the default handler, but can be useful if the exception handler needs further information such as the view currently being handled, which can be accessed as context['view']. The exception handler must also be configured in your settings, using the EXCEPTION_HANDLER setting key. For example: REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
}
 If not specified, the 'EXCEPTION_HANDLER' setting defaults to the standard exception handler provided by REST framework: REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'
}
 Note that the exception handler will only be called for responses generated by raised exceptions. It will not be used for any responses returned directly by the view, such as the HTTP_400_BAD_REQUEST responses that are returned by the generic views when serializer validation fails. API Reference APIException Signature: APIException() The base class for all exceptions raised inside an APIView class or @api_view. To provide a custom exception, subclass APIException and set the .status_code, .default_detail, and default_code attributes on the class. For example, if your API relies on a third party service that may sometimes be unreachable, you might want to implement an exception for the "503 Service Unavailable" HTTP response code. You could do this like so: from rest_framework.exceptions import APIException

class ServiceUnavailable(APIException):
    status_code = 503
    default_detail = 'Service temporarily unavailable, try again later.'
    default_code = 'service_unavailable'
 Inspecting API exceptions There are a number of different properties available for inspecting the status of an API exception. You can use these to build custom exception handling for your project. The available attributes and methods are:
.detail - Return the textual description of the error.
.get_codes() - Return the code identifier of the error.
.get_full_details() - Return both the textual description and the code identifier.  In most cases the error detail will be a simple item: >>> print(exc.detail)
You do not have permission to perform this action.
>>> print(exc.get_codes())
permission_denied
>>> print(exc.get_full_details())
{'message':'You do not have permission to perform this action.','code':'permission_denied'}
 In the case of validation errors the error detail will be either a list or dictionary of items: >>> print(exc.detail)
{"name":"This field is required.","age":"A valid integer is required."}
>>> print(exc.get_codes())
{"name":"required","age":"invalid"}
>>> print(exc.get_full_details())
{"name":{"message":"This field is required.","code":"required"},"age":{"message":"A valid integer is required.","code":"invalid"}}
 ParseError Signature: ParseError(detail=None, code=None) Raised if the request contains malformed data when accessing request.data. By default this exception results in a response with the HTTP status code "400 Bad Request". AuthenticationFailed Signature: AuthenticationFailed(detail=None, code=None) Raised when an incoming request includes incorrect authentication. By default this exception results in a response with the HTTP status code "401 Unauthenticated", but it may also result in a "403 Forbidden" response, depending on the authentication scheme in use. See the authentication documentation for more details. NotAuthenticated Signature: NotAuthenticated(detail=None, code=None) Raised when an unauthenticated request fails the permission checks. By default this exception results in a response with the HTTP status code "401 Unauthenticated", but it may also result in a "403 Forbidden" response, depending on the authentication scheme in use. See the authentication documentation for more details. PermissionDenied Signature: PermissionDenied(detail=None, code=None) Raised when an authenticated request fails the permission checks. By default this exception results in a response with the HTTP status code "403 Forbidden". NotFound Signature: NotFound(detail=None, code=None) Raised when a resource does not exists at the given URL. This exception is equivalent to the standard Http404 Django exception. By default this exception results in a response with the HTTP status code "404 Not Found". MethodNotAllowed Signature: MethodNotAllowed(method, detail=None, code=None) Raised when an incoming request occurs that does not map to a handler method on the view. By default this exception results in a response with the HTTP status code "405 Method Not Allowed". NotAcceptable Signature: NotAcceptable(detail=None, code=None) Raised when an incoming request occurs with an Accept header that cannot be satisfied by any of the available renderers. By default this exception results in a response with the HTTP status code "406 Not Acceptable". UnsupportedMediaType Signature: UnsupportedMediaType(media_type, detail=None, code=None) Raised if there are no parsers that can handle the content type of the request data when accessing request.data. By default this exception results in a response with the HTTP status code "415 Unsupported Media Type". Throttled Signature: Throttled(wait=None, detail=None, code=None) Raised when an incoming request fails the throttling checks. By default this exception results in a response with the HTTP status code "429 Too Many Requests". ValidationError Signature: ValidationError(detail, code=None) The ValidationError exception is slightly different from the other APIException classes:  The detail argument is mandatory, not optional. The detail argument may be a list or dictionary of error details, and may also be a nested data structure. By using a dictionary, you can specify field-level errors while performing object-level validation in the validate() method of a serializer. For example. raise serializers.ValidationError({'name': 'Please enter a valid name.'})
 By convention you should import the serializers module and use a fully qualified ValidationError style, in order to differentiate it from Django's built-in validation error. For example. raise serializers.ValidationError('This field must be an integer value.')
  The ValidationError class should be used for serializer and field validation, and by validator classes. It is also raised when calling serializer.is_valid with the raise_exception keyword argument: serializer.is_valid(raise_exception=True)
 The generic views use the raise_exception=True flag, which means that you can override the style of validation error responses globally in your API. To do so, use a custom exception handler, as described above. By default this exception results in a response with the HTTP status code "400 Bad Request". Generic Error Views Django REST Framework provides two error views suitable for providing generic JSON 500 Server Error and 400 Bad Request responses. (Django's default error views provide HTML responses, which may not be appropriate for an API-only application.) Use these as per Django's Customizing error views documentation. rest_framework.exceptions.server_error Returns a response with status code 500 and application/json content type. Set as handler500: handler500 = 'rest_framework.exceptions.server_error'
 rest_framework.exceptions.bad_request Returns a response with status code 400 and application/json content type. Set as handler400: handler400 = 'rest_framework.exceptions.bad_request'
 exceptions.py