Skip to content

DAH-2553: pip install lium.io fails on Python 3.13/3.14 and weighs 161 MB - #103

Merged
taiberium merged 8 commits into
mainfrom
DAH-2553-slim-install
Aug 6, 2026
Merged

DAH-2553: pip install lium.io fails on Python 3.13/3.14 and weighs 161 MB#103
taiberium merged 8 commits into
mainfrom
DAH-2553-slim-install

Conversation

@taiberium

@taiberium taiberium commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

llms-full.txt line 49 tells a caller to run pip install lium.io. On Python 3.13 and 3.14 that command fails, and it always pulls the whole chain stack.

Measured, before and after

before after
packages 84 43
site-packages 161 MB 54 MB
Python 3.13 / 3.14 install fails works

The 3.14 failure, from the released 0.0.28:

× Failed to build `bittensor-drand==2.0.0`
╰─▶ Call to `maturin.build_wheel` failed
    error: failed to get `tle` as a dependency

Nothing in that traceback mentions lium.

This is the SDK audience only. The CLI installs as a standalone binary via curl -fsSL https://lium.io/install.sh | bash and never touches pip.

What changed

Eight dependencies nothing imports are gone. Grepped the whole package: bittensor-cli, plotly, plotille, fuzzywuzzy, python-Levenshtein, netaddr, async-substrate-interface, GitPython and Jinja2 had zero imports.

bittensor moves to a provider extra. It is imported lazily inside functions, in four files, all of them provider commands or lium fund. Renting never touches it, and it is what breaks the install on new Python. The two "not installed" messages now point at pip install "lium.io[provider]", and provider status says when subnet registration reads as unknown because the extra is absent instead of leaving it unexplained.

The binary still bundles it. One binary serves renters and providers, so the build syncs --extra provider. Verified locally: the bundle contains bittensor.

The bare single-file release asset is gone. Kept for the self-update shipped before the onedir switch in 0.0.25. GitHub download counts: 8 in 0.0.25 against 53 for the tarballs, then zero across 0.0.26, 0.0.27 and 0.0.28. install.sh and the current self-update both fetch the tarball, and older builds already get the reinstall prompt added in DAH-2262.

Verification

test/test_renter_install_is_slim.py pins all three properties and fails on main. One existing test asserted the legacy asset was published and was updated, since that behaviour changed on purpose.

Clean venvs on 3.12, 3.13 and 3.14 install and import. On the slim install lium ls returns the live board, ps works, provider node list returns real data, and lium fund exits 2 with the extra hint instead of a traceback. Binary built locally from the changed spec: starts in 0.33 s, --version, ls and provider --help all work.

Full suite: 349 pass, 11 fail — the same 11 fail on untouched main.

Not in this PR

Publishing the lium alias from stubs/. Our own llms.txt and llms-full.txt give the correct install commands, so nobody following the docs guesses the wrong name.

🤖 Generated with Claude Code

@taiberium taiberium changed the title DAH-2553: make the install work on modern Python and stop shipping dead weight DAH-2553: pip install lium.io fails on Python 3.13/3.14 and weighs 161 MB Aug 5, 2026
@taiberium
taiberium requested a review from arhangel66 August 5, 2026 11:18
@taiberium
taiberium marked this pull request as ready for review August 5, 2026 11:18

@arhangel66 arhangel66 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request changes — one real bug.
lium fund --alpha on a slim install tells the user to run pip install "lium.io" — the package they already have. Reproduced on the current head in a clean Python 3.13 venv.
_alpha_fund raises LiumError here, while handle_errors escapes Rich markup only for CliFailure. As a result, Rich consumes [provider] and turns the intended pip install "lium.io[provider]" hint into pip install "lium.io".
Please raise CliFailure("provider_extra_missing", ..., EXIT_CONFIGURATION_ERROR) here, matching _legacy_tao_fund. Escaping the LiumError rendering would fix the displayed text too, but would retain the generic JSON error code and exit status.
The branch also needs rebasing onto current main: lium/cli/utils.py conflicts, and the resolution must preserve the new data parameter on CliFailure and pass e.data into _emit_json_error. Please regenerate uv.lock afterward; pyproject.toml will be 0.0.29, while the current lock records lium-io==0.0.28.
The rest of the code review checks out: bittensor is lazily imported in four files, the removed packages have no imports, and existing pip installations retain bittensor after upgrading.

@taiberium

Copy link
Copy Markdown
Collaborator Author

Good catch, reproduced it on a clean 3.13 venv.

I had escaped only the CliFailure branch, and _alpha_fund raises LiumError, which handle_errors renders on a different one. Every branch escapes now, so no message type can lose its brackets. Both fund paths are pinned by a parametrised test that fails on the previous commit.

Error: TAO funding needs the chain stack. Reason: the chain stack is not installed: pip install "lium.io[provider]"

taiberium added a commit that referenced this pull request Aug 6, 2026
lium fund --alpha raises LiumError, which handle_errors renders on a different
branch, so Rich still ate the brackets and the hint read 'pip install "lium.io"'
— the package the caller already has. Every branch escapes now, and both fund
paths are pinned by a test.

Caught by arhangel66 in review of #103.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
taiberium and others added 8 commits August 6, 2026 09:32
…ad weight

Renting a GPU pulled the whole chain stack: 84 packages and 161 MB, and on Python
3.13/3.14 the install failed outright inside bittensor-drand's Rust build, with a
traceback that never mentioned lium. Eight of those dependencies were imported by
nothing at all, and bittensor itself is imported lazily by provider commands and
lium fund only.

Renter install is now 43 packages and 54 MB and works on 3.10 through 3.14.
bittensor moves to a provider extra; the binary still bundles it, since one binary
serves both audiences. The bare single-file release asset is gone: it existed for
pre-onedir self-update, and GitHub counts show zero downloads across the last
three releases.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Removing bittensor_cli and async_substrate_interface from collect_submodules
changed nothing: both arrive transitively through bittensor, and the binary stayed
at 101 MB. Reverted so the diff does not imply a win it does not deliver. The spec
change that does matter, dropping the legacy onefile build, stays.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…s absent

_read_metagraph swallowed the ImportError and returned (None, []), which the
caller renders as 'Registered on subnet: unknown' with nothing explaining why.
That branch was unreachable while bittensor was a base dependency and becomes
reachable now, so it names the missing extra instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Four failure sites printed an error and returned, so the process exited 0: wallet
load, wallet registration, amount validation and the transfer itself. Same shape
DAH-2556 fixed across exec, rm and up; this path was missed because bittensor was
always installed, so nothing reached it in testing. The two remaining bare returns
are a user answering no to a confirmation, which is not a failure.

Verified live: lium fund with an unusable wallet now exits 2 instead of 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…s optional

Two tests for the metagraph ImportError path: it names the missing extra instead of
returning empty, and provider status surfaces that as a warning. The path cannot be
driven by hand without a live portal session, so it is pinned in tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two different situations were getting one message. Absent because nobody installed
it: add the extra. Absent because it cannot build on this interpreter: adding the
extra changes nothing, so the message has to say to use Python 3.13 or the binary,
which ships it prebuilt.

The extra is now gated on python_version < 3.14, so the install stops dying inside
a Rust build whose traceback never mentions lium; the CLI explains the gap in its
own words at the first provider command instead, with a non-zero exit code an agent
can act on.

Rich was reading lium.io[provider] as a style tag and swallowing it; CliFailure
messages are escaped once where they are rendered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lium fund --alpha raises LiumError, which handle_errors renders on a different
branch, so Rich still ate the brackets and the hint read 'pip install "lium.io"'
— the package the caller already has. Every branch escapes now, and both fund
paths are pinned by a test.

Caught by arhangel66 in review of #103.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Escaping the LiumError rendering fixed the displayed text but left the generic
error code and exit status, so a machine caller still could not tell what to
install. Both fund paths now report provider_extra_missing with the configuration
exit code. Rebased onto 0.0.29, keeping CliFailure's new data parameter and passing
it into _emit_json_error; uv.lock regenerated.

Review feedback from arhangel66 on #103.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@taiberium
taiberium force-pushed the DAH-2553-slim-install branch from 608da24 to f9c63c3 Compare August 6, 2026 05:34
@taiberium

Copy link
Copy Markdown
Collaborator Author

All three points done.

Error code, not just the text. _alpha_fund raises CliFailure("provider_extra_missing", ..., EXIT_CONFIGURATION_ERROR) now, matching _legacy_tao_fund. Both paths report the same code and exit 2:

{"error": {"code": "provider_extra_missing", "message": "... pip install \"lium.io[provider]\""}, "ok": false}

I kept the escaping as well, since the other three branches in handle_errors render our own messages too and would lose brackets the same way.

Rebased onto 0.0.29. The utils.py conflict is resolved keeping data on CliFailure and passing e.data into _emit_json_error.

uv.lock regenerated — it records 0.0.29 now, and uv sync --frozen --extra dev --extra provider succeeds.

Verified live on a clean 3.12 venv: both paths, text and --json, exit 2. Suite: 380 pass, the 11 failures also fail on untouched main.

@taiberium
taiberium merged commit bd5ba0d into main Aug 6, 2026
9 checks passed
@taiberium
taiberium deleted the DAH-2553-slim-install branch August 6, 2026 06:54
@taiberium taiberium mentioned this pull request Aug 6, 2026
arhangel66 added a commit that referenced this pull request Aug 6, 2026
arhangel66 added a commit that referenced this pull request Aug 7, 2026
* DAH-2593: stop the CLI Action layer from swallowing errors

* DAH-2593: name the rented pod when a post-rent step fails

* DAH-2593: render a failure once, and keep a hint under its error

* DAH-2593: address review on exit codes, idempotent unset and ssh error matching

* DAH-2593: reconcile with #103 — escape permission errors, wallet load is a config error
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants