Lint and document API resources

Add unimplemented authentication decorator
This commit is contained in:
Ethan Paul 2021-10-29 19:45:02 -04:00
parent 37303ccc50
commit f46168e29d
No known key found for this signature in database
GPG Key ID: D0E2CBF1245E92BF
6 changed files with 39 additions and 7 deletions

View File

@ -20,8 +20,8 @@ import sys
from kodak.application import APPLICATION
# pylint: disable=invalid-name
def main():
"""Run the development server"""
parser = argparse.ArgumentParser()
parser.add_argument(
"-b",

View File

@ -1,6 +1,7 @@
"""Shared resource base with common functionality"""
import logging
from typing import Any
from typing import Callable
from typing import Dict
from typing import List
from typing import NamedTuple
@ -20,6 +21,20 @@ ResponseBody = Optional[Union[Dict[str, Any], List[Dict[str, Any]], List[str]]]
ResponseHeaders = Dict[str, str]
def authenticated(func) -> Callable:
"""Decorator to wrap endpoints that need a client to authenticate to access
.. note:: This function has no effect if ``config.private`` is set to ``False``
"""
def _wrapper(*args, **kwargs):
return func(*args, **kwargs)
# TODO: Implement this
return _wrapper
class ResponseTuple(NamedTuple):
"""Namedtuple representing the format of a flask-restful response tuple
@ -57,8 +72,8 @@ class KodakResource(flask_restful.Resource):
self.logger = logging.getLogger()
def options(
self, *args, **kwargs
) -> ResponseTuple: # pylint: disable=unused-argument
self, *args, **kwargs # pylint: disable=unused-argument
) -> ResponseTuple:
"""Implement HTTP ``OPTIONS`` support
`Reference documentation <https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS>`_
@ -80,7 +95,7 @@ class KodakResource(flask_restful.Resource):
"""
return self.make_response(None, response.code, response.headers)
def make_response(
def make_response( # pylint: disable=no-self-use
self,
data: ResponseBody,
code: int = 200,

View File

@ -1,10 +1,18 @@
from kodak.resources._shared import authenticated
from kodak.resources._shared import KodakResource
from kodak.resources._shared import ResponseTuple
class ImageAlias(KodakResource):
"""Handle generating and returning a processed image alias"""
routes = ("/image/<string:image_name>/<string:alias>",)
@authenticated
def get(self, image_name: str, alias: str) -> ResponseTuple:
"""Retrieve an image variation"""
raise NotImplementedError
def head(self, image_name: str, alias: str) -> ResponseTuple:
"""Alias HEAD to GET"""
return self._head(self.get(image_name, alias))

View File

@ -1,18 +1,19 @@
from kodak import configuration
from kodak import database
from kodak.resources._shared import KodakResource
from kodak.resources._shared import ResponseTuple
class Heartbeat(KodakResource):
"""Expose a heartbeat endpoint to check service health"""
routes = ("/heartbeat",)
def get(self) -> ResponseTuple:
configuration.load()
"""Perform a trivial database operation and return a-ok"""
database.ImageRecord.select().count()
return self.make_response(None)
def head(self) -> ResponseTuple:
"""Alias HEAD to GET"""
return self._head(self.get())

View File

@ -1,10 +1,18 @@
from kodak.resources._shared import authenticated
from kodak.resources._shared import KodakResource
from kodak.resources._shared import ResponseTuple
class Image(KodakResource):
"""Handle requests for original source images"""
routes = ("/image/<string:image_name>",)
@authenticated
def get(self, image_name: str) -> ResponseTuple:
"""Retrieve an original source image"""
raise NotImplementedError
def head(self, image_name: str) -> ResponseTuple:
"""Alias HEAD to GET"""
return self._head(self.get(image_name))

View File

@ -21,5 +21,5 @@ class OpenAPI(KodakResource):
return self.make_response(data)
def head(self) -> ResponseTuple:
"""Alias of GET with no response body"""
"""Alias HEAD to GET"""
return self._head(self.get())