Documentation

Upload Types

Types for upload operations and results

UploadResult

Result of a successful upload operation

@dataclass(frozen=True)
class UploadResult:
image_id: str # Unique identifier
filename: str # Original filename
object_key: str # Storage object key (S3 path)
description: Optional[str] # AI-generated description
tags: Optional[list[str]] # AI-extracted tags
visible_text: Optional[str] # OCR-extracted text
confidence_score: Optional[float] # AI confidence (0-1)
description_status: DescriptionStatus = DescriptionStatus.PENDING # PENDING, COMPLETED, FAILED, etc.
thumbnail_url: Optional[str] # URL to thumbnail
created_at: Optional[datetime] # Upload timestamp
description_error: Optional[str] # Error message if failed
description_error_type: Optional[str] # Error classification
description_is_retryable: Optional[bool] # Whether retry is possible
# Properties
@property
def is_failed(self) -> bool: ...
@property
def is_completed(self) -> bool: ...
@property
def is_pending(self) -> bool: ...
# Serialization
def to_dict(self, exclude_none: bool = True) -> dict[str, Any]: ...

BatchUploadResults

List of UploadResult with convenience methods. Returned by upload() for batch uploads.

class BatchUploadResults(list):
# Properties
@property
def has_failures(self) -> bool: ...
@property
def failed_count(self) -> int: ...
@property
def succeeded_count(self) -> int: ...
@property
def pending_count(self) -> int: ...
# Methods
def failed(self) -> list[UploadResult]: ...
def succeeded(self) -> list[UploadResult]: ...
def pending(self) -> list[UploadResult]: ...
def retryable(self) -> list[UploadResult]: ...
def raise_on_failures(self) -> BatchUploadResults: ...
def summary(self) -> str: ... # "3 succeeded, 1 failed"

Tip

For single-file uploads, use upload_one() which returns UploadResult directly.

QuotaInfo

Upload quota information

@dataclass(frozen=True)
class QuotaInfo:
can_proceed: bool # Whether upload can proceed
requested: int # Number of uploads requested
available: int # Uploads still available
monthly_limit: int # Total monthly limit
current_usage: int # Current month's usage
message: Optional[str] # Quota status message

PresignedUrlInfo

Presigned URL information for S3 upload

@dataclass(frozen=True)
class PresignedUrlInfo:
upload_url: str # URL to upload the file to
upload_method: str # HTTP method (PUT or POST)
upload_headers: dict[str, str] # Headers for upload request
object_key: str # S3 object key
image_id: Optional[str] # Pre-created image ID
expires_at: Optional[datetime] # URL expiration
max_size_bytes: Optional[int] # Maximum file size
upload_fields: Optional[dict[str, str]] # Fields for POST uploads
storage_target: Optional[str] # Storage target identifier
bucket_name: Optional[str] # S3 bucket name

DescriptionResult

Result from image description

@dataclass(frozen=True)
class DescriptionResult:
operation_id: str # Unique operation identifier
description: str # Main AI-generated description
confidence_score: float # Confidence score (0-1)
key_elements: Optional[list[str]] = None # Key elements detected
tags: Optional[list[str]] = None # Extracted tags
visible_text: Optional[str] = None # OCR-extracted text
verification_level: str = "standard" # quick | standard | thorough | critical
provider_count: int = 1 # Number of AI models consulted
processing_time_ms: int = 0 # Time to generate
metadata: Optional[dict[str, Any]] = None

VerificationResult

Result from content verification

@dataclass(frozen=True)
class VerificationResult:
operation_id: str # Unique operation identifier
is_verified: bool # Whether content is accurate
confidence_score: float # Verification confidence (0-1)
risk_level: str # "low" | "medium" | "high" | "critical"
hallucination_probability: float = 0.0 # Accuracy confidence inverse (0-1)
verified_claims: Optional[list[str]] = None # Claims that were verified
issues: Optional[list[VerificationIssue]] = None # Detected issues
summary: Optional[str] = None # Summary of verification results
processing_time_ms: int = 0 # Time to process
providers_used: Optional[list[str]] = None # AI models used

Verification Types

VerificationIssue

A single issue found during verification

@dataclass(frozen=True)
class VerificationIssue:
type: str # Issue type (e.g., "hallucination", "inaccuracy", "missing")
description: str # Description of the issue
severity: str = "medium" # Severity level (low, medium, high, critical)
claim: Optional[str] = None # The specific claim that was flagged
confidence: Optional[float] = None # Confidence in this issue detection

Description Status Types

DescriptionStatus

Status of a description generation operation (returned by wait_for_description())

@dataclass(frozen=True)
class DescriptionStatus:
image_id: str # Image identifier
status: str # pending | queued | processing | completed | failed
description: Optional[str] = None # Generated description (if completed)
tags: Optional[list[str]] = None # Extracted tags (if completed)
visible_text: Optional[str] = None # OCR text (if completed)
confidence_score: Optional[float] = None # Confidence score (if completed)
error_message: Optional[str] = None # Error message (if failed)
created_at: Optional[datetime] = None # When the operation started
completed_at: Optional[datetime] = None # When the operation completed
# Properties
@property
def is_complete(self) -> bool: ... # True if completed, failed, or skipped
@property
def is_successful(self) -> bool: ... # True if completed successfully

DescriptionErrorType

Classification of description generation errors for retry strategies

class DescriptionErrorType(str, Enum):
TIMEOUT = "timeout" # VLM provider timed out (retryable)
RATE_LIMIT = "rate_limit" # Rate limit exceeded (retryable)
VLM_ERROR = "vlm_error" # VLM provider error (retryable)
VALIDATION_ERROR = "validation" # Input validation failed (permanent)
RESOURCE_LIMIT = "resource_limit" # Quota exceeded (permanent)
UNKNOWN = "unknown" # Unclassified (not retryable)

DescriptionFailure

Details about a failed description operation with error classification

@dataclass(frozen=True)
class DescriptionFailure:
image_id: str # ID of the image that failed
error_message: str # Human-readable error message
error_type: DescriptionErrorType # Classification of the error
is_retryable: bool # Whether the operation can be retried
filename: Optional[str] = None # Original filename
raw_error: Optional[str] = None # Original error details
# Class methods
@staticmethod
def classify_error(error_msg: str) -> tuple[DescriptionErrorType, bool]: ...
@classmethod
def from_error_message(cls, image_id: str, error_msg: str, filename: Optional[str] = None) -> DescriptionFailure: ...