Skip to content

Commit 623b522

Browse files
authored
fix: type fix (#399)
1 parent ac40847 commit 623b522

1 file changed

Lines changed: 56 additions & 11 deletions

File tree

services/python-bridge/main.py

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
from pydantic import BaseModel, ValidationError
2-
from typing import Optional, Union, List, TypedDict
3-
from flask import Flask, jsonify, request, abort
2+
from typing import Optional, Union, List, TypedDict, cast
3+
from flask import Flask, jsonify, request, abort, Response
44
from reddwarf.data_loader import Loader
55
from reddwarf.implementations.polis import run_pipeline
66
import logging
77
import sys
88
import traceback
99
from datetime import datetime
1010
from logging.handlers import RotatingFileHandler
11+
import pandas as pd
1112

1213
from pprint import pprint
1314

@@ -54,7 +55,7 @@ def print_summary(loader: Loader):
5455

5556

5657
@app.route("/import")
57-
def importConversation():
58+
def importConversation() -> Response:
5859
report_id = request.args.get("report_id")
5960
conversation_id = request.args.get("conversation_id")
6061
if report_id is None and conversation_id is None:
@@ -77,7 +78,7 @@ def importConversation():
7778
"votes_data": loader.votes_data,
7879
}
7980
)
80-
if conversation_id is not None:
81+
else: # conversation_id is not None
8182
logger.info(
8283
f"Loading Polis conversation from conversation_id={conversation_id}"
8384
)
@@ -116,19 +117,63 @@ class MathRequest(BaseModel):
116117
votes: List[VoteRecord]
117118

118119

120+
class ConsensusStatement(TypedDict):
121+
tid: int
122+
n_success: int
123+
n_trials: int
124+
p_success: float
125+
p_test: float
126+
cons_for: str
127+
128+
119129
class Consensus(TypedDict):
120-
agree: List
121-
disagree: List
130+
agree: List[ConsensusStatement]
131+
disagree: List[ConsensusStatement]
132+
133+
134+
class RepnessStatement(TypedDict):
135+
tid: int
136+
n_success: int
137+
n_trials: int
138+
p_success: float
139+
p_test: float
140+
repness: float
141+
repness_test: float
142+
repful_for: str # Literal["agree", "disagree"] but simplified for compatibility
143+
best_agree: Union[bool, None] # NotRequired in TypedDict
144+
n_agree: Union[int, None] # NotRequired in TypedDict
145+
146+
147+
# PolisRepness is dict[str | GroupId, list[PolisRepnessStatement]]
148+
# GroupId is an int, so the key can be str or int
149+
Repness = dict[Union[str, int], List[RepnessStatement]]
122150

123151

124152
class MathResult(TypedDict):
125-
statements_df: List
126-
participants_df: List
127-
repness: dict
153+
statements_df: List[dict]
154+
participants_df: List[dict]
155+
repness: Repness
128156
group_comment_stats: dict
129157
consensus: Consensus
130158

131159

160+
def convert_to_json_serializable(obj):
161+
"""
162+
Recursively converts pandas Series, DataFrames, and other non-JSON-serializable
163+
types to JSON-serializable formats.
164+
"""
165+
if isinstance(obj, pd.Series):
166+
return obj.to_dict()
167+
elif isinstance(obj, pd.DataFrame):
168+
return obj.to_dict(orient="records")
169+
elif isinstance(obj, dict):
170+
return {key: convert_to_json_serializable(value) for key, value in obj.items()}
171+
elif isinstance(obj, (list, tuple)):
172+
return [convert_to_json_serializable(item) for item in obj]
173+
else:
174+
return obj
175+
176+
132177
def calculate_distribution_imbalance(member_counts):
133178
"""
134179
Calculate how imbalanced the distribution is across groups.
@@ -373,9 +418,9 @@ def get_maths(
373418
"participants_df": result.participants_df.reset_index().to_dict(
374419
orient="records"
375420
),
376-
"repness": result.repness,
421+
"repness": cast(Repness, convert_to_json_serializable(result.repness)),
377422
"group_comment_stats": group_comment_stats,
378-
"consensus": result.consensus,
423+
"consensus": cast(Consensus, convert_to_json_serializable(result.consensus)),
379424
}
380425

381426

0 commit comments

Comments
 (0)