Source code for enhomie.restful.static

"""
Functions and routines associated with Enasis Network Homie Automate.

This file is part of Enasis Network software eco-system. Distribution
is permitted, for more information consult the project license file.
"""



import asyncio
from pathlib import Path
from typing import Optional

from encommon.types.strings import SEMPTY
from encommon.utils import read_text
from encommon.webkit import Content

from fastapi import APIRouter
from fastapi import HTTPException
from fastapi import Request
from fastapi import Response
from fastapi.responses import FileResponse



APIROUTER = APIRouter(
    tags=['Static Content'])

_STATIC = (
    Path(__file__).parents[1]
    / 'static')



[docs] @APIROUTER.get( '/static/images/{item}') async def get_static_images( request: Request, item: str, ) -> Response: """ Handle the API request and return using response model. :param item: Which item to locate and return contents. :returns: Response object containing relevant contents. """ local = _static_file( f'{item}.svg', 'images') content = ( Content.images(item) or SEMPTY) if local is not None: content = ( read_text(local)) await asyncio.sleep(0) return Response( content, media_type='image/svg+xml')
[docs] @APIROUTER.get( '/static/scripts/{item}') async def get_static_scripts( request: Request, item: str, ) -> Response: """ Handle the API request and return using response model. :param item: Which item to locate and return contents. :returns: Response object containing relevant contents. """ local = _static_file( f'{item}.js', 'scripts') content = ( Content.scripts(item) or SEMPTY) if local is not None: content += ( '\n\n\n' f'{read_text(local)}') await asyncio.sleep(0) return Response( content, media_type='application/javascript')
[docs] @APIROUTER.get( '/static/styles/{item}') async def get_static_styles( request: Request, item: str, ) -> Response: """ Handle the API request and return using response model. :param item: Which item to locate and return contents. :returns: Response object containing relevant contents. """ local = _static_file( f'{item}.css', 'styles') content = ( Content.styles(item) or SEMPTY) if local is not None: content += ( '\n\n\n' f'{read_text(local)}') await asyncio.sleep(0) return Response( content, media_type='text/css')
[docs] @APIROUTER.get( '/static/{file}') async def get_static( request: Request, file: str, ) -> FileResponse: """ Handle the API request and return using response model. :param file: Which file to locate and return contents. :returns: Response object containing relevant contents. """ if file[-5:] != '.html': raise HTTPException(403) path = _static_file(file) if path is None: raise HTTPException(404) await asyncio.sleep(0) return FileResponse(path)
def _static_file( path: Path | str, base: Optional[str] = None, ) -> Optional[Path]: """ Return the filesystem path object using the parameters. :param path: Complete or relative path for processing. :param base: Parent directory where the file is located. :returns: Filesystem path object using the parameters. """ static = Path(_STATIC) if base is not None: static /= Path(base) static /= path if not static.exists(): return None return static.resolve()