hanlp-haystack 1.0.1__tar.gz → 2.0.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.
@@ -0,0 +1,20 @@
1
+ # Changelog
2
+
3
+ ## [integrations/hanlp-v1.0.1] - 2025-10-14
4
+
5
+ ### 🐛 Bug Fixes
6
+
7
+ - Missing decorator output for ChineseDocumentSplitter (#2377)
8
+
9
+
10
+ ### 🧹 Chores
11
+
12
+ - Standardize readmes - part 2 (#2205)
13
+
14
+ ## [integrations/hanlp-v1.0.0] - 2025-07-22
15
+
16
+ ### 🚀 Features
17
+
18
+ - Add new HanLP integration with ChineseDocumentSplitter (#1943)
19
+
20
+ <!-- generated by git-cliff -->
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hanlp-haystack
3
- Version: 1.0.1
3
+ Version: 2.0.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
@@ -11,16 +11,15 @@ License-File: LICENSE.txt
11
11
  Classifier: Development Status :: 4 - Beta
12
12
  Classifier: License :: OSI Approved :: Apache Software License
13
13
  Classifier: Programming Language :: Python
14
- Classifier: Programming Language :: Python :: 3.9
15
14
  Classifier: Programming Language :: Python :: 3.10
16
15
  Classifier: Programming Language :: Python :: 3.11
17
16
  Classifier: Programming Language :: Python :: 3.12
18
17
  Classifier: Programming Language :: Python :: 3.13
19
18
  Classifier: Programming Language :: Python :: Implementation :: CPython
20
19
  Classifier: Programming Language :: Python :: Implementation :: PyPy
21
- Requires-Python: >=3.9
20
+ Requires-Python: >=3.10
22
21
  Requires-Dist: hanlp>=2.1.1
23
- Requires-Dist: haystack-ai>=2.13.1
22
+ Requires-Dist: haystack-ai>=2.22.0
24
23
  Description-Content-Type: text/markdown
25
24
 
26
25
  # hanlp-haystack
@@ -0,0 +1,28 @@
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
@@ -7,7 +7,7 @@ name = "hanlp-haystack"
7
7
  dynamic = ["version"]
8
8
  description = 'An integration of Han Language Processing - HanLP as a ChineseDocumentSplitter component.'
9
9
  readme = "README.md"
10
- requires-python = ">=3.9"
10
+ requires-python = ">=3.10"
11
11
  license = "Apache-2.0"
12
12
  keywords = []
13
13
  authors = [{ name = "deepset GmbH", email = "info@deepset.ai" }]
@@ -15,7 +15,6 @@ classifiers = [
15
15
  "License :: OSI Approved :: Apache Software License",
16
16
  "Development Status :: 4 - Beta",
17
17
  "Programming Language :: Python",
18
- "Programming Language :: Python :: 3.9",
19
18
  "Programming Language :: Python :: 3.10",
20
19
  "Programming Language :: Python :: 3.11",
21
20
  "Programming Language :: Python :: 3.12",
@@ -24,7 +23,7 @@ classifiers = [
24
23
  "Programming Language :: Python :: Implementation :: PyPy",
25
24
  ]
26
25
  dependencies = [
27
- "haystack-ai>=2.13.1",
26
+ "haystack-ai>=2.22.0",
28
27
  "hanlp>=2.1.1"
29
28
  ]
30
29
 
@@ -49,8 +48,8 @@ installer = "uv"
49
48
  dependencies = ["haystack-pydoc-tools", "ruff"]
50
49
 
51
50
  [tool.hatch.envs.default.scripts]
52
- docs = ["pydoc-markdown pydoc/config.yml"]
53
- fmt = "ruff check --fix {args} && ruff format {args}"
51
+ docs = ["pydoc-markdown pydoc/config_docusaurus.yml"]
52
+ fmt = "ruff check --fix {args}; ruff format {args}"
54
53
  fmt-check = "ruff check {args} && ruff format --check {args}"
55
54
 
56
55
  [tool.hatch.envs.test]
@@ -67,7 +66,7 @@ dependencies = [
67
66
  unit = 'pytest -m "not integration" {args:tests}'
68
67
  integration = 'pytest -m "integration" {args:tests}'
69
68
  all = 'pytest {args:tests}'
70
- cov-retry = 'all --cov=haystack_integrations --reruns 3 --reruns-delay 30 -x'
69
+ cov-retry = 'pytest --cov=haystack_integrations --reruns 3 --reruns-delay 30 -x {args:tests}'
71
70
  types = """mypy -p haystack_integrations.components.preprocessors.hanlp {args}"""
72
71
 
73
72
  [tool.mypy]
@@ -83,12 +82,11 @@ module = [
83
82
  ignore_missing_imports = true
84
83
 
85
84
  [tool.black]
86
- target-version = ["py38"]
85
+ target-version = ["py39"]
87
86
  line-length = 120
88
87
  skip-string-normalization = true
89
88
 
90
89
  [tool.ruff]
91
- target-version = "py38"
92
90
  line-length = 120
93
91
 
94
92
  [tool.ruff.lint]
@@ -138,10 +136,6 @@ ignore = [
138
136
  "RUF001",
139
137
  "RUF002",
140
138
  ]
141
- unfixable = [
142
- # Don't touch unused imports
143
- "F401",
144
- ]
145
139
 
146
140
  [tool.ruff.lint.isort]
147
141
  known-first-party = ["haystack_integrations"]
@@ -2,8 +2,9 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
+ from collections.abc import Callable
5
6
  from copy import deepcopy
6
- from typing import Any, Callable, Dict, List, Literal, Optional, Tuple
7
+ from typing import Any, Literal
7
8
 
8
9
  from haystack import Document, component, logging
9
10
  from haystack.core.serialization import default_from_dict, default_to_dict
@@ -59,7 +60,7 @@ class ChineseDocumentSplitter:
59
60
  split_overlap: int = 200,
60
61
  split_threshold: int = 0,
61
62
  respect_sentence_boundary: bool = False,
62
- splitting_function: Optional[Callable] = None,
63
+ splitting_function: Callable | None = None,
63
64
  granularity: Literal["coarse", "fine"] = "coarse",
64
65
  ):
65
66
  """
@@ -149,7 +150,7 @@ class ChineseDocumentSplitter:
149
150
  raise ValueError(msg)
150
151
 
151
152
  @component.output_types(documents=list[Document])
152
- def run(self, documents: List[Document]) -> Dict[str, List[Document]]:
153
+ def run(self, documents: list[Document]) -> dict[str, list[Document]]:
153
154
  """
154
155
  Split documents into smaller chunks.
155
156
 
@@ -175,7 +176,7 @@ class ChineseDocumentSplitter:
175
176
  self.chinese_tokenizer = hanlp.load(hanlp.pretrained.tok.FINE_ELECTRA_SMALL_ZH)
176
177
  self.split_sent = hanlp.load(hanlp.pretrained.eos.UD_CTB_EOS_MUL)
177
178
 
178
- def _split_by_character(self, doc: Document) -> List[Document]:
179
+ def _split_by_character(self, doc: Document) -> list[Document]:
179
180
  """
180
181
  Define a function to handle Chinese clauses
181
182
 
@@ -202,7 +203,7 @@ class ChineseDocumentSplitter:
202
203
  )
203
204
 
204
205
  # Define a function to handle Chinese clauses
205
- def chinese_sentence_split(self, text: str) -> List[Dict[str, Any]]:
206
+ def chinese_sentence_split(self, text: str) -> list[dict[str, Any]]:
206
207
  """
207
208
  Split Chinese text into sentences.
208
209
 
@@ -223,7 +224,7 @@ class ChineseDocumentSplitter:
223
224
 
224
225
  return results
225
226
 
226
- def _split_document(self, doc: Document) -> List[Document]:
227
+ def _split_document(self, doc: Document) -> list[Document]:
227
228
  if self.split_by == "sentence" or self.respect_sentence_boundary:
228
229
  return self._split_by_hanlp_sentence(doc)
229
230
 
@@ -233,8 +234,8 @@ class ChineseDocumentSplitter:
233
234
  return self._split_by_character(doc)
234
235
 
235
236
  def _concatenate_sentences_based_on_word_amount(
236
- self, sentences: List[str], split_length: int, split_overlap: int, granularity: str
237
- ) -> Tuple[List[str], List[int], List[int]]:
237
+ self, sentences: list[str], split_length: int, split_overlap: int, granularity: str
238
+ ) -> tuple[list[str], list[int], list[int]]:
238
239
  """
239
240
  Groups the sentences into chunks of `split_length` words while respecting sentence boundaries.
240
241
 
@@ -251,11 +252,11 @@ class ChineseDocumentSplitter:
251
252
  chunk_word_count = 0
252
253
  chunk_starting_page_number = 1
253
254
  chunk_start_idx = 0
254
- current_chunk: List[str] = []
255
+ current_chunk: list[str] = []
255
256
 
256
257
  # output lists
257
258
  split_start_page_numbers = []
258
- list_of_splits: List[List[str]] = []
259
+ list_of_splits: list[list[str]] = []
259
260
  split_start_indices = []
260
261
 
261
262
  for sentence_idx, sentence in enumerate(sentences):
@@ -305,7 +306,7 @@ class ChineseDocumentSplitter:
305
306
 
306
307
  return text_splits, split_start_page_numbers, split_start_indices
307
308
 
308
- def _split_by_hanlp_sentence(self, doc: Document) -> List[Document]:
309
+ def _split_by_hanlp_sentence(self, doc: Document) -> list[Document]:
309
310
  """
310
311
  Split Chinese text into sentences.
311
312
 
@@ -342,8 +343,8 @@ class ChineseDocumentSplitter:
342
343
  return split_docs
343
344
 
344
345
  def _concatenate_units(
345
- self, elements: List[str], split_length: int, split_overlap: int, split_threshold: int
346
- ) -> Tuple[List[str], List[int], List[int]]:
346
+ self, elements: list[str], split_length: int, split_overlap: int, split_threshold: int
347
+ ) -> tuple[list[str], list[int], list[int]]:
347
348
  """
348
349
  Concatenates the elements into parts of split_length units.
349
350
 
@@ -364,9 +365,9 @@ class ChineseDocumentSplitter:
364
365
  # Otherwise, proceed as before
365
366
  step = split_length - split_overlap
366
367
  step = max(step, 1)
367
- text_splits: List[str] = []
368
- splits_pages: List[int] = []
369
- splits_start_idxs: List[int] = []
368
+ text_splits: list[str] = []
369
+ splits_pages: list[int] = []
370
+ splits_start_idxs: list[int] = []
370
371
  cur_start_idx = 0
371
372
  cur_page = 1
372
373
  segments = windowed(elements, n=split_length, step=step)
@@ -399,14 +400,14 @@ class ChineseDocumentSplitter:
399
400
  return text_splits, splits_pages, splits_start_idxs
400
401
 
401
402
  def _create_docs_from_splits(
402
- self, text_splits: List[str], splits_pages: List[int], splits_start_idxs: List[int], meta: Dict[str, Any]
403
- ) -> List[Document]:
403
+ self, text_splits: list[str], splits_pages: list[int], splits_start_idxs: list[int], meta: dict[str, Any]
404
+ ) -> list[Document]:
404
405
  """
405
406
  Creates Document objects from splits enriching them with page number and the metadata of the original document.
406
407
  """
407
- documents: List[Document] = []
408
+ documents: list[Document] = []
408
409
 
409
- for i, (txt, split_idx) in enumerate(zip(text_splits, splits_start_idxs)):
410
+ for i, (txt, split_idx) in enumerate(zip(text_splits, splits_start_idxs, strict=True)):
410
411
  copied_meta = deepcopy(meta)
411
412
  copied_meta["page_number"] = splits_pages[i]
412
413
  copied_meta["split_id"] = i
@@ -460,7 +461,7 @@ class ChineseDocumentSplitter:
460
461
  overlapping_range = (0, overlapping_range[1] - overlapping_range[0])
461
462
  previous_doc.meta["_split_overlap"].append({"doc_id": current_doc.id, "range": overlapping_range})
462
463
 
463
- def _number_of_sentences_to_keep(self, sentences: List[str], split_length: int, split_overlap: int) -> int:
464
+ def _number_of_sentences_to_keep(self, sentences: list[str], split_length: int, split_overlap: int) -> int:
464
465
  """
465
466
  Returns the number of sentences to keep in the next chunk based on the `split_overlap` and `split_length`.
466
467
 
@@ -486,7 +487,7 @@ class ChineseDocumentSplitter:
486
487
  break
487
488
  return num_sentences_to_keep
488
489
 
489
- def _split_by_function(self, doc: Document) -> List[Document]:
490
+ def _split_by_function(self, doc: Document) -> list[Document]:
490
491
  """
491
492
  Split a document using a custom splitting function.
492
493
 
@@ -515,7 +516,7 @@ class ChineseDocumentSplitter:
515
516
  meta=metadata,
516
517
  )
517
518
 
518
- def to_dict(self) -> Dict[str, Any]:
519
+ def to_dict(self) -> dict[str, Any]:
519
520
  """
520
521
  Serializes the component to a dictionary.
521
522
  """
@@ -533,7 +534,7 @@ class ChineseDocumentSplitter:
533
534
  return serialized
534
535
 
535
536
  @classmethod
536
- def from_dict(cls, data: Dict[str, Any]) -> "ChineseDocumentSplitter":
537
+ def from_dict(cls, data: dict[str, Any]) -> "ChineseDocumentSplitter":
537
538
  """
538
539
  Deserializes the component from a dictionary.
539
540
  """
@@ -123,7 +123,7 @@ class TestChineseDocumentSplitter:
123
123
  splitter.warm_up()
124
124
  result = splitter.run(documents=documents)
125
125
  assert len(result["documents"]) == 2
126
- for doc, split_doc in zip(documents, result["documents"]):
126
+ for doc, split_doc in zip(documents, result["documents"], strict=True):
127
127
  assert doc.meta.items() <= split_doc.meta.items()
128
128
 
129
129
  @pytest.mark.integration
@@ -136,7 +136,7 @@ class TestChineseDocumentSplitter:
136
136
  splitter.warm_up()
137
137
  result = splitter.run(documents=documents)
138
138
  assert len(result["documents"]) == 2
139
- for doc, split_doc in zip(documents, result["documents"]):
139
+ for doc, split_doc in zip(documents, result["documents"], strict=True):
140
140
  assert doc.id == split_doc.meta["source_id"]
141
141
 
142
142
  @pytest.mark.integration
@@ -1,9 +0,0 @@
1
- # Changelog
2
-
3
- ## [integrations/hanlp-v1.0.0] - 2025-07-22
4
-
5
- ### 🚀 Features
6
-
7
- - Add new HanLP integration with ChineseDocumentSplitter (#1943)
8
-
9
- <!-- generated by git-cliff -->
@@ -1,29 +0,0 @@
1
- loaders:
2
- - type: haystack_pydoc_tools.loaders.CustomPythonLoader
3
- search_path: [../src]
4
- modules: [
5
- "haystack_integrations.components.preprocessors.hanlp.chinese_document_splitter",
6
- ]
7
- ignore_when_discovered: ["__init__"]
8
- processors:
9
- - type: filter
10
- expression:
11
- documented_only: true
12
- do_not_filter_modules: false
13
- skip_empty_modules: true
14
- - type: smart
15
- - type: crossref
16
- renderer:
17
- type: haystack_pydoc_tools.renderers.ReadmeIntegrationRenderer
18
- excerpt: HanLP integration for Haystack
19
- category_slug: integrations-api
20
- title: HanLP
21
- slug: integrations-hanlp
22
- order: 100
23
- markdown:
24
- descriptive_class_title: false
25
- classdef_code_block: false
26
- descriptive_module_title: true
27
- add_method_class_prefix: true
28
- add_member_class_prefix: false
29
- filename: _readme_github.md
File without changes