Install & Compatibility
Where this runs
tested against v1.2.9 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.738s · 47.5MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 5.3s · import 0.680s · 48MB
50MB installed
● package 50MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
Task
✓ from b2luigi import Task
LocalTarget
✓ from b2luigi import LocalTarget
✗ from luigi import LocalTarget
b2luigi provides its own enhanced LocalTarget and other file system targets; prefer these over raw luigi.LocalTarget within b2luigi workflows.
Basf2Task
✓ from b2luigi.basf2 import Basf2Task
Use this for tasks that require integration with the Belle II basf2 framework.
run
✓ from b2luigi import run
This quickstart demonstrates how to define and run a simple workflow using `b2luigi.Task` and `b2luigi.LocalTarget`. It involves two tasks: one to generate a data file and another to process it, showcasing task dependencies and ensuring output directories are created.
import b2luigi
import luigi
import os
class GenerateData(b2luigi.Task):
filename = luigi.Parameter()
def output(self):
return b2luigi.LocalTarget(f'data/{self.filename}.txt')
def run(self):
os.makedirs(os.path.dirname(self.output().path), exist_ok=True)
with self.output().open('w') as f:
f.write(f'Generated data for {self.filename}')
class ProcessData(b2luigi.Task):
filename = luigi.Parameter()
def requires(self):
return GenerateData(filename=self.filename)
def output(self):
return b2luigi.LocalTarget(f'processed_data/{self.filename}_processed.txt')
def run(self):
os.makedirs(os.path.dirname(self.output().path), exist_ok=True)
with self.input().open('r') as infile,
self.output().open('w') as outfile:
content = infile.read()
outfile.write(f'Processed: {content.upper()}')
if __name__ == '__main__':
# Use luigi.build for programmatic execution within a script.
# For command-line execution and parsing, b2luigi.run() is typically used.
luigi.build([
ProcessData(filename='example_file')
], local_scheduler=True)
print("\n--- Task completed ---")
print("Check 'data/example_file.txt' and 'processed_data/example_file_processed.txt'")
# Clean up generated files for repeated execution
# os.remove('data/example_file.txt')
# os.remove('processed_data/example_file_processed.txt')
Errors
Common errors & fixes
ValueError: The task id <task_id> to be executed by this batch worker does not exist in the locally reproduced task graph.
This error occurs when the task graph generated by the initial `b2luigi.process()` call on the submission machine differs from the task graph reproduced within the batch job environment, often due to non-deterministic parameter generation or path differences between local and batch execution.
fixEnsure that your task parameter generation and path definitions are deterministic and consistent across both local and batch execution environments. Avoid using random parameters or environment-dependent paths for task identification.
AttributeError: If the current script location cannot be determined
This typically happens when `b2luigi` attempts to determine the script's location (e.g., for relative path handling) in an interactive shell environment like a Jupyter Notebook, where `sys.argv[0]` might not provide a usable script path.
fixProvide absolute paths for relevant settings (e.g., output directories) in your `b2luigi` configuration when running in interactive environments.
ModuleNotFoundError: No module named 'b2luigi'
This error indicates that the `b2luigi` library is not installed or not accessible in the Python environment where the script is being executed.
fixInstall `b2luigi` using pip: `pip install b2luigi` or `pip3 install b2luigi`. If using a virtual environment, ensure it is activated.
RuntimeError: If the subprocess call returns a non-zero exit code
This generic error in `b2luigi` means that an external command, such as a `basf2` process or another shell script executed by `b2luigi` as a subprocess, terminated with an error (a non-zero exit code).
fixExamine the log files of the failed `b2luigi` task (which `b2luigi` typically redirects stdout/stderr to) to identify the specific error message from the external command and debug that underlying issue.
Tasks fail if part of the outputs (but not all) already exist.
This often points to the 'Thanksgiving bug' in Luigi (and thus `b2luigi`), where a task might be considered complete because an output file exists, even if the file is empty or partially written due to an interrupted process.
fixImplement atomic file writing for task outputs. `b2luigi` provides the `b2luigi.on_temporary_files` decorator or `TemporaryFileContextManager` to write to a temporary file first and then move it to the final destination only upon successful completion.
Upgrade
Version history
1.2.9latest on PyPI · released Apr 17, 2026
Audit
Dependencies
luigirequiredb2luigi is built on top of Luigi and extends its core functionalities.
setuptoolsrequiredRequired for installation and packaging; explicitly added as a dependency since v1.2.6.