tryworks
Turn PDFs, Word, PowerPoint, Excel, HTML, Markdown, email and text into LLM-ready elements, with zero required dependencies.
tryworks implements the document-partitioning call path of
unstructured: the same partition() function,
the same element types and metadata, the same chunking, the same JSON. It leaves out what most
pipelines never call, namely OCR, layout models and ingest connectors, and the 2 GB of
dependencies they bring.
from tryworks.partition.auto import partition
from tryworks.chunking.title import chunk_by_title
elements = partition("quarterly-report.docx")
chunks = chunk_by_title(elements, max_characters=1000)
for chunk in chunks:
print(chunk.metadata.page_number, chunk.text[:80])
The name: tryworks were the brick furnaces on whaling ships that rendered raw blubber into oil.
Why
Measured on Linux x86-64 with Python 3.12, reading the same document types:
unstructured[docx,pptx,xlsx,md,csv,pdf] |
tryworks[pdf] |
|
|---|---|---|
| Packages installed | 149 | 2 |
| Download size | 3,257 MB | 3.6 MB |
| Installed size (unstructured with CPU-only torch) | 2.0 GB | 9 MB |
Importing partition plus the PDF and DOCX partitioners |
4.4–6.2 s | 0.15–0.39 s |
| Partitioning the 9-document test corpus, first call included | 7.2 s | 0.59 s |
| Security advisories ever published for the installed packages | 701 | 0 |
| Lines of library code | 34,171 | 5,449 |
Base tryworks without the PDF extra is a single 80 KB wheel with no dependencies.
In practice that means:
- It fits in AWS Lambda. The zip deployment limit is 250 MB unpacked, and it cannot be raised.
- Cold starts are fast, and since August 2025 AWS bills the Lambda init phase.
- Security review is short. Two packages to approve, pin and scan, where unstructured needs 149. Air-gapped and regulated environments review each dependency individually.
- The supply-chain surface is small. Most advisories in a large tree come from its transitive dependencies, not from the library you asked for.
Numbers come from scripts/measure.py (exact resolution with uv pip compile, advisory counts
from OSV.dev) and from real installs; see Reproducing the numbers.
Neither tree had an open advisory against the versions resolved when this was measured; the
701 are historical, which is what a scanner and a triage process work through over time.
Install
pip install "tryworks @ git+https://github.com/ezzcodeezzlife/tryworks"
pip install "tryworks[pdf] @ git+https://github.com/ezzcodeezzlife/tryworks" # PDF support
Python 3.10 or newer. PDF support adds pypdfium2, bindings to PDFium, the PDF engine used in Chrome. Everything else uses the standard library.
Use
Partition
from tryworks.partition.auto import partition
elements = partition("report.pdf") # type from extension or content
elements = partition(file=open("memo.docx", "rb")) # file objects work too
elements = partition(url="https://example.com/post") # http(s) URLs
for el in elements:
print(el.category, el.metadata.page_number, el.text)
# Title 1 Quarterly Operations Memo
# NarrativeText 1 Revenue grew eleven percent year over year, ...
# ListItem 1 Expand the Rotterdam warehouse
# Table 1 Warehouse totals Units Rotterdam KR-1001 1200 ...
Each format also has its own function with unstructured's signature: partition_pdf,
partition_docx, partition_pptx, partition_xlsx, partition_html, partition_md,
partition_text, partition_csv, partition_tsv, partition_email, partition_json.
Chunk
from tryworks.chunking.title import chunk_by_title
from tryworks.chunking.basic import chunk_elements
chunks = chunk_by_title(elements, max_characters=1000, overlap=100)
chunks = partition("report.pdf", chunking_strategy="by_title", max_characters=1000)
Sections start at each Title, small sections are combined, long text is split at newlines or
spaces, and tables get chunks of their own. Tables too large for one chunk are split by row
into TableChunk elements that keep valid HTML in metadata.text_as_html.
Serialize
from tryworks.staging.base import elements_to_json, elements_from_json, elements_to_md
json_text = elements_to_json(elements) # same JSON as unstructured, readable by it
elements = elements_from_json(text=json_text)
markdown = elements_to_md(elements)
Command line
tryworks report.pdf # JSON
tryworks memo.docx --format markdown
tryworks https://example.com/post --format text --chunking-strategy by_title --max-characters 800
Moving from unstructured
Change the package name in your imports:
- from unstructured.partition.auto import partition
- from unstructured.chunking.title import chunk_by_title
+ from tryworks.partition.auto import partition
+ from tryworks.chunking.title import chunk_by_title
For code you can't edit, such as a third-party library that imports unstructured itself, register
tryworks under the unstructured import names before that code is imported:
import tryworks
tryworks.alias_as_unstructured()
This only affects imports in the current process. It installs nothing named unstructured.
Formats
| Format | Extensions | Implementation | What you get |
|---|---|---|---|
.pdf |
PDFium via pypdfium2 |
Text blocks in reading order (multi-column aware), titles, lists, headers and footers, coordinates, page numbers | |
| Word | .docx |
zipfile + ElementTree |
Style-based titles and lists, tables with merged cells, section headers and footers, links, bold/italic, page breaks |
| PowerPoint | .pptx |
zipfile + ElementTree |
One page per slide, titles, bullets with levels, tables, speaker notes |
| Excel | .xlsx |
zipfile + ElementTree |
Each sheet split into sub-tables, captions as text, dates and numbers formatted |
| HTML | .html, .htm |
html.parser |
Headings, paragraphs, nested lists, tables, code, images, links, emphasis; navigation and forms dropped |
| Markdown | .md |
Built-in renderer | Same elements as HTML |
| Text | .txt |
Standard library | Paragraphs classified as titles, prose, list items, emails, addresses |
| CSV, TSV | .csv, .tsv |
csv |
One table, delimiter detected |
.eml |
email |
Body with sender, recipients, subject and date; attachments partitioned | |
| Elements | .json |
json |
Elements saved by elements_to_json, from either library |
Compatibility with unstructured
A generated corpus with one realistic document per format is partitioned by both libraries and compared element by element (report, script). A workflow repeats the comparison weekly against the latest unstructured release.
Against unstructured 0.27.5:
- 97% of upstream elements have a tryworks element with identical text,
- 97% of those have the same element type,
- 94% have the same element id (ids hash filename, text, page and position, so this also checks ordering),
parent_id,filetype,page_number,page_name,link_urls,emphasized_text_contents,header_footer_type,sent_fromandsubjectagree on every aligned element.
Every remaining difference in the report is one of the deliberate differences listed below.
Deliberate differences
| Where | unstructured | tryworks | Why |
|---|---|---|---|
| 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 |
| PDF bullets | Consecutive bullet lines can merge into one ListItem |
One ListItem per bullet |
Each bullet is its own item |
| PDF columns | Text of a right-hand column can come after the page footer | Left column, right column, then footer | Reading order |
| PDF coordinates | pdfminer glyph boxes | PDFium glyph boxes | Within about 1 pt |
| DOCX merged cells | 0.27.5 repeats the text in every merged cell | colspan / rowspan |
Matches unstructured's main branch |
| Language | langdetect |
Script detection plus stopword profiles for 18 languages | No model dependency; results can differ on tables and fragments |
Not included
- OCR and layout models.
strategy="hi_res"and"ocr_only"raiseNotImplementedError, and scanned PDFs without embedded text produce a warning and no elements. Use unstructured or an OCR service for those. - Formats: images, audio,
.doc,.ppt,.xls,.msg,.rtf,.odt,.epub,.rst,.org,.xml. Unsupported files raiseUnsupportedFileFormatError, with a conversion hint. - PDF table structure and image extraction. PDF tables come out as text blocks.
- Pictures in DOCX and PPTX are not emitted as
Imageelements. - Token-based chunking (
max_tokens) raisesNotImplementedError; usemax_characters. - Ingest connectors, the hosted API client, and staging bricks for labeling tools.
Text classification uses the same rules as unstructured, but detects verbs with a compact
lexicon instead of NLTK. On borderline text such as short fragments, a paragraph can come out as
UncategorizedText where unstructured says NarrativeText, or the reverse.
Untrusted documents
Documents are parsed defensively: zip-bomb checks on Office files, rejection of XML entity declarations, and caps on spreadsheet cells, PDF pages, HTML nesting and chunk payloads, all adjustable through environment variables. Only http(s) URLs are fetched. See SECURITY.md.
Reproducing the numbers
# install size, packages and advisories (needs uv)
python scripts/measure.py "unstructured[docx,pptx,xlsx,md,csv,pdf]" "tryworks[pdf] @ ."
# element-by-element comparison
python tests/corpus.py compat/out/corpus
python scripts/compat.py dump tryworks compat/out/corpus compat/out/tryworks.json
python scripts/compat.py dump unstructured compat/out/corpus compat/out/upstream.json # in an env with unstructured
python scripts/compat.py compare compat/out/upstream.json compat/out/tryworks.json --markdown compat/REPORT.md
Development
pip install -e ".[dev]"
python -m pytest
See CONTRIBUTING.md. The one hard rule: the base install stays dependency-free.
License
Apache-2.0. See LICENSE and NOTICE. tryworks is not affiliated with or endorsed by Unstructured Technologies, Inc.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tryworks-0.1.2.tar.gz.
File metadata
- Download URL: tryworks-0.1.2.tar.gz
- Upload date:
- Size: 90.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
251d51098b7fe587c422e40ff4405047d569b5bf3d02908a5bcca6fedb12090d
|
|
| MD5 |
a5af2c8176fc4891ba875604a1b19a5f
|
|
| BLAKE2b-256 |
baedb3b63795ea7d9ef1842e8fd2e0c257e958631fe87240c7e59ec13fa33640
|
Provenance
The following attestation bundles were made for tryworks-0.1.2.tar.gz:
Publisher:
release.yml on ezzcodeezzlife/tryworks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tryworks-0.1.2.tar.gz -
Subject digest:
251d51098b7fe587c422e40ff4405047d569b5bf3d02908a5bcca6fedb12090d - Sigstore transparency entry: 2817082674
- Sigstore integration time:
-
Permalink:
ezzcodeezzlife/tryworks@c81288b83bcba12d1e79061bb05b70d5c0af5fa6 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/ezzcodeezzlife
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c81288b83bcba12d1e79061bb05b70d5c0af5fa6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file tryworks-0.1.2-py3-none-any.whl.
File metadata
- Download URL: tryworks-0.1.2-py3-none-any.whl
- Upload date:
- Size: 84.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5cfaa8f942f3a46eff40aef50007ba010f7f53ba564088f1fac5800c8a767636
|
|
| MD5 |
6b164281217c40669bafbda97545785d
|
|
| BLAKE2b-256 |
894b8fb2792c095d999c4925cb914f254c059b09b391a064372af099df658458
|
Provenance
The following attestation bundles were made for tryworks-0.1.2-py3-none-any.whl:
Publisher:
release.yml on ezzcodeezzlife/tryworks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tryworks-0.1.2-py3-none-any.whl -
Subject digest:
5cfaa8f942f3a46eff40aef50007ba010f7f53ba564088f1fac5800c8a767636 - Sigstore transparency entry: 2817082764
- Sigstore integration time:
-
Permalink:
ezzcodeezzlife/tryworks@c81288b83bcba12d1e79061bb05b70d5c0af5fa6 -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/ezzcodeezzlife
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c81288b83bcba12d1e79061bb05b70d5c0af5fa6 -
Trigger Event:
push
-
Statement type: