New to Kestra?
Use blueprints to kickstart your first workflows.
Fan out a list of CSV files and transform each one in parallel using isolated Python Pandas scripts in Docker, orchestrated declaratively with Kestra.
id: python-csv-each-parallel
namespace: company.team
tasks:
- id: csv
type: io.kestra.plugin.core.flow.ForEach
concurrencyLimit: 0
values:
- https://huggingface.co/datasets/kestra/datasets/raw/main/csv/orders.csv
- https://huggingface.co/datasets/kestra/datasets/raw/main/csv/products.csv
- https://huggingface.co/datasets/kestra/datasets/raw/main/csv/salaries.csv
tasks:
- id: pandas
type: io.kestra.plugin.scripts.python.Script
taskRunner:
type: io.kestra.plugin.scripts.runner.docker.Docker
dependencies:
- pandas
script: |
import pandas as pd
df = pd.read_csv("{{ taskrun.value }}")
df.info()
Process many CSV files at once by fanning them out and running a dedicated Python and Pandas script for each file in its own isolated Docker container. This blueprint reads a list of CSV URLs, loops over them in parallel, and runs Pandas inside reproducible containers so a slow or failing file never blocks the rest. It is a clean pattern for parallel CSV processing, batch data transformation, and Python data pipelines where each input is independent.
csv task is an io.kestra.plugin.core.flow.ForEach loop that iterates over a list of CSV file URLs. With concurrencyLimit: 0, every value is processed at the same time with no cap on parallelism.pandas task of type io.kestra.plugin.scripts.python.Script runs a Python script that reads the current file via pd.read_csv("{{ taskrun.value }}") and prints its schema and stats with df.info().io.kestra.plugin.scripts.runner.docker.Docker task runner, with pandas declared under dependencies so the package is installed automatically.A bare Python script can read one CSV at a time, but it cannot schedule itself, fan work out in parallel with isolation, retry a single failed file, or track lineage across runs. Kestra adds event and schedule triggers, per-task retries, full execution history and logs, and declarative YAML that captures the whole pipeline as code. ForEach gives you parallelism with a tunable concurrencyLimit, and the Docker task runner guarantees each file runs in a clean environment, filling the gap a standalone interpreter cannot.
{{ secret('NAME') }} values.df.info() output per file.csv task values with your own CSV locations.df.info() for real transformations: cleaning, aggregation, joins, or type casting.concurrencyLimit to throttle parallelism on large lists.retry for production runs.values list dynamically from an upstream task instead of hardcoding URLs.