1
0
mirror of https://github.com/enpaul/kodak.git synced 2024-11-23 15:07:13 +00:00

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 from kodak.application import APPLICATION
# pylint: disable=invalid-name
def main(): def main():
"""Run the development server"""
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument( parser.add_argument(
"-b", "-b",

View File

@ -1,6 +1,7 @@
"""Shared resource base with common functionality""" """Shared resource base with common functionality"""
import logging import logging
from typing import Any from typing import Any
from typing import Callable
from typing import Dict from typing import Dict
from typing import List from typing import List
from typing import NamedTuple from typing import NamedTuple
@ -20,6 +21,20 @@ ResponseBody = Optional[Union[Dict[str, Any], List[Dict[str, Any]], List[str]]]
ResponseHeaders = Dict[str, 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): class ResponseTuple(NamedTuple):
"""Namedtuple representing the format of a flask-restful response tuple """Namedtuple representing the format of a flask-restful response tuple
@ -57,8 +72,8 @@ class KodakResource(flask_restful.Resource):
self.logger = logging.getLogger() self.logger = logging.getLogger()
def options( def options(
self, *args, **kwargs self, *args, **kwargs # pylint: disable=unused-argument
) -> ResponseTuple: # pylint: disable=unused-argument ) -> ResponseTuple:
"""Implement HTTP ``OPTIONS`` support """Implement HTTP ``OPTIONS`` support
`Reference documentation <https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS>`_ `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) return self.make_response(None, response.code, response.headers)
def make_response( def make_response( # pylint: disable=no-self-use
self, self,
data: ResponseBody, data: ResponseBody,
code: int = 200, 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 KodakResource
from kodak.resources._shared import ResponseTuple from kodak.resources._shared import ResponseTuple
class ImageAlias(KodakResource): class ImageAlias(KodakResource):
"""Handle generating and returning a processed image alias"""
routes = ("/image/<string:image_name>/<string:alias>",) routes = ("/image/<string:image_name>/<string:alias>",)
@authenticated
def get(self, image_name: str, alias: str) -> ResponseTuple: def get(self, image_name: str, alias: str) -> ResponseTuple:
"""Retrieve an image variation"""
raise NotImplementedError 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 import database
from kodak.resources._shared import KodakResource from kodak.resources._shared import KodakResource
from kodak.resources._shared import ResponseTuple from kodak.resources._shared import ResponseTuple
class Heartbeat(KodakResource): class Heartbeat(KodakResource):
"""Expose a heartbeat endpoint to check service health"""
routes = ("/heartbeat",) routes = ("/heartbeat",)
def get(self) -> ResponseTuple: def get(self) -> ResponseTuple:
configuration.load() """Perform a trivial database operation and return a-ok"""
database.ImageRecord.select().count() database.ImageRecord.select().count()
return self.make_response(None) return self.make_response(None)
def head(self) -> ResponseTuple: def head(self) -> ResponseTuple:
"""Alias HEAD to GET"""
return self._head(self.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 KodakResource
from kodak.resources._shared import ResponseTuple from kodak.resources._shared import ResponseTuple
class Image(KodakResource): class Image(KodakResource):
"""Handle requests for original source images"""
routes = ("/image/<string:image_name>",) routes = ("/image/<string:image_name>",)
@authenticated
def get(self, image_name: str) -> ResponseTuple: def get(self, image_name: str) -> ResponseTuple:
"""Retrieve an original source image"""
raise NotImplementedError 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) return self.make_response(data)
def head(self) -> ResponseTuple: def head(self) -> ResponseTuple:
"""Alias of GET with no response body""" """Alias HEAD to GET"""
return self._head(self.get()) return self._head(self.get())