schemas.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. """Pydantic schemas returned by the formal workbench API."""
  2. from __future__ import annotations
  3. from datetime import datetime
  4. from typing import Any
  5. from uuid import UUID
  6. from pydantic import BaseModel, ConfigDict, Field
  7. class ApiSchema(BaseModel):
  8. model_config = ConfigDict(from_attributes=True)
  9. class Page(ApiSchema):
  10. total: int
  11. page: int = 1
  12. size: int = 50
  13. items: list[dict[str, Any]] = Field(default_factory=list)
  14. class ErrorResponse(ApiSchema):
  15. code: str
  16. message: str
  17. detail: dict[str, Any] = Field(default_factory=dict)
  18. class QueryBatchSchema(ApiSchema):
  19. id: UUID
  20. name: str
  21. source_type: str
  22. generation_method: str | None = None
  23. target_platforms: list[str] = Field(default_factory=list)
  24. status: str
  25. created_at: datetime | None = None
  26. updated_at: datetime | None = None
  27. class QuerySchema(ApiSchema):
  28. id: UUID
  29. batch_id: UUID | None = None
  30. query_text: str
  31. axes: dict[str, Any] = Field(default_factory=dict)
  32. keep: bool | None = None
  33. filter_reason: str | None = None
  34. status: str
  35. sort_order: int = 0
  36. class TopicTableQueryPreviewRequest(ApiSchema):
  37. topic_build_id: int = Field(gt=0)
  38. topic_id: int | None = Field(default=None, gt=0)
  39. max_queries: int = Field(default=18, ge=6, le=60)
  40. class MediaAssetSchema(ApiSchema):
  41. id: UUID
  42. item_id: UUID
  43. media_type: str
  44. source_url: str | None = None
  45. oss_url: str | None = None
  46. cdn_url: str | None = None
  47. position: int = 0
  48. status: str
  49. class ItemClassificationSchema(ApiSchema):
  50. id: UUID
  51. item_id: UUID
  52. is_creation_knowledge: bool | None = None
  53. label: str | None = None
  54. confidence: float | None = None
  55. reason: str | None = None
  56. status: str
  57. error_message: str | None = None
  58. class CandidateItemSchema(ApiSchema):
  59. id: UUID
  60. platform: str
  61. platform_item_id: str | None = None
  62. unique_key: str | None = None
  63. canonical_url: str | None = None
  64. content_type: str | None = None
  65. content_mode: str | None = None
  66. title: str | None = None
  67. author_name: str | None = None
  68. body_text: str | None = None
  69. raw_summary: str | None = None
  70. status: str
  71. metadata: dict[str, Any] = Field(default_factory=dict)
  72. error_message: str | None = None
  73. decode_summary: dict[str, Any] | None = None
  74. media_assets: list[MediaAssetSchema] = Field(default_factory=list)
  75. classification: ItemClassificationSchema | None = None
  76. class AcquisitionRunSummarySchema(ApiSchema):
  77. id: UUID
  78. run_key: str | None = None
  79. batch_id: UUID | None = None
  80. status: str
  81. query_count: int = 0
  82. job_count: int = 0
  83. candidate_count: int = 0
  84. creation_hit_count: int = 0
  85. decoded_count: int = 0
  86. payload_count: int = 0
  87. queries: list[dict[str, Any]] = Field(default_factory=list)
  88. started_at: datetime | None = None
  89. finished_at: datetime | None = None
  90. class DecodeResultSchema(ApiSchema):
  91. id: UUID
  92. item_id: UUID
  93. status: str
  94. read_result: dict[str, Any] = Field(default_factory=dict)
  95. gate_result: dict[str, Any] = Field(default_factory=dict)
  96. framing_result: dict[str, Any] = Field(default_factory=dict)
  97. class KnowledgeParticleSchema(ApiSchema):
  98. id: UUID
  99. decode_result_id: UUID | None = None
  100. item_id: UUID | None = None
  101. parent_particle_id: UUID | None = None
  102. particle_type: str
  103. title: str
  104. business_stage: str | None = None
  105. creation_stage: str | None = None
  106. content: dict[str, Any] = Field(default_factory=dict)
  107. status: str
  108. class ScopeResultSchema(ApiSchema):
  109. id: UUID
  110. particle_id: UUID | None = None
  111. item_id: UUID | None = None
  112. scope_type: str
  113. scope_value: str
  114. is_reused: bool | None = None
  115. matched_scope_id: str | None = None
  116. confidence: float | None = None
  117. status: str
  118. class PayloadDraftSchema(ApiSchema):
  119. id: UUID
  120. particle_id: UUID | None = None
  121. item_id: UUID | None = None
  122. payload: dict[str, Any] = Field(default_factory=dict)
  123. review_status: str
  124. ingest_ready: bool
  125. status: str
  126. class IngestRecordSchema(ApiSchema):
  127. id: UUID
  128. payload_draft_id: UUID | None = None
  129. target_system: str
  130. target_id: str | None = None
  131. status: str
  132. attempt_count: int = 0
  133. response_payload: dict[str, Any] = Field(default_factory=dict)
  134. error_message: str | None = None
  135. class IngestItemRequest(ApiSchema):
  136. dry_run: bool = True
  137. class IngestItemResultSchema(ApiSchema):
  138. payload_draft_id: UUID | None = None
  139. ingest_record: IngestRecordSchema
  140. class IngestItemResponse(ApiSchema):
  141. item_id: UUID
  142. dry_run: bool
  143. total: int
  144. ingested_count: int
  145. failed_count: int
  146. results: list[IngestItemResultSchema] = Field(default_factory=list)