Skip to content

Judgments facade

The recommended default entry point. See the facade guide for the routing rules and worked examples.

Judgments

Judgments

Judgments()

Federated facade over :class:ArchiveClient and :class:JudgmentSearchClient.

Example::

async with Judgments() as j:
    # Free-text → live
    hits = await j.find(text="right to privacy", limit=10)

    # Structured → archive
    hits = await j.find(judge="chandrachud", year=2020, court="sci")

    # CNR → archive (auto-routed via prefix)
    hits = await j.find(cnr="DLHC010230802020")

    # Force a specific source
    hits = await j.find(text="bail", source="live", limit=5)

    # PDF fetch — handles archive judgments + CNR strings whose prefix
    # resolves to an archive-supported court.
    pdf = await j.fetch_pdf("DLHC010230802020")
Source code in src/bharat_courts/facade.py
def __init__(self) -> None:
    self._archive = None
    self._live = None

find async

find(
    *,
    text: str | None = None,
    court: Court | str | None = None,
    year: int | tuple[int, int] | None = None,
    judge: str | None = None,
    party: str | None = None,
    citation: str | None = None,
    cnr: str | None = None,
    source: Source = "auto",
    limit: int = 50
) -> list[Judgment]

Find judgments. See module docstring for routing rules.

Source code in src/bharat_courts/facade.py
async def find(
    self,
    *,
    text: str | None = None,
    court: Court | str | None = None,
    year: int | tuple[int, int] | None = None,
    judge: str | None = None,
    party: str | None = None,
    citation: str | None = None,
    cnr: str | None = None,
    source: Source = "auto",
    limit: int = 50,
) -> list[Judgment]:
    """Find judgments. See module docstring for routing rules."""
    structured = any(x is not None for x in (court, year, judge, party, citation))
    backend = self._resolve_source(
        source=source,
        text=text,
        cnr=cnr,
        structured=structured,
    )
    _log.info("Judgments.find routing → %s", backend)

    if backend == "archive":
        return await self._find_archive(
            text=text,
            court=court,
            year=year,
            judge=judge,
            party=party,
            citation=citation,
            cnr=cnr,
            limit=limit,
        )
    return await self._find_live(text=text or "", limit=limit)

fetch_pdf async

fetch_pdf(
    judgment_or_cnr: Judgment | str,
    *,
    language: str = "english"
) -> bytes

Fetch a judgment PDF.

  • Archive judgments and CNR strings whose prefix maps to a known court → :meth:ArchiveClient.fetch_pdf.
  • Live :class:Judgment objects → not supported here yet; use JudgmentSearchClient.download_pdf directly (it needs the original :class:JudgmentResult + court_type).
Source code in src/bharat_courts/facade.py
async def fetch_pdf(
    self,
    judgment_or_cnr: Judgment | str,
    *,
    language: str = "english",
) -> bytes:
    """Fetch a judgment PDF.

    - Archive judgments and CNR strings whose prefix maps to a known
      court → :meth:`ArchiveClient.fetch_pdf`.
    - Live :class:`Judgment` objects → not supported here yet; use
      ``JudgmentSearchClient.download_pdf`` directly (it needs the
      original :class:`JudgmentResult` + ``court_type``).
    """
    if isinstance(judgment_or_cnr, Judgment) and judgment_or_cnr.source == "live":
        raise NotImplementedError(
            "PDFs for live judgments must be fetched via "
            "JudgmentSearchClient.download_pdf(judgment_result, court_type) — "
            "the live download needs the original JudgmentResult instance."
        )
    archive = await self._get_archive()
    return await archive.fetch_pdf(judgment_or_cnr, language=language)

live_to_judgment

live_to_judgment

live_to_judgment(jr: JudgmentResult) -> Judgment

Map a live :class:JudgmentResult to the unified :class:Judgment.

Field mapping:

==================== ==================================================== JudgmentResult Judgment ==================== ==================================================== title title court_name court_name_raw; resolved into court via the courts registry if a match is found source_id cnr (the judgments portal uses CNR as its id) judges judges judgment_date decision_date citation citation (when non-empty) pdf_url pdf_path (raw path; live download needs the original JudgmentResult, not just the path) metadata["disposal_nature"] disposal_nature metadata["registration_date"] date_of_registration ==================== ====================================================

Source code in src/bharat_courts/facade.py
def live_to_judgment(jr: JudgmentResult) -> Judgment:
    """Map a live :class:`JudgmentResult` to the unified :class:`Judgment`.

    Field mapping:

    ====================  ====================================================
    JudgmentResult         Judgment
    ====================  ====================================================
    ``title``              ``title``
    ``court_name``         ``court_name_raw``; resolved into ``court`` via
                           the courts registry if a match is found
    ``source_id``          ``cnr`` (the judgments portal uses CNR as its id)
    ``judges``             ``judges``
    ``judgment_date``      ``decision_date``
    ``citation``           ``citation`` (when non-empty)
    ``pdf_url``            ``pdf_path`` (raw path; live download needs the
                           original JudgmentResult, not just the path)
    ``metadata["disposal_nature"]``   ``disposal_nature``
    ``metadata["registration_date"]`` ``date_of_registration``
    ====================  ====================================================
    """
    court = get_court_by_name(jr.court_name) if jr.court_name else None
    reg_date = _parse_iso_date(jr.metadata.get("registration_date"))
    year = jr.judgment_date.year if jr.judgment_date else None
    return Judgment(
        cnr=jr.source_id or None,
        title=jr.title or None,
        court=court,
        court_name_raw=jr.court_name or "",
        judges=list(jr.judges),
        decision_date=jr.judgment_date,
        date_of_registration=reg_date,
        disposal_nature=jr.metadata.get("disposal_nature") or None,
        citation=jr.citation or None,
        pdf_path=jr.pdf_url or None,
        source="live",
        year=year,
    )