Making public version

This commit is contained in:
2023-03-09 10:15:19 +00:00
parent c0adc8bd08
commit 0e0b4794f6
11 changed files with 262 additions and 26 deletions

View File

@@ -8,4 +8,5 @@ passlib
requests
python-multipart
Pillow
joblib
joblib
celery

View File

@@ -1,7 +1,9 @@
from typing import List
import numpy as np
import requests
from pydantic import BaseModel
from sqlalchemy.ext.asyncio import AsyncSession
from sqlmodel import Field, Relationship, SQLModel
from src.exceptions.base_exception import BaseException
@@ -51,6 +53,26 @@ class Sign(SQLModelExtended, table=True):
if self.video_url is None:
raise BaseException(404, "Video url not found")
@classmethod
async def get_random(self, session: AsyncSession):
signs = await self.get_all(select_in_load=[Sign.sign_videos],session=session)
sign_videos = [len(s.sign_videos) for s in signs]
# get probability based on number of videos, lower must be more likely
# the sum must be 1
random_prob = [1 / (x + 1) for x in sign_videos]
random_prob = random_prob / np.sum(random_prob)
# get random sign
sign = np.random.choice(signs, p=random_prob)
return sign
class SignOut(BaseModel):
id: int
url: str
@@ -59,3 +81,10 @@ class SignOut(BaseModel):
video_url: str
sign_videos: List[SignVideo] = []
class SignOutSimple(BaseModel):
id: int
url: str
name: str
sign_id: str
video_url: str

View File

@@ -13,7 +13,7 @@ import src.settings as settings
from src.database.database import get_session
from src.exceptions.login_exception import LoginException
from src.models.auth import Login, User
from src.models.sign import Sign, SignOut
from src.models.sign import Sign, SignOut, SignOutSimple
from src.models.signvideo import SignVideo
from src.models.token import TokenExtended
@@ -22,6 +22,12 @@ router = APIRouter(prefix="/signs")
class SignUrl(BaseModel):
url: str
@router.get("/random", status_code=status.HTTP_200_OK, response_model=SignOutSimple)
async def get_random_sign(session: AsyncSession = Depends(get_session)):
# get a random sign where there is not much data from yet
sign = await Sign.get_random(session=session)
return sign
@router.post("/", status_code=status.HTTP_201_CREATED, response_model=SignOut)
async def add_sign(url: SignUrl, Authorize: AuthJWT = Depends(), session: AsyncSession = Depends(get_session)):
Authorize.jwt_required()
@@ -127,6 +133,7 @@ async def download_all(background_tasks: BackgroundTasks, Authorize: AuthJWT = D
return response
# define a function to delete the zip file
async def delete_zip_file(zip_path):
os.remove(zip_path)

View File

@@ -7,9 +7,11 @@ import random
import string
import subprocess
from celery import Celery
from fastapi import (APIRouter, BackgroundTasks, Depends, File, UploadFile,
status)
from fastapi.responses import FileResponse
from fastapi.concurrency import run_in_threadpool
from fastapi.responses import FileResponse, JSONResponse
from fastapi_jwt_auth import AuthJWT
from joblib import Memory
from pydantic import BaseModel
@@ -26,6 +28,9 @@ from src.utils.cryptography import verify_password
# Create a Memory object that caches data to the specified directory
cache_dir = settings.CACHE_PATH
celery_app = Celery('tasks', broker=settings.CELERY_REDIS)
async def extract_thumbnail(video_path):
proc = await asyncio.create_subprocess_exec(
"ffmpeg", "-i", video_path, "-ss", "00:00:02.000", "-vframes", "1", "-f", "image2pipe", "-"
@@ -36,15 +41,18 @@ async def extract_thumbnail(video_path):
router = APIRouter(prefix="/signs/{sign_id}/video")
@celery_app.task
def convert_video(video_filename):
command = ['ffmpeg', '-y', '-i', settings.DATA_PATH + "/" + video_filename + ".test", '-c:v', 'libx264', '-c:a', 'aac', '-strict', '-2', '-b:a', '192k', '-c:a', 'aac', '-strict', '-2', '-b:a', '192k', settings.DATA_PATH + "/" + video_filename]
# run the command
subprocess.run(command)
# delete the temporary file
os.remove(settings.DATA_PATH + "/" + video_filename + ".test")
# create the thumbnail
extract_thumbnail(settings.DATA_PATH + "/" + video_filename)
# create thumbnail
asyncio.run(extract_thumbnail(settings.DATA_PATH + "/" + video_filename))
# endpoint to upload a file and save it in the data folder
@@ -52,15 +60,14 @@ def convert_video(video_filename):
async def sign_video(
sign_id: int,
video: UploadFile,
background_tasks: BackgroundTasks,
session: AsyncSession = Depends(get_session),
Authorize: AuthJWT = Depends(),
# Authorize: AuthJWT = Depends(),
):
Authorize.jwt_required()
current_user_id: int = Authorize.get_jwt_subject()
user = await User.get_by_id(current_user_id, session)
if not user:
raise LoginException("User not found")
# Authorize.jwt_required()
# current_user_id: int = Authorize.get_jwt_subject()
# user = await User.get_by_id(current_user_id, session)
# if not user:
# raise LoginException("User not found")
sign = await Sign.get_by_id(sign_id, session)
if not sign:
raise LoginException("Sign not found")
@@ -79,12 +86,13 @@ async def sign_video(
with open(settings.DATA_PATH + "/" + video.filename + ".test", 'wb') as f:
f.write(video.file.read())
# convert the video in the background
background_tasks.add_task(convert_video, video.filename)
convert_video.delay(video.filename)
await sign_video.save(session)
return sign_video
response = JSONResponse(content={"sign_video": sign_video.dict()})
response.headers["Connection"] = "close"
return response
@router.get("/{video_id}/thumbnail/", status_code=status.HTTP_200_OK)
async def sign_video_thumbnail(

View File

@@ -17,6 +17,8 @@ DB_PORT: str = os.getenv("DB_PORT", "5432")
DB_USE_SQLITE: bool = os.getenv("DB_USE_SQLITE", False)
DB_SQLITE_PATH: str = os.getenv("DB_SQLITE_PATH", "./sqlite.db")
CELERY_REDIS: str = os.getenv("CELERY_REDIS", "redis://localhost:6379/0")
"""Storage"""
DATA_PATH: str = os.getenv("DATA_PATH", "data")
CACHE_PATH: str = os.getenv("CACHE_PATH", "cache")
@@ -31,4 +33,4 @@ REFRESH_EXPIRES: int = int(os.getenv("REFRESH_EXPIRES", 864000))
"""Standard User"""
DEFAULT_USER_ENABLED: bool = os.getenv("DEFAULT_USER_ENABLED", False)
DEFAULT_USER_EMAIL: str = os.getenv("DEFAULT_USER_EMAIL", "test@test.com")
DEFAULT_USER_PASSWORD: str = os.getenv("DEFAULT_USER_PASSWORD", "test")
DEFAULT_USER_PASSWORD: str = os.getenv("DEFAULT_USER_PASSWORD", "test")