Harden RC7 API response contracts
This commit is contained in:
@@ -1,6 +1,14 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from .common import ApiErrorEnvelope, ApiErrorItem, Envelope, PaginationEnvelope
|
||||
from .common import (
|
||||
ApiErrorEnvelope,
|
||||
ApiErrorItem,
|
||||
Envelope,
|
||||
GeoJsonFeature,
|
||||
GeoJsonFeatureCollection,
|
||||
ItemList,
|
||||
PaginationEnvelope,
|
||||
)
|
||||
from .coverage import (
|
||||
CoverageBBox,
|
||||
CoverageCatalogResponse,
|
||||
@@ -9,7 +17,7 @@ from .coverage import (
|
||||
CoverageResolveResponse,
|
||||
CoverageSourceContract,
|
||||
)
|
||||
from .project import ProjectCreate, ProjectList, ProjectRead, ProjectUpdate
|
||||
from .project import ProjectCreate, ProjectDeleteResult, ProjectList, ProjectRead, ProjectUpdate
|
||||
from .area import AreaCreate, AreaList, AreaRead, AreaUpdate
|
||||
from .analysis import ChangeDetectionRequest, ChangeDetectionSummary
|
||||
from .dataset import DatasetCreateResponse, DatasetList
|
||||
@@ -43,6 +51,7 @@ from .detection import (
|
||||
DetectionRunResponse,
|
||||
ModelAssetListResponse,
|
||||
ModelAssetRead,
|
||||
YoloPreflightResponse,
|
||||
)
|
||||
from .detection_review import DetectionReviewList, DetectionReviewRead, DetectionReviewSummary, DetectionReviewUpsert
|
||||
from .segmentation import (
|
||||
@@ -115,7 +124,12 @@ from .export import (
|
||||
MetadataExportRequest,
|
||||
ReportExportRequest,
|
||||
)
|
||||
from .qa import QaProviderComparisonRequest, QaProviderComparisonResult
|
||||
from .qa import (
|
||||
AnalysisQaResponse,
|
||||
QaProviderComparisonRequest,
|
||||
QaProviderComparisonResult,
|
||||
QualityEvidenceResponse,
|
||||
)
|
||||
from .operations import (
|
||||
RasterClipRequest,
|
||||
RasterIndexBaseRequest,
|
||||
@@ -150,6 +164,9 @@ from .operations import (
|
||||
|
||||
__all__ = [
|
||||
"Envelope",
|
||||
"ItemList",
|
||||
"GeoJsonFeature",
|
||||
"GeoJsonFeatureCollection",
|
||||
"ApiErrorEnvelope",
|
||||
"ApiErrorItem",
|
||||
"PaginationEnvelope",
|
||||
@@ -163,6 +180,7 @@ __all__ = [
|
||||
"ProjectRead",
|
||||
"ProjectUpdate",
|
||||
"ProjectList",
|
||||
"ProjectDeleteResult",
|
||||
"AreaCreate",
|
||||
"AreaRead",
|
||||
"AreaUpdate",
|
||||
@@ -198,6 +216,7 @@ __all__ = [
|
||||
"DetectionRunResponse",
|
||||
"ModelAssetListResponse",
|
||||
"ModelAssetRead",
|
||||
"YoloPreflightResponse",
|
||||
"DetectionReviewList",
|
||||
"DetectionReviewRead",
|
||||
"DetectionReviewSummary",
|
||||
@@ -295,4 +314,6 @@ __all__ = [
|
||||
"ExportContentResponse",
|
||||
"QaProviderComparisonRequest",
|
||||
"QaProviderComparisonResult",
|
||||
"AnalysisQaResponse",
|
||||
"QualityEvidenceResponse",
|
||||
]
|
||||
|
||||
@@ -25,6 +25,7 @@ class AreaRead(BaseModel):
|
||||
area_m2: float | None
|
||||
created_at: datetime | None = None
|
||||
geometry_type: str | None = None
|
||||
geometry: dict | None = None
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
|
||||
@@ -30,6 +30,12 @@ class AssistantModelRead(BaseModel):
|
||||
capabilities: list[str] = Field(default_factory=list)
|
||||
|
||||
|
||||
class AssistantModelList(BaseModel):
|
||||
items: list[AssistantModelRead]
|
||||
total: int
|
||||
default_model: str | None = None
|
||||
|
||||
|
||||
class AssistantStatus(BaseModel):
|
||||
enabled: bool
|
||||
reachable: bool
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Generic, Literal, TypeVar
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class Envelope(BaseModel):
|
||||
data: object
|
||||
DataT = TypeVar("DataT")
|
||||
|
||||
|
||||
class PaginatedEnvelope(BaseModel):
|
||||
items: list
|
||||
class Envelope(BaseModel, Generic[DataT]):
|
||||
data: DataT
|
||||
|
||||
|
||||
class ItemList(BaseModel, Generic[DataT]):
|
||||
items: list[DataT]
|
||||
total: int
|
||||
|
||||
|
||||
class PaginatedEnvelope(ItemList[DataT], Generic[DataT]):
|
||||
limit: int
|
||||
offset: int
|
||||
|
||||
@@ -28,4 +36,19 @@ class ApiErrorItem(BaseModel):
|
||||
|
||||
|
||||
class ApiErrorEnvelope(BaseModel):
|
||||
error: ApiErrorItem
|
||||
error: str
|
||||
message: str
|
||||
details: dict | list = Field(default_factory=dict)
|
||||
request_id: str | None = None
|
||||
|
||||
|
||||
class GeoJsonFeature(BaseModel):
|
||||
type: Literal["Feature"]
|
||||
id: str | int | None = None
|
||||
geometry: dict[str, Any] | None
|
||||
properties: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class GeoJsonFeatureCollection(BaseModel):
|
||||
type: Literal["FeatureCollection"]
|
||||
features: list[GeoJsonFeature]
|
||||
|
||||
@@ -129,3 +129,48 @@ class DetectionRead(BaseModel):
|
||||
class DetectionListResponse(BaseModel):
|
||||
items: list[DetectionRead]
|
||||
total: int
|
||||
|
||||
|
||||
class YoloPreflightChecks(BaseModel):
|
||||
model_config = ConfigDict(protected_namespaces=())
|
||||
|
||||
enabled: bool
|
||||
dependencies_available: bool | None = None
|
||||
model_path_set: bool | None = None
|
||||
model_file_exists: bool | None = None
|
||||
model_load_requested: bool
|
||||
model_load_ok: bool | None = None
|
||||
manifest_path_set: bool | None = None
|
||||
manifest_valid: bool | None = None
|
||||
tile_paths_exist: bool | None = None
|
||||
tile_limit_ok: bool | None = None
|
||||
|
||||
|
||||
class YoloRuntimeDetails(BaseModel):
|
||||
model_config = ConfigDict(protected_namespaces=())
|
||||
|
||||
dependencies_assumed: bool
|
||||
model_directory: str | None = None
|
||||
yolo_config_dir: str | None = None
|
||||
torch_version: str | None = None
|
||||
ultralytics_version: str | None = None
|
||||
cuda_available: bool | None = None
|
||||
|
||||
|
||||
class YoloPreflightResponse(BaseModel):
|
||||
model_config = ConfigDict(protected_namespaces=())
|
||||
|
||||
model_id: str
|
||||
model_asset_id: str | None = None
|
||||
model_path: str | None = None
|
||||
tile_manifest_path: str | None = None
|
||||
status: str
|
||||
message: str
|
||||
checks: YoloPreflightChecks
|
||||
tile_count: int
|
||||
max_tiles: int
|
||||
will_download_models: bool
|
||||
will_run_inference: bool
|
||||
runtime: YoloRuntimeDetails
|
||||
error_code: str | None = None
|
||||
details: dict | None = None
|
||||
|
||||
@@ -41,3 +41,7 @@ class ProjectList(BaseModel):
|
||||
total: int
|
||||
limit: int
|
||||
offset: int
|
||||
|
||||
|
||||
class ProjectDeleteResult(BaseModel):
|
||||
deleted: bool
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
from uuid import UUID
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from app.schemas.common import GeoJsonFeatureCollection
|
||||
|
||||
|
||||
class QaProviderComparisonRequest(BaseModel):
|
||||
candidate_dataset_id: UUID
|
||||
@@ -72,3 +75,40 @@ class QualityCheckList(BaseModel):
|
||||
total: int
|
||||
limit: int
|
||||
offset: int
|
||||
|
||||
|
||||
class QualityEvidenceResponse(BaseModel):
|
||||
quality_check_id: UUID
|
||||
project_id: UUID
|
||||
candidate_dataset_id: UUID | None = None
|
||||
reference_dataset_id: UUID
|
||||
analysis_run_id: UUID | None = None
|
||||
feature_count: int
|
||||
warnings: list[str] = Field(default_factory=list)
|
||||
geojson: GeoJsonFeatureCollection
|
||||
|
||||
|
||||
class AnalysisQaResponse(BaseModel):
|
||||
status: str
|
||||
quality_check_id: UUID
|
||||
analysis_run_id: UUID
|
||||
reference_dataset_id: UUID
|
||||
candidate_feature_count: int
|
||||
reference_feature_count: int
|
||||
candidate_feature_count_raw: int | None = None
|
||||
reference_feature_count_raw: int | None = None
|
||||
matches: int
|
||||
false_positives: int
|
||||
false_negatives: int
|
||||
precision: float | None = None
|
||||
recall: float | None = None
|
||||
f1_score: float | None = None
|
||||
mean_iou: float | None = None
|
||||
iou_threshold: float
|
||||
warnings: list[str] = Field(default_factory=list)
|
||||
coverage: dict[str, Any] | None = None
|
||||
temporal_compatibility: dict[str, Any] | None = None
|
||||
box_to_footprint_diagnostics: dict[str, Any] | None = None
|
||||
match_evidence: list[dict[str, Any]] = Field(default_factory=list)
|
||||
false_positive_evidence: list[dict[str, Any]] = Field(default_factory=list)
|
||||
false_negative_evidence: list[dict[str, Any]] = Field(default_factory=list)
|
||||
|
||||
Reference in New Issue
Block a user