DAH-2506 - Add browse-filter parity to the SDK and CLI - #97
Open
fortunelucky777 wants to merge 4 commits into
Open
DAH-2506 - Add browse-filter parity to the SDK and CLI#97fortunelucky777 wants to merge 4 commits into
fortunelucky777 wants to merge 4 commits into
Conversation
arhangel66
approved these changes
Aug 5, 2026
- ExecutorInfo: add min_gpu_count_for_rental and available_gpu_count fields - _dict_to_executor_info: wire both new fields from API dict - _is_splittable_for_count: module-level predicate helper (parity with FE) - Lium.ls(): add widen_for_splitting kwarg (default False per D2a) - decorators.py: clarifying comment — @machine stays strict - cli/ls/actions.py: pass widen_for_splitting=True (CLI opt-in only) - cli/ls/command.py: update --count help string - cli/ls/display.py: append '↯ from N' in _cfg, add field to compact_executor
- test/fixtures/splittable_executors.json: byte-identical twin of frontend fixture - test/test_client_ls_widen.py: 5 tests covering widen truth table, default-off, compact_executor field round-trip, and _cfg '↯ from N' marker
Give `lium ls` the same filter dimensions the browse page has, and route `lium up` through the same call so the two commands stop offering disjoint candidate sets. - SDK: ExecutorInfo gains reliability_score, uptime_in_minutes and the vram_gb / vram_total_gb properties; Lium.ls gains tier, min_reliability (+include_unscored), min_uptime_minutes, min_vram_gb, min_vram_total_gb, min_ports, countries, max_price_total and max_price_per_gpu. - New lium/sdk/filters.py holds the predicates. Max price (both modes), tier and min reliability are held to a fixture mirrored from the web repo, so a predicate that drifts on one side fails on the other. - max_price_total prices the split --count would actually rent, not the whole node, so a $2.50/GPU splittable node survives a $5 budget. - Lium.up gains gpu_count and sends it in the rent payload. Without it the API rents every available GPU, so widening `up` to splittable nodes would have handed over — and billed — all eight GPUs to someone who asked for one. The confirmation prompt now quotes the split, not the node. - CLI: nine new `ls` flags with grouped help, a $/h column next to $/GPU·h, available_gpu_count / reliability_score / uptime_in_minutes in --format json, and a fix for the duplicate "download" sort key that shadowed the effective download speed. - `lium up` now selects via one Lium.ls() call (widened for splitting) instead of comparing gpu_count by hand, and reuses that result instead of re-fetching. - CI runs the whole test suite instead of one file. That surfaced a real pre-existing crash in the provider generic table renderer: it called keys.index() from inside keys.sort(), and list.sort() empties the list while it runs. list.sort() is stable, so the tie-breaker was redundant anyway.
fortunelucky777
force-pushed
the
feat/2506-filter-parity
branch
from
August 5, 2026 13:51
197bc3c to
39fd7fa
Compare
0.0.29 is already published to PyPI, so the filter-parity work in this PR needs its own version to ship. Both files must stay identical — release.yml validates the dispatched version against each of them before building.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Task Link
DAH-2506
Give the
liumSDK and CLI the same node filters the web browse page gained in DAH-2506, and hold the two implementations to a shared fixture so they cannot drift apart.Problem
The web browse page and the CLI answered the same question differently.
lium lscould not filter on tier, reliability, uptime, VRAM, open ports or country at all, and its price filter compared against a different GPU count than the price it printed. A renter who found a node in the browser could not reproduce that result from the CLI.There was also a live billing hazard in the selection path.
lium upwidens its search to splittable nodes, but the rent payload carried nogpu_count, and the backend defaults to the whole node when the field is absent (gpu_count = payload.gpu_count or len(available_gpus), priced asprice_per_gpu * gpu_count). On a splittable 8-GPU node,lium up --count 1would rent and bill all eight.Solution
lium/sdk/filters.pyholds one predicate per dimension, mirroringbrowseFilterPredicates.tsin the frontend one-for-one.test/fixtures/filter_executors.jsonand the frontend'ssrc/contexts/__fixtures__/filter-executors.jsonare the same file, and both test suites assert the same accepted-ID sets for the same inputs. A change on one side that is not mirrored fails the other side's tests.Lium.upnow sendsgpu_count, the CLI threads--countinto it, and the confirmation prompt states the split before the rental is created.Changes
lium/sdk/filters.py(new) —display_gpu_countplus predicates for tier, reliability, price, uptime, VRAM per GPU, total VRAM, ports and country._is_splittable_for_countmoved here fromclient.pyand re-exported there, so existing imports keep working.ExecutorInfogainsreliability_scoreanduptime_in_minutes, plusvram_gb/vram_total_gbproperties mirroring the frontend'sgetNodeVramMb._dict_to_executor_infomaps the two new fields — it drops unknown keys, so this is required, not cosmetic.Lium.lsgains ten keyword arguments applied client-side; the docstring's "defaults to 8" claim is corrected.lium lsgains nine flags with grouped help, a$/hcolumn beside$/GPU·h, andavailable_gpu_count/reliability_score/uptime_in_minutesin--format json. A duplicatedownloadsort key is removed — it shadowed the effective speed with a raw specs value.lium upselects through a single widenedLium.ls()call instead of hand-rolled comparisons, and gains--min-cuda.price_per_houris now derived fromavailable_gpu_countrather than the physicalgpu_count, so the printed$/hagrees with what--max-pricecompares.lium/cli/provider/_render.py— fixed a crash:keys.index(k)was called from insidekeys.sort(), andlist.sort()empties the list while it runs, so it raisedValueError. This broke 5 existing tests. Out of scope for the ticket, but CI now runs the full suite and would have landed red without it..github/workflows/ci.yml— the job runspytest test/instead of a single file. Note for whoever merges: the job is renamed fromvalidate-binary-targetstotest, so branch protection needs updating if the old name is a required check.0.0.28in bothpyproject.tomlandlium/__about__.py.Deployment Steps
Use GitHub Action. Publishing to PyPI is a manual
workflow_dispatchas usual — this PR does not release.Review Request
Other PRs
lium@main, so merging it first would fail lium-docs deploys.Risks
gpu_countfix changes whatlium upactually rents. It is covered by tests asserting the exact rent payload, but it is the part of this PR worth the most review attention.mergewas used rather thanrebaseto bringmainin, deliberately, so the DAH-2254 commits this branch stacks on are not rewritten. The merge conflicts were all additive:mainadded anenable_volume_encryptionparameter exactly where this branch addedgpu_count, and both survive.Test Cases
Test Case 1 — Splitting bills the requested count
Actions
lium up --count 1against a splittable 8-GPU node.Expected Output The rent payload carries
gpu_count: 1and the confirmation prompt states the split. Before this change the backend defaulted to all 8 GPUs and billed accordingly.Test Case 2 — CLI and web agree
Actions Apply the same filter combination on the browse page and via
lium lsflags.Expected Output The same node set. This is asserted in CI on both sides against the shared fixture.
Test Case 3 — Printed price matches the price filter
Actions
lium ls --max-price-total Non a partly-rented node.Expected Output The
$/hcolumn never disagrees with the filter — both use the rentable count.Automated:
pytest test/— 367 passed, including 30 new parity tests. The fixture was confirmed byte-identical to the frontend copy.Checklist
ready-review,require-qa,breaking-changesif applicable)