Tutorial: Using Configuration Objects

On this page

Every format has a dedicated config dataclass giving you full control beyond the handful of options exposed as direct constructor kwargs. This tutorial walks through the pattern using CSVLoader as the running example, then shows how it generalizes.

The pattern

Python · 14 lines
from zerda.document_loaders import CSVLoader, CSVLoaderConfig

# Option A: direct kwargs (covers common cases)
loader = CSVLoader("data.csv", content_columns=["title"], max_rows=100)

# Option B: full config object (covers everything)
config = CSVLoaderConfig(
    content_columns=["title", "body"],
    metadata_columns=["author"],
    max_rows=100,
    skip_rows=1,
    row_joiner=" — ",
)
loader = CSVLoader("data.csv", config=config)

When config= is provided, it takes full precedence — the direct kwargs are only used to build a default config when config is None. See Configuration Reference for the complete field-by-field breakdown of every config dataclass.

Worked example: tuning a CSV load step by step

Start with the raw file:

Text · 3 lines
id,title,body,author,internal_notes
1,Intro to RAG,RAG combines retrieval with generation.,Alice,draft v1
2,Vector DBs,Vector databases store embeddings.,Bob,needs review

Attempt 1 — defaults (every column becomes content):

Python · 3 lines
docs = CSVLoader("articles.csv").load()
print(docs[0].page_content)
# "id: 1\ntitle: Intro to RAG\nbody: RAG combines retrieval with generation.\nauthor: Alice\ninternal_notes: draft v1"

This pulls in internal_notes, which you probably don't want polluting embeddings.

Attempt 2 — scope content to the meaningful fields:

Python · 6 lines
from zerda.document_loaders import CSVLoaderConfig

config = CSVLoaderConfig(content_columns=["title", "body"])
docs = CSVLoader("articles.csv", config=config).load()
print(docs[0].page_content)
# "title: Intro to RAG\nbody: RAG combines retrieval with generation."

Now author and internal_notes are dropped entirely — but you probably want author retrievable as metadata, not lost.

Attempt 3 — route author to metadata explicitly:

Python · 6 lines
config = CSVLoaderConfig(
    content_columns=["title", "body"],
    metadata_columns=["author"],
)
docs = CSVLoader("articles.csv", config=config).load()
print(docs[0].metadata["author"])   # "Alice"

internal_notes is now excluded from both content and metadata, exactly as intended.

Same pattern, other formats

PDF — page range + password:

Python · 4 lines
from zerda.document_loaders import PDFLoader, PDFLoaderConfig

config = PDFLoaderConfig(start_page=0, end_page=5, password="secret")
docs = PDFLoader("confidential_excerpt.pdf", config=config).load()

HTML — scope extraction to specific tags:

Python · 4 lines
from zerda.document_loaders import HTMLLoader, HTMLLoaderConfig

config = HTMLLoaderConfig(tags_to_extract=["article"], extract_links=True)
docs = HTMLLoader("blog_post.html", config=config).load()

Directory — custom exclusions and concurrency:

Python · 8 lines
from zerda.document_loaders import DirectoryLoader, DirectoryLoaderConfig

config = DirectoryLoaderConfig(
    exclude_patterns=["*.tmp", "archive/*"],
    max_concurrency=8,
    silent_errors=True,
)
docs = DirectoryLoader("./corpus/", config=config).load()

Watch out: GraphLoader and TableLoader behave differently

Unlike every loader above, GraphLoader and TableLoader have specific keyword-only constructor args that always override the matching config= fields:

Python · 9 lines
from zerda.document_loaders import TableLoader, TableLoaderConfig

config = TableLoaderConfig(output_format="json")
# This does NOT get "json" — it gets overwritten back to "markdown"
# because output_format defaults to "markdown" as a direct kwarg:
docs = TableLoader("data.xlsx", config=config).load()

# Correct — pass it directly too:
docs = TableLoader("data.xlsx", config=config, output_format="json").load()

See the warnings on the Graph and Table API pages for full detail.

Next steps

Related pages