hanlp-haystack 2.1.1__tar.gz → 2.2.0__tar.gz
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.
- {hanlp_haystack-2.1.1 → hanlp_haystack-2.2.0}/CHANGELOG.md +7 -0
- {hanlp_haystack-2.1.1 → hanlp_haystack-2.2.0}/PKG-INFO +3 -2
- hanlp_haystack-2.2.0/pydoc/config_docusaurus.yml +13 -0
- {hanlp_haystack-2.1.1 → hanlp_haystack-2.2.0}/pyproject.toml +18 -5
- {hanlp_haystack-2.1.1 → hanlp_haystack-2.2.0}/src/haystack_integrations/components/preprocessors/hanlp/chinese_document_splitter.py +2 -4
- {hanlp_haystack-2.1.1 → hanlp_haystack-2.2.0}/tests/test_chinese_document_splitter.py +141 -33
- hanlp_haystack-2.1.1/pydoc/config_docusaurus.yml +0 -28
- {hanlp_haystack-2.1.1 → hanlp_haystack-2.2.0}/.gitignore +0 -0
- {hanlp_haystack-2.1.1 → hanlp_haystack-2.2.0}/LICENSE.txt +0 -0
- {hanlp_haystack-2.1.1 → hanlp_haystack-2.2.0}/README.md +0 -0
- {hanlp_haystack-2.1.1 → hanlp_haystack-2.2.0}/src/haystack_integrations/components/preprocessors/hanlp/__init__.py +0 -0
- {hanlp_haystack-2.1.1 → hanlp_haystack-2.2.0}/src/haystack_integrations/components/preprocessors/py.typed +0 -0
- {hanlp_haystack-2.1.1 → hanlp_haystack-2.2.0}/tests/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hanlp-haystack
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: An integration of Han Language Processing - HanLP as a ChineseDocumentSplitter component.
|
|
5
5
|
Project-URL: Documentation, https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/hanlp#readme
|
|
6
6
|
Project-URL: Issues, https://github.com/deepset-ai/haystack-core-integrations/issues
|
|
@@ -15,12 +15,13 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
19
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
19
20
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
20
21
|
Requires-Python: >=3.10
|
|
21
22
|
Requires-Dist: hanlp>=2.1.1
|
|
22
23
|
Requires-Dist: haystack-ai>=2.22.0
|
|
23
|
-
Requires-Dist: tokenizers>=0.
|
|
24
|
+
Requires-Dist: tokenizers>=0.21.0
|
|
24
25
|
Requires-Dist: transformers<5,>=4.1.1
|
|
25
26
|
Description-Content-Type: text/markdown
|
|
26
27
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
loaders:
|
|
2
|
+
- modules:
|
|
3
|
+
- haystack_integrations.components.preprocessors.hanlp.chinese_document_splitter
|
|
4
|
+
search_path: [../src]
|
|
5
|
+
processors:
|
|
6
|
+
- type: filter
|
|
7
|
+
documented_only: true
|
|
8
|
+
skip_empty_modules: true
|
|
9
|
+
renderer:
|
|
10
|
+
description: HanLP integration for Haystack
|
|
11
|
+
id: integrations-hanlp
|
|
12
|
+
filename: hanlp.md
|
|
13
|
+
title: HanLP
|
|
@@ -19,6 +19,7 @@ classifiers = [
|
|
|
19
19
|
"Programming Language :: Python :: 3.11",
|
|
20
20
|
"Programming Language :: Python :: 3.12",
|
|
21
21
|
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Programming Language :: Python :: 3.14",
|
|
22
23
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
23
24
|
"Programming Language :: Python :: Implementation :: PyPy",
|
|
24
25
|
]
|
|
@@ -27,8 +28,8 @@ dependencies = [
|
|
|
27
28
|
"hanlp>=2.1.1",
|
|
28
29
|
# the following pins can be removed once HanLP supports transformers 5
|
|
29
30
|
"transformers>=4.1.1,<5",
|
|
30
|
-
# tokenizers is a dependency of transformers. The following version is the first one which supports Python 3.
|
|
31
|
-
"tokenizers>=0.
|
|
31
|
+
# tokenizers is a dependency of transformers. The following version is the first one which supports Python 3.14.
|
|
32
|
+
"tokenizers>=0.21.0",
|
|
32
33
|
]
|
|
33
34
|
|
|
34
35
|
[project.urls]
|
|
@@ -52,7 +53,7 @@ installer = "uv"
|
|
|
52
53
|
dependencies = ["haystack-pydoc-tools", "ruff"]
|
|
53
54
|
|
|
54
55
|
[tool.hatch.envs.default.scripts]
|
|
55
|
-
docs = ["pydoc
|
|
56
|
+
docs = ["haystack-pydoc pydoc/config_docusaurus.yml"]
|
|
56
57
|
fmt = "ruff check --fix {args}; ruff format {args}"
|
|
57
58
|
fmt-check = "ruff check {args} && ruff format --check {args}"
|
|
58
59
|
|
|
@@ -70,7 +71,8 @@ dependencies = [
|
|
|
70
71
|
unit = 'pytest -m "not integration" {args:tests}'
|
|
71
72
|
integration = 'pytest -m "integration" {args:tests}'
|
|
72
73
|
all = 'pytest {args:tests}'
|
|
73
|
-
cov-retry = 'pytest --cov=haystack_integrations --reruns 3 --reruns-delay 30 -x {args:tests}'
|
|
74
|
+
unit-cov-retry = 'pytest --cov=haystack_integrations --reruns 3 --reruns-delay 30 -x -m "not integration" {args:tests}'
|
|
75
|
+
integration-cov-append-retry = 'pytest --cov=haystack_integrations --cov-append --reruns 3 --reruns-delay 30 -x -m "integration" {args:tests}'
|
|
74
76
|
types = """mypy -p haystack_integrations.components.preprocessors.hanlp {args}"""
|
|
75
77
|
|
|
76
78
|
[tool.mypy]
|
|
@@ -96,9 +98,17 @@ line-length = 120
|
|
|
96
98
|
[tool.ruff.lint]
|
|
97
99
|
select = [
|
|
98
100
|
"A",
|
|
101
|
+
"ANN",
|
|
99
102
|
"ARG",
|
|
100
103
|
"B",
|
|
101
104
|
"C",
|
|
105
|
+
"D102", # Missing docstring in public method
|
|
106
|
+
"D103", # Missing docstring in public function
|
|
107
|
+
"D205", # 1 blank line required between summary line and description
|
|
108
|
+
"D209", # Closing triple quotes go to new line
|
|
109
|
+
"D213", # summary lines must be positioned on the second physical line of the docstring
|
|
110
|
+
"D417", # Missing argument descriptions in the docstring
|
|
111
|
+
"D419", # Docstring is empty
|
|
102
112
|
"DTZ",
|
|
103
113
|
"E",
|
|
104
114
|
"EM",
|
|
@@ -139,6 +149,8 @@ ignore = [
|
|
|
139
149
|
"ARG005",
|
|
140
150
|
"RUF001",
|
|
141
151
|
"RUF002",
|
|
152
|
+
# Allow `Any` - used legitimately for dynamic types and SDK boundaries
|
|
153
|
+
"ANN401",
|
|
142
154
|
]
|
|
143
155
|
|
|
144
156
|
[tool.ruff.lint.isort]
|
|
@@ -149,11 +161,12 @@ ban-relative-imports = "parents"
|
|
|
149
161
|
|
|
150
162
|
[tool.ruff.lint.per-file-ignores]
|
|
151
163
|
# Tests can use magic values, assertions, and relative imports
|
|
152
|
-
"tests/**/*" = ["PLR2004", "S101", "TID252"]
|
|
164
|
+
"tests/**/*" = ["D", "PLR2004", "S101", "TID252", "ANN"]
|
|
153
165
|
|
|
154
166
|
[tool.coverage.run]
|
|
155
167
|
source = ["haystack_integrations"]
|
|
156
168
|
branch = true
|
|
169
|
+
relative_files = true
|
|
157
170
|
parallel = false
|
|
158
171
|
|
|
159
172
|
[tool.coverage.report]
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
from collections.abc import Callable
|
|
6
6
|
from copy import deepcopy
|
|
7
|
+
from dataclasses import replace
|
|
7
8
|
from typing import Any, Literal
|
|
8
9
|
|
|
9
10
|
from haystack import Document, component, logging
|
|
@@ -440,10 +441,7 @@ class ChineseDocumentSplitter:
|
|
|
440
441
|
previous_doc_start_idx = splits_start_idxs[i - 1]
|
|
441
442
|
self._add_split_overlap_information(doc, doc_start_idx, previous_doc, previous_doc_start_idx)
|
|
442
443
|
|
|
443
|
-
for d in documents
|
|
444
|
-
if d.content is not None:
|
|
445
|
-
d.content = d.content.replace(" ", "")
|
|
446
|
-
return documents
|
|
444
|
+
return [replace(d, content=d.content.replace(" ", "")) if d.content is not None else d for d in documents]
|
|
447
445
|
|
|
448
446
|
@staticmethod
|
|
449
447
|
def _add_split_overlap_information(
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
#
|
|
3
3
|
# SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
|
|
5
|
+
from unittest.mock import MagicMock, patch
|
|
6
|
+
|
|
5
7
|
import pytest
|
|
6
8
|
from haystack import Document
|
|
7
9
|
from haystack.utils import deserialize_callable, serialize_callable
|
|
@@ -90,6 +92,145 @@ class TestChineseDocumentSplitter:
|
|
|
90
92
|
assert callable(splitter.splitting_function)
|
|
91
93
|
assert splitter.splitting_function("a.b.c") == ["a", "b", "c"]
|
|
92
94
|
|
|
95
|
+
def test_validate_init_parameters(self):
|
|
96
|
+
ChineseDocumentSplitter._validate_init_parameters(
|
|
97
|
+
split_by="word",
|
|
98
|
+
split_length=1000,
|
|
99
|
+
split_overlap=200,
|
|
100
|
+
split_threshold=0,
|
|
101
|
+
granularity="coarse",
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
with pytest.raises(ValueError, match="split_length must be positive"):
|
|
105
|
+
ChineseDocumentSplitter._validate_init_parameters(split_length=0)
|
|
106
|
+
|
|
107
|
+
with pytest.raises(ValueError, match="split_overlap must be non-negative"):
|
|
108
|
+
ChineseDocumentSplitter._validate_init_parameters(split_overlap=-1)
|
|
109
|
+
|
|
110
|
+
with pytest.raises(ValueError, match="split_overlap must be less than split_length"):
|
|
111
|
+
ChineseDocumentSplitter._validate_init_parameters(split_overlap=1000, split_length=500)
|
|
112
|
+
|
|
113
|
+
with pytest.raises(ValueError, match="split_threshold must be non-negative"):
|
|
114
|
+
ChineseDocumentSplitter._validate_init_parameters(split_threshold=-1)
|
|
115
|
+
|
|
116
|
+
with pytest.raises(ValueError, match="split_threshold must be less than split_length"):
|
|
117
|
+
ChineseDocumentSplitter._validate_init_parameters(split_threshold=1001, split_length=1000)
|
|
118
|
+
|
|
119
|
+
with pytest.raises(
|
|
120
|
+
ValueError,
|
|
121
|
+
match="split_by must be one of 'word', 'sentence', 'passage', 'page', 'line', 'period', 'function'",
|
|
122
|
+
):
|
|
123
|
+
ChineseDocumentSplitter._validate_init_parameters(split_by="invalid")
|
|
124
|
+
|
|
125
|
+
with pytest.raises(ValueError, match="granularity must be one of 'coarse', 'fine'"):
|
|
126
|
+
ChineseDocumentSplitter._validate_init_parameters(granularity="invalid")
|
|
127
|
+
|
|
128
|
+
def test_split_by_character_returns_empty_for_none_content(self):
|
|
129
|
+
splitter = ChineseDocumentSplitter(split_by="word")
|
|
130
|
+
assert splitter._split_by_character(Document(content=None)) == []
|
|
131
|
+
|
|
132
|
+
def test_split_by_hanlp_sentence_returns_empty_for_none_content(self):
|
|
133
|
+
splitter = ChineseDocumentSplitter(split_by="sentence")
|
|
134
|
+
assert splitter._split_by_hanlp_sentence(Document(content=None)) == []
|
|
135
|
+
|
|
136
|
+
def test_split_document_dispatches_to_function_splitter(self):
|
|
137
|
+
splitter = ChineseDocumentSplitter(split_by="function", splitting_function=custom_split)
|
|
138
|
+
doc = Document(content="a.b.c")
|
|
139
|
+
result = splitter._split_document(doc)
|
|
140
|
+
assert [d.content for d in result] == ["a", "b", "c"]
|
|
141
|
+
|
|
142
|
+
def test_split_by_function_returns_empty_for_none_content(self):
|
|
143
|
+
splitter = ChineseDocumentSplitter(split_by="function", splitting_function=custom_split)
|
|
144
|
+
assert splitter._split_by_function(Document(content=None)) == []
|
|
145
|
+
|
|
146
|
+
def test_split_by_function_raises_when_no_function_provided(self):
|
|
147
|
+
splitter = ChineseDocumentSplitter(split_by="function", splitting_function=custom_split)
|
|
148
|
+
splitter.splitting_function = None
|
|
149
|
+
with pytest.raises(ValueError, match=r"No splitting function provided\."):
|
|
150
|
+
splitter._split_by_function(Document(content="a.b"))
|
|
151
|
+
|
|
152
|
+
def test_split_by_function_raises_when_function_returns_non_list(self):
|
|
153
|
+
splitter = ChineseDocumentSplitter(split_by="function", splitting_function=lambda t: "not a list")
|
|
154
|
+
with pytest.raises(ValueError, match="must return a list of strings"):
|
|
155
|
+
splitter._split_by_function(Document(content="a.b"))
|
|
156
|
+
|
|
157
|
+
def test_split_by_function_produces_documents_with_metadata(self):
|
|
158
|
+
splitter = ChineseDocumentSplitter(split_by="function", splitting_function=custom_split)
|
|
159
|
+
doc = Document(content="a.b.c", meta={"name": "src"})
|
|
160
|
+
result = splitter._split_by_function(doc)
|
|
161
|
+
assert len(result) == 3
|
|
162
|
+
assert [d.content for d in result] == ["a", "b", "c"]
|
|
163
|
+
assert all(d.meta["source_id"] == doc.id for d in result)
|
|
164
|
+
assert all(d.meta["name"] == "src" for d in result)
|
|
165
|
+
assert [d.meta["split_id"] for d in result] == [0, 1, 2]
|
|
166
|
+
|
|
167
|
+
@pytest.mark.parametrize(
|
|
168
|
+
("previous_content", "current_content"),
|
|
169
|
+
[(None, "abc"), ("abc", None)],
|
|
170
|
+
)
|
|
171
|
+
def test_add_split_overlap_information_skips_when_content_is_none(self, previous_content, current_content):
|
|
172
|
+
previous_doc = Document(content=previous_content, meta={"_split_overlap": []})
|
|
173
|
+
current_doc = Document(content=current_content, meta={"_split_overlap": []})
|
|
174
|
+
ChineseDocumentSplitter._add_split_overlap_information(current_doc, 0, previous_doc, 0)
|
|
175
|
+
assert current_doc.meta["_split_overlap"] == []
|
|
176
|
+
assert previous_doc.meta["_split_overlap"] == []
|
|
177
|
+
|
|
178
|
+
def test_add_split_overlap_information_skips_when_no_matching_prefix(self):
|
|
179
|
+
previous_doc = Document(content="abcdef", meta={"_split_overlap": []})
|
|
180
|
+
current_doc = Document(content="xyz", meta={"_split_overlap": []})
|
|
181
|
+
ChineseDocumentSplitter._add_split_overlap_information(current_doc, 2, previous_doc, 0)
|
|
182
|
+
assert current_doc.meta["_split_overlap"] == []
|
|
183
|
+
assert previous_doc.meta["_split_overlap"] == []
|
|
184
|
+
|
|
185
|
+
@pytest.mark.parametrize("elements", [[], ["", " ", "\t"]])
|
|
186
|
+
def test_concatenate_units_returns_empty_for_empty_or_whitespace(self, elements):
|
|
187
|
+
splitter = ChineseDocumentSplitter(split_by="word", split_length=5, split_overlap=1)
|
|
188
|
+
assert splitter._concatenate_units(elements, split_length=5, split_overlap=1, split_threshold=0) == ([], [], [])
|
|
189
|
+
|
|
190
|
+
def test_concatenate_units_returns_single_chunk_for_short_input(self):
|
|
191
|
+
splitter = ChineseDocumentSplitter(split_by="word", split_length=10, split_overlap=0)
|
|
192
|
+
text_splits, pages, start_idxs = splitter._concatenate_units(
|
|
193
|
+
["a", "b", "c"], split_length=10, split_overlap=0, split_threshold=0
|
|
194
|
+
)
|
|
195
|
+
assert text_splits == ["abc"]
|
|
196
|
+
assert pages == [1]
|
|
197
|
+
assert start_idxs == [0]
|
|
198
|
+
|
|
199
|
+
def test_concatenate_units_applies_split_threshold(self):
|
|
200
|
+
splitter = ChineseDocumentSplitter(split_by="word", split_length=2, split_overlap=0)
|
|
201
|
+
text_splits, _, _ = splitter._concatenate_units(
|
|
202
|
+
["a", "b", "c"], split_length=2, split_overlap=0, split_threshold=2
|
|
203
|
+
)
|
|
204
|
+
# the trailing "c" chunk is smaller than split_threshold=2 and gets attached to previous
|
|
205
|
+
assert text_splits == ["abc"]
|
|
206
|
+
|
|
207
|
+
def test_number_of_sentences_to_keep_returns_zero_when_overlap_is_zero(self):
|
|
208
|
+
splitter = ChineseDocumentSplitter(split_by="word", split_length=10, split_overlap=0)
|
|
209
|
+
assert splitter._number_of_sentences_to_keep(["s1", "s2", "s3"], split_length=10, split_overlap=0) == 0
|
|
210
|
+
|
|
211
|
+
def test_number_of_sentences_to_keep_stops_when_overlap_reached(self):
|
|
212
|
+
splitter = ChineseDocumentSplitter(split_by="word", split_length=10, split_overlap=2)
|
|
213
|
+
# one word per sentence, so we need at least 3 sentences to exceed split_overlap=2
|
|
214
|
+
splitter.chinese_tokenizer = MagicMock(side_effect=lambda s: [s])
|
|
215
|
+
result = splitter._number_of_sentences_to_keep(["s1", "s2", "s3", "s4"], split_length=10, split_overlap=2)
|
|
216
|
+
assert result == 3
|
|
217
|
+
|
|
218
|
+
def test_number_of_sentences_to_keep_stops_when_split_length_exceeded(self):
|
|
219
|
+
splitter = ChineseDocumentSplitter(split_by="word", split_length=2, split_overlap=1)
|
|
220
|
+
# each sentence tokenizes to 5 "words", so first iteration already exceeds split_length
|
|
221
|
+
splitter.chinese_tokenizer = MagicMock(return_value=["a", "b", "c", "d", "e"])
|
|
222
|
+
assert splitter._number_of_sentences_to_keep(["s1", "s2", "s3"], split_length=2, split_overlap=1) == 0
|
|
223
|
+
|
|
224
|
+
def test_warm_up_is_idempotent(self):
|
|
225
|
+
splitter = ChineseDocumentSplitter(split_by="word")
|
|
226
|
+
with patch(
|
|
227
|
+
"haystack_integrations.components.preprocessors.hanlp.chinese_document_splitter.hanlp"
|
|
228
|
+
) as mock_hanlp:
|
|
229
|
+
mock_hanlp.load.return_value = MagicMock()
|
|
230
|
+
splitter.warm_up()
|
|
231
|
+
splitter.warm_up()
|
|
232
|
+
assert mock_hanlp.load.call_count == 2 # once for tokenizer, once for split_sent
|
|
233
|
+
|
|
93
234
|
@pytest.mark.integration
|
|
94
235
|
def test_empty_list(self):
|
|
95
236
|
splitter = ChineseDocumentSplitter()
|
|
@@ -216,36 +357,3 @@ class TestChineseDocumentSplitter:
|
|
|
216
357
|
f"Chunks {i} and {i + 1} do not overlap. "
|
|
217
358
|
f"Tail (up to 20 chars): '{overlap_prev}' vs Head (up to 20 chars): '{overlap_curr}'"
|
|
218
359
|
)
|
|
219
|
-
|
|
220
|
-
def test_validate_init_parameters(self):
|
|
221
|
-
ChineseDocumentSplitter._validate_init_parameters(
|
|
222
|
-
split_by="word",
|
|
223
|
-
split_length=1000,
|
|
224
|
-
split_overlap=200,
|
|
225
|
-
split_threshold=0,
|
|
226
|
-
granularity="coarse",
|
|
227
|
-
)
|
|
228
|
-
|
|
229
|
-
with pytest.raises(ValueError, match="split_length must be positive"):
|
|
230
|
-
ChineseDocumentSplitter._validate_init_parameters(split_length=0)
|
|
231
|
-
|
|
232
|
-
with pytest.raises(ValueError, match="split_overlap must be non-negative"):
|
|
233
|
-
ChineseDocumentSplitter._validate_init_parameters(split_overlap=-1)
|
|
234
|
-
|
|
235
|
-
with pytest.raises(ValueError, match="split_overlap must be less than split_length"):
|
|
236
|
-
ChineseDocumentSplitter._validate_init_parameters(split_overlap=1000, split_length=500)
|
|
237
|
-
|
|
238
|
-
with pytest.raises(ValueError, match="split_threshold must be non-negative"):
|
|
239
|
-
ChineseDocumentSplitter._validate_init_parameters(split_threshold=-1)
|
|
240
|
-
|
|
241
|
-
with pytest.raises(ValueError, match="split_threshold must be less than split_length"):
|
|
242
|
-
ChineseDocumentSplitter._validate_init_parameters(split_threshold=1001, split_length=1000)
|
|
243
|
-
|
|
244
|
-
with pytest.raises(
|
|
245
|
-
ValueError,
|
|
246
|
-
match="split_by must be one of 'word', 'sentence', 'passage', 'page', 'line', 'period', 'function'",
|
|
247
|
-
):
|
|
248
|
-
ChineseDocumentSplitter._validate_init_parameters(split_by="invalid")
|
|
249
|
-
|
|
250
|
-
with pytest.raises(ValueError, match="granularity must be one of 'coarse', 'fine'"):
|
|
251
|
-
ChineseDocumentSplitter._validate_init_parameters(granularity="invalid")
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
loaders:
|
|
2
|
-
- ignore_when_discovered:
|
|
3
|
-
- __init__
|
|
4
|
-
modules:
|
|
5
|
-
- haystack_integrations.components.preprocessors.hanlp.chinese_document_splitter
|
|
6
|
-
search_path:
|
|
7
|
-
- ../src
|
|
8
|
-
type: haystack_pydoc_tools.loaders.CustomPythonLoader
|
|
9
|
-
processors:
|
|
10
|
-
- do_not_filter_modules: false
|
|
11
|
-
documented_only: true
|
|
12
|
-
expression: null
|
|
13
|
-
skip_empty_modules: true
|
|
14
|
-
type: filter
|
|
15
|
-
- type: smart
|
|
16
|
-
- type: crossref
|
|
17
|
-
renderer:
|
|
18
|
-
description: HanLP integration for Haystack
|
|
19
|
-
id: integrations-hanlp
|
|
20
|
-
markdown:
|
|
21
|
-
add_member_class_prefix: false
|
|
22
|
-
add_method_class_prefix: true
|
|
23
|
-
classdef_code_block: false
|
|
24
|
-
descriptive_class_title: false
|
|
25
|
-
descriptive_module_title: true
|
|
26
|
-
filename: hanlp.md
|
|
27
|
-
title: HanLP
|
|
28
|
-
type: haystack_pydoc_tools.renderers.DocusaurusRenderer
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|