Redun .md .md

Here, we’ll see how to track redun workflows with lamindb.

Amend the workflow

Here is how to instrument a redun workflow for tracking with lamindb:

  1. Add ln.track() to the main() task (see on GitHub)

  2. Register desired output files or folders by creating artifacts for them (see on GitHub):

    ln.Artifact(output_path, key="data/results.tar.gz").save()
    
  3. Add a finish() task that calls ln.finish() (see on GitHub)

  4. Optionally cache/stage input files (see on GitHub)

Why not use @ln.flow() for main()?

Because main() in redun is typically a scheduler/executor task rather than a task that performs the actual computation. ln.flow() would then just track the execution time of scheduling, and not an actual compute run.

If one wanted to use @ln.flow() it’s advisable to wrap the scheduling main() task:

@ln.flow()
def run_pipeline(...):
    scheduler = Scheduler()
    result = scheduler.run(main(...))  # run the main task
    ln.Artifact(result.path, key="data/results.tgz").save()
    return result

Run redun

Let’s see what the input files are:

ls ./fasta
Hide code cell output
KLF4.fasta
MYC.fasta
PO5F1.fasta
SOX2.fasta

Create a lamindb test instance:

# pip install lamindb redun git+http://github.com/laminlabs/redun-lamin-fasta
lamin init --storage ./test-redun-lamin
Hide code cell output
→ initialized database testuser1/test-redun-lamin in /home/runner/work/redun-lamin/redun-
lamin/docs

Register each input file individually as an artifact:

import lamindb as ln
import json

ln.Artifact.from_dir("./fasta").save()
Hide code cell output
→ connected lamindb: testuser1/test-redun-lamin
! folder is outside existing storage location, will copy files from ./fasta to /home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/fasta
! no run & transform got linked, call `ln.track()` & re-run
! no run & transform got linked, call `ln.track()` & re-run
! no run & transform got linked, call `ln.track()` & re-run
! no run & transform got linked, call `ln.track()` & re-run
SQLRecordList([Artifact(uid='2xfEH3O2SzsCOmtJ0000', key='fasta/KLF4.fasta', description=None, suffix='.fasta', kind=None, otype=None, size=609, hash='LyuoYkWs4SgYcH7P7JLJtA', n_files=None, n_observations=None, extra_data=None, branch_id=1, created_on_id=1, space_id=1, storage_id=1, run_id=None, schema_id=None, created_by_id=1, created_at=2026-10-28 08:23:11 UTC, is_locked=False, version_tag=None, is_latest=True),
               Artifact(uid='A8dVi54KTbWg5SBB0000', key='fasta/MYC.fasta', description=None, suffix='.fasta', kind=None, otype=None, size=536, hash='WGbEtzPw-3bQEGcngO_pHQ', n_files=None, n_observations=None, extra_data=None, branch_id=1, created_on_id=1, space_id=1, storage_id=1, run_id=None, schema_id=None, created_by_id=1, created_at=2026-10-28 08:23:11 UTC, is_locked=False, version_tag=None, is_latest=True),
               Artifact(uid='u9ygeSJCACe8CTda0000', key='fasta/PO5F1.fasta', description=None, suffix='.fasta', kind=None, otype=None, size=477, hash='-7iJgveFO9ia0wE1bqVu6g', n_files=None, n_observations=None, extra_data=None, branch_id=1, created_on_id=1, space_id=1, storage_id=1, run_id=None, schema_id=None, created_by_id=1, created_at=2026-10-28 08:23:11 UTC, is_locked=False, version_tag=None, is_latest=True),
               Artifact(uid='GusEh1BzxzeKt2nl0000', key='fasta/SOX2.fasta', description=None, suffix='.fasta', kind=None, otype=None, size=414, hash='C5q_yaFXGk4SAEpfdqBwnQ', n_files=None, n_observations=None, extra_data=None, branch_id=1, created_on_id=1, space_id=1, storage_id=1, run_id=None, schema_id=None, created_by_id=1, created_at=2026-10-28 08:23:11 UTC, is_locked=False, version_tag=None, is_latest=True)])

Run the redun workflow:

redun run workflow.py main --input-dir ./fasta --tag run=test-run  1> run_logs.txt 2>run_logs.txt

Inspect the logs:

cat run_logs.txt
Hide code cell output
→ connected lamindb: testuser1/test-redun-lamin
→ script invoked with: run wor
kflow.py main --input-dir ./fasta --tag run=test-run
→ created Transform('CTEut9YSBTZz000
0', key='workflow.py'), started new Run('kmKJaSrMZFQTrZ7e') at 2026-10-28 08:23:20 UTC
• 
tip: to identify the script across renames, pass the uid: ln.track("CTEut9YSBTZz")
File(path=/home/r
unner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/results.tgz, hash=24912653)
cs_pipelin
e_tutorial.lib.digest_protein_task(input_fasta=File(path=/home/runner/work/redun-lamin/redun-lamin/d
ocs/test-redun-lamin/.lamindb/2xfEH3O2SzsCOmtJ0000.fasta, hash=3c6a0cd5), enzyme_regex='[KR]', misse
d_cleavages=0, min_length=4, max_length=75) on default
[redun] Run    Job d54eb388:  bioinformatics_
pipeline_tutorial.lib.digest_protein_task(input_fasta=File(path=/home/runner/work/redun-lamin/redun-
lamin/docs/test-redun-lamin/.lamindb/A8dVi54KTbWg5SBB0000.fasta, hash=821e187c), enzyme_regex='[KR]'
, missed_cleavages=0, min_length=4, max_length=75) on default
[redun] Run    Job fd881f0c:  bioinfor
matics_pipeline_tutorial.lib.digest_protein_task(input_fasta=File(path=/home/runner/work/redun-lamin
/redun-lamin/docs/test-redun-lamin/.lamindb/u9ygeSJCACe8CTda0000.fasta, hash=4b977f99), enzyme_regex
='[KR]', missed_cleavages=0, min_length=4, max_length=75) on default
[redun] Run    Job 66178b1a:  b
ioinformatics_pipeline_tutorial.lib.digest_protein_task(input_fasta=File(path=/home/runner/work/redu
n-lamin/redun-lamin/docs/test-redun-lamin/.lamindb/GusEh1BzxzeKt2nl0000.fasta, hash=93453059), enzym
e_regex='[KR]', missed_cleavages=0, min_length=4, max_length=75) on default
[redun] Run    Job 3fd8b
7f5:  bioinformatics_pipeline_tutorial.lib.count_amino_acids_task(input_fasta=File(path=/home/runner
/work/redun-lamin/redun-lamin/docs/test-redun-lamin/.lamindb/2xfEH3O2SzsCOmtJ0000.fasta, hash=3c6a0c
d5), input_peptides=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/2
xfEH3O2SzsCOmtJ0000.peptides.txt, hash=6b12393c), amino_acid='C') on default
[redun] Run    Job 56c1
6302:  bioinformatics_pipeline_tutorial.lib.count_amino_acids_task(input_fasta=File(path=/home/runne
r/work/redun-lamin/redun-lamin/docs/test-redun-lamin/.lamindb/A8dVi54KTbWg5SBB0000.fasta, hash=821e1
87c), input_peptides=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/
A8dVi54KTbWg5SBB0000.peptides.txt, hash=baa7462b), amino_acid='C') on default
[redun] Run    Job 118
f78e1:  bioinformatics_pipeline_tutorial.lib.count_amino_acids_task(input_fasta=File(path=/home/runn
er/work/redun-lamin/redun-lamin/docs/test-redun-lamin/.lamindb/u9ygeSJCACe8CTda0000.fasta, hash=4b97
7f99), input_peptides=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data
/u9ygeSJCACe8CTda0000.peptides.txt, hash=46584b09), amino_acid='C') on default
[redun] Run    Job eb
fc3e00:  bioinformatics_pipeline_tutorial.lib.count_amino_acids_task(input_fasta=File(path=/home/run
ner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/.lamindb/GusEh1BzxzeKt2nl0000.fasta, hash=934
53059), input_peptides=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/dat
a/GusEh1BzxzeKt2nl0000.peptides.txt, hash=499543b2), amino_acid='C') on default
[redun] Run    Job f
beebdd5:  bioinformatics_pipeline_tutorial.lib.plot_count_task(input_count=File(path=/home/runner/wo
rk/redun-lamin/redun-lamin/docs/test-redun-lamin/data/2xfEH3O2SzsCOmtJ0000.count.tsv, hash=cd7d91fd)
) on default
[redun] Run    Job 35df5a68:  bioinformatics_pipeline_tutorial.lib.plot_count_task(inpu
t_count=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/A8dVi54KTbWg5
SBB0000.count.tsv, hash=8b3d9d0a)) on default
[redun] Run    Job 1b3f9288:  bioinformatics_pipeline_
tutorial.lib.plot_count_task(input_count=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/te
st-redun-lamin/data/u9ygeSJCACe8CTda0000.count.tsv, hash=4d4c404b)) on default
[redun] Run    Job 08
d95fc4:  bioinformatics_pipeline_tutorial.lib.plot_count_task(input_count=File(path=/home/runner/wor
k/redun-lamin/redun-lamin/docs/test-redun-lamin/data/GusEh1BzxzeKt2nl0000.count.tsv, hash=b2a8e3b5))
 on default
[redun] Run    Job 0c98f443:  bioinformatics_pipeline_tutorial.lib.get_report_task(input
_counts=[File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/2xfEH3O2SzsC
OmtJ0000.count.tsv, hash=cd7d91fd), File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-re
dun-l...) on default
[redun] Run    Job 797f27e5:  bioinformatics_pipeline_tutorial.lib.archive_resu
lts_task(inputs_plots=[File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/dat
a/2xfEH3O2SzsCOmtJ0000.plot.png, hash=ed7c4ed5), File(path=/home/runner/work/redun-lamin/redun-lamin
/docs/test-redun-la..., input_report=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-r
edun-lamin/data/protein_report.tsv, hash=f02868c2)) on default
[redun] Run    Job ffab6367:  redun_l
amin_fasta.finish(results_archive=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redu
n-lamin/data/results.tgz, hash=24912653)) on default
[redun] 
[redun] | JOB STATUS 2026/10/28 08:23:
34
[redun] | TASK                                                        PENDING RUNNING  FAILED  CA
CHED    DONE   TOTAL
[redun] | 
[redun] | ALL                                                       
        0       0       0       0      16      16
[redun] | bioinformatics_pipeline_tutorial.lib.arc
hive_results_task         0       0       0       0       1       1
[redun] | bioinformatics_pipelin
e_tutorial.lib.count_amino_acids_task       0       0       0       0       4       4
[redun] | bioi
nformatics_pipeline_tutorial.lib.digest_protein_task          0       0       0       0       4     
  4
[redun] | bioinformatics_pipeline_tutorial.lib.get_report_task              0       0       0   
    0       1       1
[redun] | bioinformatics_pipeline_tutorial.lib.plot_count_task              0 
      0       0       0       4       4
[redun] | redun_lamin_fasta.finish                          
                0       0       0       0       1       1
[redun] | redun_lamin_fasta.main          
                                  0       0       0       0       1       1
[redun] 
[redun] 
[redun
] Execution duration: 14.24 seconds

View data lineage

artifact = ln.Artifact.get(key="data/results.tgz")
artifact.view_lineage()
Hide code cell output
_images/a6e0eb539181c46cb7b1eb2a4bd910eefc96d98a9be2dccdeb6c676cf9b63704.svg
artifact.run.transform.describe()
Hide code cell output
Transform: workflow.py (0000)
|   description: CLI: redun
├── uid: CTEut9YSBTZz0000                                     
│   hash: zjZMEeofUMp3FV6fxbgjYg         type: script         
│   branch: main                         space: all           
│   created_at: 2026-10-28 08:23:20 UTC  created_by: testuser1
└── source_code: 
    │ """workflow.py."""
    │ 
    │ # This code is based on a copy from https://github.com/ricomnl/bioinformatics-pi …
    │ # Copyright Rico Meinl 2022
    │ from enum import Enum
    │ 
    │ import lamindb as ln
    │ from redun import File, task
    │ 
    │ import redun_lamin_fasta
    │ from redun_lamin_fasta.lib import (
    │     archive_results_task,
    │     count_amino_acids_task,
    │     digest_protein_task,
    │     get_report_task,
    │     plot_count_task,
    │ )
    │ 
    │ redun_namespace = redun_lamin_fasta.__name__
    │ 
    │ 
    │ class Executor(str, Enum):
    │     default = "default"
    │     process = "process"
    │     batch = "batch"
    │     batch_debug = "batch_debug"
    │ 
    │ 
    │ @task()
    │ def finish(results_archive: File) -> File:
    │ …
artifact.run.describe()
Hide code cell output
Run: kmKJaSr (workflow.py)
├── uid: kmKJaSrMZFQTrZ7e                transform: workflow.py (0000)       
│   started_at: 2026-10-28 08:23:20 UTC  finished_at: 2026-10-28 08:23:34 UTC
│   status: completed                                                        
│   branch: main                         space: all                          
│   created_at: 2026-10-28 08:23:20 UTC  created_by: testuser1               
├── cli_args: 
│   │ run workflow.py main --input-dir ./fasta --tag run=test-run
├── report: 6cDeNSb
│   │ → connected lamindb: testuser1/test-redun-lamin
│   │ → created Transform('CTEut9YSBTZz0000', key='workflow.py'), started new Run('kmK …
│   │ • tip: to identify the script across renames, pass the uid: ln.track("CTEut9YSBT …
└── environment: ZZhN6lQ
    │ aiobotocore==3.10.0
    │ aiohappyeyeballs==2.7.1
    │ aiohttp==3.14.5
    │ aioitertools==0.13.0
    │ …

Explore the run on the hub

→ lamin.ai/laminlabs/lamindata/transform/taasWKawCiNA

View the database content

ln.view()
Hide code cell output
Artifact
uid key description suffix kind otype size hash n_files n_observations ... is_latest is_locked created_at branch_id created_on_id space_id storage_id run_id schema_id created_by_id
id
6 7pMfsmdWDLpLssHt0000 data/results.tgz None None None 94846 2XujeDgKmKAPqNWH3s4VPw None None ... True False 2026-10-28 08:23:34.258+00:00 1 1 1 1 1.0 None 1
4 GusEh1BzxzeKt2nl0000 fasta/SOX2.fasta None .fasta None None 414 C5q_yaFXGk4SAEpfdqBwnQ None None ... True False 2026-10-28 08:23:11.185+00:00 1 1 1 1 NaN None 1
3 u9ygeSJCACe8CTda0000 fasta/PO5F1.fasta None .fasta None None 477 -7iJgveFO9ia0wE1bqVu6g None None ... True False 2026-10-28 08:23:11.185+00:00 1 1 1 1 NaN None 1
2 A8dVi54KTbWg5SBB0000 fasta/MYC.fasta None .fasta None None 536 WGbEtzPw-3bQEGcngO_pHQ None None ... True False 2026-10-28 08:23:11.184+00:00 1 1 1 1 NaN None 1
1 2xfEH3O2SzsCOmtJ0000 fasta/KLF4.fasta None .fasta None None 609 LyuoYkWs4SgYcH7P7JLJtA None None ... True False 2026-10-28 08:23:11.183+00:00 1 1 1 1 NaN None 1

5 rows × 22 columns

Run
uid name description entrypoint started_at finished_at params extra_data reference reference_type ... created_at branch_id created_on_id space_id transform_id report_id environment_id plan_id created_by_id initiated_by_run_id
id
1 kmKJaSrMZFQTrZ7e None None None 2026-10-28 08:23:20.250+00:00 2026-10-28 08:23:34.287322+00:00 None None None None ... 2026-10-28 08:23:20.250+00:00 1 1 1 1 7 5 None 1 None

1 rows × 22 columns

Storage
uid root description type region instance_uid is_locked created_at branch_id created_on_id space_id created_by_id run_id
id
1 J4W1XaD8b6bR /home/runner/work/redun-lamin/redun-lamin/docs... None local None iQlBPgD8uaqR False 2026-10-28 08:23:08.622+00:00 1 1 1 1 None
Transform
uid key description kind source_code hash reference reference_type version_tag is_latest is_locked created_at branch_id created_on_id space_id environment_id plan_id run_id created_by_id
id
1 CTEut9YSBTZz0000 workflow.py CLI: redun script """workflow.py."""\n\n# This code is based on ... zjZMEeofUMp3FV6fxbgjYg None None None True False 2026-10-28 08:23:20.245+00:00 1 1 1 None None None 1

Appendix

Map the redun execution id

Export the run information from redun:

redun log --exec --exec-tag run=test-run --format json --no-pager > redun_exec.json

Map it on the run reference:

# load the redun execution id from the JSON and store it in the LaminDB run record
with open("redun_exec.json") as file:
    redun_exec = json.loads(file.readline())
artifact.run.reference = redun_exec["id"]
artifact.run.reference_type = "redun_id"
artifact.run.save()
Hide code cell output
Run(uid='kmKJaSrMZFQTrZ7e', name=None, description=None, entrypoint=None, started_at=2026-10-28 08:23:20 UTC, finished_at=2026-10-28 08:23:34 UTC, params=None, extra_data=None, reference='01592df4-0f2f-450f-b6e5-9f4f0b0ebeb1', reference_type='redun_id', cli_args='run workflow.py main --input-dir ./fasta --tag run=test-run', branch_id=1, created_on_id=1, space_id=1, transform_id=1, report_id=7, environment_id=5, plan_id=None, created_by_id=1, initiated_by_run_id=None, created_at=2026-10-28 08:23:20 UTC, is_locked=False)

Map the redun run report

While lamindb auto-tracks the logs of the main python process you might also want to link the dedicated redun logs:

report = ln.Artifact(
    "run_logs.txt",
    description=f"Redun run report of {redun_exec['id']}",
    run=False,
    kind="__lamindb_run__",  # mark as auxiliary artifact for the run
).save()
artifact.run.report = report
artifact.run.save()
Hide code cell output
Run(uid='kmKJaSrMZFQTrZ7e', name=None, description=None, entrypoint=None, started_at=2026-10-28 08:23:20 UTC, finished_at=2026-10-28 08:23:34 UTC, params=None, extra_data=None, reference='01592df4-0f2f-450f-b6e5-9f4f0b0ebeb1', reference_type='redun_id', cli_args='run workflow.py main --input-dir ./fasta --tag run=test-run', branch_id=1, created_on_id=1, space_id=1, transform_id=1, report_id=8, environment_id=5, plan_id=None, created_by_id=1, initiated_by_run_id=None, created_at=2026-10-28 08:23:20 UTC, is_locked=False)