feat: bambox.info.extract_print_info() public API for reading .gcode.3mf metadata - #267
Merged
Conversation
Provides a reusable way to read filament, time, weight, layer count, bed type, and printer model from an existing .gcode.3mf archive. Motivation: downstream tools (cloud upload, MCP servers, CLI status displays) were each re-implementing zip + XML + g-code header parsing. Centralizing in bambox keeps that knowledge with the archive format spec, where it belongs. Returns: - PrintInfo dataclass with sensible defaults for missing fields - Filament dataclass per slice_info <filament> element (id 1-indexed, color normalized to bare uppercase hex) - to_dict() for JSON output - extract_print_info_buffer() variant for in-memory archives Robust against malformed XML, malformed JSON, missing files, and non-numeric metadata values — only raises on BadZipFile.
…te selection Address review feedback on the bambox.info module: - Add tray_info_idx (Bambu AMS filament identifier, e.g. "GFL99") to Filament so cloud-upload consumers don't have to re-parse slice_info for it. - Re-export extract_print_info, extract_print_info_buffer, PrintInfo, and Filament from bambox/__init__.py so callers can use the documented bambox.extract_print_info(...) path and IDEs surface them at the package root. Adds a regression test. - _extract_layer_count now prefers Metadata/plate_1.gcode explicitly before falling back to the first matching plate_*.gcode — future multi-plate archives won't depend on zip name-list ordering. - Drop the unreachable KeyError catch in _extract_layer_count (the name was just produced by namelist()). - Soften the Filament.color docstring: the function strips '#' and uppercases, it does not enforce 6-char hex.
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
bambox.infomodule withextract_print_info(path) -> PrintInfoandextract_print_info_buffer(buf)for reading filament, time, weight, layer count, bed type, and printer model from an existing.gcode.3mf.PrintInfoandFilamentare JSON-serializable dataclasses (to_dict()provided).Motivation
Downstream tools (cloud upload, future MCP servers, CLI status displays) were each re-implementing zip + XML + g-code header parsing for the same fields. Centralizing in bambox keeps archive-format knowledge co-located with the rest of the archive spec.
Color values are normalized to bare uppercase hex (no leading
#) for consistency.idis preserved 1-indexed to match the<filament>attribute inslice_info.config.Out of scope
bambox info); callers use the Python API. Can be added later if needed.validate._extract_3mf_metadatato delegate here — kept self-contained for this PR to minimize blast radius.Test plan
uv run ruff check src tests— cleanuv run ruff format --check src tests— cleanuv run mypy src/bambox— clean (13 source files)uv run pytest --ignore=tests/test_e2e_cura_vs_bbl.py— 391 passed (the ignored e2e suite has pre-existing environment failures unrelated to this PR; reproduces identically on main)test_info.py— 13/13 passing, including againsttests/fixtures/e2e_cura_p1s/reference.gcode.3mf🤖 Generated with Claude Code