Source code for luna_api.app.handlers.objects_proxy_handler

""" Handler for a certain objects. """
from copy import deepcopy
from http.client import HTTPResponse
from typing import AsyncIterable

from luna3.common.luna_response import LunaResponse
from sanic.views import stream

from app.handlers.base_handler import BaseProxyHandler, ProxyRequest
from configs.configs.configs.settings.classes import ImageStoreAddressSettings, ServiceTimeoutsSettings


class _BaseObjectsProxyHandler(BaseProxyHandler):
    """
    Base objects proxy.
    """

    def checkTokenPermissions(self) -> None:
        """
        Description see :func:`~BaseRequestHandler.checkTokenPermissions`.
        """
        self.checkTokenPermissionsDefault("object")

    @property
    def serviceAddress(self) -> ImageStoreAddressSettings:
        """
        Get a image store service address
        Returns:
            image store service address
        """
        return self.config.objectsOriginStorage

    @property
    def serviceTimeouts(self) -> ServiceTimeoutsSettings:
        """
        Get a image store service timeouts
        Returns:
            image store service timeouts
        """
        return self.config.objectsOriginStorageTimeouts


[docs]class ObjectsHandler(_BaseObjectsProxyHandler): """ Handler for create new objects. See `spec_objects`_. .. _spec_objects: _static/api.html#tag/objects Resource: "/{api_version}/objects" """ allowedMethods = ("POST",)
[docs] @stream async def post(self, *args, **kwargs) -> HTTPResponse: """ Streaming 'post' method Returns: proxy response """ return await self.makeRequestToService()
[docs] async def options(self, *args, **kwargs) -> HTTPResponse: """Options method""" # fix sanic error log `body not consumed` # sanic marks all view methods as `stream` and need manual load request body. # https://github.com/sanic-org/sanic/issues/2473 await self.request.receive_body() return await super().options(*args, **kwargs)
[docs] async def requestBodyStream(self) -> AsyncIterable[bytes]: """Read request body chunks by stream.""" while True: chunk = await self.request.stream.read() if chunk is None: break yield chunk
[docs] async def prepareRequestPost(self) -> ProxyRequest: """ Prepare proxy request for method `post` Returns: proxy request """ return ProxyRequest(self.requestBodyStream(), self.prepareHeaders(), self.prepareQuery())
[docs] async def postProcessingPost(self, response: LunaResponse) -> HTTPResponse: """ Default post processing response from the service Args: response: response Returns: response in api format """ outputJson = deepcopy(response.json) objectId = response.json["object_id"] self.respHeaders["Location"] = outputJson["url"] = f"/{self.app.ctx.apiVersion}/objects/{objectId}" return self.success(201, outputJson=outputJson)
[docs] def prepareUrl(self) -> str: """ Prepare url to the LIS service. Returns: A str, url """ return f"{self.serviceUrl}/buckets/{self.serviceAddress.bucket}/objects"
[docs]class ObjectHandler(_BaseObjectsProxyHandler): """ Handler for work with an object. See `spec_objects`_. .. _spec_objects: _static/api.html#tag/objects Resource: "/{api_version}/objects/{objectId}" """ allowedMethods = ("GET", "DELETE", "HEAD")
[docs] def prepareUrl(self) -> str: """ Prepare url to the LIS service. Returns: same url with correct api version """ objectId = self.request.match_info.get("objectId") return f"{self.serviceUrl}/buckets/{self.serviceAddress.bucket}/objects/{objectId}"