Remove submodule, just put Dependencies in ./libs
This commit is contained in:
@@ -0,0 +1,460 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
werkzeug.exceptions
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This module implements a number of Python exceptions you can raise from
|
||||
within your views to trigger a standard non-200 response.
|
||||
|
||||
|
||||
Usage Example
|
||||
-------------
|
||||
|
||||
::
|
||||
|
||||
from werkzeug.wrappers import BaseRequest
|
||||
from werkzeug.wsgi import responder
|
||||
from werkzeug.exceptions import HTTPException, NotFound
|
||||
|
||||
def view(request):
|
||||
raise NotFound()
|
||||
|
||||
@responder
|
||||
def application(environ, start_response):
|
||||
request = BaseRequest(environ)
|
||||
try:
|
||||
return view(request)
|
||||
except HTTPException, e:
|
||||
return e
|
||||
|
||||
|
||||
As you can see from this example those exceptions are callable WSGI
|
||||
applications. Because of Python 2.4 compatibility those do not extend
|
||||
from the response objects but only from the python exception class.
|
||||
|
||||
As a matter of fact they are not Werkzeug response objects. However you
|
||||
can get a response object by calling ``get_response()`` on a HTTP
|
||||
exception.
|
||||
|
||||
Keep in mind that you have to pass an environment to ``get_response()``
|
||||
because some errors fetch additional information from the WSGI
|
||||
environment.
|
||||
|
||||
If you want to hook in a different exception page to say, a 404 status
|
||||
code, you can add a second except for a specific subclass of an error::
|
||||
|
||||
@responder
|
||||
def application(environ, start_response):
|
||||
request = BaseRequest(environ)
|
||||
try:
|
||||
return view(request)
|
||||
except NotFound, e:
|
||||
return not_found(request)
|
||||
except HTTPException, e:
|
||||
return e
|
||||
|
||||
|
||||
:copyright: (c) 2010 by the Werkzeug Team, see AUTHORS for more details.
|
||||
:license: BSD, see LICENSE for more details.
|
||||
"""
|
||||
import sys
|
||||
from werkzeug._internal import HTTP_STATUS_CODES, _get_environ
|
||||
|
||||
|
||||
class HTTPException(Exception):
|
||||
"""
|
||||
Baseclass for all HTTP exceptions. This exception can be called as WSGI
|
||||
application to render a default error page or you can catch the subclasses
|
||||
of it independently and render nicer error messages.
|
||||
"""
|
||||
|
||||
code = None
|
||||
description = None
|
||||
|
||||
def __init__(self, description=None):
|
||||
Exception.__init__(self, '%d %s' % (self.code, self.name))
|
||||
if description is not None:
|
||||
self.description = description
|
||||
|
||||
@classmethod
|
||||
def wrap(cls, exception, name=None):
|
||||
"""This method returns a new subclass of the exception provided that
|
||||
also is a subclass of `BadRequest`.
|
||||
"""
|
||||
class newcls(cls, exception):
|
||||
def __init__(self, arg=None, description=None):
|
||||
cls.__init__(self, description)
|
||||
exception.__init__(self, arg)
|
||||
newcls.__module__ = sys._getframe(1).f_globals.get('__name__')
|
||||
newcls.__name__ = name or cls.__name__ + exception.__name__
|
||||
return newcls
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""The status name."""
|
||||
return HTTP_STATUS_CODES[self.code]
|
||||
|
||||
def get_description(self, environ):
|
||||
"""Get the description."""
|
||||
environ = _get_environ(environ)
|
||||
return self.description
|
||||
|
||||
def get_body(self, environ):
|
||||
"""Get the HTML body."""
|
||||
return (
|
||||
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n'
|
||||
'<title>%(code)s %(name)s</title>\n'
|
||||
'<h1>%(name)s</h1>\n'
|
||||
'%(description)s\n'
|
||||
) % {
|
||||
'code': self.code,
|
||||
'name': escape(self.name),
|
||||
'description': self.get_description(environ)
|
||||
}
|
||||
|
||||
def get_headers(self, environ):
|
||||
"""Get a list of headers."""
|
||||
return [('Content-Type', 'text/html')]
|
||||
|
||||
def get_response(self, environ):
|
||||
"""Get a response object.
|
||||
|
||||
:param environ: the environ for the request.
|
||||
:return: a :class:`BaseResponse` object or a subclass thereof.
|
||||
"""
|
||||
# lazily imported for various reasons. For one, we can use the exceptions
|
||||
# with custom responses (testing exception instances against types) and
|
||||
# so we don't ever have to import the wrappers, but also because there
|
||||
# are circular dependencies when bootstrapping the module.
|
||||
environ = _get_environ(environ)
|
||||
from werkzeug.wrappers import BaseResponse
|
||||
headers = self.get_headers(environ)
|
||||
return BaseResponse(self.get_body(environ), self.code, headers)
|
||||
|
||||
def __call__(self, environ, start_response):
|
||||
"""Call the exception as WSGI application.
|
||||
|
||||
:param environ: the WSGI environment.
|
||||
:param start_response: the response callable provided by the WSGI
|
||||
server.
|
||||
"""
|
||||
response = self.get_response(environ)
|
||||
return response(environ, start_response)
|
||||
|
||||
def __str__(self):
|
||||
return unicode(self).encode('utf-8')
|
||||
|
||||
def __unicode__(self):
|
||||
if 'description' in self.__dict__:
|
||||
txt = self.description
|
||||
else:
|
||||
txt = self.name
|
||||
return '%d: %s' % (self.code, txt)
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s \'%s\'>' % (self.__class__.__name__, self)
|
||||
|
||||
|
||||
class _ProxyException(HTTPException):
|
||||
"""An HTTP exception that expands renders a WSGI application on error."""
|
||||
|
||||
def __init__(self, response):
|
||||
Exception.__init__(self, 'proxy exception for %r' % response)
|
||||
self.response = response
|
||||
|
||||
def get_response(self, environ):
|
||||
return self.response
|
||||
|
||||
|
||||
class BadRequest(HTTPException):
|
||||
"""*400* `Bad Request`
|
||||
|
||||
Raise if the browser sends something to the application the application
|
||||
or server cannot handle.
|
||||
"""
|
||||
code = 400
|
||||
description = (
|
||||
'<p>The browser (or proxy) sent a request that this server could '
|
||||
'not understand.</p>'
|
||||
)
|
||||
|
||||
|
||||
class Unauthorized(HTTPException):
|
||||
"""*401* `Unauthorized`
|
||||
|
||||
Raise if the user is not authorized. Also used if you want to use HTTP
|
||||
basic auth.
|
||||
"""
|
||||
code = 401
|
||||
description = (
|
||||
'<p>The server could not verify that you are authorized to access '
|
||||
'the URL requested. You either supplied the wrong credentials (e.g. '
|
||||
'a bad password), or your browser doesn\'t understand how to supply '
|
||||
'the credentials required.</p><p>In case you are allowed to request '
|
||||
'the document, please check your user-id and password and try '
|
||||
'again.</p>'
|
||||
)
|
||||
|
||||
|
||||
class Forbidden(HTTPException):
|
||||
"""*403* `Forbidden`
|
||||
|
||||
Raise if the user doesn't have the permission for the requested resource
|
||||
but was authenticated.
|
||||
"""
|
||||
code = 403
|
||||
description = (
|
||||
'<p>You don\'t have the permission to access the requested resource. '
|
||||
'It is either read-protected or not readable by the server.</p>'
|
||||
)
|
||||
|
||||
|
||||
class NotFound(HTTPException):
|
||||
"""*404* `Not Found`
|
||||
|
||||
Raise if a resource does not exist and never existed.
|
||||
"""
|
||||
code = 404
|
||||
description = (
|
||||
'<p>The requested URL was not found on the server.</p>'
|
||||
'<p>If you entered the URL manually please check your spelling and '
|
||||
'try again.</p>'
|
||||
)
|
||||
|
||||
|
||||
class MethodNotAllowed(HTTPException):
|
||||
"""*405* `Method Not Allowed`
|
||||
|
||||
Raise if the server used a method the resource does not handle. For
|
||||
example `POST` if the resource is view only. Especially useful for REST.
|
||||
|
||||
The first argument for this exception should be a list of allowed methods.
|
||||
Strictly speaking the response would be invalid if you don't provide valid
|
||||
methods in the header which you can do with that list.
|
||||
"""
|
||||
code = 405
|
||||
|
||||
def __init__(self, valid_methods=None, description=None):
|
||||
"""Takes an optional list of valid http methods
|
||||
starting with werkzeug 0.3 the list will be mandatory."""
|
||||
HTTPException.__init__(self, description)
|
||||
self.valid_methods = valid_methods
|
||||
|
||||
def get_headers(self, environ):
|
||||
headers = HTTPException.get_headers(self, environ)
|
||||
if self.valid_methods:
|
||||
headers.append(('Allow', ', '.join(self.valid_methods)))
|
||||
return headers
|
||||
|
||||
def get_description(self, environ):
|
||||
m = escape(environ.get('REQUEST_METHOD', 'GET'))
|
||||
return '<p>The method %s is not allowed for the requested URL.</p>' % m
|
||||
|
||||
|
||||
class NotAcceptable(HTTPException):
|
||||
"""*406* `Not Acceptable`
|
||||
|
||||
Raise if the server can't return any content conforming to the
|
||||
`Accept` headers of the client.
|
||||
"""
|
||||
code = 406
|
||||
|
||||
description = (
|
||||
'<p>The resource identified by the request is only capable of '
|
||||
'generating response entities which have content characteristics '
|
||||
'not acceptable according to the accept headers sent in the '
|
||||
'request.</p>'
|
||||
)
|
||||
|
||||
|
||||
class RequestTimeout(HTTPException):
|
||||
"""*408* `Request Timeout`
|
||||
|
||||
Raise to signalize a timeout.
|
||||
"""
|
||||
code = 408
|
||||
description = (
|
||||
'<p>The server closed the network connection because the browser '
|
||||
'didn\'t finish the request within the specified time.</p>'
|
||||
)
|
||||
|
||||
|
||||
class Gone(HTTPException):
|
||||
"""*410* `Gone`
|
||||
|
||||
Raise if a resource existed previously and went away without new location.
|
||||
"""
|
||||
code = 410
|
||||
description = (
|
||||
'<p>The requested URL is no longer available on this server and '
|
||||
'there is no forwarding address.</p><p>If you followed a link '
|
||||
'from a foreign page, please contact the author of this page.'
|
||||
)
|
||||
|
||||
|
||||
class LengthRequired(HTTPException):
|
||||
"""*411* `Length Required`
|
||||
|
||||
Raise if the browser submitted data but no ``Content-Length`` header which
|
||||
is required for the kind of processing the server does.
|
||||
"""
|
||||
code = 411
|
||||
description = (
|
||||
'<p>A request with this method requires a valid <code>Content-'
|
||||
'Length</code> header.</p>'
|
||||
)
|
||||
|
||||
|
||||
class PreconditionFailed(HTTPException):
|
||||
"""*412* `Precondition Failed`
|
||||
|
||||
Status code used in combination with ``If-Match``, ``If-None-Match``, or
|
||||
``If-Unmodified-Since``.
|
||||
"""
|
||||
code = 412
|
||||
description = (
|
||||
'<p>The precondition on the request for the URL failed positive '
|
||||
'evaluation.</p>'
|
||||
)
|
||||
|
||||
|
||||
class RequestEntityTooLarge(HTTPException):
|
||||
"""*413* `Request Entity Too Large`
|
||||
|
||||
The status code one should return if the data submitted exceeded a given
|
||||
limit.
|
||||
"""
|
||||
code = 413
|
||||
description = (
|
||||
'<p>The data value transmitted exceeds the capacity limit.</p>'
|
||||
)
|
||||
|
||||
|
||||
class RequestURITooLarge(HTTPException):
|
||||
"""*414* `Request URI Too Large`
|
||||
|
||||
Like *413* but for too long URLs.
|
||||
"""
|
||||
code = 414
|
||||
description = (
|
||||
'<p>The length of the requested URL exceeds the capacity limit '
|
||||
'for this server. The request cannot be processed.</p>'
|
||||
)
|
||||
|
||||
|
||||
class UnsupportedMediaType(HTTPException):
|
||||
"""*415* `Unsupported Media Type`
|
||||
|
||||
The status code returned if the server is unable to handle the media type
|
||||
the client transmitted.
|
||||
"""
|
||||
code = 415
|
||||
description = (
|
||||
'<p>The server does not support the media type transmitted in '
|
||||
'the request.</p>'
|
||||
)
|
||||
|
||||
|
||||
class InternalServerError(HTTPException):
|
||||
"""*500* `Internal Server Error`
|
||||
|
||||
Raise if an internal server error occurred. This is a good fallback if an
|
||||
unknown error occurred in the dispatcher.
|
||||
"""
|
||||
code = 500
|
||||
description = (
|
||||
'<p>The server encountered an internal error and was unable to '
|
||||
'complete your request. Either the server is overloaded or there '
|
||||
'is an error in the application.</p>'
|
||||
)
|
||||
|
||||
|
||||
class NotImplemented(HTTPException):
|
||||
"""*501* `Not Implemented`
|
||||
|
||||
Raise if the application does not support the action requested by the
|
||||
browser.
|
||||
"""
|
||||
code = 501
|
||||
description = (
|
||||
'<p>The server does not support the action requested by the '
|
||||
'browser.</p>'
|
||||
)
|
||||
|
||||
|
||||
class BadGateway(HTTPException):
|
||||
"""*502* `Bad Gateway`
|
||||
|
||||
If you do proxying in your application you should return this status code
|
||||
if you received an invalid response from the upstream server it accessed
|
||||
in attempting to fulfill the request.
|
||||
"""
|
||||
code = 502
|
||||
description = (
|
||||
'<p>The proxy server received an invalid response from an upstream '
|
||||
'server.</p>'
|
||||
)
|
||||
|
||||
|
||||
class ServiceUnavailable(HTTPException):
|
||||
"""*503* `Service Unavailable`
|
||||
|
||||
Status code you should return if a service is temporarily unavailable.
|
||||
"""
|
||||
code = 503
|
||||
description = (
|
||||
'<p>The server is temporarily unable to service your request due to '
|
||||
'maintenance downtime or capacity problems. Please try again '
|
||||
'later.</p>'
|
||||
)
|
||||
|
||||
|
||||
default_exceptions = {}
|
||||
__all__ = ['HTTPException']
|
||||
|
||||
def _find_exceptions():
|
||||
for name, obj in globals().iteritems():
|
||||
try:
|
||||
if getattr(obj, 'code', None) is not None:
|
||||
default_exceptions[obj.code] = obj
|
||||
__all__.append(obj.__name__)
|
||||
except TypeError: # pragma: no cover
|
||||
continue
|
||||
_find_exceptions()
|
||||
del _find_exceptions
|
||||
|
||||
|
||||
#: raised by the request functions if they were unable to decode the
|
||||
#: incoming data properly.
|
||||
HTTPUnicodeError = BadRequest.wrap(UnicodeError, 'HTTPUnicodeError')
|
||||
|
||||
|
||||
class Aborter(object):
|
||||
"""
|
||||
When passed a dict of code -> exception items it can be used as
|
||||
callable that raises exceptions. If the first argument to the
|
||||
callable is an integer it will be looked up in the mapping, if it's
|
||||
a WSGI application it will be raised in a proxy exception.
|
||||
|
||||
The rest of the arguments are forwarded to the exception constructor.
|
||||
"""
|
||||
|
||||
def __init__(self, mapping=None, extra=None):
|
||||
if mapping is None:
|
||||
mapping = default_exceptions
|
||||
self.mapping = dict(mapping)
|
||||
if extra is not None:
|
||||
self.mapping.update(extra)
|
||||
|
||||
def __call__(self, code, *args, **kwargs):
|
||||
if not args and not kwargs and not isinstance(code, (int, long)):
|
||||
raise _ProxyException(code)
|
||||
if code not in self.mapping:
|
||||
raise LookupError('no exception for %r' % code)
|
||||
raise self.mapping[code](*args, **kwargs)
|
||||
|
||||
abort = Aborter()
|
||||
|
||||
|
||||
# imported here because of circular dependencies of werkzeug.utils
|
||||
from werkzeug.utils import escape
|
||||
Reference in New Issue
Block a user