Spaces:
Running
Running
File size: 5,088 Bytes
3493993 40e751d 3493993 b07a262 3493993 da0c6f1 3493993 40e751d 3493993 40e751d 3493993 cf9dee4 b07a262 3493993 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | from __future__ import annotations
from typing import Annotated
from uuid import UUID
from fastapi import APIRouter, Header, HTTPException, Query, Request, status
from app.generation.schemas.requests import (
GenerationJobAttemptView,
GenerationJobView,
GenerationProviderView,
GenerationRequestCreate,
GenerationRequestView,
)
from app.generation.model_registry import GenerationModelView
router = APIRouter(prefix="/v1/generation", tags=["generation"])
def _generation(request: Request):
service = request.app.state.container.generation
service.ensure_ready()
return service
def _identity(request: Request) -> tuple[str, str]:
context = request.state.auth
if not context.workspace_id or not context.user_id:
# The credential itself is never a workspace. API-key middleware
# resolves the authoritative membership before this route runs.
raise HTTPException(status_code=403, detail="No active workspace membership.")
return context.workspace_id, context.user_id
@router.get("/providers", response_model=list[GenerationProviderView])
async def list_providers(request: Request) -> list[GenerationProviderView]:
return _generation(request).list_providers()
@router.get(
"/providers/{provider}", response_model=GenerationProviderView
)
async def get_provider(request: Request, provider: str) -> GenerationProviderView:
return _generation(request).get_provider(provider)
@router.get("/models", response_model=list[GenerationModelView])
async def list_models(
request: Request,
provider: str | None = Query(default=None, min_length=1, max_length=64),
) -> list[GenerationModelView]:
return _generation(request).list_models(provider=provider)
@router.get("/providers/{provider}/models/{model_id}", response_model=GenerationModelView)
async def get_model(
request: Request, provider: str, model_id: str
) -> GenerationModelView:
return _generation(request).get_model(provider, model_id)
@router.post(
"/requests",
response_model=GenerationRequestView,
status_code=status.HTTP_202_ACCEPTED,
)
async def create_request(
request: Request,
payload: GenerationRequestCreate,
idempotency_key: Annotated[
str, Header(alias="Idempotency-Key", min_length=8, max_length=255)
],
) -> GenerationRequestView:
workspace_id, user_id = _identity(request)
return await _generation(request).create(
workspace_id=workspace_id,
user_id=user_id,
payload=payload,
idempotency_key=idempotency_key,
project_id=payload.project_id,
)
@router.get("/requests", response_model=list[GenerationRequestView])
async def list_requests(
request: Request,
offset: int = Query(default=0, ge=0),
limit: int = Query(default=100, ge=1, le=500),
project_id: UUID | None = Query(default=None),
) -> list[GenerationRequestView]:
workspace_id, user_id = _identity(request)
return await _generation(request).list_requests(
workspace_id,
user_id,
offset=offset,
limit=limit,
project_id=str(project_id) if project_id else None,
)
@router.get("/requests/{generation_request_id}", response_model=GenerationRequestView)
async def get_request(
request: Request, generation_request_id: str
) -> GenerationRequestView:
workspace_id, user_id = _identity(request)
return await _generation(request).get_request(
workspace_id, user_id, generation_request_id
)
@router.get("/jobs/{generation_job_id}", response_model=GenerationJobView)
async def get_job(request: Request, generation_job_id: str) -> GenerationJobView:
workspace_id, user_id = _identity(request)
return await _generation(request).get_job(
workspace_id, user_id, generation_job_id
)
@router.post(
"/jobs/{generation_job_id}/retry",
response_model=GenerationRequestView,
status_code=status.HTTP_202_ACCEPTED,
)
async def retry_failed_job(
request: Request,
generation_job_id: str,
idempotency_key: Annotated[
str, Header(alias="Idempotency-Key", min_length=8, max_length=255)
],
) -> GenerationRequestView:
workspace_id, user_id = _identity(request)
return await _generation(request).retry_failed_job(
workspace_id,
user_id,
generation_job_id,
idempotency_key=idempotency_key,
)
@router.get(
"/jobs/{generation_job_id}/attempts",
response_model=list[GenerationJobAttemptView],
)
async def list_job_attempts(
request: Request, generation_job_id: str
) -> list[GenerationJobAttemptView]:
workspace_id, user_id = _identity(request)
return await _generation(request).list_job_attempts(
workspace_id, user_id, generation_job_id
)
@router.post(
"/jobs/{generation_job_id}/cancel", response_model=GenerationJobView
)
async def cancel_job(request: Request, generation_job_id: str) -> GenerationJobView:
workspace_id, user_id = _identity(request)
return await _generation(request).cancel(
workspace_id, user_id, generation_job_id
)
|