exif / src /models /image_metadata.py
xtremekratos's picture
init
1516b25
Raw
History Blame Contribute Delete
4.22 kB
from typing import Any, Dict, List, Optional, Union
from pydantic import BaseModel, Field
from datetime import datetime
# ============================================================
# Parameter Models
# ============================================================
class CaptureParameters(BaseModel):
created_at: Optional[datetime] = None
edited_at: Optional[datetime] = None
class GPSParameters(BaseModel):
latitude: Optional[float] = None
longitude: Optional[float] = None
altitude: Optional[float] = None
direction: Optional[float] = None
speed: Optional[float] = None
speed_unit: Optional[str] = None
raw: Dict[str, Any] = Field(default_factory=dict)
class CameraParameters(BaseModel):
make: Optional[str] = None
model: Optional[str] = None
software: Optional[str] = None
lens_make: Optional[str] = None
lens_model: Optional[str] = None
focal_length_mm: Optional[float] = None
focal_length_35mm: Optional[int] = None
aperture: Optional[float] = None
exposure_time: Optional[float] = None
iso: Optional[int] = None
flash: Optional[str] = None
class DeviceParameters(BaseModel):
make: Optional[str] = None
model: Optional[str] = None
software: Optional[str] = None
class AiPromptParameters(BaseModel):
prompt: Optional[str] = None
negative_prompt: Optional[str] = None
workflow: Optional[str] = None
model: Optional[str] = None
sampler: Optional[str] = None
seed: Optional[int] = None
cfg_scale: Optional[float] = None
steps: Optional[int] = None
raw_parameters: Optional[str] = None
class AiGenerationParameters(BaseModel):
label: Optional[str] = None
provider: Optional[str] = None
digital_source_type: Optional[str] = None
class EditParameters(BaseModel):
label: Optional[str] = None
tool: Optional[str] = None
provider: Optional[str] = None
history: List[str] = Field(default_factory=list)
software: Optional[str] = None
class DepthMapParameters(BaseModel):
depth_present: bool = False
width: Optional[int] = None
height: Optional[int] = None
confidence: float = 0.0
class DownloadParameters(BaseModel):
source: Optional[str] = None
original_filename: Optional[str] = None
class MakerNoteParameters(BaseModel):
make: Optional[str] = None
raw: Dict[str, Any] = Field(default_factory=dict)
# ============================================================
# Attribute Model
# ============================================================
class Attribute(BaseModel):
type: str # 'capture', 'gps', 'camera', 'device', 'ai_prompt', 'ai_generation', 'ai_edit', 'depth_map', 'download'
weight: float
is_ai: bool = False
ai_confidence: float = 0.0
comments: Optional[str] = None
parameters: Union[
CaptureParameters,
GPSParameters,
CameraParameters,
DeviceParameters,
AiPromptParameters,
AiGenerationParameters,
EditParameters,
DepthMapParameters,
DownloadParameters,
MakerNoteParameters,
Dict[str, Any]
]
# ============================================================
# Top Level Models
# ============================================================
class AnalysisResult(BaseModel):
is_ai: bool
ai_confidence: float
real_confidence: float = 0.0
edited_confidence: float = 0.0
class FileInfo(BaseModel):
path: str
mime_type: Optional[str]
image_format: Optional[str]
width: Optional[int]
height: Optional[int]
dpi: Optional[float] = None
color_space: Optional[str] = None
orientation: Optional[int] = None
size_bytes: Optional[int] = None
class Attachments(BaseModel):
depth_map: Optional[str] = None
class ProcessMetadata(BaseModel):
started_at: Optional[datetime] = None
completed_at: Optional[datetime] = None
duration: Optional[float] = None
class ImageMetadataResult(BaseModel):
analysis: AnalysisResult
file: FileInfo
attachments: Attachments
attributes: List[Attribute] = Field(default_factory=list)
metadata: ProcessMetadata
raw: Optional[Dict[str, Any]] = None # Optional raw data if needed