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 lamindb: testuser1/test-redun-lamin

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='gXngsbHLkFcXP6P10000', version_tag=None, is_latest=True, key='fasta/SOX2.fasta', description=None, suffix='.fasta', kind=None, otype=None, size=414, hash='C5q_yaFXGk4SAEpfdqBwnQ', n_files=None, n_observations=None, branch_id=1, space_id=1, storage_id=3, run_id=None, schema_id=None, created_by_id=3, created_at=2026-02-11 19:55:52 UTC, is_locked=False),
               Artifact(uid='7P33AhOyaYTZci8i0000', version_tag=None, is_latest=True, key='fasta/MYC.fasta', description=None, suffix='.fasta', kind=None, otype=None, size=536, hash='WGbEtzPw-3bQEGcngO_pHQ', n_files=None, n_observations=None, branch_id=1, space_id=1, storage_id=3, run_id=None, schema_id=None, created_by_id=3, created_at=2026-02-11 19:55:52 UTC, is_locked=False),
               Artifact(uid='tZwsKOVfnupw5dlJ0000', version_tag=None, is_latest=True, key='fasta/PO5F1.fasta', description=None, suffix='.fasta', kind=None, otype=None, size=477, hash='-7iJgveFO9ia0wE1bqVu6g', n_files=None, n_observations=None, branch_id=1, space_id=1, storage_id=3, run_id=None, schema_id=None, created_by_id=3, created_at=2026-02-11 19:55:52 UTC, is_locked=False),
               Artifact(uid='hyhl52JjF0MXGRk10000', version_tag=None, is_latest=True, key='fasta/KLF4.fasta', description=None, suffix='.fasta', kind=None, otype=None, size=609, hash='LyuoYkWs4SgYcH7P7JLJtA', n_files=None, n_observations=None, branch_id=1, space_id=1, storage_id=3, run_id=None, schema_id=None, created_by_id=3, created_at=2026-02-11 19:55:52 UTC, is_locked=False)])

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 workflow.py main --input-dir ./fasta --tag run=test-run
 created Transform('Htw2ugaRxhbk0000', key='workflow.py'), started new Run('t3paALC2BW7dVMrY') at 2026-02-11 19:55:59 UTC
 recommendation: to identify the script across renames, pass the uid: ln.track("Htw2ugaRxhbk")
File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/results.tgz, hash=86381501)
_tutorial.lib.digest_protein_task(input_fasta=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/.lamindb/gXngsbHLkFcXP6P10000.fasta, hash=32058002), enzyme_regex='[KR]', missed_cleavages=0, min_length=4, max_length=75) on default
[redun] Run    Job dba19e7a:  bioinformatics_pipeline_tutorial.lib.digest_protein_task(input_fasta=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/.lamindb/7P33AhOyaYTZci8i0000.fasta, hash=89acbfb0), enzyme_regex='[KR]', missed_cleavages=0, min_length=4, max_length=75) on default
[redun] Run    Job 42a5db77:  bioinformatics_pipeline_tutorial.lib.digest_protein_task(input_fasta=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/.lamindb/tZwsKOVfnupw5dlJ0000.fasta, hash=a0a2965c), enzyme_regex='[KR]', missed_cleavages=0, min_length=4, max_length=75) on default
[redun] Run    Job 6a21d5b4:  bioinformatics_pipeline_tutorial.lib.digest_protein_task(input_fasta=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/.lamindb/hyhl52JjF0MXGRk10000.fasta, hash=e73f7857), enzyme_regex='[KR]', missed_cleavages=0, min_length=4, max_length=75) on default
[redun] Run    Job e2f45317:  bioinformatics_pipeline_tutorial.lib.count_amino_acids_task(input_fasta=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/.lamindb/gXngsbHLkFcXP6P10000.fasta, hash=32058002), input_peptides=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/gXngsbHLkFcXP6P10000.peptides.txt, hash=49bdbdd0), amino_acid='C') on default
[redun] Run    Job 1c63e786:  bioinformatics_pipeline_tutorial.lib.count_amino_acids_task(input_fasta=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/.lamindb/7P33AhOyaYTZci8i0000.fasta, hash=89acbfb0), input_peptides=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/7P33AhOyaYTZci8i0000.peptides.txt, hash=44da0983), amino_acid='C') on default
[redun] Run    Job 6decff95:  bioinformatics_pipeline_tutorial.lib.count_amino_acids_task(input_fasta=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/.lamindb/tZwsKOVfnupw5dlJ0000.fasta, hash=a0a2965c), input_peptides=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/tZwsKOVfnupw5dlJ0000.peptides.txt, hash=6aa096e8), amino_acid='C') on default
[redun] Run    Job cc8d708a:  bioinformatics_pipeline_tutorial.lib.count_amino_acids_task(input_fasta=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/.lamindb/hyhl52JjF0MXGRk10000.fasta, hash=e73f7857), input_peptides=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/hyhl52JjF0MXGRk10000.peptides.txt, hash=77aa8a45), amino_acid='C') on default
[redun] Run    Job 82f9fc1d:  bioinformatics_pipeline_tutorial.lib.plot_count_task(input_count=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/gXngsbHLkFcXP6P10000.count.tsv, hash=10fb2e46)) on default
[redun] Run    Job 5a31ccec:  bioinformatics_pipeline_tutorial.lib.plot_count_task(input_count=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/7P33AhOyaYTZci8i0000.count.tsv, hash=640aad04)) on default
[redun] Run    Job a4847056:  bioinformatics_pipeline_tutorial.lib.plot_count_task(input_count=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/tZwsKOVfnupw5dlJ0000.count.tsv, hash=7a3f8a7e)) on default
[redun] Run    Job d5cf3e9c:  bioinformatics_pipeline_tutorial.lib.plot_count_task(input_count=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/hyhl52JjF0MXGRk10000.count.tsv, hash=1a579aaf)) on default
[redun] Run    Job 6b5791de:  bioinformatics_pipeline_tutorial.lib.get_report_task(input_counts=[File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/gXngsbHLkFcXP6P10000.count.tsv, hash=10fb2e46), File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-l...) on default
[redun] Run    Job 555695b2:  bioinformatics_pipeline_tutorial.lib.archive_results_task(inputs_plots=[File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/gXngsbHLkFcXP6P10000.plot.png, hash=0a5bab4a), 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-redun-lamin/data/protein_report.tsv, hash=ecfbfed1)) on default
[redun] Run    Job 55215571:  redun_lamin_fasta.finish(results_archive=File(path=/home/runner/work/redun-lamin/redun-lamin/docs/test-redun-lamin/data/results.tgz, hash=86381501)) on default
[redun] 
[redun] | JOB STATUS 2026/02/11 19:56:05
[redun] | TASK                                                        PENDING RUNNING  FAILED  CACHED    DONE   TOTAL
[redun] | 
[redun] | ALL                                                               0       0       0       0      16      16
[redun] | bioinformatics_pipeline_tutorial.lib.archive_results_task         0       0       0       0       1       1
[redun] | bioinformatics_pipeline_tutorial.lib.count_amino_acids_task       0       0       0       0       4       4
[redun] | bioinformatics_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: 5.67 seconds

View data lineage

artifact = ln.Artifact.get(key="data/results.tgz")
artifact.view_lineage()
Hide code cell output
_images/19cb91d2cad77bdc973088a125339fd96c24c2945eddcd5a89705c3e6a52d2c1.svg
artifact.transform.describe()
Hide code cell output
Transform: workflow.py (0000)
|   description: CLI: redun
├── uid: Htw2ugaRxhbk0000                                     
hash: zjZMEeofUMp3FV6fxbgjYg         type: script         
branch: main                         space: all           
created_at: 2026-02-11 19:55:59 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: t3paALC (workflow.py)
├── uid: t3paALC2BW7dVMrY                transform: workflow.py (0000)       
                                     |   description: CLI: redun         
started_at: 2026-02-11 19:55:59 UTC  finished_at: 2026-02-11 19:56:05 UTC
status: completed                                                        
branch: main                         space: all                          
created_at: 2026-02-11 19:55:59 UTC  created_by: testuser1               
├── cli_args: 
run workflow.py main --input-dir ./fasta --tag run=test-run
├── report: 9n9vTVm
→ connected lamindb: testuser1/test-redun-lamin
→ created Transform('Htw2ugaRxhbk0000', key='workflow.py'), started new Run('t3p …
• recommendation: to identify the script across renames, pass the uid: ln.track( …
└── environment: lnDGt37
    aiobotocore==2.26.0
    aiohappyeyeballs==2.6.1
    aiohttp==3.13.3
    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 version_tag is_latest is_locked created_at branch_id space_id storage_id run_id schema_id created_by_id
id
6 Epl5Pjlho3iWI5kF0000 data/results.tgz None .tgz None None 94332 iEoeB1IcWlSo41UQ7xZU7w None None None True False 2026-02-11 19:56:05.149000+00:00 1 1 3 1.0 None 3
4 hyhl52JjF0MXGRk10000 fasta/KLF4.fasta None .fasta None None 609 LyuoYkWs4SgYcH7P7JLJtA None None None True False 2026-02-11 19:55:52.070000+00:00 1 1 3 NaN None 3
3 tZwsKOVfnupw5dlJ0000 fasta/PO5F1.fasta None .fasta None None 477 -7iJgveFO9ia0wE1bqVu6g None None None True False 2026-02-11 19:55:52.069000+00:00 1 1 3 NaN None 3
2 7P33AhOyaYTZci8i0000 fasta/MYC.fasta None .fasta None None 536 WGbEtzPw-3bQEGcngO_pHQ None None None True False 2026-02-11 19:55:52.068000+00:00 1 1 3 NaN None 3
1 gXngsbHLkFcXP6P10000 fasta/SOX2.fasta None .fasta None None 414 C5q_yaFXGk4SAEpfdqBwnQ None None None True False 2026-02-11 19:55:52.068000+00:00 1 1 3 NaN None 3
Run
uid name entrypoint started_at finished_at params reference reference_type cli_args is_locked created_at branch_id space_id transform_id report_id environment_id created_by_id initiated_by_run_id
id
1 t3paALC2BW7dVMrY None None 2026-02-11 19:55:59.681454+00:00 2026-02-11 19:56:05.176892+00:00 None None None run workflow.py main --input-dir ./fasta --tag... False 2026-02-11 19:55:59.682000+00:00 1 1 1 7 5 3 None
Storage
uid root description type region instance_uid is_locked created_at branch_id space_id created_by_id run_id
id
3 KejDwMe2t4AG /home/runner/work/redun-lamin/redun-lamin/docs... None local None iQlBPgD8uaqR False 2026-02-11 19:55:48.603000+00:00 1 1 3 None
Transform
uid key description kind source_code hash reference reference_type version_tag is_latest is_locked created_at branch_id space_id environment_id created_by_id
id
1 Htw2ugaRxhbk0000 workflow.py CLI: redun script """workflow.py."""\n\n# This code is based on ... zjZMEeofUMp3FV6fxbgjYg None None None True False 2026-02-11 19:55:59.679000+00:00 1 1 None 3

Appendix

Map the redun execution id

If we want to be able to query LaminDB for redun execution ID, this here is a way to get it:

# export the run information from redun
!redun log --exec --exec-tag run=test-run --format json --no-pager > redun_exec.json
# 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='t3paALC2BW7dVMrY', name=None, entrypoint=None, started_at=2026-02-11 19:55:59 UTC, finished_at=2026-02-11 19:56:05 UTC, params=None, reference='badf618d-13c7-45f0-9b08-f6077d4866aa', reference_type='redun_id', cli_args='run workflow.py main --input-dir ./fasta --tag run=test-run', branch_id=1, space_id=1, transform_id=1, report_id=7, environment_id=5, created_by_id=3, initiated_by_run_id=None, created_at=2026-02-11 19:55:59 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='t3paALC2BW7dVMrY', name=None, entrypoint=None, started_at=2026-02-11 19:55:59 UTC, finished_at=2026-02-11 19:56:05 UTC, params=None, reference='badf618d-13c7-45f0-9b08-f6077d4866aa', reference_type='redun_id', cli_args='run workflow.py main --input-dir ./fasta --tag run=test-run', branch_id=1, space_id=1, transform_id=1, report_id=8, environment_id=5, created_by_id=3, initiated_by_run_id=None, created_at=2026-02-11 19:55:59 UTC, is_locked=False)