How to load local files with SimpleDirectoryReader in LlamaIndex

Local files become useful to LlamaIndex only after a reader turns their contents and filesystem details into Document objects. SimpleDirectoryReader handles that boundary for a directory or an explicit list of paths without requiring an LLM, embedding model, or API credential.

The directory form reads only the top level unless recursive=True is set. A narrow required_exts list prevents unrelated cache files or exports from joining the corpus, while input_files restricts a load to named paths.

The returned Document objects keep source metadata beside the extracted text, allowing later ingestion and indexing stages to retain file provenance. This matters when an application must distinguish files with similar content or trace a result back to its local source.

Steps to load local files with LlamaIndex SimpleDirectoryReader:

  1. Create the local support_docs source directory.
    $ mkdir support_docs
  2. Add the billing runbook to the source directory.
    $ printf '%s\n' 'Billing support runbook: refund ticket 7421 belongs to Maya.' > support_docs/billing.txt
  3. Add the shipping runbook to the source directory.
    $ printf '%s\n' 'Shipping support runbook: delivery delays are reviewed by the logistics desk.' > support_docs/shipping.txt
  4. Create the directory-loading section in load_local_files.py.
    load_local_files.py
    from pathlib import Path
     
    from llama_index.core import SimpleDirectoryReader
     
     
    source_dir = Path("support_docs")
    directory_documents = SimpleDirectoryReader(
        input_dir=str(source_dir),
        required_exts=[".txt"],
        filename_as_id=True,
    ).load_data()
  5. Append the explicit-file loading section to load_local_files.py.
    billing_documents = SimpleDirectoryReader(
        input_files=[str(source_dir / "billing.txt")],
        filename_as_id=True,
    ).load_data()

    The input_files form admits exact paths already selected by the application. With input_dir, recursive=True also admits files from nested directories.

  6. Append the document-boundary checks to load_local_files.py.
    file_names = sorted(
        document.metadata["file_name"] for document in directory_documents
    )
    metadata_fields = ["file_name", "file_path", "file_size", "file_type"]
    billing_text = billing_documents[0].get_content(metadata_mode="none").strip()
     
    assert file_names == ["billing.txt", "shipping.txt"]
    assert all(field in directory_documents[0].metadata for field in metadata_fields)
    assert len(billing_documents) == 1
    assert "refund ticket 7421" in billing_text
     
    print(f"directory_documents={len(directory_documents)}")
    print("directory_files=" + ",".join(file_names))
    print("metadata_fields=" + ",".join(metadata_fields))
    print(f"selected_documents={len(billing_documents)}")
    print(f"selected_text={billing_text}")
  7. Review the completed load_local_files.py file before execution.
    load_local_files.py
    from pathlib import Path
     
    from llama_index.core import SimpleDirectoryReader
     
     
    source_dir = Path("support_docs")
    directory_documents = SimpleDirectoryReader(
        input_dir=str(source_dir),
        required_exts=[".txt"],
        filename_as_id=True,
    ).load_data()
     
    billing_documents = SimpleDirectoryReader(
        input_files=[str(source_dir / "billing.txt")],
        filename_as_id=True,
    ).load_data()
     
    file_names = sorted(
        document.metadata["file_name"] for document in directory_documents
    )
    metadata_fields = ["file_name", "file_path", "file_size", "file_type"]
    billing_text = billing_documents[0].get_content(metadata_mode="none").strip()
     
    assert file_names == ["billing.txt", "shipping.txt"]
    assert all(field in directory_documents[0].metadata for field in metadata_fields)
    assert len(billing_documents) == 1
    assert "refund ticket 7421" in billing_text
     
    print(f"directory_documents={len(directory_documents)}")
    print("directory_files=" + ",".join(file_names))
    print("metadata_fields=" + ",".join(metadata_fields))
    print(f"selected_documents={len(billing_documents)}")
    print(f"selected_text={billing_text}")
  8. Run load_local_files.py to verify the directory and explicit-file loads.
    $ python load_local_files.py
    directory_documents=2
    directory_files=billing.txt,shipping.txt
    metadata_fields=file_name,file_path,file_size,file_type
    selected_documents=1
    selected_text=Billing support runbook: refund ticket 7421 belongs to Maya.