Skip to content

Audit: SDK's two headline entry points are broken (module shadowing + launch TypeError + wrong truffle field keys); no tests #2

Description

@scttfrdmn

Audit of the spore.host Python bindings (python-sdk spore package + truffle/bindings/python). The spore SDK's two documented entry points both fail, and the failures ship green because there are no tests.

P0 — spore.truffle / spore.spawn top-level access is broken (module shadowing)

spore/__init__.py:11 does from . import truffle, spawn, which binds the submodules as real attributes on the package. The lazy-default-client hook __getattr__ (only called when normal lookup fails) therefore never fires for truffle/spawn. So the documented quickstart —

import spore
spore.truffle.find("nvidia h100")   # AttributeError: module 'spore.truffle' has no attribute 'find'

— resolves spore.truffle to the module (no .find), not a TruffleClient. Verified: type(spore.truffle) == module, hasattr(spore.truffle,'find') == False. Every example in examples/ uses this broken path.
Fix: don't import the submodules into the package namespace (drop them from from . import … / __all__), or make the top-level API an explicit default-client accessor rather than relying on __getattr__ shadowed by real modules.

P0 — SpawnClient.launch() raises TypeError on every call

spawn.py:202-211 constructs Instance(..., private_ip=..., availability_zone=...) but the Instance dataclass (spawn.py:15-29) has no private_ip or availability_zone fields → TypeError: __init__() got an unexpected keyword argument 'private_ip'. Verified against the dataclass fields. launch() cannot succeed.
Fix: add the fields to Instance (and map them in _parse), or drop them from the launch() constructor call.

P1 — truffle.find() returns zeroed memory / GPU-memory / AZs (wrong JSON keys)

truffle.py:_parse reads memory_mi_b, gpu_memory_mi_b, available_a_zs, v_cp_us, gp_us — a mangled auto-snake-casing. The REST API (truffleaws.InstanceTypeResult) actually emits memory_mib, gpu_memory_mib, availability_zones, vcpus, gpus. vcpus/gpus survive via fallback, but:

  • memory_gib → always 0.0 (reads memory_mi_b, absent; else memory_gib, also absent — API sends memory_mib)
  • gpu_memory_gib → always 0.0 (no fallback)
  • available_azs → always empty (API sends availability_zones)
    Fix: map to the real keys: memory_mib, gpu_memory_mib, availability_zones, vcpus, gpus (÷1024 for the MiB→GiB fields). (spawn's instances.go keys, by contrast, match spawn._parse correctly — that path is fine.)

P1 — No tests; CI masks all of the above

There is no tests/ dir. CI (test-python-build.yaml) runs pytest tests/ … || echo "No tests yet" (swallows absence) and a smoke check of only import spore; spore.__version__ — which passes because all three bugs are one level deeper than a bare import. A broken SDK ships green.
Fix: add tests that (a) call spore.truffle.find/spore.spawn.launch against a mocked Client.get/post (responses/requests-mock), asserting parsed fields; (b) make CI fail on missing tests. These three bugs are all caught by a single "does the documented quickstart run?" test.

Separate: truffle/bindings/python (native CGO) is non-functional / not committed

setup.py + Makefile build truffle/native.go and test_native.py imports from truffle import Truffle, …, but there is no truffle/ package, no native.go, no __init__.py in the repo — only docs (README/CGO_IMPLEMENTATION/NATIVE_CGO), a Makefile, setup.py, and the test. So the package can't build or import. The README presents it as a finished "10-50× faster" product. Also placeholder metadata (author="Your Name", you@example.com, MIT while the suite is Apache-2.0), package name truffle-aws. Recommend: either commit the missing native.go+wrapper, or clearly mark the dir WIP/remove it so it isn't mistaken for a shippable binding. (Filed here for visibility; may warrant its own issue in spore-host/truffle.)

lagotto — no gap

The hosted REST API exposes no lagotto/capacity-watch endpoints, and the SDK doesn't claim lagotto coverage. So "no lagotto bindings" is a scoping reality (nothing to call), not a defect.

Suggested priority

Fix the two P0s + P1 field-mapping together (they're all in the same two small files and all covered by one quickstart test), add the test + CI gate, then decide the CGO binding's fate separately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions