diff --git a/adafruit_wsgi/__init__.py b/adafruit_wsgi/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/adafruit_wsgi/request.py b/adafruit_wsgi/request.py index cacaeb0..68a8b1f 100644 --- a/adafruit_wsgi/request.py +++ b/adafruit_wsgi/request.py @@ -11,6 +11,11 @@ """ import re +try: + from typing import Dict +except ImportError: + pass + class Request: """ @@ -18,7 +23,7 @@ class Request: A higher level abstraction of the raw WSGI Environ dictionary. """ - def __init__(self, environ): + def __init__(self, environ: Dict[str, str]) -> None: self._method = environ["REQUEST_METHOD"] self._path = environ["PATH_INFO"] self._query_params = self.__parse_query_params(environ.get("QUERY_STRING", "")) @@ -27,21 +32,21 @@ def __init__(self, environ): self._wsgi_environ = environ @property - def method(self): + def method(self) -> str: """ the HTTP Method Type of this request """ return self._method @property - def path(self): + def path(self) -> str: """ the path this request was made to """ return self._path @property - def query_params(self): + def query_params(self) -> Dict[str, str]: """ Request query parameters, represented as a dictionary of param name to param value @@ -49,7 +54,7 @@ def query_params(self): return self._query_params @property - def headers(self): + def headers(self) -> Dict[str, str]: """ Request headers, represented as a dictionary of header name to header value @@ -64,14 +69,14 @@ def body(self): return self._body @property - def wsgi_environ(self): + def wsgi_environ(self) -> Dict[str, str]: """ The raw WSGI Environment dictionary representation of the request """ return self._wsgi_environ @staticmethod - def __parse_query_params(query_string): + def __parse_query_params(query_string: str) -> Dict[str, str]: param_list = query_string.split("&") params = {} for param in param_list: @@ -81,7 +86,7 @@ def __parse_query_params(query_string): return params @staticmethod - def __parse_headers(environ): + def __parse_headers(environ: Dict[str, str]) -> Dict[str, str]: headers = {} # Content Type and Content Length headers diff --git a/adafruit_wsgi/wsgi_app.py b/adafruit_wsgi/wsgi_app.py index 3315aa7..2ba4572 100644 --- a/adafruit_wsgi/wsgi_app.py +++ b/adafruit_wsgi/wsgi_app.py @@ -28,6 +28,11 @@ import re +try: + from typing import Any, AnyStr, Callable, Dict, List, Optional, Sequence, Tuple +except ImportError: + pass + from adafruit_wsgi.request import Request __version__ = "0.0.0-auto.0" @@ -43,7 +48,7 @@ def __init__(self): self._routes = [] self._variable_re = re.compile("^<([a-zA-Z]+)>$") - def __call__(self, environ, start_response): + def __call__(self, environ: Dict[str, str], start_response: Callable): """ Called whenever the server gets a request. The environ dict has details about the request per wsgi specification. @@ -66,7 +71,7 @@ def __call__(self, environ, start_response): start_response(status, headers) return resp_data - def on_request(self, methods, rule, request_handler): + def on_request(self, methods: List[str], rule: str, request_handler: Callable): """ Register a Request Handler for a particular HTTP method and path. request_handler will be called whenever a matching HTTP request is received. @@ -95,7 +100,7 @@ def on_request(self, methods, rule, request_handler): (re.compile(regex), {"methods": methods, "func": request_handler}) ) - def route(self, rule, methods=None): + def route(self, rule: str, methods: Optional[List[str]] = None): """ A decorator to register a route rule with an endpoint function. if no methods are provided, default to GET @@ -104,9 +109,11 @@ def route(self, rule, methods=None): methods = ["GET"] return lambda func: self.on_request(methods, rule, func) - def _match_route(self, path, method): + def _match_route( + self, path: str, method: str + ) -> Optional[Tuple[Sequence[AnyStr], Dict[str, Any]]]: for matcher, route in self._routes: match = matcher.match(path) if match and method in route["methods"]: - return (match.groups(), route) + return match.groups(), route return None