-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathschemas.py
More file actions
107 lines (79 loc) · 3.19 KB
/
Copy pathschemas.py
File metadata and controls
107 lines (79 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
from datetime import datetime
from typing import Literal
from pydantic import BaseModel, ConfigDict, Field, field_validator
class StrictModel(BaseModel):
model_config = ConfigDict(extra="forbid")
class CommunityPost(StrictModel):
post_id: str = Field(min_length=1, max_length=100)
subreddit: str = Field(min_length=1, max_length=100)
title: str = Field(min_length=1, max_length=500)
body: str = Field(max_length=20_000)
author_karma: int | None = None
author_account_age_days: int | None = Field(default=None, ge=0)
posting_frequency: str | None = Field(default=None, min_length=1, max_length=100)
upvote_ratio: float | None = Field(default=None, ge=0, le=1)
score: int
community_flags: int | None = Field(default=None, ge=0)
num_comments: int | None = Field(default=None, ge=0)
url: str | None = None
created_at: datetime
@field_validator("created_at")
@classmethod
def require_timezone(cls, value):
if value.tzinfo is None:
raise ValueError("created_at must include a timezone")
return value
class ClassifierOutput(StrictModel):
engagement_score: float = Field(ge=0, le=1)
engagement_tier: Literal["low", "medium", "high"]
score_signal: float = Field(ge=0, le=1)
comment_signal: float = Field(ge=0, le=1)
reasoning: str = Field(min_length=1, max_length=2_000)
class ClassificationResult(ClassifierOutput):
post_id: str
class PolicyResult(StrictModel):
post_id: str
status: Literal["pass", "review", "reject"]
passes_filter: bool
filter_reason: str
policy_citation: Literal["Policy 1.1", "Policy 1.2", "Policy 1.3"]
confidence: Literal["high", "medium", "low"]
class TrendCandidate(StrictModel):
topic: str
post_ids: list[str]
representative_excerpt: str
sentiment: Literal["positive", "negative", "neutral", "mixed"]
class TrendCandidateOutput(StrictModel):
topic_clusters: list[TrendCandidate]
dominant_theme: str
class TopicCluster(TrendCandidate):
post_count: int = Field(ge=0)
support_share: float = Field(ge=0, le=1)
active_week_buckets: list[int]
recurrence_ratio: float = Field(ge=0, le=1)
status: Literal["signal", "trend"]
class TrendOutput(StrictModel):
topic_clusters: list[TopicCluster]
dominant_theme: str
confirmed_trend_count: int = Field(ge=0)
emerging_flag: bool
class Alert(StrictModel):
alert_type: str
severity: Literal["low", "medium", "high"]
summary: str
recommended_action: str
class LensOutput(StrictModel):
community_health_index: float = Field(ge=0, le=100)
engagement_weighted_sentiment: float = Field(ge=-1, le=1)
dominant_narrative: str
signal_quality_score: float = Field(ge=0, le=1)
alerts: list[Alert]
cmo_briefing: str
class AppealRequest(StrictModel):
post_id: str = Field(min_length=1, max_length=100)
appellant: str = Field(min_length=1, max_length=100)
rationale: str = Field(min_length=1, max_length=2_000)
class AppealRecord(AppealRequest):
appeal_id: str = Field(min_length=1, max_length=100)
policy_status_at_submission: Literal["pass", "review", "reject"]
review_status: Literal["pending", "accepted", "denied"] = "pending"