Skip to content

feat: bambox.info.extract_print_info() public API for reading .gcode.3mf metadata - #267

Merged
pzfreo merged 3 commits into
mainfrom
feat/print-info-api
May 28, 2026
Merged

feat: bambox.info.extract_print_info() public API for reading .gcode.3mf metadata#267
pzfreo merged 3 commits into
mainfrom
feat/print-info-api

Conversation

@pzfreo

@pzfreo pzfreo commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • New bambox.info module with extract_print_info(path) -> PrintInfo and extract_print_info_buffer(buf) for reading filament, time, weight, layer count, bed type, and printer model from an existing .gcode.3mf.
  • PrintInfo and Filament are JSON-serializable dataclasses (to_dict() provided).
  • 13 unit tests covering minimal/multi-filament fixtures, bed-type extraction, the real reference archive, and robustness (bad zip, malformed XML/JSON, non-numeric metadata).

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. id is preserved 1-indexed to match the <filament> attribute in slice_info.config.

Out of scope

  • No new CLI command (bambox info); callers use the Python API. Can be added later if needed.
  • No refactor of validate._extract_3mf_metadata to delegate here — kept self-contained for this PR to minimize blast radius.

Test plan

  • uv run ruff check src tests — clean
  • uv run ruff format --check src tests — clean
  • uv 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)
  • New test_info.py — 13/13 passing, including against tests/fixtures/e2e_cura_p1s/reference.gcode.3mf

🤖 Generated with Claude Code

pzfreo added 2 commits May 28, 2026 07:56
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.
@pzfreo
pzfreo merged commit a2609f1 into main May 28, 2026
12 checks passed
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.

1 participant