doc-redaction 2.2.1__tar.gz → 2.2.2__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.
- {doc_redaction-2.2.1/doc_redaction.egg-info → doc_redaction-2.2.2}/PKG-INFO +8 -2
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/README.md +12 -1
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/README_PYPI.md +7 -1
- {doc_redaction-2.2.1 → doc_redaction-2.2.2/doc_redaction.egg-info}/PKG-INFO +8 -2
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/pyproject.toml +1 -1
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/config.py +1 -1
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/custom_image_analyser_engine.py +94 -1
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/MANIFEST.in +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/agent_routes.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/app.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/cli_redact.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction/__init__.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction/api.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction/cli_api.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction/cli_redact.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction/data_anonymise.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction/file_conversion.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction/file_redaction.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction/find_duplicate_pages.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction/find_duplicate_tabular.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction/gradio_app.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction/helper_functions.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction/install_deps.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction/lambda_entrypoint.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction/redaction_review.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction/summaries.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction.egg-info/SOURCES.txt +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction.egg-info/dependency_links.txt +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction.egg-info/entry_points.txt +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction.egg-info/requires.txt +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/doc_redaction.egg-info/top_level.txt +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/favicon.png +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/intros/long_intro.txt +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/intros/short_intro.txt +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/intros/short_intro_responsible.txt +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/lambda_entrypoint.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/load_dynamo_logs.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/load_s3_logs.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/mcp_doc_redaction/__init__.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/mcp_doc_redaction/artifact_bundle.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/mcp_doc_redaction/gradio_transport.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/mcp_doc_redaction/schemas.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/mcp_doc_redaction/server.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/setup.cfg +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/test/test_agent_apply_review_redactions.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/test/test_annotation_color_parsing.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/test/test_cli_smoke.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/test/test_gradio_doc_redact_simple.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/test/test_gradio_summarise_simple.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/test/test_gradio_transport_sse.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/test/test_gradio_upload_staging.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/test/test_gui_only.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/test/test_mcp_doc_redaction_bundle.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/test/test_mcp_doc_redaction_extract_paths.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/test/test_package_api_smoke.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/test/test_placeholder_bbox_scaling.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/test/test_redaction_overlay_export.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/test/test_redaction_types.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/test/test_review_ocr_visualisation_export.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/__init__.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/apply_hf_zero_gpu_readme_frontmatter.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/auth.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/aws_functions.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/aws_textract.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/cli_usage_logger.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/custom_csvlogger.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/data_anonymise.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/file_conversion.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/file_redaction.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/find_duplicate_pages.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/find_duplicate_tabular.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/helper_functions.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/llm_entity_detection.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/llm_entity_detection_prompts.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/llm_funcs.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/load_spacy_model_custom_recognisers.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/presidio_analyzer_custom.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/quickstart.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/redaction_review.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/redaction_types.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/run_vlm.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/secure_path_utils.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/secure_regex_utils.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/simplified_api.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/summaries.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/textract_batch_call.py +0 -0
- {doc_redaction-2.2.1 → doc_redaction-2.2.2}/tools/word_segmenter.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: doc_redaction
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2
|
|
4
4
|
Summary: Redact PDF/image-based documents, Word, or CSV/XLSX files using a Gradio-based GUI interface
|
|
5
5
|
Author-email: Sean Pedrick-Case <spedrickcase@lambeth.gov.uk>
|
|
6
6
|
Maintainer-email: Sean Pedrick-Case <spedrickcase@lambeth.gov.uk>
|
|
@@ -190,7 +190,13 @@ For programmatic use (CLI-first API matching Gradio `api_name` routes), see **[P
|
|
|
190
190
|
python -m app
|
|
191
191
|
```
|
|
192
192
|
|
|
193
|
-
|
|
193
|
+
**Important: your working directory matters.** When you run `python -m app`, the app treats your *current folder* as the “app folder”:
|
|
194
|
+
|
|
195
|
+
- It will load configuration from `config/app_config.env` *relative to the folder you run it from* (and `python -m doc_redaction.install_deps` will also create/update that file there).
|
|
196
|
+
- It may create new folders in that location (for example `config/`, `output/`, `input/`, `logs/`, `usage/`, `feedback/`, and temporary/cache folders depending on your settings).
|
|
197
|
+
- The full set of bundled UI example files (`example_data/`) is part of the **Git repository checkout** rather than the PyPI wheel. If you run from a “random” directory after a PyPI install, you should expect the Examples section to be missing unless you provide your own `example_data/` folder.
|
|
198
|
+
|
|
199
|
+
In practice, the **smoothest UI experience** (examples, bundled assets, docs links, predictable relative paths) is still usually via a **repository checkout** or **Docker**, but PyPI install is sufficient to launch the UI as long as you run it from a suitable working folder and have the system dependencies available (or run `python -m doc_redaction.install_deps` first).
|
|
194
200
|
|
|
195
201
|
#### Install from source (repository checkout / development)
|
|
196
202
|
|
|
@@ -127,7 +127,13 @@ For programmatic use (CLI-first API matching Gradio `api_name` routes), see **[P
|
|
|
127
127
|
python -m app
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
**Important: your working directory matters.** When you run `python -m app`, the app treats your *current folder* as the “app folder”:
|
|
131
|
+
|
|
132
|
+
- It will look for configuration at `config/app_config.env` *relative to the folder you run it from* (and `python -m doc_redaction.install_deps` will also write `config/app_config.env` there).
|
|
133
|
+
- It may create new folders in that location (for example `config/`, `output/`, `input/`, `logs/`, `usage/`, `feedback/`, and temporary/cache folders depending on your settings).
|
|
134
|
+
- The full set of bundled UI example files (`example_data/`) is part of the **Git repository checkout** rather than the PyPI wheel. If you run from a “random” directory after a PyPI install, you should expect the Examples section to be missing unless you provide your own `example_data/` folder.
|
|
135
|
+
|
|
136
|
+
In practice, the **smoothest UI experience** (examples, bundled assets, docs links, predictable relative paths) is still usually via a **repository checkout** or **Docker**, but PyPI install is sufficient to launch the UI as long as you run it from a suitable working folder and have the system dependencies available (or run `python -m doc_redaction.install_deps` first).
|
|
131
137
|
|
|
132
138
|
#### Install from source (repository checkout / development)
|
|
133
139
|
|
|
@@ -243,6 +249,11 @@ These settings are useful for all users, regardless of whether you are using AWS
|
|
|
243
249
|
* Provide the path to the respective installation folders (for Poppler, point to the `bin` sub-directory).
|
|
244
250
|
* **Examples:** `POPPLER_FOLDER=C:/Program Files/poppler-24.02.0/bin/` `TESSERACT_FOLDER=tesseract/`
|
|
245
251
|
|
|
252
|
+
* `TESSERACT_DATA_FOLDER`
|
|
253
|
+
* If Tesseract runs but you see an error like `Error opening data file ./eng.traineddata` or `Tesseract couldn't load any languages`, this is usually because it can't find the `tessdata/` language files.
|
|
254
|
+
* Set this to the folder that contains `eng.traineddata` (typically a `tessdata` directory).
|
|
255
|
+
* **Examples (Windows):** `TESSERACT_DATA_FOLDER=C:/Program Files/Tesseract-OCR/tessdata`
|
|
256
|
+
|
|
246
257
|
* `SHOW_LANGUAGE_SELECTION=True`
|
|
247
258
|
* Set to `True` to display a language selection dropdown in the UI for OCR processing.
|
|
248
259
|
|
|
@@ -116,7 +116,13 @@ For programmatic use (CLI-first API matching Gradio `api_name` routes), see **[P
|
|
|
116
116
|
python -m app
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
**Important: your working directory matters.** When you run `python -m app`, the app treats your *current folder* as the “app folder”:
|
|
120
|
+
|
|
121
|
+
- It will load configuration from `config/app_config.env` *relative to the folder you run it from* (and `python -m doc_redaction.install_deps` will also create/update that file there).
|
|
122
|
+
- It may create new folders in that location (for example `config/`, `output/`, `input/`, `logs/`, `usage/`, `feedback/`, and temporary/cache folders depending on your settings).
|
|
123
|
+
- The full set of bundled UI example files (`example_data/`) is part of the **Git repository checkout** rather than the PyPI wheel. If you run from a “random” directory after a PyPI install, you should expect the Examples section to be missing unless you provide your own `example_data/` folder.
|
|
124
|
+
|
|
125
|
+
In practice, the **smoothest UI experience** (examples, bundled assets, docs links, predictable relative paths) is still usually via a **repository checkout** or **Docker**, but PyPI install is sufficient to launch the UI as long as you run it from a suitable working folder and have the system dependencies available (or run `python -m doc_redaction.install_deps` first).
|
|
120
126
|
|
|
121
127
|
#### Install from source (repository checkout / development)
|
|
122
128
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: doc_redaction
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2
|
|
4
4
|
Summary: Redact PDF/image-based documents, Word, or CSV/XLSX files using a Gradio-based GUI interface
|
|
5
5
|
Author-email: Sean Pedrick-Case <spedrickcase@lambeth.gov.uk>
|
|
6
6
|
Maintainer-email: Sean Pedrick-Case <spedrickcase@lambeth.gov.uk>
|
|
@@ -190,7 +190,13 @@ For programmatic use (CLI-first API matching Gradio `api_name` routes), see **[P
|
|
|
190
190
|
python -m app
|
|
191
191
|
```
|
|
192
192
|
|
|
193
|
-
|
|
193
|
+
**Important: your working directory matters.** When you run `python -m app`, the app treats your *current folder* as the “app folder”:
|
|
194
|
+
|
|
195
|
+
- It will load configuration from `config/app_config.env` *relative to the folder you run it from* (and `python -m doc_redaction.install_deps` will also create/update that file there).
|
|
196
|
+
- It may create new folders in that location (for example `config/`, `output/`, `input/`, `logs/`, `usage/`, `feedback/`, and temporary/cache folders depending on your settings).
|
|
197
|
+
- The full set of bundled UI example files (`example_data/`) is part of the **Git repository checkout** rather than the PyPI wheel. If you run from a “random” directory after a PyPI install, you should expect the Examples section to be missing unless you provide your own `example_data/` folder.
|
|
198
|
+
|
|
199
|
+
In practice, the **smoothest UI experience** (examples, bundled assets, docs links, predictable relative paths) is still usually via a **repository checkout** or **Docker**, but PyPI install is sufficient to launch the UI as long as you run it from a suitable working folder and have the system dependencies available (or run `python -m doc_redaction.install_deps` first).
|
|
194
200
|
|
|
195
201
|
#### Install from source (repository checkout / development)
|
|
196
202
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "doc_redaction"
|
|
7
|
-
version = "2.2.
|
|
7
|
+
version = "2.2.2"
|
|
8
8
|
description = "Redact PDF/image-based documents, Word, or CSV/XLSX files using a Gradio-based GUI interface"
|
|
9
9
|
readme = "README_PYPI.md"
|
|
10
10
|
authors = [
|
|
@@ -1166,7 +1166,7 @@ SHOW_OCR_GUI_OPTIONS = convert_string_to_boolean(
|
|
|
1166
1166
|
)
|
|
1167
1167
|
|
|
1168
1168
|
SHOW_LOCAL_OCR_MODEL_OPTIONS = convert_string_to_boolean(
|
|
1169
|
-
get_or_create_env_var("SHOW_LOCAL_OCR_MODEL_OPTIONS", "
|
|
1169
|
+
get_or_create_env_var("SHOW_LOCAL_OCR_MODEL_OPTIONS", "True")
|
|
1170
1170
|
)
|
|
1171
1171
|
|
|
1172
1172
|
SHOW_PADDLE_MODEL_OPTIONS = convert_string_to_boolean(
|
|
@@ -6,6 +6,7 @@ import json
|
|
|
6
6
|
import math
|
|
7
7
|
import os
|
|
8
8
|
import re
|
|
9
|
+
import shutil
|
|
9
10
|
import threading
|
|
10
11
|
import time
|
|
11
12
|
from concurrent.futures import ThreadPoolExecutor
|
|
@@ -111,6 +112,97 @@ from tools.secure_path_utils import validate_folder_containment
|
|
|
111
112
|
from tools.secure_regex_utils import safe_sanitize_text
|
|
112
113
|
from tools.word_segmenter import AdaptiveSegmenter
|
|
113
114
|
|
|
115
|
+
# ---- Tesseract discovery helpers -------------------------------------------------
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _is_probable_tessdata_dir(path: str) -> bool:
|
|
119
|
+
try:
|
|
120
|
+
if not path:
|
|
121
|
+
return False
|
|
122
|
+
p = os.path.abspath(os.path.expandvars(os.path.expanduser(path)))
|
|
123
|
+
if not os.path.isdir(p):
|
|
124
|
+
return False
|
|
125
|
+
# If eng.traineddata exists, it's definitely a tessdata dir. Otherwise allow
|
|
126
|
+
# the folder if it contains *any* traineddata (language packs vary).
|
|
127
|
+
if os.path.isfile(os.path.join(p, "eng.traineddata")):
|
|
128
|
+
return True
|
|
129
|
+
for name in os.listdir(p):
|
|
130
|
+
if name.lower().endswith(".traineddata"):
|
|
131
|
+
return True
|
|
132
|
+
except Exception:
|
|
133
|
+
return False
|
|
134
|
+
return False
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _guess_tessdata_dir_from_tesseract_exe(tesseract_exe: str | None) -> str | None:
|
|
138
|
+
if not tesseract_exe:
|
|
139
|
+
return None
|
|
140
|
+
exe_dir = os.path.dirname(os.path.abspath(tesseract_exe))
|
|
141
|
+
|
|
142
|
+
# Common Windows installer layout:
|
|
143
|
+
# C:\Program Files\Tesseract-OCR\tesseract.exe
|
|
144
|
+
# C:\Program Files\Tesseract-OCR\tessdata\eng.traineddata
|
|
145
|
+
candidate = os.path.join(exe_dir, "tessdata")
|
|
146
|
+
if _is_probable_tessdata_dir(candidate):
|
|
147
|
+
return candidate
|
|
148
|
+
|
|
149
|
+
# Common conda-forge layout on Windows:
|
|
150
|
+
# <prefix>\Library\bin\tesseract.exe
|
|
151
|
+
# <prefix>\Library\share\tessdata\eng.traineddata
|
|
152
|
+
up1 = os.path.dirname(exe_dir)
|
|
153
|
+
up2 = os.path.dirname(up1)
|
|
154
|
+
conda_candidate = os.path.join(up2, "share", "tessdata")
|
|
155
|
+
if _is_probable_tessdata_dir(conda_candidate):
|
|
156
|
+
return conda_candidate
|
|
157
|
+
|
|
158
|
+
return None
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def _resolve_tessdata_dir() -> str | None:
|
|
162
|
+
"""
|
|
163
|
+
Return an absolute tessdata directory if we can find one.
|
|
164
|
+
Priority:
|
|
165
|
+
1) Existing TESSDATA_PREFIX if it points to a valid tessdata dir
|
|
166
|
+
2) tools.config.TESSERACT_DATA_FOLDER if it points to a valid tessdata dir
|
|
167
|
+
3) Guess based on tesseract executable location (PATH / pytesseract config)
|
|
168
|
+
"""
|
|
169
|
+
env_prefix = os.environ.get("TESSDATA_PREFIX", "")
|
|
170
|
+
if _is_probable_tessdata_dir(env_prefix):
|
|
171
|
+
return os.path.abspath(env_prefix)
|
|
172
|
+
|
|
173
|
+
try:
|
|
174
|
+
from tools.config import TESSERACT_DATA_FOLDER
|
|
175
|
+
|
|
176
|
+
if _is_probable_tessdata_dir(TESSERACT_DATA_FOLDER):
|
|
177
|
+
return os.path.abspath(TESSERACT_DATA_FOLDER)
|
|
178
|
+
except Exception:
|
|
179
|
+
# config import is optional for library use
|
|
180
|
+
pass
|
|
181
|
+
|
|
182
|
+
tesseract_exe = getattr(
|
|
183
|
+
pytesseract.pytesseract, "tesseract_cmd", None
|
|
184
|
+
) or shutil.which("tesseract")
|
|
185
|
+
return _guess_tessdata_dir_from_tesseract_exe(tesseract_exe)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def _ensure_tessdata_available_in_env(existing_config: str | None) -> str | None:
|
|
189
|
+
"""
|
|
190
|
+
Ensure Tesseract can find language traineddata files by:
|
|
191
|
+
- setting TESSDATA_PREFIX if we can resolve tessdata dir
|
|
192
|
+
- adding --tessdata-dir to the tesseract config string when not already present
|
|
193
|
+
"""
|
|
194
|
+
tessdata_dir = _resolve_tessdata_dir()
|
|
195
|
+
if not tessdata_dir:
|
|
196
|
+
return existing_config
|
|
197
|
+
|
|
198
|
+
os.environ.setdefault("TESSDATA_PREFIX", tessdata_dir)
|
|
199
|
+
|
|
200
|
+
cfg = (existing_config or "").strip()
|
|
201
|
+
if "--tessdata-dir" in cfg:
|
|
202
|
+
return cfg
|
|
203
|
+
return (cfg + f' --tessdata-dir "{tessdata_dir}"').strip()
|
|
204
|
+
|
|
205
|
+
|
|
114
206
|
# AWS Comprehend billing: 1 unit = 100 characters (entity recognition, PII, etc.)
|
|
115
207
|
COMPREHEND_CHARACTERS_PER_UNIT = 100
|
|
116
208
|
|
|
@@ -8516,10 +8608,11 @@ class CustomImageAnalyzerEngine:
|
|
|
8516
8608
|
|
|
8517
8609
|
elif self.ocr_engine == "tesseract":
|
|
8518
8610
|
|
|
8611
|
+
tesseract_cfg = _ensure_tessdata_available_in_env(self.tesseract_config)
|
|
8519
8612
|
ocr_data = pytesseract.image_to_data(
|
|
8520
8613
|
image,
|
|
8521
8614
|
output_type=pytesseract.Output.DICT,
|
|
8522
|
-
config=
|
|
8615
|
+
config=tesseract_cfg,
|
|
8523
8616
|
lang=self.tesseract_lang, # Ensure the Tesseract language data (e.g., fra.traineddata) is installed on your system.
|
|
8524
8617
|
)
|
|
8525
8618
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|