40 lines
1.3 KiB
Python
40 lines
1.3 KiB
Python
"""Upload preflight API (US05-01).
|
|
|
|
Preflight is a command, not a resource read: it contacts the Immich server, hashes
|
|
the current bytes, and issues a token. It uploads nothing — starting a batch is
|
|
US05-02, so there is deliberately no start endpoint here.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, Request
|
|
from fastapi.responses import JSONResponse
|
|
from pydantic import BaseModel
|
|
|
|
from photo_pipeline.services.uploads import UploadError, UploadService
|
|
|
|
router = APIRouter(tags=["uploads"])
|
|
|
|
|
|
class PreflightRequest(BaseModel):
|
|
# ``None`` means every album; an explicit list scopes the check.
|
|
albums: list[str] | None = None
|
|
# Approving a partial upload is an explicit act, never a default.
|
|
allow_partial: bool = False
|
|
|
|
|
|
def _service(request: Request) -> UploadService:
|
|
return UploadService(request.app.state.session_factory, config=request.app.state.config)
|
|
|
|
|
|
@router.post("/upload-preflight")
|
|
def preflight(request: Request, body: PreflightRequest | None = None):
|
|
body = body or PreflightRequest()
|
|
try:
|
|
return _service(request).preflight(body.albums, allow_partial=body.allow_partial)
|
|
except UploadError as error:
|
|
return JSONResponse(
|
|
status_code=422,
|
|
content={"error": {"code": "unknown_album", "message": str(error)}},
|
|
)
|