view video.py @ 32:d83dbda8bccf

quieter log
author drewp@bigasterisk.com
date Mon, 26 Aug 2024 22:33:57 -0700
parents 1e058bea3ac2
children ed16fdbb3996
line wrap: on
line source

import asyncio
import json
import logging
from pathlib import Path

import uvicorn
from prometheus_client import Gauge
from sse_starlette.sse import EventSourceResponse
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

import dl_queue
from video_file_store import VideoFileStore
from video_ingest import VideoIngest

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


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.add_route("/metrics", handle_metrics)

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


uvicorn.run(main,
            host="0.0.0.0",
            port=8004,
            log_level=logging.INFO,
            factory=True)