A powerful Python-based tool for reading, interpreting, and converting standard and binary G-code (.bgcode) files.
It can optionally integrate a native C++ binary (bgcode) β shipped as an opt-in, platform-specific
companion package (see Installation) β and uses web scraping (3) to retrieve command
documentation from Marlin firmware resources or a local (1) / package (2) marlin_mapping.json file.
Using this order (1) > (2) > (3) in default use() / CLI mode!
- β Translate raw G-code lines into human-readable explanations
- β
Supports
.gcode,.bgcode, and.gxformats - β
Integrates with native C++ converter (
bgcode) for decoding binary formats - β Able to automatically scrapes G/M-code documentation from Marlin's official site or use a local one
- β Supports embedded thumbnails (base64 or binary)
- β
CLI access via
gcode-translatorcommand
git clone https://github.com/herrdivad/GCode_Translator
cd GCode_Translator/
pip install -e . # base package only (binary-free)pip install -e . installs only the binary-free base package β no bgcode companion.
To also work on .bgcode conversion locally, add the companion in one of two ways:
# a) via the extra β resolves the companion from the git URL in pyproject.toml (needs the
# branch pushed to GitHub); the base package stays editable, the companion does not:
pip install -e ".[linux]"
# b) fully local & editable β install the companion straight from its folder, so edits to
# the companion package take effect without a push (recommended while developing it):
pip install -e ./companion/bgcode-linuxThe base package is binary-free (MIT only) and handles .gcode and .gx files:
pip install git+https://github.com/herrdivad/GCode_TranslatorTo also convert Prusa .bgcode files, install the platform's bgcode companion binary
via an extra. The companion is AGPL-3.0 and is only pulled in when you ask for it:
# Linux (available):
pip install "gcode-translator[linux] @ git+https://github.com/herrdivad/GCode_Translator.git"
# Windows (available) β self-contained /MT build, needs no VC++ Redistributable:
pip install "gcode-translator[windows] @ git+https://github.com/herrdivad/GCode_Translator.git"
# macOS: planned β the [macos] extra is reserved for when its companion binary
# is added under companion/.Each extra is guarded by a platform marker, so requesting the "wrong" one for your OS is
a harmless no-op. Without a companion installed, .bgcode conversion fails with a clear
message telling you which extra to install; .gcode / .gx handling is unaffected.
| Platform | Extra | Status | Install (pinned to the current release) |
|---|---|---|---|
| Linux | [linux] |
β available | pip install "gcode-translator[linux] @ git+https://github.com/herrdivad/GCode_Translator.git@v1.2.0" |
| Windows | [windows] |
β available | pip install "gcode-translator[windows] @ git+https://github.com/herrdivad/GCode_Translator.git@v1.2.0" |
| macOS | [macos] |
π§ planned | not yet available β install the base package only: pip install "git+https://github.com/herrdivad/GCode_Translator.git@v1.2.0" |
| any | (none) | β always | base package, binary-free, .gcode / .gx only |
The [macos] extra already exists in pyproject.toml but points at a companion directory
that has not been added yet, so requesting it on macOS fails at install time. Until the
macOS binary ships, use the base package there; everything except .bgcode decoding works.
Dropping the @v1.2.0 ref installs whatever is currently on master β convenient for
"give me the latest", but not reproducible. For anything you want to be able to rebuild
later, keep the tag. See RELEASING.md for the release workflow and
CHANGELOG.md for what changed between versions.
pip install -e ".[dev]" # installs pytest
pytest # full suite (~10s)
pytest -m "not slow" # skip the large-file integration test (~7s)The suite (tests/) covers command translation, metadata extraction, dict aggregation,
thumbnail/.gx image handling, and the use() library API. Unit tests use inline G-code
snippets; integration tests run real files from exFiles/ end-to-end (PrusaSlicer and
AnycubicSlicer), so the metadata/command behaviour is checked against actual slicer output.
After installation, use the command:
gcode-translator path/to/your/file.gcodeIt processes the G-code file and outputs interpreted descriptions line by line into a file named output.txt (overwrite!).
Required:
platformdirs(MIT license)- locates the per-user cache directory. The G/M-code mapping ships read-only inside the package; a freshly scraped mapping is cached under
platformdirs.user_cache_dir("gcode-translator")(e.g.~/.cache/gcode-translator/on Linux) instead of being written into the installed package.
- locates the per-user cache directory. The G/M-code mapping ships read-only inside the package; a freshly scraped mapping is cached under
Optional β only for re-scraping the Marlin mapping (pip install gcode-translator[scrape]):
selenium- selenium requires Chrome or Chromium installed and accessible in headless mode.
beautifulsoup4
The translator works fully offline using the bundled mapping; the [scrape] extras are only needed when you explicitly fetch a fresh mapping from marlinfw.org. Without them, the scraping path raises a clear error telling you to install the extra.
The bgcode binaries are not part of the MIT base package. They ship as separate,
opt-in, platform-specific companion packages, installed only via the matching extra
(see Installation):
- Linux β
companion/bgcode-linux/, via[linux] - Windows β
companion/bgcode-windows/, via[windows]
Once installed, the binary is used automatically to convert Prusa .bgcode files. It is a
separately compiled build of the Prusa3D libbgcode project,
which is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). The binaries
are therefore not covered by this project's MIT license; when using or redistributing them
you must comply with the AGPL-3.0. Each companion ships the full AGPL-3.0 license text plus its
own Corresponding Source record (commit, build environment, and β for Windows β the build-script
patch), e.g. companion/bgcode-linux/LICENSE.AGPL-3.0.txt.
The Linux build is a clean upstream checkout; the Windows build uses the unmodified libbgcode
source with two documented patches to the dependency build scripts only (static /MT runtime +
a CMake policy floor), recorded in the Windows companion's CORRESPONDING_SOURCE.md.
bgcode is invoked only as a separate subprocess (arm's-length communication via command-line
arguments and files). Under the FSF's GPL FAQ on mere aggregation
this does not create a combined work, so the MIT-licensed Python code keeps its MIT license.
Distributing the AGPL binary, however, carries the AGPL's own obligations (see below).
Corresponding Source (AGPL-3.0 Β§6). The shipped binary corresponds exactly to this public revision (verified by hash):
| Field | Value |
|---|---|
| Binary SHA-256 | 15c6fe4d54defc4d375524452f433ff3f4e7a10e3b23f89c14096cd5484c1f4b |
| Repository | https://github.com/prusa3d/libbgcode |
| Version | libbgcode 0.2.0 |
| Commit | 5041c093b33e2748e76d6b326f2251310823f3df (branch main, 2025-02-20) |
| Local modifications | none (clean upstream checkout) |
Build environment used to produce the shipped binary:
| Field | Value |
|---|---|
| Target | ELF 64-bit x86-64, dynamically linked, GNU/Linux |
| Toolchain | GNU g++ 11.4.0 |
| Build system | CMake 3.22.1 |
| Configure/build | CMake preset default β CMAKE_BUILD_TYPE=Release, deps preset default |
Reproduce from a clean checkout:
git clone https://github.com/prusa3d/libbgcode
cd libbgcode
git checkout 5041c093b33e2748e76d6b326f2251310823f3df
cmake --preset default # configures deps + project (Release)
cmake --build --preset default
# resulting tool: build-default/src/LibBGCode/cmd/bgcodeWritten Offer. The Corresponding Source for the exact version above is publicly available at the commit link. In addition, for at least three (3) years from the date of distribution, the author will provide, on request, a copy of the complete Corresponding Source of this binary. Contact: david.herrmann@kit.edu
The full AGPL-3.0 compliance statement is also recorded in LICENSE.
You can also use it programmatically. use() returns the aggregated result
([g_dict, m_dict, other_dict]) and, when called as a library, is side-effect free
(no files written, no stdout output):
from gcode_translator.GCode_Translator import use
# Library mode: returns data, writes nothing.
g_codes, m_codes, other = use("your_file.gcode")
# Opt in to file output explicitly if you want it:
result = use("your_file.gcode", output_txt_path="output.txt", preview_path="preview.png")
# Get the embedded thumbnail(s) as raw bytes, without writing any file:
dicts, previews = use("your_file.gcode", return_preview=True)
for img in previews: # a file may contain several thumbnails
... # e.g. hand the bytes to a converter / PIL.ImageThe result is [g_dict, m_dict, other_dict]: G-commands, M-commands, and everything else.
Slicer metadata written as ; key = value or ; key: value comments (e.g.
temperature, filament_type, nozzle_diameter) is collected into other_dict, so the
converter can read print settings that have no direct G/M-command equivalent.
A command (or setting) usually appears many times. The aggregation argument of use()
controls how those repeated values are reduced. Given, for example:
M104 S210
M104 S210
M104 S230
G1 X10 Y5
G1 X20 Y2
| Mode | M104 value |
G1 (movement) value |
Notes |
|---|---|---|---|
"compact" (default) |
["S210", "S230"] |
{"X": [10.0, 20.0], "Y": [2.0, 5.0]} |
Unique values; movement commands (G0βG3) become per-axis [min, max] ranges. A single unique value is returned as a scalar ("S210"). |
"count" |
{"S210": 2, "S230": 1} |
{"X10 Y5": 1, "X20 Y2": 1} |
{value: occurrences} for every command, movement included. |
"full" |
["S210", "S210", "S230"] |
["X10 Y5", "X20 Y2"] |
Every occurrence, in order, duplicates kept (the original behaviour). |
result = use("your_file.gcode", aggregation="count") # "compact" | "count" | "full"Why this matters: a high-frequency command can otherwise explode the result β in one real
file SET_VELOCITY_LIMIT occurred 59,825 times with only 2 distinct values, so
"compact"/"count" reduce that single entry from 59,825 items to 2. "compact" is the
default because it is the most readable; "count" keeps frequencies; "full" keeps raw data.
An unknown mode raises ValueError.
The CLI (
gcode-translator <file>) keeps the old behavior and writesoutput.txtandpreview.pnginto the current directory.
- chemotion-converter-app as part of the gcode_reader
.
βββ gcode_translator/ # the installable base package (MIT, binary-free)
β βββ __init__.py
β βββ GCode_Translator.py # CLI entry point, use() API and translation logic
β βββ Binary_GCode_Translator.py # binary decoding (.bgcode via companion binary, .gx preview)
β βββ GCode_Mapping.py # G/M code mapping via web scraping (Marlin)
β βββ helper.py # parser and helper functions
β βββ marlin_mapping.json # bundled mapping for offline use (no Internet needed)
βββ companion/ # opt-in, platform-specific binary packages (installed via extras)
β βββ bgcode-linux/ # AGPL-3.0 Linux bgcode binary + its own pyproject/README/license
β β βββ pyproject.toml # package "gcode-translator-bgcode-linux"
β β βββ README.md # AGPL-3.0 Corresponding Source record
β β βββ LICENSE.AGPL-3.0.txt # full AGPL-3.0 text, shipped with the binary
β β βββ gcode_translator_bgcode_linux/
β β βββ __init__.py # exposes binary_path()
β β βββ bgcode # native C++ executable (AGPL-3.0, unmodified)
β βββ bgcode-windows/ # AGPL-3.0 Windows bgcode.exe (static /MT, no VC++ redist needed)
β βββ pyproject.toml # package "gcode-translator-bgcode-windows"
β βββ README.md # AGPL-3.0 overview + build/patch summary
β βββ LICENSE.AGPL-3.0.txt # full AGPL-3.0 text, shipped with the binary
β βββ gcode_translator_bgcode_windows/
β βββ __init__.py # exposes binary_path()
β βββ bgcode.exe # native build (AGPL-3.0; source unmodified, build scripts patched)
β βββ CORRESPONDING_SOURCE.md # AGPL-3.0 Β§6 record (shipped in the wheel)
β βββ *.patch # dependency build-script patch (part of Corresponding Source)
βββ tests/ # pytest suite (run: pytest)
β βββ conftest.py # shared fixtures / sample-file paths
β βββ test_use.py # end-to-end use() API tests
β βββ test_binary.py # .bgcode / .gx binary handling
β βββ test_mapping.py # mapping / scraper tests
β βββ test_aggregation.py # value-aggregation modes
β βββ test_explain_line.py # single-line explanation
β βββ test_helper.py # helper-function tests
β βββ test_integration.py # full real-file integration tests (slicers)
βββ exFiles/ # real-world sample G-code files used by the tests (empty on GitHub due to rights issues)
βββ LICENSE # project MIT license + bgcode AGPL-3.0 compliance notice
βββ README.md
βββ pyproject.toml # build config, dependencies, package data
Contributions, suggestions, and bug reports are welcome.
Please open an issue or a pull request.
MIT License β see LICENSE.
David Herrmann
david.herrmann@kit.edu