itcloud/backend/src/app/api/schemas.py

152 lines
3.2 KiB
Python
Raw Normal View History

2025-12-30 13:35:19 +01:00
"""Pydantic schemas for API requests and responses."""
from datetime import datetime
from typing import Optional
from pydantic import BaseModel, EmailStr, Field
from app.domain.models import AssetStatus, AssetType
# Auth schemas
class UserRegister(BaseModel):
"""User registration request."""
email: EmailStr
password: str = Field(min_length=8, max_length=100)
class UserLogin(BaseModel):
"""User login request."""
email: EmailStr
password: str
class Token(BaseModel):
"""JWT token response."""
access_token: str
refresh_token: str
token_type: str = "bearer"
class UserResponse(BaseModel):
"""User information response."""
id: str
email: str
is_active: bool
created_at: datetime
model_config = {"from_attributes": True}
# Asset schemas
class AssetResponse(BaseModel):
"""Asset information response."""
id: str
user_id: str
type: AssetType
status: AssetStatus
original_filename: str
content_type: str
size_bytes: int
sha256: Optional[str] = None
captured_at: Optional[datetime] = None
width: Optional[int] = None
height: Optional[int] = None
duration_sec: Optional[float] = None
storage_key_original: str
storage_key_thumb: Optional[str] = None
created_at: datetime
deleted_at: Optional[datetime] = None
model_config = {"from_attributes": True}
class AssetListResponse(BaseModel):
"""Paginated list of assets."""
items: list[AssetResponse]
next_cursor: Optional[str] = None
has_more: bool
class CreateUploadRequest(BaseModel):
"""Request to create an upload."""
original_filename: str = Field(max_length=512)
content_type: str = Field(max_length=100)
size_bytes: int = Field(gt=0)
class CreateUploadResponse(BaseModel):
"""Response with upload credentials."""
asset_id: str
upload_url: str
upload_method: str = "presigned_post"
fields: Optional[dict] = None
class FinalizeUploadRequest(BaseModel):
"""Request to finalize an upload."""
etag: Optional[str] = None
sha256: Optional[str] = Field(None, max_length=64)
# Download URLs
class DownloadUrlResponse(BaseModel):
"""Pre-signed download URL."""
url: str
expires_in: int
# Share schemas
class CreateShareRequest(BaseModel):
"""Request to create a share link."""
asset_id: Optional[str] = None
album_id: Optional[str] = None
expires_in_seconds: Optional[int] = Field(None, gt=0)
password: Optional[str] = None
class ShareResponse(BaseModel):
"""Share link information."""
id: str
owner_user_id: str
asset_id: Optional[str] = None
album_id: Optional[str] = None
token: str
expires_at: Optional[datetime] = None
created_at: datetime
revoked_at: Optional[datetime] = None
model_config = {"from_attributes": True}
class ShareAccessRequest(BaseModel):
"""Request to access a shared resource."""
password: Optional[str] = None
2025-12-30 13:50:46 +01:00
class ShareWithAssetResponse(BaseModel):
"""Share with asset information."""
share: ShareResponse
asset: Optional[AssetResponse] = None
2025-12-30 13:35:19 +01:00
# Error response
class ErrorResponse(BaseModel):
"""Standard error response."""
error: dict[str, str | dict]