Legora / db /parsers /bsa /chunker.py
sai-Rohan's picture
added more complex bsa parser
660dde6
Raw
History Blame Contribute Delete
14.9 kB
from __future__ import annotations
from dataclasses import (
dataclass,
asdict
)
from typing import (
List,
Optional
)
# =========================================================
# CHUNK MODEL
# =========================================================
@dataclass
class LegalChunk:
chunk_id: str
level: str
document: str
chapter_no: Optional[str]
section_no: Optional[str]
clause_no: Optional[str]
sub_clause_no: Optional[str]
roman_no: Optional[str]
illustration_no: Optional[str]
explanation_no: Optional[str]
title: str
text: str
enriched_text: str
parent_id: Optional[str]
# =========================================================
# CHUNKER
# =========================================================
class LegalChunker:
def __init__(
self,
document_name="BSA"
):
self.document_name = document_name
# =====================================================
# CONTEXT
# =====================================================
def build_context(
self,
title="",
section_no="",
clause_no="",
sub_clause_no="",
roman_no="",
illustration_no="",
explanation_no=""
):
parts = [
self.document_name
]
if section_no:
parts.append(
f"Section {section_no}"
)
if title:
parts.append(title)
if clause_no:
parts.append(
f"Clause ({clause_no})"
)
if sub_clause_no:
parts.append(
f"SubClause ({sub_clause_no})"
)
if roman_no:
parts.append(
f"Roman ({roman_no})"
)
if explanation_no:
parts.append(
f"Explanation {explanation_no}"
)
if illustration_no:
parts.append(
f"Illustration {illustration_no}"
)
return "\n".join(parts)
# =====================================================
# MAIN
# =====================================================
def chunk_document(
self,
document
) -> List[LegalChunk]:
chunks = []
for chapter in document.chapters:
for section in chapter.sections:
section_id = (
f"BSA-{section.section_no}"
)
title = getattr(
section,
"title",
getattr(
section,
"section_title",
""
)
)
# =================================
# SECTION
# =================================
chunks.append(
LegalChunk(
chunk_id=
section_id,
level=
"section",
document=
"bsa",
chapter_no=
chapter.chapter_no,
section_no=
section.section_no,
clause_no=None,
sub_clause_no=None,
roman_no=None,
illustration_no=None,
explanation_no=None,
title=
title,
text=
section.text,
enriched_text=
self.build_context(
title=title,
section_no=
section.section_no
)
+ "\n\n"
+ section.text,
parent_id=None
)
)
# =================================
# CLAUSES
# =================================
for clause in section.clauses:
clause_id = (
f"{section_id}"
f"({clause.clause_no})"
)
chunks.append(
LegalChunk(
chunk_id=
clause_id,
level=
"clause",
document=
"bsa",
chapter_no=
chapter.chapter_no,
section_no=
section.section_no,
clause_no=
clause.clause_no,
sub_clause_no=None,
roman_no=None,
illustration_no=None,
explanation_no=None,
title=
title,
text=
clause.text,
enriched_text=
self.build_context(
title=title,
section_no=
section.section_no,
clause_no=
clause.clause_no
)
+ "\n\n"
+ clause.text,
parent_id=
section_id
)
)
# =============================
# SUBCLAUSES
# =============================
for sub in clause.sub_clauses:
sub_id = (
f"{clause_id}"
f"({sub.sub_clause_no})"
)
chunks.append(
LegalChunk(
chunk_id=
sub_id,
level=
"subclause",
document=
"bsa",
chapter_no=
chapter.chapter_no,
section_no=
section.section_no,
clause_no=
clause.clause_no,
sub_clause_no=
sub.sub_clause_no,
roman_no=None,
illustration_no=None,
explanation_no=None,
title=
title,
text=
sub.text,
enriched_text=
self.build_context(
title=title,
section_no=
section.section_no,
clause_no=
clause.clause_no,
sub_clause_no=
sub.sub_clause_no
)
+ "\n\n"
+ sub.text,
parent_id=
clause_id
)
)
# =========================
# ROMANS
# =========================
for roman in sub.roman_clauses:
roman_id = (
f"{sub_id}"
f"({roman.roman_no})"
)
chunks.append(
LegalChunk(
chunk_id=
roman_id,
level=
"roman",
document=
"bsa",
chapter_no=
chapter.chapter_no,
section_no=
section.section_no,
clause_no=
clause.clause_no,
sub_clause_no=
sub.sub_clause_no,
roman_no=
roman.roman_no,
illustration_no=None,
explanation_no=None,
title=
title,
text=
roman.text,
enriched_text=
self.build_context(
title=title,
section_no=
section.section_no,
clause_no=
clause.clause_no,
sub_clause_no=
sub.sub_clause_no,
roman_no=
roman.roman_no
)
+ "\n\n"
+ roman.text,
parent_id=
sub_id
)
)
# =================================
# EXPLANATIONS
# =================================
for exp in section.explanations:
exp_no = (
exp.explanation_no
or "0"
)
exp_id = (
f"{section_id}"
f"-EXP-{exp_no}"
)
chunks.append(
LegalChunk(
chunk_id=
exp_id,
level=
"explanation",
document=
"bsa",
chapter_no=
chapter.chapter_no,
section_no=
section.section_no,
clause_no=None,
sub_clause_no=None,
roman_no=None,
illustration_no=None,
explanation_no=
exp_no,
title=
title,
text=
exp.text,
enriched_text=
self.build_context(
title=title,
section_no=
section.section_no,
explanation_no=
exp_no
)
+ "\n\n"
+ exp.text,
parent_id=
section_id
)
)
# =================================
# ILLUSTRATIONS
# =================================
for ill in section.illustrations:
ill_no = (
ill.illustration_no
or "0"
)
ill_id = (
f"{section_id}"
f"-ILL-{ill_no}"
)
chunks.append(
LegalChunk(
chunk_id=
ill_id,
level=
"illustration",
document=
"bsa",
chapter_no=
chapter.chapter_no,
section_no=
section.section_no,
clause_no=None,
sub_clause_no=None,
roman_no=None,
illustration_no=
ill_no,
explanation_no=None,
title=
title,
text=
ill.text,
enriched_text=
self.build_context(
title=title,
section_no=
section.section_no,
illustration_no=
ill_no
)
+ "\n\n"
+ ill.text,
parent_id=
section_id
)
)
return chunks
# =========================================================
# EXPORT
# =========================================================
def chunks_to_dicts(
chunks: List[LegalChunk]
):
return [
asdict(chunk)
for chunk in chunks
]