From 99544eb2b31bddb8a7bbf0e590cb1e3bb16af6ec Mon Sep 17 00:00:00 2001 From: Chandrasekharan M Date: Thu, 17 Sep 2026 14:05:49 +0530 Subject: [PATCH 1/6] chore: license the package under MIT The LICENSE file and the metadata PyPI reads, matching the Python clients. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_014f9oEEYspPH4fmPULTnLkJ --- LICENSE | 21 +++++++++++++++++++++ pyproject.toml | 11 +++++++++++ 2 files changed, 32 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c5adfe1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Zipstack + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/pyproject.toml b/pyproject.toml index 903875e..ff9617b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,6 +5,17 @@ dynamic = ["version"] description = "Unified, LLM-friendly CLI for the Unstract suite of products" readme = "README.md" requires-python = ">=3.12" +license = {text = "MIT"} +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Operating System :: POSIX :: Linux", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Programming Language :: Python", + "Topic :: Software Development :: Libraries :: Python Modules", +] dependencies = [ # Pinned to a major: `--discover` describes the CLI by reading Click's own From f99fa383c5b4df1a313b8def52bfb94a130b9a2d Mon Sep 17 00:00:00 2001 From: Chandrasekharan M Date: Thu, 17 Sep 2026 14:06:31 +0530 Subject: [PATCH 2/6] docs: badges under the title and a place to ask questions The three PyPI badges and the closing section the Python clients carry. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_014f9oEEYspPH4fmPULTnLkJ --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index a60782d..9bc7d5a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,8 @@ # unstract-cli +[![PyPI - Downloads](https://img.shields.io/pypi/dm/unstract-cli)](https://pypi.org/project/unstract-cli/) +[![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2FZipstack%2Funstract-cli%2Fmain%2Fpyproject.toml) +](https://pypi.org/project/unstract-cli/) +[![PyPI - Version](https://img.shields.io/pypi/v/unstract-cli)](https://pypi.org/project/unstract-cli/) `unstract` runs [LLMWhisperer](https://docs.unstract.com/llmwhisperer/) text extraction and [Unstract](https://docs.unstract.com/unstract/) API deployments @@ -152,3 +156,9 @@ uv sync --extra dev uv run pytest uv run ruff check . ``` + +## Questions and Feedback + +On Slack, [join great conversations](https://join-slack.unstract.com/) around LLMs, their ecosystem and leveraging them to automate the previously unautomatable! + +[Unstract Cloud](https://unstract.com/): Signup and Try! From f7bfc8fdd0a14009425de3d85d9743f3eac7accd Mon Sep 17 00:00:00 2001 From: Chandrasekharan M Date: Thu, 17 Sep 2026 14:06:42 +0530 Subject: [PATCH 3/6] docs: put the first command on the first screen Usage follows set-up; configuration detail comes after it. The clone note goes -- six required flags do not fit a one-line example, and `--help` has them. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_014f9oEEYspPH4fmPULTnLkJ --- README.md | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 9bc7d5a..76c8429 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,26 @@ unstract auth whoami # which organisation the platform key belongs t unstract config doctor --probe # where each setting resolved from, keys checked ``` +## Usage + +```bash +# Extract text from a document (path or URL); waits for the result +unstract whisper extract invoice.pdf -o raw > invoice.txt + +# What deployments can I run? +unstract docstudio deployment ls + +# Run one and wait for the structured result +unstract docstudio deployment run invoice-parser invoice.pdf + +# Long job: submit, then check later +unstract docstudio deployment run invoice-parser invoice.pdf --no-wait +unstract docstudio deployment status invoice-parser +``` + +`--help` on any command lists its options; `unstract --discover full` prints +the whole command tree, every flag and the exit-code table as JSON. + ## Configuration `~/.unstract/config.toml`, or `$UNSTRACT_CONFIG`, or `--config`, or a @@ -95,29 +115,6 @@ export LLMWHISPERER_BASE_URL=... # self-hosted only `--llmwhisperer-key`; `-` reads it from stdin) and the host as `--base-url`, so it runs without a terminal too. -## Usage - -```bash -# Extract text from a document (path or URL); waits for the result -unstract whisper extract invoice.pdf -o raw > invoice.txt - -# What deployments can I run? -unstract docstudio deployment ls - -# Run one and wait for the structured result -unstract docstudio deployment run invoice-parser invoice.pdf - -# Long job: submit, then check later -unstract docstudio deployment run invoice-parser invoice.pdf --no-wait -unstract docstudio deployment status invoice-parser -``` - -`--help` on any command lists its options; `unstract --discover full` prints -the whole command tree, every flag and the exit-code table as JSON. - -> **Note:** `clone` moves one organisation's resources into another using two -> admin platform keys, `UNSTRACT_SRC_PLATFORM_KEY` and `UNSTRACT_TGT_PLATFORM_KEY`. - ## Output for scripts and agents **Parsing anything? Pass `-o json`.** stdout then carries exactly one envelope, From 1ae49d621962cf1c5c39684cfdcf011cb1a12271 Mon Sep 17 00:00:00 2001 From: Chandrasekharan M Date: Thu, 17 Sep 2026 14:07:02 +0530 Subject: [PATCH 4/6] docs: one line per exit code The longer explanations belong on the docs page. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_014f9oEEYspPH4fmPULTnLkJ --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 76c8429..b7d14af 100644 --- a/README.md +++ b/README.md @@ -138,12 +138,12 @@ Failures exit non-zero with a stable code: | 2 | usage error | | 3 | authentication failed | | 4 | not found | -| 5 | validation failed — also a completed run in which a document failed; the full result, successful documents included, is in `error.details` | +| 5 | validation failed, including a run in which a document failed | | 6 | rate limited | -| 7 | timed out (the job handle is in the error payload — resume, do not resubmit) | +| 7 | timed out; the job handle is in the error payload | | 8 | server error | -| 9 | result already consumed (one-shot read; use `--save` next time) | -| 10 | the result was read but could not be saved — it is in `error.details` | +| 9 | result already consumed | +| 10 | result read but not saved; it is in `error.details` | | 130 | interrupted (128 + SIGINT) — the user stopped it, not a failure | ## Development From 252f0d419b8c8e10c78934818287869cbd70c0be Mon Sep 17 00:00:00 2001 From: Chandrasekharan M Date: Thu, 17 Sep 2026 14:08:09 +0530 Subject: [PATCH 5/6] chore: classify the package as a console tool Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_014f9oEEYspPH4fmPULTnLkJ --- pyproject.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ff9617b..1bfbbd0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,13 +8,15 @@ requires-python = ">=3.12" license = {text = "MIT"} classifiers = [ "Development Status :: 4 - Beta", + "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: POSIX :: Linux", "Operating System :: MacOS :: MacOS X", "Operating System :: Microsoft :: Windows", "Programming Language :: Python", - "Topic :: Software Development :: Libraries :: Python Modules", + "Programming Language :: Python :: 3.12", + "Topic :: Utilities", ] dependencies = [ From a3a0d4ec493c83fe8a799328ee6f903f9a11b709 Mon Sep 17 00:00:00 2001 From: Chandrasekharan M Date: Thu, 17 Sep 2026 14:12:36 +0530 Subject: [PATCH 6/6] docs: keep the recovery step on the timeout and consumed rows Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_014f9oEEYspPH4fmPULTnLkJ --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b7d14af..a3381a8 100644 --- a/README.md +++ b/README.md @@ -140,9 +140,9 @@ Failures exit non-zero with a stable code: | 4 | not found | | 5 | validation failed, including a run in which a document failed | | 6 | rate limited | -| 7 | timed out; the job handle is in the error payload | +| 7 | timed out; resume with the job handle in the error payload, do not resubmit | | 8 | server error | -| 9 | result already consumed | +| 9 | result already consumed (one-shot read); pass `--save` next time | | 10 | result read but not saved; it is in `error.details` | | 130 | interrupted (128 + SIGINT) — the user stopped it, not a failure |