Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f68924a
refactor(client): issue requests through a generated transport
chandrasekharan-zipstack Aug 11, 2026
c1ab0af
test(client): pin behaviour against the last released client
chandrasekharan-zipstack Aug 11, 2026
04d997d
fix(client): map a connect timeout to ConnectTimeout, not Timeout
chandrasekharan-zipstack Aug 11, 2026
d0130d0
fix(client): raise ReadTimeout, not a bare Timeout, on a read timeout
chandrasekharan-zipstack Aug 12, 2026
e84a935
chore(sdk): generate from the backend's own committed spec
chandrasekharan-zipstack Aug 12, 2026
c291e36
feat(client): accept the deployment's request parameters on structure…
chandrasekharan-zipstack Aug 12, 2026
ed89066
feat(client): accept the status endpoint's query parameters
chandrasekharan-zipstack Aug 12, 2026
d704489
chore(sdk): regenerate from the remediated spec
chandrasekharan-zipstack Aug 12, 2026
68e83c0
chore(tools): fail generation when the generator warns
chandrasekharan-zipstack Aug 12, 2026
20b686b
fix(client): spell query booleans the way the released client did
chandrasekharan-zipstack Aug 12, 2026
981e659
fix(client): post to the deployment URL the caller gave
chandrasekharan-zipstack Aug 12, 2026
29d4ac3
fix(client): translate the transport failures that were escaping
chandrasekharan-zipstack Aug 12, 2026
e210cdf
test: compare the headers that actually go on the wire
chandrasekharan-zipstack Aug 12, 2026
f8f13f3
ci: fail when the committed SDK is not what the spec generates
chandrasekharan-zipstack Aug 12, 2026
49acebd
feat(client): allow a socket timeout to be configured
chandrasekharan-zipstack Aug 12, 2026
a24afd2
test: pin how the status endpoint is read
chandrasekharan-zipstack Aug 12, 2026
f1bdd97
test: pin the parity baseline by digest
chandrasekharan-zipstack Aug 12, 2026
22ed443
build: bound httpx to the series the transport is generated against
chandrasekharan-zipstack Aug 12, 2026
0882b45
fix(client): treat an explicit None as unset on the optional execute …
chandrasekharan-zipstack Aug 12, 2026
4d3c4a9
docs: trim comments that narrate rather than explain
chandrasekharan-zipstack Aug 12, 2026
19a5644
fix: poll status under the deployment URL's own path prefix
chandrasekharan-zipstack Aug 12, 2026
54f09f4
feat!: drop the `unstract` console script
chandrasekharan-zipstack Aug 12, 2026
27dd806
fix: follow redirects, refuse a blank execution id, translate InvalidURL
chandrasekharan-zipstack Aug 12, 2026
114aef8
fix: poll the endpoint the service returned, query and all
chandrasekharan-zipstack Aug 12, 2026
a77ef6a
docs: record the deliberate differences, and pin the parity row exactly
chandrasekharan-zipstack Aug 13, 2026
5ae45fd
fix: give the generator its own venv on PATH
chandrasekharan-zipstack Aug 13, 2026
38b53dc
docs: drop the behaviour-drift list and the draft release notes
chandrasekharan-zipstack Aug 17, 2026
0c9d545
UN-4010 [FIX] keep the deployment key on the configured origin
chandrasekharan-zipstack Aug 17, 2026
d67dda4
UN-4010 [MISC] pin the origin against every spelling of a foreign host
chandrasekharan-zipstack Aug 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src/unstract/api_deployments/sdk_docstudio/** linguist-generated=true
34 changes: 31 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ jobs:
matrix:
python-version: ["3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0

- uses: actions/setup-python@v5
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ matrix.python-version }}

- name: Install uv
uses: astral-sh/setup-uv@v6
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0
with:
version: "0.6.14"
enable-cache: true
Expand All @@ -37,3 +37,31 @@ jobs:

- name: Tests (pytest)
run: uv run pytest tests/ -v

sdk-drift:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0

- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.12"

- name: Install uv
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0
with:
version: "0.6.14"
enable-cache: true

# The generated tree is committed, so an edit to it reviews like any
# other change and then disappears on the next regeneration. Same for a
# spec change that never had the generator run over it.
- name: Regenerate from the committed spec
run: ./tools/gen_sdk.sh

# `git add -N` first: a diff alone cannot see a file the generator has
# newly created, which is exactly what a spec growing an endpoint does.
- name: Fail if the committed SDK is not what the spec generates
run: |
git add -N -- src/unstract/api_deployments/sdk_docstudio
git diff --exit-code -- src/unstract/api_deployments/sdk_docstudio
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,18 @@ client = APIDeploymentsClient(
The retry logic uses exponential backoff with full jitter and respects the `Retry-After` header on 429 responses.


## Unstract CLI
## Cloning an organization

Installing `unstract-client` also provides the `unstract` command:
Installing `unstract-client` also provides a clone command. The `unstract`
console script this package used to install is gone — the name now belongs to
the `unstract-cli` package — so invoke it as a module:

```bash
pip install unstract-client
unstract --help
python -m unstract.clone --help
```

### `unstract clone`
### `python -m unstract.clone`

Clones an organization's resources to another org, on the same or a different
deployment (e.g. promote **dev** → **QA** → **prod**). Covers adapters,
Expand All @@ -124,7 +126,7 @@ so keys never land in shell history:
export UNSTRACT_SRC_PLATFORM_KEY="<source platform key>"
export UNSTRACT_TGT_PLATFORM_KEY="<target platform key>"

unstract clone \
python -m unstract.clone \
--source-url https://dev.example.com --source-org org_dev123 \
--target-url https://qa.example.com --target-org org_qa456 \
--dry-run
Expand Down Expand Up @@ -152,14 +154,14 @@ failed run can be resumed by re-running the same command.

#### Compatibility

`unstract clone` is capability-probed: each phase checks for its endpoint on the
Cloning is capability-probed: each phase checks for its endpoint on the
source and target, and clones only what both orgs support. A capability missing on
either side is reported and skipped — the run never fails because of a version
difference. Cloning a newer source into an older target therefore drops the entity
types the target lacks (listed in the end-of-run report).

- Run the source and target on the same (or a newer-target) Unstract build.
- Use `unstract-client >= 1.4.0`, the first release that ships `unstract clone`.
- Use `unstract-client >= 1.4.0`, the first release that ships the clone command.

## Questions and Feedback

Expand Down
12 changes: 9 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ authors = [
{name = "Zipstack Inc", email = "devsupport@zipstack.com"},
]
dependencies = [
# The transport layer is generated against httpx; attrs backs its models.
# Upper-bounded because the generated code is written against one minor
# series: a bump has to be regenerated and re-tested, not resolved into.
"httpx>=0.27,<0.29",
"attrs>=23.2",
# Kept for its exception classes, which callers catch by name.
"requests>=2.32.3",
"tenacity>=8.2.0",
"click>=8.1",
Expand All @@ -27,9 +33,6 @@ classifiers = [
"Topic :: Software Development :: Libraries :: Python Modules",
]

[project.scripts]
unstract = "unstract.cli:main"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
Expand Down Expand Up @@ -64,6 +67,9 @@ lint = [

[tool.ruff]
line-length = 88
# Generated and vendored code is overwritten wholesale by its refresh script, so
# a lint finding there can never be fixed in place.
extend-exclude = ["src/unstract/api_deployments/sdk_docstudio", "tests/baseline"]

[tool.ruff.lint]
select = ["E", "F", "W", "I"]
Expand Down
Loading
Loading