view video.py @ 25:bf860a23d0c1

deployment and metrics
author drewp@bigasterisk.com
date Thu, 29 Jun 2023 13:57:34 -0700
parents 9e56e86a6814
children 27a754f8e8f8
line wrap: on
line source

import asyncio
import json
import logging
from pathlib import Path

from prometheus_client import Gauge
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.responses import HTMLResponse, JSONResponse, Response
from starlette.routing import Route
from starlette_exporter import PrometheusMiddleware, handle_metrics
from sse_starlette.sse import EventSourceResponse

from video_file_store import VideoFileStore
from video_ingest import VideoIngest
import dl_queue

logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger()
logging.getLogger('sse_starlette').setLevel(logging.WARNING)


def root(req):
    return HTMLResponse("api")


async def videos(req: Request) -> JSONResponse:
    subdir = req.query_params.get('subdir', '/')  # danger user input
    vfInDir = store.findInDir(subdir)
    return JSONResponse({
        "videos": [{
            'webRelPath': vf.webRelPath,
            'label': vf.label,
            'thumbRelPath': await store.getOrCreateThumb(vf),
        } for vf in vfInDir],
        "subdirs":
        list(store.findSubdirs(subdir)),
    })


def folderTree(req: Request) -> JSONResponse:
    return JSONResponse(store.folderTree())


async def ingestVideoUrl(req: Request) -> Response:
    folder = req.query_params['folder']
    url = await req.body()
    await svc.ingestUrl(url.decode('utf8'), folder)
    return Response(status_code=202)


async def ingestVideoUpload(req: Request) -> Response:
    name = req.query_params['name']
    await svc.addContent(name, req.body())
    return Response(status_code=200)


async def ingestQueue(req: Request) -> EventSourceResponse:

    async def g():
        async for ev in svc.events():
            yield json.dumps(ev)

    return EventSourceResponse(g())


store = VideoFileStore(top=Path('/data'))
svc = VideoIngest(store)


def main():

    app = Starlette(
        debug=True,
        routes=[
            Route('/video/api/', root),
            Route('/video/api/videos', videos),
            Route('/video/api/folderTree', folderTree),
            Route('/video/api/ingest/videoUpload',
                  ingestVideoUpload,
                  methods=['POST']),
            Route('/video/api/ingest/videoUrl',
                  ingestVideoUrl,
                  methods=['POST']),
            Route('/video/api/ingest/queue', ingestQueue),
        ],
    )

    app.add_middleware(PrometheusMiddleware, app_name='video_api')
    app.add_route("/video/api/metrics", handle_metrics)

    app.state.processTask = asyncio.create_task(dl_queue.process())
    return app


app = main()