fastapi-startkit 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fastapi_startkit/__init__.py +3 -0
- fastapi_startkit/application.py +40 -0
- fastapi_startkit/configuration/Configuration.py +80 -0
- fastapi_startkit/configuration/__init__.py +2 -0
- fastapi_startkit/configuration/helpers.py +5 -0
- fastapi_startkit/configuration/providers/ConfigurationProvider.py +16 -0
- fastapi_startkit/configuration/providers/__init__.py +1 -0
- fastapi_startkit/container/__init__.py +1 -0
- fastapi_startkit/container/container.py +494 -0
- fastapi_startkit/environment/environment.py +76 -0
- fastapi_startkit/exceptions/DD.py +38 -0
- fastapi_startkit/exceptions/ExceptionHandler.py +76 -0
- fastapi_startkit/exceptions/__init__.py +38 -0
- fastapi_startkit/exceptions/exceptionite/__init__.py +0 -0
- fastapi_startkit/exceptions/exceptionite/blocks.py +101 -0
- fastapi_startkit/exceptions/exceptionite/controllers.py +13 -0
- fastapi_startkit/exceptions/exceptionite/solutions.py +66 -0
- fastapi_startkit/exceptions/exceptionite/tabs.py +19 -0
- fastapi_startkit/exceptions/exceptions.py +218 -0
- fastapi_startkit/exceptions/handlers/DumpExceptionHandler.py +104 -0
- fastapi_startkit/exceptions/handlers/HttpExceptionHandler.py +28 -0
- fastapi_startkit/exceptions/handlers/ModelNotFoundHandler.py +13 -0
- fastapi_startkit/facades/Auth.py +5 -0
- fastapi_startkit/facades/Auth.pyi +32 -0
- fastapi_startkit/facades/Broadcast.py +5 -0
- fastapi_startkit/facades/Cache.py +5 -0
- fastapi_startkit/facades/Config.py +5 -0
- fastapi_startkit/facades/Config.pyi +14 -0
- fastapi_startkit/facades/Dump.py +5 -0
- fastapi_startkit/facades/Dump.pyi +26 -0
- fastapi_startkit/facades/Facade.py +5 -0
- fastapi_startkit/facades/Gate.py +5 -0
- fastapi_startkit/facades/Gate.pyi +32 -0
- fastapi_startkit/facades/Hash.py +5 -0
- fastapi_startkit/facades/Hash.pyi +28 -0
- fastapi_startkit/facades/Loader.py +5 -0
- fastapi_startkit/facades/Loader.pyi +30 -0
- fastapi_startkit/facades/Mail.py +5 -0
- fastapi_startkit/facades/Mail.pyi +14 -0
- fastapi_startkit/facades/Notification.py +5 -0
- fastapi_startkit/facades/Notification.pyi +25 -0
- fastapi_startkit/facades/Queue.py +5 -0
- fastapi_startkit/facades/Queue.pyi +10 -0
- fastapi_startkit/facades/RateLimiter.py +5 -0
- fastapi_startkit/facades/RateLimiter.pyi +43 -0
- fastapi_startkit/facades/Request.py +5 -0
- fastapi_startkit/facades/Request.pyi +88 -0
- fastapi_startkit/facades/Response.py +5 -0
- fastapi_startkit/facades/Response.pyi +68 -0
- fastapi_startkit/facades/Session.py +5 -0
- fastapi_startkit/facades/Session.pyi +59 -0
- fastapi_startkit/facades/Storage.py +5 -0
- fastapi_startkit/facades/Storage.pyi +12 -0
- fastapi_startkit/facades/Url.py +5 -0
- fastapi_startkit/facades/Url.pyi +22 -0
- fastapi_startkit/facades/View.py +5 -0
- fastapi_startkit/facades/View.pyi +54 -0
- fastapi_startkit/facades/__init__.py +19 -0
- fastapi_startkit/loader/Loader.py +78 -0
- fastapi_startkit/loader/__init__.py +1 -0
- fastapi_startkit/providers/ConfigurationProvider.py +13 -0
- fastapi_startkit/providers/Provider.py +14 -0
- fastapi_startkit/providers/__init__.py +4 -0
- fastapi_startkit/utils/__init__.py +0 -0
- fastapi_startkit/utils/collections.py +545 -0
- fastapi_startkit/utils/console.py +39 -0
- fastapi_startkit/utils/data/mime.types +1863 -0
- fastapi_startkit/utils/filesystem.py +100 -0
- fastapi_startkit/utils/http.py +101 -0
- fastapi_startkit/utils/location.py +90 -0
- fastapi_startkit/utils/str.py +120 -0
- fastapi_startkit/utils/structures.py +97 -0
- fastapi_startkit/utils/time.py +58 -0
- fastapi_startkit-0.1.0.dist-info/METADATA +13 -0
- fastapi_startkit-0.1.0.dist-info/RECORD +76 -0
- fastapi_startkit-0.1.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Module for the LoadEnvironment class."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class LoadEnvironment:
|
|
9
|
+
"""This class is used for loading the environment from .env and .env.* files."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, environment=None, override=True, only=None, base_path=None):
|
|
12
|
+
"""LoadEnvironment constructor.
|
|
13
|
+
|
|
14
|
+
Keyword Arguments:
|
|
15
|
+
env {string} -- An additional environment file that you want to load. (default: {None})
|
|
16
|
+
override {bool} -- Whether or not the environment variables found should overwrite existing ones. (default: {False})
|
|
17
|
+
only {string} -- If this is set then it will only load that environment. (default: {None})
|
|
18
|
+
base_path {string} -- The base path to look for the environment file. (default: {None})
|
|
19
|
+
"""
|
|
20
|
+
from dotenv import load_dotenv
|
|
21
|
+
|
|
22
|
+
self.env = load_dotenv
|
|
23
|
+
self.base_path = Path(base_path) if base_path else Path(".")
|
|
24
|
+
|
|
25
|
+
if only:
|
|
26
|
+
self._load_environment(only, override=override)
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
env_path = str(self.base_path / ".env")
|
|
30
|
+
self.env(env_path, override=override)
|
|
31
|
+
|
|
32
|
+
if os.environ.get("APP_ENV"):
|
|
33
|
+
self._load_environment(os.environ.get("APP_ENV"), override=override)
|
|
34
|
+
if environment:
|
|
35
|
+
self._load_environment(environment, override=override)
|
|
36
|
+
|
|
37
|
+
if "PYTEST_CURRENT_TEST" in os.environ:
|
|
38
|
+
self._load_environment("testing", override=override)
|
|
39
|
+
|
|
40
|
+
def _load_environment(self, environment, override=False):
|
|
41
|
+
"""Load the environment depending on the env file.
|
|
42
|
+
|
|
43
|
+
Arguments:
|
|
44
|
+
environment {string} -- Name of the environment file to load from
|
|
45
|
+
|
|
46
|
+
Keyword Arguments:
|
|
47
|
+
override {bool} -- Whether the environment file should overwrite existing environment keys. (default: {False})
|
|
48
|
+
"""
|
|
49
|
+
env_path = str(self.base_path / f".env.{environment}")
|
|
50
|
+
self.env(dotenv_path=env_path, override=override)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def env(value, default="", cast=True):
|
|
54
|
+
"""Helper to retrieve the value of an environment variable or returns
|
|
55
|
+
a default value. In addition, if type can be inferred then the value can be casted to the
|
|
56
|
+
inferred type."""
|
|
57
|
+
env_var = os.getenv(value, default)
|
|
58
|
+
|
|
59
|
+
if not cast:
|
|
60
|
+
return env_var
|
|
61
|
+
|
|
62
|
+
if env_var == "":
|
|
63
|
+
env_var = default
|
|
64
|
+
|
|
65
|
+
if isinstance(env_var, bool):
|
|
66
|
+
return env_var
|
|
67
|
+
elif env_var is None:
|
|
68
|
+
return None
|
|
69
|
+
elif env_var.isnumeric():
|
|
70
|
+
return int(env_var)
|
|
71
|
+
elif env_var in ("false", "False"):
|
|
72
|
+
return False
|
|
73
|
+
elif env_var in ("true", "True"):
|
|
74
|
+
return True
|
|
75
|
+
else:
|
|
76
|
+
return env_var
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
import warnings
|
|
3
|
+
|
|
4
|
+
from .exceptions import DumpException
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
warnings.warn(
|
|
8
|
+
"DD class will be removed in Masonite 5. Please use Dump facade instead.",
|
|
9
|
+
DeprecationWarning,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class DD:
|
|
14
|
+
def __init__(self, container):
|
|
15
|
+
self.app = container
|
|
16
|
+
|
|
17
|
+
def die_and_dump(self, *args):
|
|
18
|
+
"""Dump all provided args and die, ie raise a DumpException."""
|
|
19
|
+
self.dump(*args)
|
|
20
|
+
raise DumpException
|
|
21
|
+
|
|
22
|
+
def dump(self, *args):
|
|
23
|
+
"""Dump all provided args and let flow continue. This does not raise a DumpException."""
|
|
24
|
+
print(
|
|
25
|
+
inspect.stack()[1].function,
|
|
26
|
+
inspect.stack()[1].filename,
|
|
27
|
+
inspect.stack()[1].lineno,
|
|
28
|
+
)
|
|
29
|
+
if self.app.has("ObjDumpList"):
|
|
30
|
+
dump_list = self.app.make("ObjDumpList")
|
|
31
|
+
else:
|
|
32
|
+
dump_list = []
|
|
33
|
+
start = len(dump_list)
|
|
34
|
+
for i, obj in enumerate(args):
|
|
35
|
+
dump_name = f"ObjDump{start + i}"
|
|
36
|
+
self.app.bind(dump_name, obj)
|
|
37
|
+
dump_list.append(dump_name)
|
|
38
|
+
self.app.bind("ObjDumpList", dump_list)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
class ExceptionHandler:
|
|
2
|
+
def __init__(self, application, driver_config=None):
|
|
3
|
+
self.application = application
|
|
4
|
+
self.drivers = {}
|
|
5
|
+
self.driver_config = driver_config or {}
|
|
6
|
+
self.options = {}
|
|
7
|
+
|
|
8
|
+
def set_options(self, options):
|
|
9
|
+
self.options = options
|
|
10
|
+
return self
|
|
11
|
+
|
|
12
|
+
def add_driver(self, name, driver):
|
|
13
|
+
self.drivers.update({name: driver})
|
|
14
|
+
|
|
15
|
+
def set_configuration(self, config):
|
|
16
|
+
self.driver_config = config
|
|
17
|
+
return self
|
|
18
|
+
|
|
19
|
+
def get_driver(self, name=None):
|
|
20
|
+
if name is None:
|
|
21
|
+
return self.drivers[self.driver_config.get("default")]
|
|
22
|
+
return self.drivers[name]
|
|
23
|
+
|
|
24
|
+
def get_config_options(self, driver=None):
|
|
25
|
+
if driver is None:
|
|
26
|
+
return self.driver_config[self.driver_config.get("default")]
|
|
27
|
+
|
|
28
|
+
return self.driver_config.get(driver, {})
|
|
29
|
+
|
|
30
|
+
def handle(self, exception):
|
|
31
|
+
response = self.application.make("response")
|
|
32
|
+
request = self.application.make("request")
|
|
33
|
+
|
|
34
|
+
self.application.make("event").fire(
|
|
35
|
+
f"masonite.exception.{exception.__class__.__name__}", exception
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# add headers to response if any
|
|
39
|
+
if hasattr(exception, "get_headers"):
|
|
40
|
+
headers = exception.get_headers()
|
|
41
|
+
response.with_headers(headers)
|
|
42
|
+
|
|
43
|
+
# if an exception handler is registered for this exception, use it instead
|
|
44
|
+
# add headers to response if any
|
|
45
|
+
if hasattr(exception, "get_headers"):
|
|
46
|
+
headers = exception.get_headers()
|
|
47
|
+
response.with_headers(headers)
|
|
48
|
+
|
|
49
|
+
if self.application.has(f"{exception.__class__.__name__}Handler"):
|
|
50
|
+
return self.application.make(
|
|
51
|
+
f"{exception.__class__.__name__}Handler"
|
|
52
|
+
).handle(exception)
|
|
53
|
+
|
|
54
|
+
# handle exception in production
|
|
55
|
+
if not self.application.is_debug():
|
|
56
|
+
# for HTTP error codes (500, 404, 403...) a specific page should be displayed
|
|
57
|
+
# if a renderable exception is raised let it be displayed
|
|
58
|
+
if hasattr(exception, "is_http_exception") or hasattr(
|
|
59
|
+
exception, "get_response"
|
|
60
|
+
):
|
|
61
|
+
return self.application.make("HttpExceptionHandler").handle(exception)
|
|
62
|
+
|
|
63
|
+
# else fallback to an unknown exception that should be displayed as a 500 error
|
|
64
|
+
exception.get_status = lambda: 500
|
|
65
|
+
exception.get_response = lambda: str(exception) or "Unknown error"
|
|
66
|
+
return self.application.make("HttpExceptionHandler").handle(exception)
|
|
67
|
+
|
|
68
|
+
# handle exception in development mode with Exceptionite
|
|
69
|
+
exceptionite = self.get_driver("exceptionite")
|
|
70
|
+
exceptionite.start(exception)
|
|
71
|
+
exceptionite.render("terminal")
|
|
72
|
+
|
|
73
|
+
if request.accepts_json():
|
|
74
|
+
return response.view(exceptionite.render("json"), status=500)
|
|
75
|
+
else:
|
|
76
|
+
return response.view(exceptionite.render("web"), status=500)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from .ExceptionHandler import ExceptionHandler
|
|
2
|
+
from .handlers.DumpExceptionHandler import DumpExceptionHandler
|
|
3
|
+
from .handlers.HttpExceptionHandler import HttpExceptionHandler
|
|
4
|
+
from .handlers.ModelNotFoundHandler import ModelNotFoundHandler
|
|
5
|
+
from .DD import DD
|
|
6
|
+
from .exceptions import (
|
|
7
|
+
AuthorizationException,
|
|
8
|
+
InvalidRouteCompileException,
|
|
9
|
+
RouteMiddlewareNotFound,
|
|
10
|
+
ContainerError,
|
|
11
|
+
MissingContainerBindingNotFound,
|
|
12
|
+
StrictContainerException,
|
|
13
|
+
ResponseError,
|
|
14
|
+
InvalidHTTPStatusCode,
|
|
15
|
+
RequiredContainerBindingNotFound,
|
|
16
|
+
ViewException,
|
|
17
|
+
RouteNotFoundException,
|
|
18
|
+
DumpException,
|
|
19
|
+
InvalidSecretKey,
|
|
20
|
+
InvalidCSRFToken,
|
|
21
|
+
NotificationException,
|
|
22
|
+
InvalidToken,
|
|
23
|
+
ProjectLimitReached,
|
|
24
|
+
ProjectProviderTimeout,
|
|
25
|
+
ProjectProviderHttpError,
|
|
26
|
+
ProjectTargetNotEmpty,
|
|
27
|
+
MixFileNotFound,
|
|
28
|
+
MixManifestNotFound,
|
|
29
|
+
InvalidConfigurationLocation,
|
|
30
|
+
InvalidConfigurationSetup,
|
|
31
|
+
InvalidPackageName,
|
|
32
|
+
LoaderNotFound,
|
|
33
|
+
QueueException,
|
|
34
|
+
AmbiguousError,
|
|
35
|
+
MethodNotAllowedException,
|
|
36
|
+
ModelNotFoundException,
|
|
37
|
+
ThrottleRequestsException,
|
|
38
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from exceptionite import Block
|
|
2
|
+
|
|
3
|
+
from ... import __version__
|
|
4
|
+
from ...helpers import optional
|
|
5
|
+
from ...utils.str import get_controller_name
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def recursive_serializer(data):
|
|
9
|
+
if isinstance(data, (int, bool, str, bytes)):
|
|
10
|
+
return data
|
|
11
|
+
elif isinstance(data, (list, tuple)):
|
|
12
|
+
return [recursive_serializer(item) for item in data]
|
|
13
|
+
elif isinstance(data, dict):
|
|
14
|
+
return {key: recursive_serializer(val) for key, val in data.items()}
|
|
15
|
+
elif callable(data):
|
|
16
|
+
return str(data)
|
|
17
|
+
elif hasattr(data, "serialize"):
|
|
18
|
+
return data.serialize()
|
|
19
|
+
else:
|
|
20
|
+
return str(data)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class AppBlock(Block):
|
|
24
|
+
id = "application"
|
|
25
|
+
name = "Application"
|
|
26
|
+
icon = "DesktopComputerIcon"
|
|
27
|
+
has_sections = True
|
|
28
|
+
|
|
29
|
+
def build(self):
|
|
30
|
+
request = self.handler.app.make("request")
|
|
31
|
+
route = request.get_route()
|
|
32
|
+
|
|
33
|
+
data = {
|
|
34
|
+
"Info": {
|
|
35
|
+
"Masonite Version": __version__,
|
|
36
|
+
"Environment": self.handler.app.environment(),
|
|
37
|
+
"Debug": self.handler.app.is_debug(),
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# add app route data
|
|
42
|
+
if route:
|
|
43
|
+
data.update(
|
|
44
|
+
{
|
|
45
|
+
"Route": {
|
|
46
|
+
"Controller": get_controller_name(route.controller),
|
|
47
|
+
"Name": route.get_name(),
|
|
48
|
+
"Middlewares": route.get_middlewares(),
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
# add user route data
|
|
54
|
+
user = request.user()
|
|
55
|
+
if user:
|
|
56
|
+
data.update(
|
|
57
|
+
{
|
|
58
|
+
"User": {
|
|
59
|
+
"E-mail": optional(user).email,
|
|
60
|
+
"ID": optional(user).id,
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
return data
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class RequestBlock(Block):
|
|
69
|
+
id = "request"
|
|
70
|
+
name = "Request"
|
|
71
|
+
icon = "SwitchHorizontalIcon"
|
|
72
|
+
has_sections = True
|
|
73
|
+
|
|
74
|
+
def build(self):
|
|
75
|
+
request = self.handler.app.make("request")
|
|
76
|
+
# serialize inputs (e.g. in case of file)
|
|
77
|
+
inputs = {}
|
|
78
|
+
for name, value in request.all().items():
|
|
79
|
+
inputs[name] = recursive_serializer(value)
|
|
80
|
+
return {
|
|
81
|
+
"Parameters": {
|
|
82
|
+
"Path": request.get_path(),
|
|
83
|
+
"Input": inputs or None,
|
|
84
|
+
"Request Method": request.get_request_method(),
|
|
85
|
+
},
|
|
86
|
+
"Headers": request.header_bag.to_dict(),
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class ConfigBlock(Block):
|
|
91
|
+
id = "config"
|
|
92
|
+
name = "Configuration"
|
|
93
|
+
icon = "CogIcon"
|
|
94
|
+
has_sections = True
|
|
95
|
+
|
|
96
|
+
def build(self):
|
|
97
|
+
data = {}
|
|
98
|
+
for section, config_data in self.handler.app.make("config").all().items():
|
|
99
|
+
section_name = section.title()
|
|
100
|
+
data[section_name] = recursive_serializer(config_data)
|
|
101
|
+
return data
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from ...request import Request
|
|
2
|
+
from ...controllers import Controller
|
|
3
|
+
from ...response import Response
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ExceptioniteController(Controller):
|
|
7
|
+
def run_action(self, request: Request, response: Response):
|
|
8
|
+
handler = request.app.make("exception_handler").get_driver("exceptionite")
|
|
9
|
+
data = handler.run_action(request.input("action_id"), request.input("options"))
|
|
10
|
+
try:
|
|
11
|
+
return response.json({"message": "ok", "data": data}, 200)
|
|
12
|
+
except: # noqa: E722
|
|
13
|
+
return response.json({"message": "An error happened", "data": data}, 400)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
class TableNotFound:
|
|
2
|
+
def title(self):
|
|
3
|
+
return "Table Not Found"
|
|
4
|
+
|
|
5
|
+
def description(self):
|
|
6
|
+
return "You are trying to make a query on a table that cannot be found. Check that :table migration exists and that migrations have been ran with 'python craft migrate' command."
|
|
7
|
+
|
|
8
|
+
def regex(self):
|
|
9
|
+
return r"no such table: (?P<table>(\w+))"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MissingCSRFToken:
|
|
13
|
+
def title(self):
|
|
14
|
+
return "Missing CSRF Token"
|
|
15
|
+
|
|
16
|
+
def description(self):
|
|
17
|
+
return "You are trying to make a sensitive request without providing a CSRF token. Your request might be vulnerable to Cross Site Request Forgery. To resolve this issue you should use {{ csrf_field }} in HTML forms or add X-CSRF-TOKEN header in AJAX requests."
|
|
18
|
+
|
|
19
|
+
def regex(self):
|
|
20
|
+
return r"Missing CSRF Token"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class InvalidCSRFToken:
|
|
24
|
+
def title(self):
|
|
25
|
+
return "The session does not match the CSRF token"
|
|
26
|
+
|
|
27
|
+
def description(self):
|
|
28
|
+
return "Try clearing your cookies for the localhost domain in your browsers developer tools."
|
|
29
|
+
|
|
30
|
+
def regex(self):
|
|
31
|
+
return r"Invalid CSRF Token"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class TemplateNotFound:
|
|
35
|
+
def title(self):
|
|
36
|
+
return "Template Not Found"
|
|
37
|
+
|
|
38
|
+
def description(self):
|
|
39
|
+
return """':template.html' view file has not been found in registered view locations. Please verify the spelling of the template and that it exists in locations declared in Kernel file. You can check
|
|
40
|
+
available view locations with app.make('view.locations')."""
|
|
41
|
+
|
|
42
|
+
def regex(self):
|
|
43
|
+
return r"Template '(?P<template>(\w+))' not found"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class NoneResponse:
|
|
47
|
+
def title(self):
|
|
48
|
+
return "Response cannot be None"
|
|
49
|
+
|
|
50
|
+
def description(self):
|
|
51
|
+
return """Ensure that the controller method used in this request returned something. A controller method cannot return None or nothing.
|
|
52
|
+
If you don't want to return a value you can return an empty string ''."""
|
|
53
|
+
|
|
54
|
+
def regex(self):
|
|
55
|
+
return r"Responses cannot be of type: None."
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class RouteMiddlewareNotFound:
|
|
59
|
+
def title(self):
|
|
60
|
+
return "Did you register the middleware key in your Kernel.py file?"
|
|
61
|
+
|
|
62
|
+
def description(self):
|
|
63
|
+
return "Check your Kernel.py file inside your 'route_middleware' attribute and look for a :middleware key"
|
|
64
|
+
|
|
65
|
+
def regex(self):
|
|
66
|
+
return r"Could not find the \'(?P<middleware>(\w+))\' middleware key"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from exceptionite import Tab
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class DumpsTab(Tab):
|
|
5
|
+
id = "dumps"
|
|
6
|
+
name = "Dumps"
|
|
7
|
+
component = "DumpsTab"
|
|
8
|
+
icon = "CodeIcon"
|
|
9
|
+
advertise_content = True
|
|
10
|
+
empty_msg = "Nothing dumped !"
|
|
11
|
+
|
|
12
|
+
def build(self):
|
|
13
|
+
dumps = self.handler.app.make("dumper").get_serialized_dumps()
|
|
14
|
+
return {
|
|
15
|
+
"dumps": dumps,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
def has_content(self):
|
|
19
|
+
return len(self.handler.app.make("dumper").get_dumps()) > 0
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
class DriverNotFound(Exception):
|
|
2
|
+
pass
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DriverLibraryNotFound(Exception):
|
|
6
|
+
pass
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FileTypeException(Exception):
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class RequiredContainerBindingNotFound(Exception):
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class MissingContainerBindingNotFound(Exception):
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class UnacceptableDriverType(Exception):
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ContainerError(Exception):
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class InvalidCSRFToken(Exception):
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class InvalidHTTPStatusCode(Exception):
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class RouteMiddlewareNotFound(Exception):
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ResponseError(Exception):
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class InvalidAutoloadPath(Exception):
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class AutoloadContainerOverwrite(Exception):
|
|
50
|
+
pass
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class InvalidSecretKey(Exception):
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class InvalidToken(Exception):
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class StrictContainerException(Exception):
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class InvalidRouteCompileException(Exception):
|
|
66
|
+
pass
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class RouteException(Exception):
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class RouteNotFoundException(Exception):
|
|
74
|
+
is_http_exception = True
|
|
75
|
+
|
|
76
|
+
def __init__(self, message):
|
|
77
|
+
super().__init__(message)
|
|
78
|
+
self.message = message or "Route Not Found"
|
|
79
|
+
|
|
80
|
+
def get_response(self):
|
|
81
|
+
return self.message
|
|
82
|
+
|
|
83
|
+
def get_status(self):
|
|
84
|
+
return 404
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class MethodNotAllowedException(Exception):
|
|
88
|
+
is_http_exception = True
|
|
89
|
+
|
|
90
|
+
def __init__(self, allowed_methods, method):
|
|
91
|
+
allowed_list = ", ".join(allowed_methods)
|
|
92
|
+
message = f"{method} method not allowed for this route. Supported methods are: {allowed_list}."
|
|
93
|
+
super().__init__(message)
|
|
94
|
+
self.message = message
|
|
95
|
+
self.headers = {"Allow": allowed_list}
|
|
96
|
+
|
|
97
|
+
def get_response(self):
|
|
98
|
+
return self.message
|
|
99
|
+
|
|
100
|
+
def get_headers(self):
|
|
101
|
+
return self.headers
|
|
102
|
+
|
|
103
|
+
def get_status(self):
|
|
104
|
+
return 405
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class DebugException(Exception):
|
|
108
|
+
pass
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class DumpException(Exception):
|
|
112
|
+
pass
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class ViewException(Exception):
|
|
116
|
+
pass
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class QueueException(Exception):
|
|
120
|
+
pass
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class AmbiguousError(Exception):
|
|
124
|
+
pass
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class ProjectLimitReached(Exception):
|
|
128
|
+
pass
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class ProjectProviderTimeout(Exception):
|
|
132
|
+
pass
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class ProjectProviderHttpError(Exception):
|
|
136
|
+
pass
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class ProjectTargetNotEmpty(Exception):
|
|
140
|
+
pass
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class NotificationException(Exception):
|
|
144
|
+
pass
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class ModelNotFoundException(Exception):
|
|
148
|
+
is_http_exception = True
|
|
149
|
+
|
|
150
|
+
def get_response(self):
|
|
151
|
+
return "Model Not Found"
|
|
152
|
+
|
|
153
|
+
def get_status(self):
|
|
154
|
+
return 404
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class AuthorizationException(Exception):
|
|
158
|
+
is_http_exception = True
|
|
159
|
+
|
|
160
|
+
def __init__(self, message="", status=403):
|
|
161
|
+
super().__init__(message)
|
|
162
|
+
self.message = message or "Action not authorized"
|
|
163
|
+
self.status = status or 403
|
|
164
|
+
|
|
165
|
+
def get_response(self):
|
|
166
|
+
return self.message
|
|
167
|
+
|
|
168
|
+
def get_status(self):
|
|
169
|
+
return self.status
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class ThrottleRequestsException(Exception):
|
|
173
|
+
def __init__(self, message="Too many attempts", status=429, headers={}):
|
|
174
|
+
super().__init__(message)
|
|
175
|
+
self.message = message
|
|
176
|
+
self.status = status
|
|
177
|
+
self.headers = headers
|
|
178
|
+
|
|
179
|
+
def get_headers(self):
|
|
180
|
+
return self.headers
|
|
181
|
+
|
|
182
|
+
def get_response(self):
|
|
183
|
+
return self.message
|
|
184
|
+
|
|
185
|
+
def get_status(self):
|
|
186
|
+
return self.status
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class GateDoesNotExist(Exception):
|
|
190
|
+
pass
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class PolicyDoesNotExist(Exception):
|
|
194
|
+
pass
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
class MixManifestNotFound(Exception):
|
|
198
|
+
pass
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class MixFileNotFound(Exception):
|
|
202
|
+
pass
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class InvalidConfigurationLocation(Exception):
|
|
206
|
+
pass
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
class InvalidConfigurationSetup(Exception):
|
|
210
|
+
pass
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class InvalidPackageName(Exception):
|
|
214
|
+
pass
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
class LoaderNotFound(Exception):
|
|
218
|
+
pass
|