diff --git a/docs/source/conf.py b/docs/source/conf.py index 74403b1..62b35df 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -34,10 +34,14 @@ "private-members": False, } + +# TODO: Make the flask intermapping work intersphinx_mapping = { "python": ("https://docs.python.org/3/", None), "sphinx": ("https://www.sphinx-doc.org/en/master/", None), + "flask": ("https://flask.palletsprojects.com/en/2.0.x/", None), } + intersphinx_disabled_domains = ["std"] templates_path = ["_templates"] diff --git a/flask_utils/__init__.py b/flask_utils/__init__.py index 81d8b8c..06b02a6 100644 --- a/flask_utils/__init__.py +++ b/flask_utils/__init__.py @@ -1,5 +1,5 @@ # Increment versions here according to SemVer -__version__ = "0.7.0" +__version__ = "0.7.1" from flask_utils.utils import is_it_true from flask_utils.errors import GoneError diff --git a/flask_utils/decorators.py b/flask_utils/decorators.py index 9d4a51e..7abf242 100644 --- a/flask_utils/decorators.py +++ b/flask_utils/decorators.py @@ -41,7 +41,10 @@ def _is_optional(type_hint: Type) -> bool: # type: ignore """Check if the type hint is :data:`~typing.Optional`. :param type_hint: Type hint to check. + :type type_hint: Type + :return: True if the type hint is :data:`~typing.Optional`, False otherwise. + :rtype: bool :Example: @@ -62,7 +65,10 @@ def _make_optional(type_hint: Type) -> Type: # type: ignore """Wrap type hint with :data:`~typing.Optional` if it's not already. :param type_hint: Type hint to wrap. + :type type_hint: Type + :return: Type hint wrapped with :data:`~typing.Optional`. + :rtype: Type :Example: @@ -85,10 +91,14 @@ def _is_allow_empty(value: Any, type_hint: Type, allow_empty: bool) -> bool: # """Determine if the value is considered empty and whether it's allowed. :param value: Value to check. + :type value: Any :param type_hint: Type hint to check against. + :type type_hint: Type :param allow_empty: Whether to allow empty values. + :type allow_empty: bool :return: True if the value is empty and allowed, False otherwise. + :rtype: bool :Example: @@ -118,11 +128,16 @@ def _check_type(value: Any, expected_type: Type, allow_empty: bool = False, curr """Check if the value matches the expected type, recursively if necessary. :param value: Value to check. + :type value: Any :param expected_type: Expected type. + :type expected_type: Type :param allow_empty: Whether to allow empty values. + :type allow_empty: bool :param curr_depth: Current depth of the recursive check. + :type curr_depth: int :return: True if the value matches the expected type, False otherwise. + :rtype: bool :Example: @@ -202,7 +217,9 @@ def validate_params( :param parameters: Dictionary of parameters to validate. The keys are parameter names and the values are the expected types. + :type parameters: Dict[Any, Any] :param allow_empty: Allow empty values for parameters. Defaults to False. + :type allow_empty: bool :raises BadRequestError: If the JSON body is malformed, the Content-Type header is missing or incorrect, required parameters are missing, diff --git a/flask_utils/errors/__init__.py b/flask_utils/errors/__init__.py index d32f7db..d0f5c0a 100644 --- a/flask_utils/errors/__init__.py +++ b/flask_utils/errors/__init__.py @@ -20,7 +20,10 @@ def _register_error_handlers(application: Flask) -> None: This function will register all the error handlers for the application :param application: The Flask application to register the error handlers + :type application: flask.Flask + :return: None + :rtype: None .. versionchanged:: 0.5.0 Made the function private. If you want to register the custom error handlers, you need to @@ -50,7 +53,10 @@ def generate_badrequest(error: BadRequestError) -> Response: a custom message and the 400 code :param error: The error body + :type error: BadRequestError + :return: Returns the response formatted + :rtype: flask.Response """ return _generate_error_json(error, 400) @@ -61,7 +67,10 @@ def generate_conflict(error: ConflictError) -> Response: a custom message and the 409 code :param error: The error body + :type error: ConflictError + :return: Returns the response formatted + :rtype: flask.Response """ return _generate_error_json(error, 409) @@ -73,7 +82,10 @@ def generate_forbidden(error: ForbiddenError) -> Response: a custom message and the 403 code :param error: The error body + :type error: ForbiddenError + :return: Returns the response formatted + :rtype: flask.Response """ return _generate_error_json(error, 403) @@ -85,7 +97,10 @@ def generate_notfound(error: NotFoundError) -> Response: a custom message and the 404 code. :param error: The error body + :type error: NotFoundError + :return: Returns the response formatted + :rtype: flask.Response """ return _generate_error_json(error, 404) @@ -97,7 +112,10 @@ def generate_unauthorized(error: UnauthorizedError) -> Response: a custom message and the 401 code. :param error: The error body + :type error: UnauthorizedError + :return: Returns the response formatted + :rtype: flask.Response """ return _generate_error_json(error, 401) @@ -109,7 +127,10 @@ def generate_origin_is_unreachable(error: OriginIsUnreachableError) -> Response: a custom message and the 523 code. :param error: The error body + :type error: OriginIsUnreachableError + :return: Returns the response formatted + :rtype: flask.Response """ return _generate_error_json(error, 523) @@ -121,7 +142,10 @@ def generate_web_server_is_down(error: WebServerIsDownError) -> Response: a custom message and the 521 code. :param error: The error body + :type error: WebServerIsDownError + :return: Returns the response formatted + :rtype: flask.Response """ return _generate_error_json(error, 521) @@ -133,7 +157,10 @@ def generate_failed_dependency(error: FailedDependencyError) -> Response: a custom message and the 424 code. :param error: The error body + :type error: FailedDependencyError + :return: Returns the response formatted + :rtype: flask.Response """ return _generate_error_json(error, 424) @@ -145,7 +172,10 @@ def generate_gone(error: GoneError) -> Response: a custom message and the 410 code. :param error: The error body + :type error: GoneError + :return: Returns the response formatted + :rtype: flask.Response """ return _generate_error_json(error, 410) @@ -157,7 +187,10 @@ def generate_unprocessable_entity(error: UnprocessableEntityError) -> Response: a custom message and the 422 code. :param error: The error body + :type error: UnprocessableEntityError + :return: Returns the response formatted + :rtype: flask.Response """ return _generate_error_json(error, 422) @@ -169,7 +202,10 @@ def generate_service_unavailable(error: ServiceUnavailableError) -> Response: a custom message and the 503 code. :param error: The error body + :type error: ServiceUnavailableError + :return: Returns the response formatted + :rtype: flask.Response """ return _generate_error_json(error, 503) diff --git a/flask_utils/errors/_error_template.py b/flask_utils/errors/_error_template.py index 15714e8..f8ce779 100644 --- a/flask_utils/errors/_error_template.py +++ b/flask_utils/errors/_error_template.py @@ -9,8 +9,13 @@ def _generate_error_json(error: _BaseFlaskException, status_code: int) -> Respon This function is used to generate a json of the error passed :param error: The error containing the message and solution + :type error: _BaseFlaskException + :param status_code: The status code of the error. + :type status_code: int + :return: Returns a json containing all the info + :rtype: flask.Response :Example: diff --git a/flask_utils/errors/badrequest.py b/flask_utils/errors/badrequest.py index b79c24a..d103183 100644 --- a/flask_utils/errors/badrequest.py +++ b/flask_utils/errors/badrequest.py @@ -9,7 +9,9 @@ class BadRequestError(_BaseFlaskException): When raised, it will return a 400 status code with the message and solution provided. :param msg: The message to be displayed in the error. + :type msg: str :param solution: The solution to the error. + :type solution: Optional[str] :Example: diff --git a/flask_utils/errors/base_class.py b/flask_utils/errors/base_class.py index e68ea55..d28df2a 100644 --- a/flask_utils/errors/base_class.py +++ b/flask_utils/errors/base_class.py @@ -2,6 +2,34 @@ class _BaseFlaskException(Exception): + """ + This is the base class for all the exceptions in this package. + + :param msg: The message to be displayed in the error. + :type msg: str + :param solution: The solution to the error. + :type solution: Optional[str] + :param status_code: The status code of the error. + :type status_code: Optional[int] + :param name: The name of the error. + :type name: Optional[str] + + :Example: + + .. code-block:: python + + from flask_utils.errors import _BaseFlaskException + + class MyError(_BaseFlaskException): + self.name = "MyError" + self.msg = msg + self.solution = solution + self.status_code = 666 + + .. versionadded:: 0.1.0 + """ + name: Optional[str] = None msg: Optional[str] = None solution: Optional[str] = "Try again." + status_code: Optional[int] = 400 diff --git a/flask_utils/errors/conflict.py b/flask_utils/errors/conflict.py index 6cc4a60..4bea39f 100644 --- a/flask_utils/errors/conflict.py +++ b/flask_utils/errors/conflict.py @@ -9,7 +9,9 @@ class ConflictError(_BaseFlaskException): When raised, it will return a 409 status code with the message and solution provided. :param msg: The message to be displayed in the error. + :type msg: str :param solution: The solution to the error. + :type solution: Optional[str] :Example: diff --git a/flask_utils/errors/failed_dependency.py b/flask_utils/errors/failed_dependency.py index b83f37b..533a909 100644 --- a/flask_utils/errors/failed_dependency.py +++ b/flask_utils/errors/failed_dependency.py @@ -9,7 +9,9 @@ class FailedDependencyError(_BaseFlaskException): When raised, it will return a 424 status code with the message and solution provided. :param msg: The message to be displayed in the error. + :type msg: str :param solution: The solution to the error. + :type solution: Optional[str] :Example: diff --git a/flask_utils/errors/forbidden.py b/flask_utils/errors/forbidden.py index 10c3d11..5978e83 100644 --- a/flask_utils/errors/forbidden.py +++ b/flask_utils/errors/forbidden.py @@ -9,7 +9,9 @@ class ForbiddenError(_BaseFlaskException): When raised, it will return a 403 status code with the message and solution provided. :param msg: The message to be displayed in the error. + :type msg: str :param solution: The solution to the error. + :type solution: Optional[str] :Example: diff --git a/flask_utils/errors/gone.py b/flask_utils/errors/gone.py index 7b33fe6..81377cd 100644 --- a/flask_utils/errors/gone.py +++ b/flask_utils/errors/gone.py @@ -9,7 +9,9 @@ class GoneError(_BaseFlaskException): When raised, it will return a 410 status code with the message and solution provided. :param msg: The message to be displayed in the error. + :type msg: str :param solution: The solution to the error. + :type solution: Optional[str] :Example: diff --git a/flask_utils/errors/notfound.py b/flask_utils/errors/notfound.py index 649800f..128e807 100644 --- a/flask_utils/errors/notfound.py +++ b/flask_utils/errors/notfound.py @@ -9,7 +9,9 @@ class NotFoundError(_BaseFlaskException): When raised, it will return 404 status code with the message and solution provided. :param msg: The message to be displayed in the error. + :type msg: str :param solution: The solution to the error. + :type solution: Optional[str] :Example: diff --git a/flask_utils/errors/origin_is_unreachable.py b/flask_utils/errors/origin_is_unreachable.py index 2558044..48990c8 100644 --- a/flask_utils/errors/origin_is_unreachable.py +++ b/flask_utils/errors/origin_is_unreachable.py @@ -9,7 +9,9 @@ class OriginIsUnreachableError(_BaseFlaskException): When raised, it will return a 523 status code with the message and solution provided. :param msg: The message to be displayed in the error. + :type msg: str :param solution: The solution to the error. + :type solution: Optional[str] :Example: diff --git a/flask_utils/errors/service_unavailable.py b/flask_utils/errors/service_unavailable.py index c814a19..dfcd3b6 100644 --- a/flask_utils/errors/service_unavailable.py +++ b/flask_utils/errors/service_unavailable.py @@ -9,7 +9,9 @@ class ServiceUnavailableError(_BaseFlaskException): When raised, it will return a 503 status code with the message and solution provided. :param msg: The message to be displayed in the error. + :type msg: str :param solution: The solution to the error. + :type solution: Optional[str] :Example: diff --git a/flask_utils/errors/unauthorized.py b/flask_utils/errors/unauthorized.py index 6751a25..6811a1d 100644 --- a/flask_utils/errors/unauthorized.py +++ b/flask_utils/errors/unauthorized.py @@ -9,7 +9,9 @@ class UnauthorizedError(_BaseFlaskException): When raised, it will return a 401 status code with the message and solution provided. :param msg: The message to be displayed in the error. + :type msg: str :param solution: The solution to the error. + :type solution: Optional[str] :Example: diff --git a/flask_utils/errors/unprocessableentity.py b/flask_utils/errors/unprocessableentity.py index 63afbb8..d4db72f 100644 --- a/flask_utils/errors/unprocessableentity.py +++ b/flask_utils/errors/unprocessableentity.py @@ -9,7 +9,9 @@ class UnprocessableEntityError(_BaseFlaskException): When raised, it will return a 422 status code with the message and solution provided. :param msg: The message to be displayed in the error. + :type msg: str :param solution: The solution to the error. + :type solution: Optional[str] :Example: diff --git a/flask_utils/errors/web_server_is_down.py b/flask_utils/errors/web_server_is_down.py index 8ded8ee..42797b3 100644 --- a/flask_utils/errors/web_server_is_down.py +++ b/flask_utils/errors/web_server_is_down.py @@ -9,7 +9,9 @@ class WebServerIsDownError(_BaseFlaskException): When raised, it will return a 521 status code with the message and solution provided. :param msg: The message to be displayed in the error. + :type msg: str :param solution: The solution to the error. + :type solution: Optional[str] :Example: diff --git a/flask_utils/extension.py b/flask_utils/extension.py index 368e3d1..3ed1610 100644 --- a/flask_utils/extension.py +++ b/flask_utils/extension.py @@ -13,7 +13,10 @@ class FlaskUtils(object): Call :meth:`init_app` to configure the extension on an application. :param app: Flask application instance. - :param register_error_handlers: Register the custom error handlers. Default is True. + :type app: Optional[Flask] + + :param register_error_handlers: Register the custom error handlers. Default is ``True``. + :param register_error_handlers: bool :Example: @@ -34,6 +37,30 @@ class FlaskUtils(object): """ def __init__(self, app: Optional[Flask] = None, register_error_handlers: bool = True): + """ + :param app: Flask application instance. + :type app: Optional[Flask] + + :param register_error_handlers: Register the custom error handlers. Default is ``True``. + :type register_error_handlers: bool + + :Example: + + .. code-block:: python + + from flask import Flask + from flask_utils import FlaskUtils + + app = Flask(__name__) + fu = FlaskUtils(app) + + # or + + fu = FlaskUtils() + fu.init_app(app) + + .. versionadded:: 0.5.0 + """ self.has_error_handlers_registered = False if app is not None: @@ -42,7 +69,10 @@ def __init__(self, app: Optional[Flask] = None, register_error_handlers: bool = def init_app(self, app: Flask, register_error_handlers: bool = True) -> None: """ :param app: The Flask application to initialize. + :type app: Flask + :param register_error_handlers: Register the custom error handlers. Default is ``True``. + :type register_error_handlers: bool Initialize a Flask application for use with this extension instance. This must be called before any request is handled by the application. diff --git a/flask_utils/utils.py b/flask_utils/utils.py index f8d3120..5d21f60 100644 --- a/flask_utils/utils.py +++ b/flask_utils/utils.py @@ -4,7 +4,10 @@ def is_it_true(value: str) -> bool: Useful for flask's request.form.get() method and request.args.get() method :param value: String value to check if it is true + :type value: str + :return: True if value is true, False otherwise + :rtype: bool :Example: