tryworks 0.1.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.
- tryworks-0.1.0/.gitignore +8 -0
- tryworks-0.1.0/LICENSE +201 -0
- tryworks-0.1.0/NOTICE +17 -0
- tryworks-0.1.0/PKG-INFO +270 -0
- tryworks-0.1.0/README.md +246 -0
- tryworks-0.1.0/pyproject.toml +57 -0
- tryworks-0.1.0/scripts/compat.py +257 -0
- tryworks-0.1.0/scripts/measure.py +137 -0
- tryworks-0.1.0/src/tryworks/__init__.py +16 -0
- tryworks-0.1.0/src/tryworks/__main__.py +72 -0
- tryworks-0.1.0/src/tryworks/__version__.py +1 -0
- tryworks-0.1.0/src/tryworks/_patterns.py +48 -0
- tryworks-0.1.0/src/tryworks/chunking/__init__.py +25 -0
- tryworks-0.1.0/src/tryworks/chunking/base.py +356 -0
- tryworks-0.1.0/src/tryworks/chunking/basic.py +48 -0
- tryworks-0.1.0/src/tryworks/chunking/title.py +69 -0
- tryworks-0.1.0/src/tryworks/cleaners/__init__.py +0 -0
- tryworks-0.1.0/src/tryworks/cleaners/core.py +229 -0
- tryworks-0.1.0/src/tryworks/compat.py +58 -0
- tryworks-0.1.0/src/tryworks/documents/__init__.py +0 -0
- tryworks-0.1.0/src/tryworks/documents/coordinates.py +79 -0
- tryworks-0.1.0/src/tryworks/documents/elements.py +553 -0
- tryworks-0.1.0/src/tryworks/partition/__init__.py +0 -0
- tryworks-0.1.0/src/tryworks/partition/_html_table.py +42 -0
- tryworks-0.1.0/src/tryworks/partition/_ooxml.py +167 -0
- tryworks-0.1.0/src/tryworks/partition/auto.py +247 -0
- tryworks-0.1.0/src/tryworks/partition/common.py +412 -0
- tryworks-0.1.0/src/tryworks/partition/csv.py +82 -0
- tryworks-0.1.0/src/tryworks/partition/docx.py +515 -0
- tryworks-0.1.0/src/tryworks/partition/email.py +135 -0
- tryworks-0.1.0/src/tryworks/partition/html.py +538 -0
- tryworks-0.1.0/src/tryworks/partition/json.py +31 -0
- tryworks-0.1.0/src/tryworks/partition/md.py +285 -0
- tryworks-0.1.0/src/tryworks/partition/pdf.py +259 -0
- tryworks-0.1.0/src/tryworks/partition/pptx.py +214 -0
- tryworks-0.1.0/src/tryworks/partition/text.py +93 -0
- tryworks-0.1.0/src/tryworks/partition/text_type.py +341 -0
- tryworks-0.1.0/src/tryworks/partition/xlsx.py +276 -0
- tryworks-0.1.0/src/tryworks/staging/__init__.py +0 -0
- tryworks-0.1.0/src/tryworks/staging/base.py +258 -0
- tryworks-0.1.0/tests/conftest.py +16 -0
- tryworks-0.1.0/tests/corpus.py +355 -0
- tryworks-0.1.0/tests/test_auto_cli_compat.py +102 -0
- tryworks-0.1.0/tests/test_chunking.py +127 -0
- tryworks-0.1.0/tests/test_elements.py +155 -0
- tryworks-0.1.0/tests/test_partition_formats.py +354 -0
- tryworks-0.1.0/tests/test_security.py +75 -0
- tryworks-0.1.0/tests/test_text_rules.py +126 -0
tryworks-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
tryworks-0.1.0/NOTICE
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
tryworks
|
|
2
|
+
Copyright 2026 The tryworks contributors
|
|
3
|
+
|
|
4
|
+
This product is an independent implementation of the public Python API of
|
|
5
|
+
"unstructured" (https://github.com/Unstructured-IO/unstructured),
|
|
6
|
+
Copyright 2022 Unstructured Technologies, Inc., licensed under the
|
|
7
|
+
Apache License, Version 2.0.
|
|
8
|
+
|
|
9
|
+
The element types, metadata field names, function signatures and chunking
|
|
10
|
+
semantics of tryworks are modeled on that API so tryworks can serve as a
|
|
11
|
+
drop-in replacement for its document-partitioning call path. tryworks does
|
|
12
|
+
not contain source code copied from unstructured, and its test corpus is
|
|
13
|
+
generated by tryworks' own scripts rather than taken from unstructured's
|
|
14
|
+
example documents.
|
|
15
|
+
|
|
16
|
+
"Unstructured" is a name of Unstructured Technologies, Inc. tryworks is not
|
|
17
|
+
affiliated with, endorsed by, or sponsored by Unstructured Technologies, Inc.
|
tryworks-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: tryworks
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Partition documents into LLM-ready elements. The call path of unstructured, with zero required dependencies.
|
|
5
|
+
License-Expression: Apache-2.0
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
License-File: NOTICE
|
|
8
|
+
Keywords: chunking,document parsing,docx,llm,pdf,rag,unstructured
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Text Processing
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: openpyxl>=3.1; extra == 'dev'
|
|
17
|
+
Requires-Dist: pypdfium2>=4.30; extra == 'dev'
|
|
18
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
19
|
+
Requires-Dist: python-docx>=1.1; extra == 'dev'
|
|
20
|
+
Requires-Dist: python-pptx>=1.0; extra == 'dev'
|
|
21
|
+
Provides-Extra: pdf
|
|
22
|
+
Requires-Dist: pypdfium2>=4.30; extra == 'pdf'
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# tryworks
|
|
26
|
+
|
|
27
|
+
[](https://github.com/ezzcodeezzlife/tryworks/actions/workflows/ci.yml)
|
|
28
|
+

|
|
29
|
+

|
|
30
|
+
[](LICENSE)
|
|
31
|
+
|
|
32
|
+
**Turn PDFs, Word, PowerPoint, Excel, HTML, Markdown, email and text into LLM-ready elements, with
|
|
33
|
+
zero required dependencies.**
|
|
34
|
+
|
|
35
|
+
tryworks implements the document-partitioning call path of
|
|
36
|
+
[unstructured](https://github.com/Unstructured-IO/unstructured): the same `partition()` function,
|
|
37
|
+
the same element types and metadata, the same chunking, the same JSON. It leaves out what most
|
|
38
|
+
pipelines never call, namely OCR, layout models and ingest connectors, and the 2 GB of
|
|
39
|
+
dependencies they bring.
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from tryworks.partition.auto import partition
|
|
43
|
+
from tryworks.chunking.title import chunk_by_title
|
|
44
|
+
|
|
45
|
+
elements = partition("quarterly-report.docx")
|
|
46
|
+
chunks = chunk_by_title(elements, max_characters=1000)
|
|
47
|
+
|
|
48
|
+
for chunk in chunks:
|
|
49
|
+
print(chunk.metadata.page_number, chunk.text[:80])
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
> The name: tryworks were the brick furnaces on whaling ships that rendered raw blubber into oil.
|
|
53
|
+
|
|
54
|
+
## Why
|
|
55
|
+
|
|
56
|
+
Measured on Linux x86-64 with Python 3.12, reading the same document types:
|
|
57
|
+
|
|
58
|
+
| | `unstructured[docx,pptx,xlsx,md,csv,pdf]` | `tryworks[pdf]` |
|
|
59
|
+
|---|---:|---:|
|
|
60
|
+
| Packages installed | 149 | **2** |
|
|
61
|
+
| Download size | 3,257 MB | **3.6 MB** |
|
|
62
|
+
| Installed size (unstructured with CPU-only torch) | 2.0 GB | **9 MB** |
|
|
63
|
+
| Importing `partition` plus the PDF and DOCX partitioners | 4.4–6.2 s | **0.15–0.39 s** |
|
|
64
|
+
| Partitioning the 9-document test corpus, first call included | 7.2 s | **0.59 s** |
|
|
65
|
+
| Security advisories ever published for the installed packages | 701 | **0** |
|
|
66
|
+
| Lines of library code | 34,171 | 5,449 |
|
|
67
|
+
|
|
68
|
+
Base `tryworks` without the PDF extra is a single 80 KB wheel with no dependencies.
|
|
69
|
+
|
|
70
|
+
In practice that means:
|
|
71
|
+
|
|
72
|
+
- **It fits in AWS Lambda.** The zip deployment limit is 250 MB unpacked, and it cannot be raised.
|
|
73
|
+
- **Cold starts are fast**, and since August 2025 AWS bills the Lambda init phase.
|
|
74
|
+
- **Security review is short.** Two packages to approve, pin and scan, where unstructured needs
|
|
75
|
+
149. Air-gapped and regulated environments review each dependency individually.
|
|
76
|
+
- **The supply-chain surface is small.** Most advisories in a large tree come from its transitive
|
|
77
|
+
dependencies, not from the library you asked for.
|
|
78
|
+
|
|
79
|
+
Numbers come from `scripts/measure.py` (exact resolution with `uv pip compile`, advisory counts
|
|
80
|
+
from OSV.dev) and from real installs; see [Reproducing the numbers](#reproducing-the-numbers).
|
|
81
|
+
Neither tree had an open advisory against the versions resolved when this was measured; the
|
|
82
|
+
701 are historical, which is what a scanner and a triage process work through over time.
|
|
83
|
+
|
|
84
|
+
## Install
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pip install "tryworks @ git+https://github.com/ezzcodeezzlife/tryworks"
|
|
88
|
+
pip install "tryworks[pdf] @ git+https://github.com/ezzcodeezzlife/tryworks" # PDF support
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Python 3.10 or newer. PDF support adds [pypdfium2](https://github.com/pypdfium2-team/pypdfium2),
|
|
92
|
+
bindings to PDFium, the PDF engine used in Chrome. Everything else uses the standard library.
|
|
93
|
+
|
|
94
|
+
## Use
|
|
95
|
+
|
|
96
|
+
### Partition
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from tryworks.partition.auto import partition
|
|
100
|
+
|
|
101
|
+
elements = partition("report.pdf") # type from extension or content
|
|
102
|
+
elements = partition(file=open("memo.docx", "rb")) # file objects work too
|
|
103
|
+
elements = partition(url="https://example.com/post") # http(s) URLs
|
|
104
|
+
|
|
105
|
+
for el in elements:
|
|
106
|
+
print(el.category, el.metadata.page_number, el.text)
|
|
107
|
+
# Title 1 Quarterly Operations Memo
|
|
108
|
+
# NarrativeText 1 Revenue grew eleven percent year over year, ...
|
|
109
|
+
# ListItem 1 Expand the Rotterdam warehouse
|
|
110
|
+
# Table 1 Warehouse totals Units Rotterdam KR-1001 1200 ...
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Each format also has its own function with unstructured's signature: `partition_pdf`,
|
|
114
|
+
`partition_docx`, `partition_pptx`, `partition_xlsx`, `partition_html`, `partition_md`,
|
|
115
|
+
`partition_text`, `partition_csv`, `partition_tsv`, `partition_email`, `partition_json`.
|
|
116
|
+
|
|
117
|
+
### Chunk
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
from tryworks.chunking.title import chunk_by_title
|
|
121
|
+
from tryworks.chunking.basic import chunk_elements
|
|
122
|
+
|
|
123
|
+
chunks = chunk_by_title(elements, max_characters=1000, overlap=100)
|
|
124
|
+
chunks = partition("report.pdf", chunking_strategy="by_title", max_characters=1000)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Sections start at each Title, small sections are combined, long text is split at newlines or
|
|
128
|
+
spaces, and tables get chunks of their own. Tables too large for one chunk are split by row
|
|
129
|
+
into `TableChunk` elements that keep valid HTML in `metadata.text_as_html`.
|
|
130
|
+
|
|
131
|
+
### Serialize
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from tryworks.staging.base import elements_to_json, elements_from_json, elements_to_md
|
|
135
|
+
|
|
136
|
+
json_text = elements_to_json(elements) # same JSON as unstructured, readable by it
|
|
137
|
+
elements = elements_from_json(text=json_text)
|
|
138
|
+
markdown = elements_to_md(elements)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Command line
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
tryworks report.pdf # JSON
|
|
145
|
+
tryworks memo.docx --format markdown
|
|
146
|
+
tryworks https://example.com/post --format text --chunking-strategy by_title --max-characters 800
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Moving from unstructured
|
|
150
|
+
|
|
151
|
+
Change the package name in your imports:
|
|
152
|
+
|
|
153
|
+
```diff
|
|
154
|
+
- from unstructured.partition.auto import partition
|
|
155
|
+
- from unstructured.chunking.title import chunk_by_title
|
|
156
|
+
+ from tryworks.partition.auto import partition
|
|
157
|
+
+ from tryworks.chunking.title import chunk_by_title
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
For code you can't edit, such as a third-party library that imports `unstructured` itself, register
|
|
161
|
+
tryworks under the `unstructured` import names before that code is imported:
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
import tryworks
|
|
165
|
+
tryworks.alias_as_unstructured()
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
This only affects imports in the current process. It installs nothing named `unstructured`.
|
|
169
|
+
|
|
170
|
+
## Formats
|
|
171
|
+
|
|
172
|
+
| Format | Extensions | Implementation | What you get |
|
|
173
|
+
|---|---|---|---|
|
|
174
|
+
| PDF | `.pdf` | PDFium via `pypdfium2` | Text blocks in reading order (multi-column aware), titles, lists, headers and footers, coordinates, page numbers |
|
|
175
|
+
| Word | `.docx` | `zipfile` + `ElementTree` | Style-based titles and lists, tables with merged cells, section headers and footers, links, bold/italic, page breaks |
|
|
176
|
+
| PowerPoint | `.pptx` | `zipfile` + `ElementTree` | One page per slide, titles, bullets with levels, tables, speaker notes |
|
|
177
|
+
| Excel | `.xlsx` | `zipfile` + `ElementTree` | Each sheet split into sub-tables, captions as text, dates and numbers formatted |
|
|
178
|
+
| HTML | `.html`, `.htm` | `html.parser` | Headings, paragraphs, nested lists, tables, code, images, links, emphasis; navigation and forms dropped |
|
|
179
|
+
| Markdown | `.md` | Built-in renderer | Same elements as HTML |
|
|
180
|
+
| Text | `.txt` | Standard library | Paragraphs classified as titles, prose, list items, emails, addresses |
|
|
181
|
+
| CSV, TSV | `.csv`, `.tsv` | `csv` | One table, delimiter detected |
|
|
182
|
+
| Email | `.eml` | `email` | Body with sender, recipients, subject and date; attachments partitioned |
|
|
183
|
+
| Elements | `.json` | `json` | Elements saved by `elements_to_json`, from either library |
|
|
184
|
+
|
|
185
|
+
## Compatibility with unstructured
|
|
186
|
+
|
|
187
|
+
A generated corpus with one realistic document per format is partitioned by both libraries and
|
|
188
|
+
compared element by element ([report](compat/REPORT.md), [script](scripts/compat.py)). A
|
|
189
|
+
[workflow](.github/workflows/compat.yml) repeats the comparison weekly against the latest
|
|
190
|
+
unstructured release.
|
|
191
|
+
|
|
192
|
+
Against unstructured 0.27.5:
|
|
193
|
+
|
|
194
|
+
- **97%** of upstream elements have a tryworks element with identical text,
|
|
195
|
+
- **97%** of those have the same element type,
|
|
196
|
+
- **94%** have the same element id (ids hash filename, text, page and position, so this also
|
|
197
|
+
checks ordering),
|
|
198
|
+
- `parent_id`, `filetype`, `page_number`, `page_name`, `link_urls`, `emphasized_text_contents`,
|
|
199
|
+
`header_footer_type`, `sent_from` and `subject` agree on every aligned element.
|
|
200
|
+
|
|
201
|
+
Every remaining difference in the report is one of the deliberate differences listed below.
|
|
202
|
+
|
|
203
|
+
### Deliberate differences
|
|
204
|
+
|
|
205
|
+
| Where | unstructured | tryworks | Why |
|
|
206
|
+
|---|---|---|---|
|
|
207
|
+
| Markdown lists | Python-Markdown joins a numbered list with the bullet list after it and turns items next to blank lines into paragraphs | Separate lists, every item a `ListItem` | CommonMark behavior; bullets stay bullets |
|
|
208
|
+
| PDF bullets | Consecutive bullet lines can merge into one `ListItem` | One `ListItem` per bullet | Each bullet is its own item |
|
|
209
|
+
| PDF columns | Text of a right-hand column can come after the page footer | Left column, right column, then footer | Reading order |
|
|
210
|
+
| PDF coordinates | pdfminer glyph boxes | PDFium glyph boxes | Within about 1 pt |
|
|
211
|
+
| DOCX merged cells | 0.27.5 repeats the text in every merged cell | `colspan` / `rowspan` | Matches unstructured's main branch |
|
|
212
|
+
| Language | `langdetect` | Script detection plus stopword profiles for 18 languages | No model dependency; results can differ on tables and fragments |
|
|
213
|
+
|
|
214
|
+
### Not included
|
|
215
|
+
|
|
216
|
+
- **OCR and layout models.** `strategy="hi_res"` and `"ocr_only"` raise `NotImplementedError`, and
|
|
217
|
+
scanned PDFs without embedded text produce a warning and no elements. Use unstructured or an OCR
|
|
218
|
+
service for those.
|
|
219
|
+
- **Formats:** images, audio, `.doc`, `.ppt`, `.xls`, `.msg`, `.rtf`, `.odt`, `.epub`, `.rst`,
|
|
220
|
+
`.org`, `.xml`. Unsupported files raise `UnsupportedFileFormatError`, with a conversion hint.
|
|
221
|
+
- **PDF table structure and image extraction.** PDF tables come out as text blocks.
|
|
222
|
+
- **Pictures in DOCX and PPTX** are not emitted as `Image` elements.
|
|
223
|
+
- **Token-based chunking** (`max_tokens`) raises `NotImplementedError`; use `max_characters`.
|
|
224
|
+
- Ingest connectors, the hosted API client, and staging bricks for labeling tools.
|
|
225
|
+
|
|
226
|
+
Text classification uses the same rules as unstructured, but detects verbs with a compact
|
|
227
|
+
lexicon instead of NLTK. On borderline text such as short fragments, a paragraph can come out as
|
|
228
|
+
`UncategorizedText` where unstructured says `NarrativeText`, or the reverse.
|
|
229
|
+
|
|
230
|
+
## Untrusted documents
|
|
231
|
+
|
|
232
|
+
Documents are parsed defensively: zip-bomb checks on Office files, rejection of XML entity
|
|
233
|
+
declarations, and caps on spreadsheet cells, PDF pages, HTML nesting and chunk payloads, all
|
|
234
|
+
adjustable through environment variables. Only http(s) URLs are fetched. See
|
|
235
|
+
[SECURITY.md](SECURITY.md).
|
|
236
|
+
|
|
237
|
+
## Reproducing the numbers
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
# install size, packages and advisories (needs uv)
|
|
241
|
+
python scripts/measure.py "unstructured[docx,pptx,xlsx,md,csv,pdf]" "tryworks[pdf] @ ."
|
|
242
|
+
|
|
243
|
+
# element-by-element comparison
|
|
244
|
+
python tests/corpus.py compat/out/corpus
|
|
245
|
+
python scripts/compat.py dump tryworks compat/out/corpus compat/out/tryworks.json
|
|
246
|
+
python scripts/compat.py dump unstructured compat/out/corpus compat/out/upstream.json # in an env with unstructured
|
|
247
|
+
python scripts/compat.py compare compat/out/upstream.json compat/out/tryworks.json --markdown compat/REPORT.md
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Development
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
pip install -e ".[dev]"
|
|
254
|
+
python -m pytest
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md). The one hard rule: the base install stays
|
|
258
|
+
dependency-free.
|
|
259
|
+
|
|
260
|
+
## How this was built
|
|
261
|
+
|
|
262
|
+
tryworks was written with [Claude Code](https://claude.com/claude-code) under human direction. It
|
|
263
|
+
is an independent implementation of unstructured's public API; no unstructured source code was
|
|
264
|
+
copied. Confidence in it comes from things you can check yourself: the test suite, which runs on
|
|
265
|
+
Linux, macOS and Windows, and the differential comparison against unstructured above.
|
|
266
|
+
|
|
267
|
+
## License
|
|
268
|
+
|
|
269
|
+
Apache-2.0. See [LICENSE](LICENSE) and [NOTICE](NOTICE). tryworks is not affiliated with or
|
|
270
|
+
endorsed by Unstructured Technologies, Inc.
|