indico_toolkit 6.1.0__tar.gz → 6.14.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.
- indico_toolkit-6.14.0/PKG-INFO +144 -0
- indico_toolkit-6.14.0/README.md +109 -0
- indico_toolkit-6.14.0/indico_toolkit/__init__.py +24 -0
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/association/__init__.py +10 -0
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/association/association.py +4 -3
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/association/extracted_tokens.py +16 -14
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/association/line_items.py +24 -15
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/association/positioning.py +68 -45
- indico_toolkit-6.14.0/indico_toolkit/auto_populate/__init__.py +3 -0
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/auto_populate/populator.py +56 -43
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/auto_populate/types.py +14 -6
- indico_toolkit-6.14.0/indico_toolkit/auto_review/__init__.py +6 -0
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/auto_review/auto_review_functions.py +1 -2
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/auto_review/auto_reviewer.py +12 -13
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/client.py +12 -8
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/errors.py +6 -0
- indico_toolkit-6.14.0/indico_toolkit/etloutput/__init__.py +210 -0
- indico_toolkit-6.14.0/indico_toolkit/etloutput/cell.py +47 -0
- indico_toolkit-6.14.0/indico_toolkit/etloutput/errors.py +16 -0
- indico_toolkit-6.14.0/indico_toolkit/etloutput/etloutput.py +110 -0
- indico_toolkit-6.14.0/indico_toolkit/etloutput/range.py +30 -0
- indico_toolkit-6.14.0/indico_toolkit/etloutput/table.py +44 -0
- indico_toolkit-6.14.0/indico_toolkit/etloutput/token.py +25 -0
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/indico_wrapper/__init__.py +12 -3
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/indico_wrapper/dataset.py +32 -14
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/indico_wrapper/doc_extraction.py +17 -7
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/indico_wrapper/download.py +46 -18
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/indico_wrapper/indico_wrapper.py +25 -22
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/indico_wrapper/modelop.py +18 -10
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/indico_wrapper/reviewer.py +22 -9
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/indico_wrapper/workflow.py +27 -27
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/metrics/__init__.py +9 -2
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/metrics/compare_ground_truth.py +14 -9
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/metrics/compare_models.py +40 -21
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/metrics/metrics.py +78 -35
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/metrics/plotting.py +31 -12
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/ocr/__init__.py +7 -1
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/ocr/customocr_object.py +6 -5
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/ocr/ondoc_object.py +10 -9
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/ocr/standard_object.py +7 -3
- indico_toolkit-6.14.0/indico_toolkit/pipelines/__init__.py +3 -0
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/pipelines/file_processing.py +26 -20
- indico_toolkit-6.14.0/indico_toolkit/polling/__init__.py +8 -0
- indico_toolkit-6.14.0/indico_toolkit/polling/autoreview.py +204 -0
- indico_toolkit-6.14.0/indico_toolkit/polling/downstream.py +145 -0
- indico_toolkit-6.14.0/indico_toolkit/polling/queries.py +68 -0
- indico_toolkit-6.14.0/indico_toolkit/results/__init__.py +104 -0
- indico_toolkit-6.14.0/indico_toolkit/results/document.py +78 -0
- indico_toolkit-6.14.0/indico_toolkit/results/errors.py +4 -0
- indico_toolkit-6.14.0/indico_toolkit/results/model.py +60 -0
- indico_toolkit-6.14.0/indico_toolkit/results/normalization.py +159 -0
- indico_toolkit-6.14.0/indico_toolkit/results/predictionlist.py +395 -0
- indico_toolkit-6.14.0/indico_toolkit/results/predictions/__init__.py +88 -0
- indico_toolkit-6.14.0/indico_toolkit/results/predictions/box.py +58 -0
- indico_toolkit-6.14.0/indico_toolkit/results/predictions/citation.py +47 -0
- indico_toolkit-6.14.0/indico_toolkit/results/predictions/classification.py +50 -0
- indico_toolkit-6.14.0/indico_toolkit/results/predictions/documentextraction.py +160 -0
- indico_toolkit-6.14.0/indico_toolkit/results/predictions/extraction.py +35 -0
- indico_toolkit-6.14.0/indico_toolkit/results/predictions/formextraction.py +121 -0
- indico_toolkit-6.14.0/indico_toolkit/results/predictions/group.py +29 -0
- indico_toolkit-6.14.0/indico_toolkit/results/predictions/prediction.py +41 -0
- indico_toolkit-6.14.0/indico_toolkit/results/predictions/span.py +43 -0
- indico_toolkit-6.14.0/indico_toolkit/results/predictions/summarization.py +103 -0
- indico_toolkit-6.14.0/indico_toolkit/results/predictions/unbundling.py +51 -0
- indico_toolkit-6.14.0/indico_toolkit/results/result.py +152 -0
- indico_toolkit-6.14.0/indico_toolkit/results/review.py +32 -0
- indico_toolkit-6.14.0/indico_toolkit/results/utilities.py +73 -0
- indico_toolkit-6.14.0/indico_toolkit/retry.py +94 -0
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/snapshots/__init__.py +2 -0
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/snapshots/snapshot.py +49 -28
- indico_toolkit-6.14.0/indico_toolkit/structure/__init__.py +3 -0
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/structure/create_structure.py +23 -17
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/structure/queries.py +24 -3
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/structure/utils.py +6 -2
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/types/__init__.py +11 -3
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/types/classification.py +16 -3
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/types/extractions.py +32 -12
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/types/predictions.py +9 -7
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/types/workflow_object.py +7 -5
- indico_toolkit-6.14.0/pyproject.toml +76 -0
- indico_toolkit-6.1.0/.github/workflows/build.yml +0 -64
- indico_toolkit-6.1.0/.gitignore +0 -136
- indico_toolkit-6.1.0/CHANGELOG.md +0 -149
- indico_toolkit-6.1.0/PKG-INFO +0 -106
- indico_toolkit-6.1.0/README.md +0 -84
- indico_toolkit-6.1.0/examples/auto_review_predictions.py +0 -53
- indico_toolkit-6.1.0/examples/copy_teach_task.py +0 -20
- indico_toolkit-6.1.0/examples/create_auto_classification_workflow.py +0 -28
- indico_toolkit-6.1.0/examples/create_full_structure.py +0 -44
- indico_toolkit-6.1.0/examples/dataset_tasks.py +0 -26
- indico_toolkit-6.1.0/examples/ground_truth_metrics.py +0 -92
- indico_toolkit-6.1.0/examples/manipulate_pdfs.py +0 -21
- indico_toolkit-6.1.0/examples/merge_snapshots.py +0 -52
- indico_toolkit-6.1.0/examples/model_metrics.py +0 -53
- indico_toolkit-6.1.0/examples/pdf_highlighter.py +0 -37
- indico_toolkit-6.1.0/examples/row_association.py +0 -33
- indico_toolkit-6.1.0/examples/submitting_to_doc_extraction.py +0 -24
- indico_toolkit-6.1.0/examples/submitting_to_workflow.py +0 -22
- indico_toolkit-6.1.0/indico_toolkit/__init__.py +0 -6
- indico_toolkit-6.1.0/indico_toolkit/auto_populate/__init__.py +0 -1
- indico_toolkit-6.1.0/indico_toolkit/auto_review/__init__.py +0 -1
- indico_toolkit-6.1.0/indico_toolkit/pipelines/__init__.py +0 -1
- indico_toolkit-6.1.0/indico_toolkit/retry.py +0 -27
- indico_toolkit-6.1.0/pyproject.toml +0 -31
- indico_toolkit-6.1.0/requirements.txt +0 -9
- indico_toolkit-6.1.0/setup.py +0 -24
- indico_toolkit-6.1.0/tests/__init__.py +0 -0
- indico_toolkit-6.1.0/tests/association/__init__.py +0 -0
- indico_toolkit-6.1.0/tests/association/conftest.py +0 -46
- indico_toolkit-6.1.0/tests/association/data/three_row_invoice/preds.json +0 -56
- indico_toolkit-6.1.0/tests/association/data/three_row_invoice/tokens.json +0 -87
- indico_toolkit-6.1.0/tests/association/data/token_page/tokens.json +0 -110
- indico_toolkit-6.1.0/tests/association/data/two_row_bank_statement/preds.json +0 -54
- indico_toolkit-6.1.0/tests/association/data/two_row_bank_statement/tokens.json +0 -62
- indico_toolkit-6.1.0/tests/association/test_extracted_tokens.py +0 -62
- indico_toolkit-6.1.0/tests/association/test_line_items.py +0 -111
- indico_toolkit-6.1.0/tests/association/test_positioning.py +0 -350
- indico_toolkit-6.1.0/tests/association/test_splitting.py +0 -26
- indico_toolkit-6.1.0/tests/auto_populate/test_populator.py +0 -77
- indico_toolkit-6.1.0/tests/auto_review/__init__.py +0 -0
- indico_toolkit-6.1.0/tests/auto_review/test_auto_review.py +0 -177
- indico_toolkit-6.1.0/tests/conftest.py +0 -207
- indico_toolkit-6.1.0/tests/data/auto_class/class_a/sample_two_pages.pdf +0 -0
- indico_toolkit-6.1.0/tests/data/auto_class/class_b/inv_sample2.pdf +0 -0
- indico_toolkit-6.1.0/tests/data/auto_review/preds.json +0 -146
- indico_toolkit-6.1.0/tests/data/samples/fin_disc.pdf +0 -0
- indico_toolkit-6.1.0/tests/data/samples/fin_disc_classification.json +0 -21
- indico_toolkit-6.1.0/tests/data/samples/fin_disc_result.json +0 -489
- indico_toolkit-6.1.0/tests/data/samples/fin_disc_snapshot.csv +0 -17343
- indico_toolkit-6.1.0/tests/data/samples/staggered_loop_recruiter_example.json +0 -103
- indico_toolkit-6.1.0/tests/data/snapshots/populator_snapshot.csv +0 -17723
- indico_toolkit-6.1.0/tests/data/snapshots/snapshot.csv +0 -2088
- indico_toolkit-6.1.0/tests/data/snapshots/updated_snapshot.csv +0 -336
- indico_toolkit-6.1.0/tests/indico_wrapper/__init__.py +0 -0
- indico_toolkit-6.1.0/tests/indico_wrapper/test_dataset.py +0 -44
- indico_toolkit-6.1.0/tests/indico_wrapper/test_doc_extraction.py +0 -59
- indico_toolkit-6.1.0/tests/indico_wrapper/test_download.py +0 -37
- indico_toolkit-6.1.0/tests/indico_wrapper/test_indico_wrapper.py +0 -53
- indico_toolkit-6.1.0/tests/indico_wrapper/test_modelops.py +0 -67
- indico_toolkit-6.1.0/tests/indico_wrapper/test_reviewer.py +0 -56
- indico_toolkit-6.1.0/tests/indico_wrapper/test_workflow.py +0 -49
- indico_toolkit-6.1.0/tests/integration/__init__.py +0 -0
- indico_toolkit-6.1.0/tests/integration/test_snapshot_upload.py +0 -18
- indico_toolkit-6.1.0/tests/integration/test_workflow_rows.py +0 -25
- indico_toolkit-6.1.0/tests/metrics/__init__.py +0 -0
- indico_toolkit-6.1.0/tests/metrics/test_compare_ground_truth.py +0 -188
- indico_toolkit-6.1.0/tests/metrics/test_compare_models.py +0 -45
- indico_toolkit-6.1.0/tests/metrics/test_metrics.py +0 -56
- indico_toolkit-6.1.0/tests/metrics/test_plotting.py +0 -25
- indico_toolkit-6.1.0/tests/ocr/__init__.py +0 -0
- indico_toolkit-6.1.0/tests/ocr/test_customocr_object.py +0 -46
- indico_toolkit-6.1.0/tests/ocr/test_ondoc_object.py +0 -62
- indico_toolkit-6.1.0/tests/ocr/test_standard_object.py +0 -33
- indico_toolkit-6.1.0/tests/pipelines/__init__.py +0 -0
- indico_toolkit-6.1.0/tests/pipelines/test_file_processing.py +0 -72
- indico_toolkit-6.1.0/tests/pytest.ini +0 -3
- indico_toolkit-6.1.0/tests/snapshots/__init__.py +0 -0
- indico_toolkit-6.1.0/tests/snapshots/conftest.py +0 -21
- indico_toolkit-6.1.0/tests/snapshots/test_snapshot.py +0 -184
- indico_toolkit-6.1.0/tests/structure/test_create_structure.py +0 -2
- indico_toolkit-6.1.0/tests/test_create_client.py +0 -16
- indico_toolkit-6.1.0/tests/test_retry.py +0 -23
- indico_toolkit-6.1.0/tests/types/__init__.py +0 -0
- indico_toolkit-6.1.0/tests/types/conftest.py +0 -40
- indico_toolkit-6.1.0/tests/types/test_classifications.py +0 -44
- indico_toolkit-6.1.0/tests/types/test_extractions.py +0 -134
- indico_toolkit-6.1.0/tests/types/test_predictions.py +0 -34
- indico_toolkit-6.1.0/tests/types/test_worflow_result.py +0 -41
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/LICENSE +0 -0
- {indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/association/splitting.py +0 -0
- /indico_toolkit-6.1.0/indico_toolkit/structure/__init__.py → /indico_toolkit-6.14.0/indico_toolkit/py.typed +0 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: indico-toolkit
|
|
3
|
+
Version: 6.14.0
|
|
4
|
+
Summary: Classes, functions, and abstractions for Indico IPA
|
|
5
|
+
License: MIT
|
|
6
|
+
Author: Indico Solutions Engineering
|
|
7
|
+
Author-email: solutionsengineering@indicodata.ai
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Provides-Extra: all
|
|
16
|
+
Provides-Extra: downloads
|
|
17
|
+
Provides-Extra: examples
|
|
18
|
+
Provides-Extra: metrics
|
|
19
|
+
Provides-Extra: predictions
|
|
20
|
+
Provides-Extra: snapshots
|
|
21
|
+
Requires-Dist: indico-client (>=6.14.0,<7.0.0)
|
|
22
|
+
Requires-Dist: pandas (>=2.2.3,<3.0.0) ; extra == "all"
|
|
23
|
+
Requires-Dist: pandas (>=2.2.3,<3.0.0) ; extra == "downloads"
|
|
24
|
+
Requires-Dist: pandas (>=2.2.3,<3.0.0) ; extra == "examples"
|
|
25
|
+
Requires-Dist: pandas (>=2.2.3,<3.0.0) ; extra == "metrics"
|
|
26
|
+
Requires-Dist: pandas (>=2.2.3,<3.0.0) ; extra == "predictions"
|
|
27
|
+
Requires-Dist: pandas (>=2.2.3,<3.0.0) ; extra == "snapshots"
|
|
28
|
+
Requires-Dist: plotly (>=5.2.1,<6.0.0) ; extra == "all"
|
|
29
|
+
Requires-Dist: plotly (>=5.2.1,<6.0.0) ; extra == "metrics"
|
|
30
|
+
Requires-Dist: tqdm (>=4.50.0,<5.0.0) ; extra == "all"
|
|
31
|
+
Requires-Dist: tqdm (>=4.50.0,<5.0.0) ; extra == "downloads"
|
|
32
|
+
Project-URL: source, https://github.com/IndicoDataSolutions/Indico-Solutions-Toolkit
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
# Indico Toolkit
|
|
36
|
+
|
|
37
|
+
**This repository contains software that is not officially supported by Indico. It may
|
|
38
|
+
be outdated or contain bugs. The operations it performs are potentially destructive.
|
|
39
|
+
Use at your own risk.**
|
|
40
|
+
|
|
41
|
+
Classes, functions, and abstractions for building workflows using the Indico IPA
|
|
42
|
+
(Intelligent Process Automation) platform.
|
|
43
|
+
|
|
44
|
+
- [Polling Classes](https://github.com/IndicoDataSolutions/indico-toolkit-python/tree/main/indico_toolkit/polling/__init__.py)
|
|
45
|
+
that implement best-practices polling behavior for Auto Review and Downstream
|
|
46
|
+
processes. Easily plug in business logic without the boilerplate.
|
|
47
|
+
- [Result File](https://github.com/IndicoDataSolutions/indico-toolkit-python/blob/main/indico_toolkit/results/__init__.py)
|
|
48
|
+
and [Etl Output](https://github.com/IndicoDataSolutions/indico-toolkit-python/blob/main/indico_toolkit/etloutput/__init__.py)
|
|
49
|
+
Data Classes that parse standard IPA JSON output into idiomatic, type-safe Python dataclasses.
|
|
50
|
+
- [Metrics Classes](https://github.com/IndicoDataSolutions/indico-toolkit-python/blob/main/indico_toolkit/metrics/__init__.py)
|
|
51
|
+
to compare model performance, evaluate ground truth, and plot statistics.
|
|
52
|
+
- [Snapshot Classes](https://github.com/IndicoDataSolutions/indico-toolkit-python/blob/main/indico_toolkit/snapshots/snapshot.py)
|
|
53
|
+
to concatenate, merge, filter, and manipulate snapshot CSVs.
|
|
54
|
+
|
|
55
|
+
...and more in the [Examples](https://github.com/IndicoDataSolutions/indico-toolkit-python/tree/main/examples) folder.
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
## Installation
|
|
59
|
+
|
|
60
|
+
**Indico Toolkit does not use semantic versioning.**
|
|
61
|
+
|
|
62
|
+
Indico Toolkit versions match the minimum IPA version required to use its functionality.
|
|
63
|
+
E.g. `indico-toolkit==6.14.0` makes use of functionality introduced in IPA 6.14, and
|
|
64
|
+
some functionality requires IPA 6.14 or later to use.
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install indico-toolkit
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Some functionality requires optional dependencies that can be installed with extras.
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install 'indico-toolkit[all]'
|
|
74
|
+
pip install 'indico-toolkit[downloads]'
|
|
75
|
+
pip install 'indico-toolkit[examples]'
|
|
76
|
+
pip install 'indico-toolkit[metrics]'
|
|
77
|
+
pip install 'indico-toolkit[predictions]'
|
|
78
|
+
pip install 'indico-toolkit[snapshots]'
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
## Contributing
|
|
83
|
+
|
|
84
|
+
Indico Toolkit uses Poetry 2.X for package and dependency management.
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
### Setup
|
|
88
|
+
|
|
89
|
+
Clone the source repository with Git.
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
git clone git@github.com:IndicoDataSolutions/indico-toolkit-python.git
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Install dependencies with Poetry.
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
poetry install
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Formatting, linting, type checking, and tests are defined as
|
|
102
|
+
[Poe](https://poethepoet.natn.io/) tasks in `pyproject.toml`.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
poetry run poe {format,check,test,all}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Code changes or additions should pass `poetry run poe all` before opening a PR.
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
### Tests
|
|
112
|
+
|
|
113
|
+
Indico Toolkit has three test suites: required unit tests, extra unit tests, and
|
|
114
|
+
integration tests.
|
|
115
|
+
|
|
116
|
+
By default, only required unit tests are executed. Extra unit tests and integration
|
|
117
|
+
tests are skipped.
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
poetry run poe {test,all}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Extra unit tests are skipped when their dependencies are not installed. To execute extra
|
|
124
|
+
unit tests, install one or more extras and run the tests.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
poetry install --all-extras
|
|
128
|
+
poetry run poe {test,all}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Integration tests make API calls to an IPA environment and require a host and API token
|
|
132
|
+
to execute. These tests create datasets, setup workflows, and train models. **Expect
|
|
133
|
+
them to take tens of minutes to run.**
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
poetry run poe test-integration \
|
|
137
|
+
--host try.indico.io \
|
|
138
|
+
--token indico_api_token.txt
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Make liberal use of pytest's `--last-failed` and `--failed-first`
|
|
142
|
+
[flags](https://docs.pytest.org/en/stable/how-to/cache.html) to speed up integration
|
|
143
|
+
test execution when writing code.
|
|
144
|
+
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Indico Toolkit
|
|
2
|
+
|
|
3
|
+
**This repository contains software that is not officially supported by Indico. It may
|
|
4
|
+
be outdated or contain bugs. The operations it performs are potentially destructive.
|
|
5
|
+
Use at your own risk.**
|
|
6
|
+
|
|
7
|
+
Classes, functions, and abstractions for building workflows using the Indico IPA
|
|
8
|
+
(Intelligent Process Automation) platform.
|
|
9
|
+
|
|
10
|
+
- [Polling Classes](https://github.com/IndicoDataSolutions/indico-toolkit-python/tree/main/indico_toolkit/polling/__init__.py)
|
|
11
|
+
that implement best-practices polling behavior for Auto Review and Downstream
|
|
12
|
+
processes. Easily plug in business logic without the boilerplate.
|
|
13
|
+
- [Result File](https://github.com/IndicoDataSolutions/indico-toolkit-python/blob/main/indico_toolkit/results/__init__.py)
|
|
14
|
+
and [Etl Output](https://github.com/IndicoDataSolutions/indico-toolkit-python/blob/main/indico_toolkit/etloutput/__init__.py)
|
|
15
|
+
Data Classes that parse standard IPA JSON output into idiomatic, type-safe Python dataclasses.
|
|
16
|
+
- [Metrics Classes](https://github.com/IndicoDataSolutions/indico-toolkit-python/blob/main/indico_toolkit/metrics/__init__.py)
|
|
17
|
+
to compare model performance, evaluate ground truth, and plot statistics.
|
|
18
|
+
- [Snapshot Classes](https://github.com/IndicoDataSolutions/indico-toolkit-python/blob/main/indico_toolkit/snapshots/snapshot.py)
|
|
19
|
+
to concatenate, merge, filter, and manipulate snapshot CSVs.
|
|
20
|
+
|
|
21
|
+
...and more in the [Examples](https://github.com/IndicoDataSolutions/indico-toolkit-python/tree/main/examples) folder.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
**Indico Toolkit does not use semantic versioning.**
|
|
27
|
+
|
|
28
|
+
Indico Toolkit versions match the minimum IPA version required to use its functionality.
|
|
29
|
+
E.g. `indico-toolkit==6.14.0` makes use of functionality introduced in IPA 6.14, and
|
|
30
|
+
some functionality requires IPA 6.14 or later to use.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install indico-toolkit
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Some functionality requires optional dependencies that can be installed with extras.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install 'indico-toolkit[all]'
|
|
40
|
+
pip install 'indico-toolkit[downloads]'
|
|
41
|
+
pip install 'indico-toolkit[examples]'
|
|
42
|
+
pip install 'indico-toolkit[metrics]'
|
|
43
|
+
pip install 'indico-toolkit[predictions]'
|
|
44
|
+
pip install 'indico-toolkit[snapshots]'
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
## Contributing
|
|
49
|
+
|
|
50
|
+
Indico Toolkit uses Poetry 2.X for package and dependency management.
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
### Setup
|
|
54
|
+
|
|
55
|
+
Clone the source repository with Git.
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
git clone git@github.com:IndicoDataSolutions/indico-toolkit-python.git
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Install dependencies with Poetry.
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
poetry install
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Formatting, linting, type checking, and tests are defined as
|
|
68
|
+
[Poe](https://poethepoet.natn.io/) tasks in `pyproject.toml`.
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
poetry run poe {format,check,test,all}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Code changes or additions should pass `poetry run poe all` before opening a PR.
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
### Tests
|
|
78
|
+
|
|
79
|
+
Indico Toolkit has three test suites: required unit tests, extra unit tests, and
|
|
80
|
+
integration tests.
|
|
81
|
+
|
|
82
|
+
By default, only required unit tests are executed. Extra unit tests and integration
|
|
83
|
+
tests are skipped.
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
poetry run poe {test,all}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Extra unit tests are skipped when their dependencies are not installed. To execute extra
|
|
90
|
+
unit tests, install one or more extras and run the tests.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
poetry install --all-extras
|
|
94
|
+
poetry run poe {test,all}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Integration tests make API calls to an IPA environment and require a host and API token
|
|
98
|
+
to execute. These tests create datasets, setup workflows, and train models. **Expect
|
|
99
|
+
them to take tens of minutes to run.**
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
poetry run poe test-integration \
|
|
103
|
+
--host try.indico.io \
|
|
104
|
+
--token indico_api_token.txt
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Make liberal use of pytest's `--last-failed` and `--failed-first`
|
|
108
|
+
[flags](https://docs.pytest.org/en/stable/how-to/cache.html) to speed up integration
|
|
109
|
+
test execution when writing code.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Classes, functions, and abstractions for Indico IPA"""
|
|
2
|
+
|
|
3
|
+
from .client import create_client
|
|
4
|
+
from .errors import (
|
|
5
|
+
ToolkitAuthError,
|
|
6
|
+
ToolkitError,
|
|
7
|
+
ToolkitInputError,
|
|
8
|
+
ToolkitInstantiationError,
|
|
9
|
+
ToolkitPopulationError,
|
|
10
|
+
ToolkitStaggeredLoopError,
|
|
11
|
+
ToolkitStatusError,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
__all__ = (
|
|
15
|
+
"create_client",
|
|
16
|
+
"ToolkitAuthError",
|
|
17
|
+
"ToolkitError",
|
|
18
|
+
"ToolkitInputError",
|
|
19
|
+
"ToolkitInstantiationError",
|
|
20
|
+
"ToolkitPopulationError",
|
|
21
|
+
"ToolkitStaggeredLoopError",
|
|
22
|
+
"ToolkitStatusError",
|
|
23
|
+
)
|
|
24
|
+
__version__ = "6.14.0"
|
|
@@ -3,3 +3,13 @@ from .extracted_tokens import ExtractedTokens
|
|
|
3
3
|
from .line_items import LineItems
|
|
4
4
|
from .positioning import Positioning
|
|
5
5
|
from .splitting import split_prediction
|
|
6
|
+
|
|
7
|
+
__all__ = (
|
|
8
|
+
"Association",
|
|
9
|
+
"ExtractedTokens",
|
|
10
|
+
"LineItems",
|
|
11
|
+
"Positioning",
|
|
12
|
+
"sequences_exact",
|
|
13
|
+
"sequences_overlap",
|
|
14
|
+
"split_prediction",
|
|
15
|
+
)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
from typing import Union, List, Dict
|
|
2
|
-
from collections import defaultdict
|
|
3
1
|
from abc import ABC, abstractmethod
|
|
4
|
-
from
|
|
2
|
+
from collections import defaultdict
|
|
3
|
+
from typing import Dict, List, Union
|
|
4
|
+
|
|
5
|
+
from ..types import Extractions
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class Association(ABC):
|
{indico_toolkit-6.1.0 → indico_toolkit-6.14.0}/indico_toolkit/association/extracted_tokens.py
RENAMED
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
from typing import List, Union
|
|
2
|
-
|
|
3
|
-
from
|
|
4
|
-
from
|
|
2
|
+
|
|
3
|
+
from ..types import Extractions
|
|
4
|
+
from .association import Association, _check_if_token_match_found, sequences_overlap
|
|
5
5
|
|
|
6
6
|
# TODO: add test that 'errored_predictions' actually works with ValueErrors
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class ExtractedTokens(Association):
|
|
10
10
|
"""
|
|
11
|
-
Class to collect all extracted tokens, e.g. to enable highlighting of source
|
|
11
|
+
Class to collect all extracted tokens, e.g. to enable highlighting of source
|
|
12
|
+
document
|
|
12
13
|
"""
|
|
13
14
|
|
|
14
|
-
def __init__(
|
|
15
|
-
self, predictions: Union[List[dict], Extractions],
|
|
16
|
-
):
|
|
15
|
+
def __init__(self, predictions: Union[List[dict], Extractions]):
|
|
17
16
|
super().__init__(predictions)
|
|
18
17
|
|
|
19
18
|
def match_pred_to_token(self, pred: dict, ocr_tokens: List[dict], pred_index: int):
|
|
20
19
|
"""
|
|
21
|
-
Append matching token positions to self.mapped_positions, if no matches for
|
|
20
|
+
Append matching token positions to self.mapped_positions, if no matches for
|
|
21
|
+
pred, raise ValueError
|
|
22
22
|
|
|
23
23
|
Args:
|
|
24
24
|
pred (dict): Indico extraction model prediction
|
|
25
25
|
ocr_tokens (List[dict]): List of OCR tokens
|
|
26
|
-
pred_index (int): unique number for each prediction so that tokens can be
|
|
26
|
+
pred_index (int): unique number for each prediction so that tokens can be
|
|
27
|
+
linked to it
|
|
27
28
|
|
|
28
29
|
Raises:
|
|
29
30
|
ValueError: No matching token was found
|
|
@@ -46,21 +47,22 @@ class ExtractedTokens(Association):
|
|
|
46
47
|
_check_if_token_match_found(pred, no_match)
|
|
47
48
|
return match_token_index
|
|
48
49
|
|
|
49
|
-
def collect_tokens(
|
|
50
|
-
self, ocr_tokens: List[dict], raise_for_no_match: bool = True,
|
|
51
|
-
):
|
|
50
|
+
def collect_tokens(self, ocr_tokens: List[dict], raise_for_no_match: bool = True):
|
|
52
51
|
"""
|
|
53
52
|
Collect all extracted tokens and with pred text and label added to dictionaries
|
|
54
53
|
Args:
|
|
55
54
|
ocr_tokens (List[dict]): Tokens from 'ondocument' OCR config output
|
|
56
|
-
raise_for_no_match (bool): raise exception if a matching token isn't found for a
|
|
55
|
+
raise_for_no_match (bool): raise exception if a matching token isn't found for a
|
|
56
|
+
prediction
|
|
57
57
|
"""
|
|
58
58
|
self._separate_manually_added_predictions()
|
|
59
59
|
self._predictions = self.sort_predictions_by_start_index(self._predictions)
|
|
60
60
|
match_index = 0
|
|
61
61
|
for pred_ind, pred in enumerate(self._predictions):
|
|
62
62
|
try:
|
|
63
|
-
match_index = self.match_pred_to_token(
|
|
63
|
+
match_index = self.match_pred_to_token(
|
|
64
|
+
pred, ocr_tokens[match_index:], pred_ind
|
|
65
|
+
)
|
|
64
66
|
except ValueError as e:
|
|
65
67
|
if raise_for_no_match:
|
|
66
68
|
raise ValueError(e)
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
"""Associate row items"""
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
from collections import defaultdict
|
|
4
4
|
from copy import deepcopy
|
|
5
|
-
from
|
|
6
|
-
|
|
5
|
+
from typing import Iterable, List, Union
|
|
6
|
+
|
|
7
|
+
from ..types import Extractions
|
|
8
|
+
from .association import Association, _check_if_token_match_found, sequences_overlap
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
class LineItems(Association):
|
|
10
12
|
"""
|
|
11
|
-
Class for associating line items given extraction predictions and ondocument OCR
|
|
13
|
+
Class for associating line items given extraction predictions and ondocument OCR
|
|
14
|
+
tokens
|
|
12
15
|
|
|
13
16
|
Example Usage:
|
|
14
17
|
|
|
@@ -31,8 +34,8 @@ class LineItems(Association):
|
|
|
31
34
|
"""
|
|
32
35
|
Args:
|
|
33
36
|
predictions (List[dict]): List of extraction predictions
|
|
34
|
-
line_item_fields (Iterable[str]): Fields/labels to include as line item values,
|
|
35
|
-
|
|
37
|
+
line_item_fields (Iterable[str]): Fields/labels to include as line item values,
|
|
38
|
+
other values will not be assigned a row_number.
|
|
36
39
|
"""
|
|
37
40
|
self.predictions = self.validate_prediction_formatting(predictions)
|
|
38
41
|
self.line_item_fields: Iterable[str] = line_item_fields
|
|
@@ -78,13 +81,16 @@ class LineItems(Association):
|
|
|
78
81
|
return match_token_index
|
|
79
82
|
|
|
80
83
|
def get_bounding_boxes(
|
|
81
|
-
self, ocr_tokens: List[dict], raise_for_no_match: bool = True
|
|
84
|
+
self, ocr_tokens: List[dict], raise_for_no_match: bool = True
|
|
82
85
|
):
|
|
83
86
|
"""
|
|
84
|
-
Adds keys for bounding box top/bottom/left/right and page number to line item
|
|
87
|
+
Adds keys for bounding box top/bottom/left/right and page number to line item
|
|
88
|
+
predictions
|
|
89
|
+
|
|
85
90
|
Args:
|
|
86
91
|
ocr_tokens (List[dict]): Tokens from 'ondocument' OCR config output
|
|
87
|
-
raise_for_no_match (bool): raise exception if a matching token isn't found for a
|
|
92
|
+
raise_for_no_match (bool): raise exception if a matching token isn't found for a
|
|
93
|
+
prediction
|
|
88
94
|
"""
|
|
89
95
|
predictions = deepcopy(self.predictions)
|
|
90
96
|
predictions = self._remove_unneeded_predictions(predictions)
|
|
@@ -117,7 +123,8 @@ class LineItems(Association):
|
|
|
117
123
|
page_number = starting_pred["page_num"]
|
|
118
124
|
row_number = 1
|
|
119
125
|
for pred in self._mapped_positions:
|
|
120
|
-
# if the top of one box equals the bottom of another, we still want a new
|
|
126
|
+
# if the top of one box equals the bottom of another, we still want a new
|
|
127
|
+
# line
|
|
121
128
|
if pred["bbTop"] >= max_bot or pred["page_num"] != page_number:
|
|
122
129
|
row_number += 1
|
|
123
130
|
page_number = pred["page_num"]
|
|
@@ -129,8 +136,8 @@ class LineItems(Association):
|
|
|
129
136
|
@property
|
|
130
137
|
def grouped_line_items(self) -> List[List[dict]]:
|
|
131
138
|
"""
|
|
132
|
-
After row number has been assigned to predictions, returns line item predictions
|
|
133
|
-
list of lists where each list is a row.
|
|
139
|
+
After row number has been assigned to predictions, returns line item predictions
|
|
140
|
+
as a list of lists where each list is a row.
|
|
134
141
|
"""
|
|
135
142
|
rows = defaultdict(list)
|
|
136
143
|
for pred in self._mapped_positions:
|
|
@@ -139,7 +146,8 @@ class LineItems(Association):
|
|
|
139
146
|
|
|
140
147
|
def _remove_unneeded_predictions(self, predictions: List[dict]) -> List[dict]:
|
|
141
148
|
"""
|
|
142
|
-
Remove predictions that are not line item fields or don't have valid start/end
|
|
149
|
+
Remove predictions that are not line item fields or don't have valid start/end
|
|
150
|
+
index data
|
|
143
151
|
"""
|
|
144
152
|
valid_line_item_preds = []
|
|
145
153
|
for pred in predictions:
|
|
@@ -159,8 +167,9 @@ class LineItems(Association):
|
|
|
159
167
|
|
|
160
168
|
def _get_first_valid_line_item_pred(self) -> dict:
|
|
161
169
|
if len(self._mapped_positions) == 0:
|
|
162
|
-
raise
|
|
163
|
-
"Whoops! You have no line_item_fields predictions.
|
|
170
|
+
raise RuntimeError(
|
|
171
|
+
"Whoops! You have no line_item_fields predictions. "
|
|
172
|
+
"Did you run get_bounding_boxes?"
|
|
164
173
|
)
|
|
165
174
|
return self._mapped_positions[0]
|
|
166
175
|
|