|
| 1 | +import uuid |
| 2 | +from functools import wraps |
| 3 | +from typing import Any, Callable, List, Tuple |
| 4 | + |
| 5 | +from fastapi import APIRouter, Body, HTTPException, status |
| 6 | +from fastapi_versioning import versioned_api_route |
| 7 | + |
| 8 | +from jobs import JobsManager |
| 9 | +from jobs.exceptions import JobNotFound |
| 10 | +from jobs.models import Job, JobMethod |
| 11 | + |
| 12 | +jobs_router_v2 = APIRouter( |
| 13 | + prefix="/jobs", |
| 14 | + tags=["jobs_v2"], |
| 15 | + route_class=versioned_api_route(2, 0), |
| 16 | + responses={status.HTTP_404_NOT_FOUND: {"description": "Not found"}}, |
| 17 | +) |
| 18 | + |
| 19 | + |
| 20 | +def jobs_to_http_exception(endpoint: Callable[..., Any]) -> Callable[..., Any]: |
| 21 | + @wraps(endpoint) |
| 22 | + async def wrapper(*args: Tuple[Any], **kwargs: dict[str, Any]) -> Any: |
| 23 | + try: |
| 24 | + return await endpoint(*args, **kwargs) |
| 25 | + except JobNotFound as error: |
| 26 | + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(error)) from error |
| 27 | + except Exception as error: |
| 28 | + raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(error)) from error |
| 29 | + |
| 30 | + return wrapper |
| 31 | + |
| 32 | + |
| 33 | +@jobs_router_v2.post("/{route:path}", status_code=status.HTTP_202_ACCEPTED) |
| 34 | +@jobs_to_http_exception |
| 35 | +async def create(route: str, body: Any = Body(...), method: JobMethod = JobMethod.POST, retries: int = 5) -> Job: |
| 36 | + job = Job(id=str(uuid.uuid4()), route=route, method=method, body=body, retries=retries) |
| 37 | + JobsManager.add(job) |
| 38 | + return job |
| 39 | + |
| 40 | + |
| 41 | +@jobs_router_v2.get("/", status_code=status.HTTP_200_OK) |
| 42 | +@jobs_to_http_exception |
| 43 | +async def fetch() -> List[Job]: |
| 44 | + return JobsManager.get() |
| 45 | + |
| 46 | + |
| 47 | +@jobs_router_v2.get("/{identifier}", status_code=status.HTTP_200_OK) |
| 48 | +@jobs_to_http_exception |
| 49 | +async def fetch_by_identifier(identifier: str) -> Job: |
| 50 | + return JobsManager.get_by_identifier(identifier) |
| 51 | + |
| 52 | + |
| 53 | +@jobs_router_v2.delete("/{identifier}", status_code=status.HTTP_204_NO_CONTENT) |
| 54 | +@jobs_to_http_exception |
| 55 | +async def delete(identifier: str) -> None: |
| 56 | + JobsManager.delete(identifier) |
0 commit comments