Legora / db /parsers /bns /chunker.py
sai-Rohan's picture
combined results of all parsers and made a single pipeline
dbabef2
Raw
History Blame Contribute Delete
11.5 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]
title: str
text: str
enriched_text: str
parent_id: Optional[str]
# =========================================================
# CHUNKER
# =========================================================
class LegalChunker:
def __init__(
self,
document_name: str = "BNS"
):
self.document_name = document_name
# -----------------------------------------------------
# Helpers
# -----------------------------------------------------
def build_context(
self,
title: str,
section_no: str = "",
clause_no: str = "",
sub_clause_no: str = "",
roman_no: str = ""
) -> str:
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 Clause ({roman_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"BNS-{section.section_no}"
)
title = (
getattr(
section,
"title",
""
)
)
# =================================
# SECTION CHUNK
# =================================
section_chunk = LegalChunk(
chunk_id=section_id,
level="section",
document="bns",
chapter_no=
chapter.chapter_no,
section_no=
section.section_no,
clause_no=None,
sub_clause_no=None,
roman_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
)
chunks.append(
section_chunk
)
# =================================
# CLAUSES
# =================================
for clause in section.clauses:
clause_id = (
f"{section_id}"
f"({clause.clause_no})"
)
clause_chunk = LegalChunk(
chunk_id=
clause_id,
level=
"clause",
document=
"bns",
chapter_no=
chapter.chapter_no,
section_no=
section.section_no,
clause_no=
clause.clause_no,
sub_clause_no=
None,
roman_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
)
chunks.append(
clause_chunk
)
# =============================
# SUB CLAUSES
# =============================
for sub in clause.sub_clauses:
sub_id = (
f"{clause_id}"
f"({sub.sub_clause_no})"
)
sub_chunk = LegalChunk(
chunk_id=
sub_id,
level=
"subclause",
document=
"bns",
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,
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
)
chunks.append(
sub_chunk
)
# =========================
# ROMAN CLAUSES
# =========================
for roman in sub.roman_clauses:
roman_id = (
f"{sub_id}"
f"({roman.roman_no})"
)
roman_chunk = LegalChunk(
chunk_id=
roman_id,
level=
"roman",
document=
"bns",
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,
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
)
chunks.append(
roman_chunk
)
# =================================
# EXPLANATIONS
# =================================
for explanation in (
section.explanations
):
explanation_id = (
f"{section_id}"
f"-EXP-"
f"{explanation.explanation_no}"
)
chunk = LegalChunk(
chunk_id=
explanation_id,
level=
"explanation",
document=
"bns",
chapter_no=
chapter.chapter_no,
section_no=
section.section_no,
clause_no=None,
sub_clause_no=None,
roman_no=None,
title=title,
text=
explanation.text,
enriched_text=
self.build_context(
title=title,
section_no=
section.section_no
)
+ "\n\n"
+ explanation.text,
parent_id=
section_id
)
chunks.append(
chunk
)
return chunks
# =========================================================
# EXPORT
# =========================================================
def chunks_to_dicts(
chunks: List[LegalChunk]
):
return [
asdict(chunk)
for chunk in chunks
]