A pipeline applies a sequence of operators to a dataset and writes the result.
DocETL has two first-class ways to write pipelines:
Every example in these docs shows both, in tabs. The two convert into each other: frame.to_yaml("pipeline.yaml") and docetl.Frame.from_yaml("pipeline.yaml").
The required pieces are:
Optional settings (default model, system prompts) are covered below.
The input data: JSON, CSV, or Parquet files, a directory of documents, or an in-memory list of dicts. See Datasets and Frames.
Operators define the transformations applied to your data — map, filter, reduce, resolve, and others. See the Operators documentation.
The pipeline specification lists the steps to execute and the output:
In the Frame API, the pipeline is the chain of operations itself, and the terminal write method defines the output:
DocETL caches LLM results by default, so re-running a pipeline retrieves unchanged results from the cache instead of recomputing them. Clear it with docetl clear-cache.
Relative paths — dataset path, output path, and intermediate_dir — resolve against the directory you run from, not the location of the YAML file or Python script.
For a complete worked pipeline, see the Tutorial.
The docetl run command's options:
Run the configuration specified in the YAML file.
Parameters:
| yaml_file | Path |
Path to the YAML file containing the pipeline configuration. |
Argument(..., help='Path to the YAML file containing the pipeline configuration') |
| max_threads | int | None |
Maximum number of threads to use for running operations. |
Option(None, help='Maximum number of threads to use for running operations') |
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192 | @app.command()
def run(
yaml_file: Path = typer.Argument(
..., help="Path to the YAML file containing the pipeline configuration"
),
max_threads: int | None = typer.Option(
None, help="Maximum number of threads to use for running operations"
),
):
"""
Run the configuration specified in the YAML file.
Args:
yaml_file (Path): Path to the YAML file containing the pipeline configuration.
max_threads (int | None): Maximum number of threads to use for running operations.
"""
# Get the current working directory (where the user called the command)
cwd = os.getcwd()
# Load .env file from the current working directory
env_file = os.path.join(cwd, ".env")
if os.path.exists(env_file):
load_dotenv(env_file)
runner = DSLRunner.from_yaml(str(yaml_file), max_threads=max_threads)
runner.load_run_save()
|
handler: python options: members: - run show_root_full_path: false show_root_toc_entry: false show_root_heading: false show_source: false show_name: false
Two optimizers are available, covered in the Optimization section:
Operations without an explicit model use the pipeline default. bypass_cache skips the LLM cache for the whole pipeline (overridable per operation):
Self-hosted models
If you're hosting your own models with an OpenAI-compatible API (Ollama, LM Studio, etc.), you can specify the base URLs:
An optional description of the dataset and the persona the LLM should adopt, applied to every operation in the pipeline: