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.
Files changed (76) hide show
  1. fastapi_startkit/__init__.py +3 -0
  2. fastapi_startkit/application.py +40 -0
  3. fastapi_startkit/configuration/Configuration.py +80 -0
  4. fastapi_startkit/configuration/__init__.py +2 -0
  5. fastapi_startkit/configuration/helpers.py +5 -0
  6. fastapi_startkit/configuration/providers/ConfigurationProvider.py +16 -0
  7. fastapi_startkit/configuration/providers/__init__.py +1 -0
  8. fastapi_startkit/container/__init__.py +1 -0
  9. fastapi_startkit/container/container.py +494 -0
  10. fastapi_startkit/environment/environment.py +76 -0
  11. fastapi_startkit/exceptions/DD.py +38 -0
  12. fastapi_startkit/exceptions/ExceptionHandler.py +76 -0
  13. fastapi_startkit/exceptions/__init__.py +38 -0
  14. fastapi_startkit/exceptions/exceptionite/__init__.py +0 -0
  15. fastapi_startkit/exceptions/exceptionite/blocks.py +101 -0
  16. fastapi_startkit/exceptions/exceptionite/controllers.py +13 -0
  17. fastapi_startkit/exceptions/exceptionite/solutions.py +66 -0
  18. fastapi_startkit/exceptions/exceptionite/tabs.py +19 -0
  19. fastapi_startkit/exceptions/exceptions.py +218 -0
  20. fastapi_startkit/exceptions/handlers/DumpExceptionHandler.py +104 -0
  21. fastapi_startkit/exceptions/handlers/HttpExceptionHandler.py +28 -0
  22. fastapi_startkit/exceptions/handlers/ModelNotFoundHandler.py +13 -0
  23. fastapi_startkit/facades/Auth.py +5 -0
  24. fastapi_startkit/facades/Auth.pyi +32 -0
  25. fastapi_startkit/facades/Broadcast.py +5 -0
  26. fastapi_startkit/facades/Cache.py +5 -0
  27. fastapi_startkit/facades/Config.py +5 -0
  28. fastapi_startkit/facades/Config.pyi +14 -0
  29. fastapi_startkit/facades/Dump.py +5 -0
  30. fastapi_startkit/facades/Dump.pyi +26 -0
  31. fastapi_startkit/facades/Facade.py +5 -0
  32. fastapi_startkit/facades/Gate.py +5 -0
  33. fastapi_startkit/facades/Gate.pyi +32 -0
  34. fastapi_startkit/facades/Hash.py +5 -0
  35. fastapi_startkit/facades/Hash.pyi +28 -0
  36. fastapi_startkit/facades/Loader.py +5 -0
  37. fastapi_startkit/facades/Loader.pyi +30 -0
  38. fastapi_startkit/facades/Mail.py +5 -0
  39. fastapi_startkit/facades/Mail.pyi +14 -0
  40. fastapi_startkit/facades/Notification.py +5 -0
  41. fastapi_startkit/facades/Notification.pyi +25 -0
  42. fastapi_startkit/facades/Queue.py +5 -0
  43. fastapi_startkit/facades/Queue.pyi +10 -0
  44. fastapi_startkit/facades/RateLimiter.py +5 -0
  45. fastapi_startkit/facades/RateLimiter.pyi +43 -0
  46. fastapi_startkit/facades/Request.py +5 -0
  47. fastapi_startkit/facades/Request.pyi +88 -0
  48. fastapi_startkit/facades/Response.py +5 -0
  49. fastapi_startkit/facades/Response.pyi +68 -0
  50. fastapi_startkit/facades/Session.py +5 -0
  51. fastapi_startkit/facades/Session.pyi +59 -0
  52. fastapi_startkit/facades/Storage.py +5 -0
  53. fastapi_startkit/facades/Storage.pyi +12 -0
  54. fastapi_startkit/facades/Url.py +5 -0
  55. fastapi_startkit/facades/Url.pyi +22 -0
  56. fastapi_startkit/facades/View.py +5 -0
  57. fastapi_startkit/facades/View.pyi +54 -0
  58. fastapi_startkit/facades/__init__.py +19 -0
  59. fastapi_startkit/loader/Loader.py +78 -0
  60. fastapi_startkit/loader/__init__.py +1 -0
  61. fastapi_startkit/providers/ConfigurationProvider.py +13 -0
  62. fastapi_startkit/providers/Provider.py +14 -0
  63. fastapi_startkit/providers/__init__.py +4 -0
  64. fastapi_startkit/utils/__init__.py +0 -0
  65. fastapi_startkit/utils/collections.py +545 -0
  66. fastapi_startkit/utils/console.py +39 -0
  67. fastapi_startkit/utils/data/mime.types +1863 -0
  68. fastapi_startkit/utils/filesystem.py +100 -0
  69. fastapi_startkit/utils/http.py +101 -0
  70. fastapi_startkit/utils/location.py +90 -0
  71. fastapi_startkit/utils/str.py +120 -0
  72. fastapi_startkit/utils/structures.py +97 -0
  73. fastapi_startkit/utils/time.py +58 -0
  74. fastapi_startkit-0.1.0.dist-info/METADATA +13 -0
  75. fastapi_startkit-0.1.0.dist-info/RECORD +76 -0
  76. fastapi_startkit-0.1.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,68 @@
1
+ from typing import Any
2
+
3
+ class Response:
4
+ """Response facade."""
5
+
6
+ def json(payload: Any, status: int = 200) -> bytes:
7
+ """Set the response as a JSON response."""
8
+ ...
9
+ def make_headers(content_type: str = "text/html; charset=utf-8") -> None:
10
+ """Recompute Content-Length of the response after modyifing it."""
11
+ ...
12
+ def header(name: str, value: str = None) -> "None|str":
13
+ """Get response header for the given name if no value provided or add headers to response."""
14
+ ...
15
+ def get_headers(self) -> list:
16
+ """Get all response headers."""
17
+ ...
18
+ def cookie(name: str, value: str = None, **options) -> "None|str":
19
+ """Get response cookie for the given name if no value provided or add cookie to
20
+ the response with the given name, value and options."""
21
+ ...
22
+ def delete_cookie(name: str) -> "Response":
23
+ """Delete the cookie with the given name from the response."""
24
+ ...
25
+ def get_response_content(self) -> bytes:
26
+ """Get response content."""
27
+ ...
28
+ def status(status: "str|int") -> "Response":
29
+ """Set HTTP status code of the response."""
30
+ ...
31
+ def is_status(code: int) -> bool:
32
+ """Check if response has the given status code."""
33
+ ...
34
+ def get_status_code(self) -> str:
35
+ """Gets the HTTP status code of the response as a human string, like "200 OK"."""
36
+ ...
37
+ def get_status(self): ...
38
+ def data(self) -> bytes:
39
+ """Get the response content as bytes."""
40
+ ...
41
+ def converted_data(self) -> "str|bytes":
42
+ """Get the response content as string or bytes so that the WSGI server handles it."""
43
+ ...
44
+ def view(view: Any, status: int = 200) -> "bytes|Response":
45
+ """Set the response as a string or view."""
46
+ ...
47
+ def back(self) -> "Response":
48
+ """Set the response as a redirect response back to previous path defined from the
49
+ request."""
50
+ ...
51
+ def redirect(
52
+ location: str = None,
53
+ name: str = None,
54
+ params: dict = {},
55
+ url: str = None,
56
+ status: int = 302,
57
+ ) -> "Response":
58
+ """Set the response as a redirect response. The redirection location can be defined
59
+ with the location URL or with a route name. If a route name is used, route params can
60
+ be provided."""
61
+
62
+ ...
63
+ def to_bytes(self) -> "bytes":
64
+ """Converts the response to bytes."""
65
+ ...
66
+ def download(name: str, location: str, force: bool = False) -> "Response":
67
+ """Set the response as a file download response."""
68
+ ...
@@ -0,0 +1,5 @@
1
+ from .Facade import Facade
2
+
3
+
4
+ class Session(metaclass=Facade):
5
+ key = "session"
@@ -0,0 +1,59 @@
1
+ from typing import Any
2
+
3
+ class Session:
4
+ """Session facade."""
5
+
6
+ def add_driver(name: str, driver: Any) -> None:
7
+ """Register a new session driver with the given name."""
8
+ ...
9
+ def driver(driver: str) -> Any:
10
+ """Get a registered session driver with the given name."""
11
+ ...
12
+ def set_configuration(config: dict) -> "Session":
13
+ """Set session driver options."""
14
+ ...
15
+ def get_driver(name: str = None) -> Any:
16
+ """Get the default session driver or the driver with the given name."""
17
+ ...
18
+ def get_config_options(driver: str = None) -> dict:
19
+ """Get the options of the default session driver or of the driver with the given name."""
20
+ ...
21
+ def start(driver: str = None) -> "Session":
22
+ """Initialize session."""
23
+ ...
24
+ def get_data(self) -> dict:
25
+ """Get all session data."""
26
+ ...
27
+ def save(driver: str = None) -> None:
28
+ """Save session data for the default session driver or the given named driver."""
29
+ ...
30
+ def set(key: str, value: Any) -> None:
31
+ """Save value in default session."""
32
+ ...
33
+ def increment(key: str, count: int = 1) -> None:
34
+ """Increment session key with given count."""
35
+ ...
36
+ def decrement(key: str, count: int = 1) -> None:
37
+ """Decrement session key with given count."""
38
+ ...
39
+ def has(key: str) -> bool:
40
+ """Check if key is present in default session."""
41
+ ...
42
+ def get(key: str) -> Any:
43
+ """Get value of the given key in default session."""
44
+ ...
45
+ def pull(key: str) -> Any:
46
+ """Get and remove value for the given key in session."""
47
+ ...
48
+ def flush(self) -> None:
49
+ """Delete all keys from session."""
50
+ ...
51
+ def delete(key: str) -> "None|Any":
52
+ """Delete the given key from session."""
53
+ ...
54
+ def flash(key: str, value: Any) -> None:
55
+ """Save temporary value into session."""
56
+ ...
57
+ def all(self) -> dict:
58
+ """Get all session data."""
59
+ ...
@@ -0,0 +1,5 @@
1
+ from .Facade import Facade
2
+
3
+
4
+ class Storage(metaclass=Facade):
5
+ key = "storage"
@@ -0,0 +1,12 @@
1
+ from typing import Any
2
+
3
+ class Storage:
4
+ """File storage facade."""
5
+
6
+ def add_driver(name: str, driver: str): ...
7
+ def set_configuration(config: dict) -> "Storage": ...
8
+ def get_driver(name: str = None) -> Any: ...
9
+ def get_config_options(name: str = None) -> dict: ...
10
+ def disk(name: str = "default") -> Any:
11
+ """Get the file manager instance for the given disk name."""
12
+ ...
@@ -0,0 +1,5 @@
1
+ from .Facade import Facade
2
+
3
+
4
+ class Url(metaclass=Facade):
5
+ key = "url"
@@ -0,0 +1,22 @@
1
+ class Url:
2
+ """URL helper facade."""
3
+
4
+ def url(path: str = "") -> str:
5
+ """Generates a fully qualified url to the given path. If no path is given this will return
6
+ the base url domain."""
7
+ ...
8
+ def asset(alias: str, filename: str) -> str:
9
+ """Generates a fully qualified URL for the given asset using the given disk
10
+ Example:
11
+ asset("local", "avatar.jpg") (take first pat)
12
+ asset("s3.private", "doc.pdf") (when multiple paths are specified for the disk)
13
+ """
14
+ ...
15
+ def route(name: str, params: dict = {}, absolute: bool = True) -> str:
16
+ """Generates a fully qualified URL to the given route name.
17
+ Example:
18
+ route("users.home") : http://masonite.app/dashboard/
19
+ route("users.profile", {"id": 1}) : http://masonite.app/users/1/profile/
20
+ route("users.profile", {"id": 1}, absolute=False) : /users/1/profile/
21
+ """
22
+ ...
@@ -0,0 +1,5 @@
1
+ from .Facade import Facade
2
+
3
+
4
+ class View(metaclass=Facade):
5
+ key = "view"
@@ -0,0 +1,54 @@
1
+ from typing import Callable, Any
2
+ from jinja2 import PackageLoader, BaseLoader
3
+
4
+ class View:
5
+ """View facade."""
6
+
7
+ def render(template: str, dictionary: dict = {}) -> "View":
8
+ """Render the given template name with the given context as string."""
9
+ ...
10
+ def get_content(self) -> str:
11
+ """Get the rendered content as string."""
12
+ ...
13
+ def hydrate_from_composers(self):
14
+ """Add data into the view from specified composers."""
15
+ ...
16
+ def composer(composer_name: str, dictionary: dict) -> "View":
17
+ """Add/Update composer with the given name and data."""
18
+ ...
19
+ def share(dictionary: dict) -> "View":
20
+ """Share data to all templates."""
21
+ ...
22
+ def exists(template: str) -> bool:
23
+ """Check if a template with the given name exists."""
24
+ ...
25
+ def add_location(template_location: str, loader: "BaseLoader" = PackageLoader):
26
+ """Add location directory from which view templates can be loaded. The Jinja2 loader type
27
+ can be specified."""
28
+ ...
29
+ def add_namespaced_location(namespace: str, template_location: str):
30
+ """Add namespaced location directory from which view templates can be loaded."""
31
+ ...
32
+ def add_from_package(package_name: str, path_in_package: str): ...
33
+ def filter(name: str, function: Callable):
34
+ """Add filter functions to views with the given name."""
35
+ ...
36
+ def add_extension(extension: str) -> "View":
37
+ """Register Jinja2 extension to views."""
38
+ ...
39
+ def load_template(template: str):
40
+ """Private method for loading all the locations into the current environment."""
41
+ ...
42
+ def get_current_loaders(self):
43
+ """Get all enabled Jinja2 loaders."""
44
+ ...
45
+ def set_separator(token: str) -> "View":
46
+ """Change separator for view names (default is /)."""
47
+ ...
48
+ def set_file_extension(extension: str) -> "View":
49
+ """Change file view extension (default is .html)."""
50
+ ...
51
+ def get_response(self) -> str:
52
+ """Get the rendered content as string."""
53
+ ...
54
+ def test(key: str, obj: Any) -> "View": ...
@@ -0,0 +1,19 @@
1
+ from .Facade import Facade
2
+ from .Request import Request
3
+ from .Response import Response
4
+ from .Mail import Mail
5
+ from .Hash import Hash
6
+ from .Url import Url
7
+ from .Session import Session
8
+ from .View import View
9
+ from .Gate import Gate
10
+ from .Auth import Auth
11
+ from .Config import Config
12
+ from .Loader import Loader
13
+ from .Notification import Notification
14
+ from .Storage import Storage
15
+ from .Dump import Dump
16
+ from .Queue import Queue
17
+ from .Cache import Cache
18
+ from .RateLimiter import RateLimiter
19
+ from .Broadcast import Broadcast
@@ -0,0 +1,78 @@
1
+ """Loader class to easily list, find or load any object in a given module, or folder."""
2
+ import inspect
3
+ import pkgutil
4
+ import os
5
+
6
+ from ..exceptions import LoaderNotFound
7
+ from ..utils.str import as_filepath
8
+ from ..utils.structures import load
9
+
10
+
11
+ def parameters_filter(obj_name, obj):
12
+ return (
13
+ obj_name.isupper()
14
+ and not obj_name.startswith("__")
15
+ and not obj_name.endswith("__")
16
+ )
17
+
18
+
19
+ class Loader:
20
+ def get_modules(self, files_or_directories, raise_exception=False):
21
+ if not isinstance(files_or_directories, list):
22
+ files_or_directories = [files_or_directories]
23
+
24
+ _modules = {}
25
+ module_paths = list(map(as_filepath, files_or_directories))
26
+ for module_loader, name, _ in pkgutil.iter_modules(module_paths):
27
+ module = load(
28
+ f"{os.path.relpath(module_loader.path)}.{name}",
29
+ raise_exception=raise_exception,
30
+ )
31
+ _modules.update({name: module})
32
+ return _modules
33
+
34
+ def find(self, class_instance, paths, class_name, raise_exception=False):
35
+ _classes = self.find_all(class_instance, paths, raise_exception)
36
+ for name, obj in _classes.items():
37
+ if name == class_name:
38
+ return obj
39
+ if raise_exception:
40
+ raise LoaderNotFound(
41
+ f"No {class_instance} named {class_name} has been found in {paths}"
42
+ )
43
+ return None
44
+
45
+ def find_all(self, class_instance, paths, raise_exception=False):
46
+ _classes = {}
47
+ for module in self.get_modules(paths, raise_exception).values():
48
+ for obj_name, obj in inspect.getmembers(module):
49
+ # check if obj is the same class as the given one
50
+ if inspect.isclass(obj) and issubclass(obj, class_instance):
51
+ # check if the class really belongs to those paths to load internal only
52
+ if obj.__module__.startswith(module.__package__):
53
+ _classes.update({obj_name: obj})
54
+ if not len(_classes.keys()) and raise_exception:
55
+ raise LoaderNotFound(f"No {class_instance} have been found in {paths}")
56
+ return _classes
57
+
58
+ def get_object(self, path_or_module, object_name, raise_exception=False):
59
+ return load(path_or_module, object_name, raise_exception=raise_exception)
60
+
61
+ def get_objects(self, path_or_module, filter_method=None, raise_exception=False):
62
+ """Returns a dictionary of objects from the given path (file or dotted). The dictionary can
63
+ be filtered if a given callable is given."""
64
+ if isinstance(path_or_module, str):
65
+ module = load(path_or_module, raise_exception=raise_exception)
66
+ else:
67
+ module = path_or_module
68
+ if not module:
69
+ return None
70
+ return dict(inspect.getmembers(module, filter_method))
71
+
72
+ def get_parameters(self, module_or_path):
73
+ _parameters = {}
74
+ for name, obj in self.get_objects(module_or_path).items():
75
+ if parameters_filter(name, obj):
76
+ _parameters.update({name: obj})
77
+
78
+ return _parameters
@@ -0,0 +1 @@
1
+ from .Loader import Loader
@@ -0,0 +1,13 @@
1
+ from .Provider import Provider
2
+ from ..configuration import Configuration
3
+ import os
4
+
5
+ class ConfigurationProvider(Provider):
6
+ def register(self):
7
+ self.application.bind('config.location', os.path.join(self.application.base_path, "config"))
8
+ configuration = Configuration(self.application)
9
+ configuration.load()
10
+ self.application.bind("config", configuration)
11
+
12
+ def boot(self):
13
+ pass
@@ -0,0 +1,14 @@
1
+ from typing import TYPE_CHECKING
2
+
3
+ if TYPE_CHECKING:
4
+ from ..container import Container
5
+
6
+ class Provider:
7
+ def __init__(self, application) -> None:
8
+ self.application = application
9
+
10
+ def register(self) -> None:
11
+ pass
12
+
13
+ def boot(self) -> None:
14
+ pass
@@ -0,0 +1,4 @@
1
+ from .Provider import Provider
2
+ from .ConfigurationProvider import ConfigurationProvider
3
+
4
+ __all__ = ["Provider", "ConfigurationProvider"]
File without changes