lexichunk 0.9.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lexichunk/__init__.py +66 -0
- lexichunk/_patterns.py +66 -0
- lexichunk/chunker.py +2049 -0
- lexichunk/documents.py +571 -0
- lexichunk/enrichment/__init__.py +1 -0
- lexichunk/enrichment/clause_type.py +660 -0
- lexichunk/enrichment/context.py +152 -0
- lexichunk/exceptions.py +25 -0
- lexichunk/ingestion/__init__.py +49 -0
- lexichunk/ingestion/_common.py +240 -0
- lexichunk/ingestion/docling.py +258 -0
- lexichunk/ingestion/markdown.py +111 -0
- lexichunk/ingestion/unstructured.py +171 -0
- lexichunk/integrations/__init__.py +1 -0
- lexichunk/integrations/langchain.py +361 -0
- lexichunk/integrations/llama_index.py +440 -0
- lexichunk/jurisdiction/__init__.py +207 -0
- lexichunk/jurisdiction/eu.py +182 -0
- lexichunk/jurisdiction/uk.py +144 -0
- lexichunk/jurisdiction/us.py +259 -0
- lexichunk/metrics.py +106 -0
- lexichunk/models.py +661 -0
- lexichunk/offsets.py +369 -0
- lexichunk/parsers/__init__.py +15 -0
- lexichunk/parsers/definitions.py +831 -0
- lexichunk/parsers/references.py +954 -0
- lexichunk/parsers/structure.py +1352 -0
- lexichunk/py.typed +0 -0
- lexichunk/strategies/__init__.py +34 -0
- lexichunk/strategies/_cascade.py +186 -0
- lexichunk/strategies/clause_aware.py +923 -0
- lexichunk/strategies/fallback.py +448 -0
- lexichunk/utils.py +92 -0
- lexichunk-0.9.0.dist-info/METADATA +881 -0
- lexichunk-0.9.0.dist-info/RECORD +38 -0
- lexichunk-0.9.0.dist-info/WHEEL +5 -0
- lexichunk-0.9.0.dist-info/licenses/LICENSE +21 -0
- lexichunk-0.9.0.dist-info/top_level.txt +1 -0
lexichunk/__init__.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""lexichunk — Legal document chunking SDK for RAG pipelines."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
from .chunker import ClassificationHook, LegalChunker
|
|
6
|
+
from .enrichment.clause_type import ClassificationResult
|
|
7
|
+
from .exceptions import (
|
|
8
|
+
ConfigurationError,
|
|
9
|
+
InputError,
|
|
10
|
+
LexichunkError,
|
|
11
|
+
ParsingError,
|
|
12
|
+
)
|
|
13
|
+
from .jurisdiction import (
|
|
14
|
+
register_jurisdiction,
|
|
15
|
+
registered_jurisdictions,
|
|
16
|
+
unregister_jurisdiction,
|
|
17
|
+
)
|
|
18
|
+
from .metrics import PipelineMetrics, StageMetric
|
|
19
|
+
from .offsets import OffsetMap, sanitize_with_map
|
|
20
|
+
|
|
21
|
+
# Library hygiene: don't emit "no handlers found" warnings for consumers who
|
|
22
|
+
# haven't configured logging. See docs/architecture.md "Logging and
|
|
23
|
+
# observability" for the DEBUG/WARNING policy this package follows.
|
|
24
|
+
logging.getLogger(__name__).addHandler(logging.NullHandler())
|
|
25
|
+
from .models import (
|
|
26
|
+
BatchError,
|
|
27
|
+
BatchResult,
|
|
28
|
+
ClauseType,
|
|
29
|
+
CrossReference,
|
|
30
|
+
DefinedTerm,
|
|
31
|
+
DocumentSection,
|
|
32
|
+
HierarchyNode,
|
|
33
|
+
Jurisdiction,
|
|
34
|
+
JurisdictionPatterns,
|
|
35
|
+
LegalChunk,
|
|
36
|
+
Section,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
__version__ = "0.9.0"
|
|
40
|
+
__all__ = [
|
|
41
|
+
"LegalChunker",
|
|
42
|
+
"ClassificationHook",
|
|
43
|
+
"LegalChunk",
|
|
44
|
+
"Section",
|
|
45
|
+
"HierarchyNode",
|
|
46
|
+
"CrossReference",
|
|
47
|
+
"ClassificationResult",
|
|
48
|
+
"DefinedTerm",
|
|
49
|
+
"ClauseType",
|
|
50
|
+
"DocumentSection",
|
|
51
|
+
"Jurisdiction",
|
|
52
|
+
"JurisdictionPatterns",
|
|
53
|
+
"BatchResult",
|
|
54
|
+
"BatchError",
|
|
55
|
+
"PipelineMetrics",
|
|
56
|
+
"StageMetric",
|
|
57
|
+
"OffsetMap",
|
|
58
|
+
"sanitize_with_map",
|
|
59
|
+
"register_jurisdiction",
|
|
60
|
+
"unregister_jurisdiction",
|
|
61
|
+
"registered_jurisdictions",
|
|
62
|
+
"LexichunkError",
|
|
63
|
+
"ConfigurationError",
|
|
64
|
+
"ParsingError",
|
|
65
|
+
"InputError",
|
|
66
|
+
]
|
lexichunk/_patterns.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Shared regex fragments for matching quoted defined-term names.
|
|
2
|
+
|
|
3
|
+
This module imports nothing from lexichunk, so both
|
|
4
|
+
:mod:`lexichunk.jurisdiction` and :mod:`lexichunk.parsers` can use it without
|
|
5
|
+
creating an import cycle.
|
|
6
|
+
|
|
7
|
+
Two defects motivated pulling these fragments out of the twenty-odd places
|
|
8
|
+
that previously spelled them inline:
|
|
9
|
+
|
|
10
|
+
* Every term-capture group used ``[A-Za-z\\s\\-]`` — letters, whitespace and
|
|
11
|
+
hyphen only. A document defining ``"R&D"``, ``"C++ Code"`` and
|
|
12
|
+
``"Level 1 Support"`` yielded *zero* terms, and the same happened for
|
|
13
|
+
``"Section 409A Plan"``, ``"Schedule 2 Services"`` and ``"Tier1"``. These
|
|
14
|
+
are ordinary term names in technology and commercial contracts, and the
|
|
15
|
+
loss was silent and total — not a mis-attachment, an absence.
|
|
16
|
+
|
|
17
|
+
* Nothing constrained what could precede an opening quote. In
|
|
18
|
+
``1.1 "Client's Data" means the data supplied by the client.`` the regex
|
|
19
|
+
engine treated the apostrophe inside ``Client's`` as an opening single
|
|
20
|
+
quote, matched ``[a-z]`` = ``s``, then ``" Data"``, then the real closing
|
|
21
|
+
``"`` — producing the bogus term ``"s Data"``. Possessive term names
|
|
22
|
+
("Seller's Knowledge", "Purchaser's Group", "Guarantor's Obligations") are
|
|
23
|
+
standard M&A and commercial drafting.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
#: Characters permitted *inside* a defined-term name, after the initial
|
|
29
|
+
#: letter. Digits and ``&``/``+`` are required by real term names; the two
|
|
30
|
+
#: apostrophe forms are required by possessive ones. Parentheses are
|
|
31
|
+
#: deliberately excluded so ``"Affiliate(s)"`` still reaches the dedicated
|
|
32
|
+
#: parenthesised-plural pattern rather than being captured verbatim.
|
|
33
|
+
TERM_CHARS = r"A-Za-z0-9\s\-&+'’"
|
|
34
|
+
|
|
35
|
+
#: A term name beginning with an upper-case letter.
|
|
36
|
+
TERM_UPPER = rf"[A-Z][{TERM_CHARS}]{{1,60}}"
|
|
37
|
+
|
|
38
|
+
#: A term name beginning with a lower-case letter.
|
|
39
|
+
TERM_LOWER = rf"[a-z][{TERM_CHARS}]{{1,60}}"
|
|
40
|
+
|
|
41
|
+
#: A term name beginning with a letter of either case.
|
|
42
|
+
TERM_ANY = rf"[A-Za-z][{TERM_CHARS}]{{1,60}}"
|
|
43
|
+
|
|
44
|
+
#: As :data:`TERM_ANY` but allowing a one-character name — used by the
|
|
45
|
+
#: parenthesised-plural pattern, where the ``(s)`` follows the stem.
|
|
46
|
+
TERM_ANY_SHORT = rf"[A-Za-z][{TERM_CHARS}]{{0,60}}"
|
|
47
|
+
|
|
48
|
+
#: A real opening quote is never preceded by a word character; a possessive
|
|
49
|
+
#: apostrophe always is. Guarding every opening-quote class with this
|
|
50
|
+
#: lookbehind is what stops ``Client's`` from opening a quote of its own.
|
|
51
|
+
#: It is a zero-width assertion, so it never shifts a capture group's number.
|
|
52
|
+
NOT_AFTER_WORD = r"(?<![A-Za-z0-9])"
|
|
53
|
+
|
|
54
|
+
#: Opening-quote character class, always used behind :data:`NOT_AFTER_WORD`.
|
|
55
|
+
OPEN_QUOTE = r"[\"'“‘]"
|
|
56
|
+
|
|
57
|
+
#: Closing-quote character class.
|
|
58
|
+
CLOSE_QUOTE = r"[\"'”’]"
|
|
59
|
+
|
|
60
|
+
#: Opening/closing pair for straight double + curly double quotes only.
|
|
61
|
+
OPEN_DOUBLE = r"[\"“]"
|
|
62
|
+
CLOSE_DOUBLE = r"[\"”]"
|
|
63
|
+
|
|
64
|
+
#: Opening/closing pair for straight single + curly single quotes only.
|
|
65
|
+
OPEN_SINGLE = r"['‘]"
|
|
66
|
+
CLOSE_SINGLE = r"['’]"
|