# How to Export Evaluation Results to CSV Format in the Hiring Agent

> Learn how to export evaluation results to CSV format in the Hiring Agent. This guide details the automatic CSV export process using score.py for efficient data handling.

- Repository: [HackerRank/hiring-agent](https://github.com/interviewstreet/hiring-agent)
- Tags: how-to-guide
- Published: 2026-06-28

---

**The hiring-agent repository automatically exports candidate evaluations to a CSV file by flattening the `EvaluationData` object via `transform_evaluation_response` and appending rows using Python's standard `csv` module in [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py).**

The interviewstreet/hiring-agent repository evaluates candidate resumes, GitHub profiles, and optional blog data, then structures the results for CSV export. When you run the evaluation workflow, the system converts complex evaluation objects into flat dictionaries and writes them to `resume_evaluations.csv` using UTF-8 encoding and comma-separated values.

## Understanding the CSV Export Architecture

The export workflow relies on two core components that handle data transformation and file I/O operations.

### Flattening Evaluation Data with transform_evaluation_response

The `transform_evaluation_response` function in [`main/transform.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/transform.py) (lines 511‑741) serves as the primary data transformer. This function receives the raw `EvaluationData` object produced by the LLM evaluator, along with basic resume and GitHub information, and flattens everything into a single dictionary where each key maps to a column value.

The function extracts fields such as `file_name`, `name`, `total_work_experience`, four score categories, bonus points, deductions, and key strengths. It returns a dictionary (`csv_row`) that serves as the direct input for the CSV writer.

### Writing Rows to Disk in score.py

The actual CSV writing logic resides in [`main/score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/score.py) (lines 342‑354). After an evaluation completes, the code calls the transformer and handles file operations:

```python
csv_row = transform_evaluation_response(
    file_name=resume_path,
    resume_data=resume,
    github_data=github,
    evaluation=score,
)
csv_path = "resume_evaluations.csv"
file_exists = os.path.exists(csv_path)

with open(csv_path, "a", newline="", encoding="utf-8") as csvfile:
    fieldnames = list(csv_row.keys())
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    if not file_exists:
        writer.writeheader()
    writer.writerow(csv_row)

```

This implementation automatically creates the header row on the first run and appends subsequent rows, yielding a cumulative CSV containing all evaluated candidates.

## Step-by-Step Export Process

The export evaluation results to CSV workflow follows this sequence:

1. **Run the evaluator** – The `_evaluate_resume` function (lines 62‑88 in [`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py)) evaluates the resume and returns an `EvaluationData` instance.
2. **Convert to flat dictionary** – `transform_evaluation_response` extracts relevant fields from the resume, GitHub profile, and evaluation object.
3. **Write or append to CSV** – The system opens or creates `resume_evaluations.csv`, writes the header once, then appends the new row using `csv.DictWriter`.

## Complete Implementation Example

You can run this minimal script from the repository root to evaluate a resume and export the results to CSV:

```python
from pathlib import Path
from score import _evaluate_resume, print_evaluation_results
from models import JSONResume
from github import fetch_and_display_github_info
from transform import transform_evaluation_response
import csv
import os

def export_to_csv(resume_path: Path):
    # Load JSON resume

    resume = JSONResume.from_file(resume_path)

    # Optional: fetch GitHub data if username is present

    github = None
    if resume.basics and resume.basics.github:
        github = fetch_and_display_github_info(resume.basics.github)

    # Run the evaluation

    evaluation = _evaluate_resume(resume, github_data=github)

    # Pretty-print results (optional)

    print_evaluation_results(evaluation, candidate_name=resume.basics.name or "Candidate")

    # Build the CSV row

    csv_row = transform_evaluation_response(
        file_name=str(resume_path),
        resume_data=resume,
        github_data=github,
        evaluation=evaluation,
    )

    # Append to CSV (creates header on first run)

    csv_path = "resume_evaluations.csv"
    file_exists = os.path.exists(csv_path)

    with open(csv_path, "a", newline="", encoding="utf-8") as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=list(csv_row.keys()))
        if not file_exists:
            writer.writeheader()
        writer.writerow(csv_row)

    print(f"\n✅ Evaluation exported to {csv_path}")

# Example usage

if __name__ == "__main__":
    export_to_csv(Path("sample_resume.json"))

```

Running this script evaluates the supplied resume, prints a human-readable summary to the console, and appends a line to `resume_evaluations.csv` containing every column produced by `transform_evaluation_response`.

## Key Source Files for CSV Export

The following files handle the export evaluation results to CSV functionality:

- **[`main/score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/score.py)** – Orchestrates evaluation, prints results, and writes CSV rows using `csv.DictWriter`.
- **[`main/transform.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/transform.py)** – Contains `transform_evaluation_response` which converts the rich `EvaluationData` object into a flat CSV-compatible dictionary.
- **[`main/models.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/models.py)** – Defines the `EvaluationData` Pydantic model used throughout the export process.
- **[`main/evaluator.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/evaluator.py)** – Calls the LLM and parses JSON output into `EvaluationData`.
- **[`main/github.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/github.py)** – Fetches public GitHub profile data for inclusion in the CSV export.

## Summary

- **`transform_evaluation_response`** in [`main/transform.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/transform.py) (lines 511‑741) flattens complex evaluation objects into dictionary rows suitable for CSV export.
- **[`score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/score.py)** (lines 342‑354) handles file I/O, automatically creating headers on first write and appending subsequent evaluations to `resume_evaluations.csv`.
- The export uses Python's standard `csv` module with UTF-8 encoding, ensuring compatibility with Excel, Google Sheets, and data pipelines.
- Each evaluation run adds one row to the cumulative CSV file, making it easy to track multiple candidates over time.

## Frequently Asked Questions

### What columns are included in the exported CSV?

The CSV includes fields extracted by `transform_evaluation_response` such as `file_name`, `name`, `total_work_experience`, four score categories (technical skills, experience, education, and soft skills), bonus points, deductions, key strengths, and other metadata from the resume and GitHub profile. The exact columns depend on the fields present in the `EvaluationData` model and the input resume data.

### Can I customize the CSV filename?

Yes. While the default implementation in [`main/score.py`](https://github.com/interviewstreet/hiring-agent/blob/main/main/score.py) uses `resume_evaluations.csv`, you can modify the `csv_path` variable in your own scripts or fork the repository to accept a filename parameter. The `export_to_csv` example above can be modified to accept a custom path argument instead of hardcoding the filename.

### How does the system handle multiple candidate evaluations?

The CSV writer uses append mode (`"a"`) and checks `os.path.exists()` to determine if it should write the header. This means you can run the evaluation multiple times across different candidate files, and each evaluation will add a new row to the same CSV file without duplicating headers or overwriting existing data.

### Is the CSV export compatible with Excel and Google Sheets?

Yes. The export uses UTF-8 encoding and the standard comma-separated format via Python's `csv` module. The file opens correctly in Microsoft Excel, Google Sheets, LibreOffice Calc, and can be imported into pandas DataFrames using `pd.read_csv()` without additional encoding parameters.