Добавил очередь
This commit is contained in:
25
app/api/v1/endpoints/tasks.py
Normal file
25
app/api/v1/endpoints/tasks.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from fastapi import APIRouter
|
||||
from fastapi import HTTPException
|
||||
from celery.result import AsyncResult
|
||||
|
||||
from app.core.celery import celery_app
|
||||
from app.schemas import TaskStatusResponse
|
||||
from app.schemas import DownloadResponse
|
||||
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/status/{task_id}", response_model=TaskStatusResponse)
|
||||
def get_task_status(task_id: str):
|
||||
result = AsyncResult(task_id, app=celery_app)
|
||||
|
||||
if result is None:
|
||||
raise HTTPException(status_code=404, detail="Task not found")
|
||||
|
||||
response = TaskStatusResponse(
|
||||
task_id=task_id,
|
||||
status=result.status,
|
||||
result=DownloadResponse(**result.result) if result.successful() else None,
|
||||
)
|
||||
return response
|
||||
@@ -1,12 +1,12 @@
|
||||
from fastapi import APIRouter
|
||||
from app.services import YouTubeService
|
||||
from app.schemas import DownloadResponse
|
||||
from app.schemas import TaskCreateResponse
|
||||
from app.schemas import DownloadRequest
|
||||
from app.tasks import download_youtube
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.post("/", response_model=DownloadResponse)
|
||||
@router.post("/", response_model=TaskCreateResponse)
|
||||
async def download_video(data: DownloadRequest):
|
||||
response_data = YouTubeService.download(data)
|
||||
return response_data
|
||||
task = download_youtube.delay(data.url, data.quality)
|
||||
return TaskCreateResponse(task_id=task.id, status=task.status)
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
from fastapi import APIRouter
|
||||
from app.api.v1.endpoints import youtube
|
||||
from app.api.v1.endpoints import tasks
|
||||
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
router.include_router(youtube.router, prefix="/youtube", tags=["YouTube"])
|
||||
router.include_router(tasks.router, prefix="/tasks", tags=["Tasks"])
|
||||
|
||||
24
app/core/celery.py
Normal file
24
app/core/celery.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from celery import Celery
|
||||
|
||||
from app.core.config import REDIS_URL, ssl_options
|
||||
|
||||
|
||||
celery_app = Celery(
|
||||
"celery_worker",
|
||||
broker=f"{REDIS_URL}/0",
|
||||
backend=f"{REDIS_URL}/1",
|
||||
)
|
||||
|
||||
|
||||
celery_app.conf.update(
|
||||
broker_use_ssl=ssl_options,
|
||||
redis_backend_use_ssl=ssl_options,
|
||||
task_serializer=["json"],
|
||||
result_serializer=["json"],
|
||||
accept_content=["json"],
|
||||
enable_utc=True,
|
||||
timezone="UTC",
|
||||
broker_connection_retry_on_startup=True,
|
||||
task_acks_late=True,
|
||||
task_reject_on_worker_lost=True,
|
||||
)
|
||||
32
app/core/config.py
Normal file
32
app/core/config.py
Normal file
@@ -0,0 +1,32 @@
|
||||
import ssl
|
||||
from pathlib import Path
|
||||
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
S3_ACCESS_KEY: str
|
||||
S3_SECRET_KEY: str
|
||||
S3_BUCKET_NAME: str
|
||||
S3_ENDPOINT_URL: str
|
||||
S3_REGION_NAME: str
|
||||
S3_SIGNATURE_VERSION: str
|
||||
|
||||
REDIS_HOST: str
|
||||
REDIS_PORT: str
|
||||
REDIS_PASSWORD: str
|
||||
|
||||
BASE_DIR: Path = Path(__file__).resolve().parent.parent.parent
|
||||
|
||||
model_config = SettingsConfigDict(env_file=BASE_DIR / ".env")
|
||||
|
||||
|
||||
settings = Settings()
|
||||
|
||||
|
||||
REDIS_URL = (
|
||||
f"redis://:{settings.REDIS_PASSWORD}@{settings.REDIS_HOST}:{settings.REDIS_PORT}"
|
||||
)
|
||||
|
||||
|
||||
ssl_options = {"ssl_cert_reqs": ssl.CERT_NONE}
|
||||
@@ -1,11 +1,20 @@
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, HttpUrl
|
||||
|
||||
|
||||
class DownloadRequest(BaseModel):
|
||||
url: str
|
||||
url: HttpUrl
|
||||
quality: int
|
||||
|
||||
|
||||
class DownloadResponse(BaseModel):
|
||||
video: str
|
||||
audio: str
|
||||
video: HttpUrl
|
||||
audio: HttpUrl
|
||||
|
||||
|
||||
class TaskCreateResponse(BaseModel):
|
||||
task_id: str
|
||||
status: str
|
||||
|
||||
|
||||
class TaskStatusResponse(TaskCreateResponse):
|
||||
result: DownloadResponse | None = None
|
||||
|
||||
16
app/tasks.py
Normal file
16
app/tasks.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from app.core.celery import celery_app
|
||||
from app.services import YouTubeService
|
||||
from app.schemas import DownloadRequest
|
||||
|
||||
|
||||
@celery_app.task(
|
||||
bind=True,
|
||||
name="download_youtube",
|
||||
autoretry_for=(Exception,),
|
||||
retry_kwargs={"max_retries": 3},
|
||||
retry_backoff=True,
|
||||
)
|
||||
def download_youtube(self, url: str, quality: int) -> dict:
|
||||
request = DownloadRequest(url=url, quality=quality)
|
||||
response = YouTubeService.download(request)
|
||||
return response.model_dump()
|
||||
Reference in New Issue
Block a user