Files
sentinel-orbit-downloader/src/sentinel_orbit_downloader/api/schemas.py
T

206 lines
5.0 KiB
Python

from __future__ import annotations
from typing import Any
from pydantic import BaseModel, ConfigDict, Field, model_validator
class HealthResponse(BaseModel):
status: str
db_path: str
class RegionSummary(BaseModel):
adcode: str
name: str
level: str
parent_adcode: str | None = None
parent_name: str | None = None
province_adcode: str | None = None
province_name: str | None = None
label: str
bbox: list[float] | None = None
simplify_tolerance: float
class RegionDetail(RegionSummary):
center: list[float] | None = None
centroid: list[float] | None = None
geometry_json: dict[str, Any]
wkt: str
simplified_wkt: str
children_num: int | None = None
tree_id: str | None = None
class RegionImportRequest(BaseModel):
source_path: str = Field(default="\u5168\u56fd\u884c\u653f\u533a.geojson")
simplify_tolerance: float = Field(default=0.01, gt=0)
class RegionImportResponse(BaseModel):
source_path: str
simplify_tolerance: float
total_features: int
imported: int
class ProjectCreateRequest(BaseModel):
name: str
data_root: str
description: str | None = None
slug: str | None = None
class ProjectResponse(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
name: str
slug: str
data_root: str
description: str | None = None
created_at: str
updated_at: str
class JobSummary(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
project_id: int | None = None
source_type: str
source_value: str | None = None
region_adcode: str | None = None
region_name: str | None = None
start_time: str
end_time: str
processing_level: str
beam_mode: str | None = None
flight_direction: str | None = None
polarization: str | None = None
relative_orbit: int | None = None
max_results: int
status: str
result_count: int | None = None
data_dir: str | None = None
orbit_dir: str | None = None
manifest_path: str | None = None
error_message: str | None = None
created_at: str
finished_at: str | None = None
class JobSceneResponse(BaseModel):
job_id: int
scene_id: str
selected: int
product_status: str
orbit_status: str
product_path: str | None = None
orbit_path: str | None = None
platform: str | None = None
start_time: str | None = None
stop_time: str | None = None
processing_level: str | None = None
flight_direction: str | None = None
relative_orbit: int | None = None
size_mb: float | None = None
class JobEventResponse(BaseModel):
id: int
level: str
message: str
created_at: str
class JobDetailResponse(BaseModel):
job: JobSummary
scenes: list[JobSceneResponse]
events: list[JobEventResponse] = Field(default_factory=list)
class UploadedAoiResponse(BaseModel):
name: str
source_format: str
geometry_type: str
feature_count: int
bbox: list[float] = Field(default_factory=list)
wkt: str
class SearchJobCreateRequest(BaseModel):
project_id: int | None = None
bbox: str | None = None
wkt: str | None = None
region_adcode: str | None = None
source_name: str | None = None
start: str
end: str
processing_level: str = "SLC"
beam_mode: str | None = "IW"
flight_direction: str | None = None
polarization: str | None = None
relative_orbit: int | None = None
max_results: int = Field(default=50, ge=1)
manifest_path: str | None = None
raw_region: bool = False
@model_validator(mode="after")
def validate_aoi(self) -> "SearchJobCreateRequest":
provided = [self.bbox, self.wkt, self.region_adcode]
count = sum(1 for value in provided if value)
if count != 1:
raise ValueError("provide exactly one of bbox, wkt, or region_adcode")
return self
class SearchJobCreateResponse(BaseModel):
job: JobSummary
scenes: list[JobSceneResponse]
class DownloadJobCreateRequest(BaseModel):
job_id: int = Field(ge=1)
data_dir: str | None = None
orbit_dir: str | None = None
manifest_path: str | None = None
skip_data: bool = False
skip_orbits: bool = False
processes: int = Field(default=3, ge=1)
ignore_orbit_errors: bool = False
username: str | None = None
password: str | None = None
@model_validator(mode="after")
def validate_download_flags(self) -> "DownloadJobCreateRequest":
if self.skip_data and self.skip_orbits:
raise ValueError("skip_data and skip_orbits cannot both be true")
return self
class DownloadJobCreateResponse(BaseModel):
message: str
job: JobSummary
class MessageResponse(BaseModel):
message: str
class EarthdataSettingsRequest(BaseModel):
username: str
password: str
class EarthdataSettingsResponse(BaseModel):
username: str | None = None
has_password: bool = False
class JobDeleteResponse(BaseModel):
message: str
deleted_count: int
deleted_job_ids: list[int] = Field(default_factory=list)