feat: local storage logic & endpoints

This commit is contained in:
Senko-san
2026-06-07 15:34:06 +03:00
parent dfd512a13f
commit 81ea93c371
23 changed files with 945 additions and 18 deletions
+27 -9
View File
@@ -1,20 +1,38 @@
"""Audio streaming endpoints: direct stream and HLS."""
"""Audio streaming endpoint direct stream with Range support."""
import uuid
from typing import Any
from typing import Annotated
from fastapi import APIRouter
from fastapi import APIRouter, Header
from fastapi.responses import StreamingResponse
from app.api.deps import StreamingServiceDep
router = APIRouter(prefix="/stream", tags=["streaming"])
@router.get("/{track_id}")
async def stream_track(track_id: uuid.UUID) -> Any: ...
async def stream_track(
track_id: uuid.UUID,
service: StreamingServiceDep,
range_header: Annotated[str | None, Header(alias="Range")] = None,
) -> StreamingResponse:
result = await service.open_stream(track_id, range_header)
headers = {
"Accept-Ranges": "bytes",
"Content-Length": str(result.content_length),
}
@router.get("/{track_id}/hls/playlist.m3u8")
async def hls_playlist(track_id: uuid.UUID) -> Any: ...
if result.is_partial:
headers["Content-Range"] = f"bytes {result.start}-{result.end}/{result.total_size}"
status_code = 206
else:
status_code = 200
@router.get("/{track_id}/hls/{segment}")
async def hls_segment(track_id: uuid.UUID, segment: str) -> Any: ...
return StreamingResponse(
result.stream,
status_code=status_code,
headers=headers,
media_type=result.content_type,
)
+17 -4
View File
@@ -1,11 +1,24 @@
"""Local file upload endpoint."""
from typing import Any
from typing import Annotated
from fastapi import APIRouter
from fastapi import APIRouter, File, UploadFile
from app.api.deps import CurrentUser, UploadServiceDep
from app.api.schemas.upload import UploadResponse
router = APIRouter(prefix="/upload", tags=["upload"])
@router.post("")
async def upload_file() -> Any: ...
@router.post("", response_model=UploadResponse)
async def upload_file(
file: Annotated[UploadFile, File()],
current_user: CurrentUser,
service: UploadServiceDep,
) -> UploadResponse:
result = await service.handle_upload(upload=file, user=current_user)
return UploadResponse(
track_id=result.track_id,
title=result.title,
already_exists=result.already_exists,
)