From e2d5e55ca30475da1b1038d4ff9a22d618ca79e6 Mon Sep 17 00:00:00 2001 From: Scoder12 <34356756+Scoder12@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:11:39 -0700 Subject: [PATCH] Initial code for needs_params --- src/replit/maqpy/utils.py | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/replit/maqpy/utils.py b/src/replit/maqpy/utils.py index 4399014..95c47d9 100644 --- a/src/replit/maqpy/utils.py +++ b/src/replit/maqpy/utils.py @@ -1,6 +1,6 @@ """Utitilities to make development easier.""" from functools import wraps -from typing import Any, Callable +from typing import Any, Callable, Tuple import flask @@ -52,3 +52,36 @@ def needs_signin(func: Callable = None, login_html: str = sign_in_snippet) -> Ca return decorator(func) else: # called with options, eg @needs_signin(login_html='...') return decorator + + +def needs_params(*param_names: str, onerror: Callable[Tuple[str]] = None) -> Callable: + """Require paramaters before a handler can be activated. + + Args: + param_names (str): The paramaters that must be in the request. + onerror (Callable): A function to handle when a paramater is missing. + If no function is specified a handler that returns a descriptive error and + 400 Bad Request status code will be used. + + Raises: + TypeError: No paramaters were provided or an invalid one was provided. + NotImplementedError: If the handler is called. + + Returns: + Callable: The new handler. + """ + if len(param_names) < 1: + raise TypeError("You must specify at least one required paramater name") + # If function is used as a decorator with no arguments, the first argument will be + # a function, so type check all of the param names to catch mistakes + if not all(isinstance(p, str) for p in param_names): + raise TypeError("All paramater names should be strings.") + + def decorator(func: Callable) -> Callable: + @wraps(func) + def handler(*args: Any, **kwargs: Any) -> flask.Response: + raise NotImplementedError() + + return handler + + return decorator