SarahXia0405 commited on
Commit
a596edc
·
verified ·
1 Parent(s): cdb6eba

Update src/extractors.py

Browse files
Files changed (1) hide show
  1. src/extractors.py +30 -13
src/extractors.py CHANGED
@@ -1,14 +1,15 @@
1
  from __future__ import annotations
 
2
  import pandas as pd
3
 
4
- from schema import ExtractionResult, DealSnapshot, ClassifiedTable
5
  from normalize import clean_text, find_first
6
  from table_classifier import classify_table
7
 
 
8
  def extract_snapshot_from_text(text: str) -> DealSnapshot:
9
  t = clean_text(text)
10
 
11
- # VERY IMPORTANT: 先用 deterministic regex 抽取你最常用字段
12
  property_name = find_first([
13
  r"Property Name[:\s]+(.+?)(?:\s{2,}|Address|Location|$)",
14
  r"Offering Memorandum[:\s]+(.+?)(?:\s{2,}|$)",
@@ -74,28 +75,44 @@ def extract_snapshot_from_text(text: str) -> DealSnapshot:
74
 
75
  return snapshot
76
 
77
- def extract_tables(read) -> list[ClassifiedTable]:
78
- out = []
79
- for tb in getattr(read, "tables", []) or []:
80
- page = int(tb.get("page", -1))
81
- rows = tb.get("rows", []) or []
 
 
 
82
  if not rows:
83
  continue
84
 
85
- headers = rows[0]
86
  data_rows = rows[1:] if len(rows) > 1 else []
 
87
  table_type = classify_table(headers=headers, rows=data_rows)
88
 
89
- # make df
90
- df = pd.DataFrame(data_rows, columns=[h or f"col_{i}" for i, h in enumerate(headers)])
91
- out.append(ClassifiedTable(page=page, table_type=table_type, df=df.to_dict(orient="records")))
 
 
 
 
 
 
 
 
 
 
 
 
92
  return out
93
 
94
- def extract_deal_snapshot(filename: str, read) -> ExtractionResult:
 
95
  snapshot = extract_snapshot_from_text(read.text or "")
96
  tables = extract_tables(read)
97
 
98
- # NOTE: streamlit 展示时需要 dataframe,所以 dict->df 在 UI 里做
99
  return ExtractionResult(
100
  filename=filename,
101
  snapshot=snapshot,
 
1
  from __future__ import annotations
2
+
3
  import pandas as pd
4
 
5
+ from schema import ExtractionResult, DealSnapshot, ClassifiedTable, ReadResult
6
  from normalize import clean_text, find_first
7
  from table_classifier import classify_table
8
 
9
+
10
  def extract_snapshot_from_text(text: str) -> DealSnapshot:
11
  t = clean_text(text)
12
 
 
13
  property_name = find_first([
14
  r"Property Name[:\s]+(.+?)(?:\s{2,}|Address|Location|$)",
15
  r"Offering Memorandum[:\s]+(.+?)(?:\s{2,}|$)",
 
75
 
76
  return snapshot
77
 
78
+
79
+ def extract_tables(read: ReadResult) -> list[ClassifiedTable]:
80
+ out: list[ClassifiedTable] = []
81
+
82
+ for tb in (read.tables or []):
83
+ # ✅ tb is TableExtract (pydantic model), NOT dict
84
+ page = int(tb.page) if tb.page is not None else -1
85
+ rows = tb.rows or []
86
  if not rows:
87
  continue
88
 
89
+ headers = rows[0] if len(rows) >= 1 else []
90
  data_rows = rows[1:] if len(rows) > 1 else []
91
+
92
  table_type = classify_table(headers=headers, rows=data_rows)
93
 
94
+ # DataFrame -> json-serializable rows (list[dict])
95
+ if headers:
96
+ cols = [(h.strip() if isinstance(h, str) and h.strip() else f"col_{i}") for i, h in enumerate(headers)]
97
+ df = pd.DataFrame(data_rows, columns=cols)
98
+ else:
99
+ df = pd.DataFrame(data_rows)
100
+
101
+ out.append(
102
+ ClassifiedTable(
103
+ page=page,
104
+ table_type=table_type,
105
+ rows=df.to_dict(orient="records"), # ✅ schema field is rows
106
+ )
107
+ )
108
+
109
  return out
110
 
111
+
112
+ def extract_deal_snapshot(filename: str, read: ReadResult) -> ExtractionResult:
113
  snapshot = extract_snapshot_from_text(read.text or "")
114
  tables = extract_tables(read)
115
 
 
116
  return ExtractionResult(
117
  filename=filename,
118
  snapshot=snapshot,