> ## Documentation Index
> Fetch the complete documentation index at: https://docs.validio.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Export Metrics to CSV

> Fetch and export validator metrics to CSV one day at a time using the Validio SDK, handling API response limits.

## Overview

Fetch the metrics of a validator segment for the last 7 days, one day at a time, and write them to a CSV file. Fetching one day at a time accounts for the API response limit, which returns a maximum of 3000 results per request. When a time range holds more results, only the most recent 3000 are returned. Results older than the [metric retention period](https://docs.validio.io/v10.2/docs/segmentation/metric-retention.md) are not returned.

To fetch metrics for all segments of a validator, first call [`segments`](https://docs.validio.io/api-reference/graphql/queries/segments), which returns a list of all segments.

## Steps

**1. Construct the query**

Select the values of interest for each metric type. If you know which threshold the validator uses, you only need that fragment.

**2. Create a CSV writer**

Create a CSV writer. For a specific validator, where the keys are known and a single threshold is used, a [`DictWriter`](https://docs.python.org/3/library/csv.html#csv.DictWriter) is a better fit, because you don't have to keep track of the columns.

**3. Iterate over each day**

For each day, execute the query and pass the validator ID, the segment ID, and the time range.

**4. Write the result**

For each day's response, iterate over the values and write them to the CSV file. The first value's keys become the header row.

## Full code sample

```python title="Python" theme={null}
import csv
import os
from datetime import datetime, timedelta
from pathlib import Path

from validio_sdk.client import Client


async def example(
    validator_id: str = os.environ["EXAMPLE_VALIDATOR_ID"],
    segment_id: str = os.environ["EXAMPLE_SEGMENT_ID"],
):
    client = Client()
    query = """
    query ValidatorSegmentMetrics($input: ValidatorSegmentMetricsInput!) {
        validatorSegmentMetrics(input: $input) {
            ... on ValidatorMetricWithDifferenceThresholdHistory {
                values {
                    startTime
                    endTime
                    isIncident
                    diffUpperBound: upperBound
                    diffLowerBound: lowerBound
                    value
                }
            }
            ... on ValidatorMetricWithDynamicThresholdHistory {
                values {
                    startTime
                    endTime
                    isIncident
                    decisionBoundsType
                    upperBound
                    lowerBound
                    value
                }
            }
            ... on ValidatorMetricWithFixedThresholdHistory {
                values {
                    startTime
                    endTime
                    isIncident
                    operator
                    bound
                    value
                }
            }
        }
    }
    """

    with Path("metrics.csv").open("w", encoding="utf-8") as csv_file:
        writer = csv.writer(csv_file)
        result_keys = []

        # Fetch metrics for the last 7 days, one day at a time to account for
        # response limits.
        for days_ago in range(7, 0, -1):
            start = datetime.now() - timedelta(days=days_ago)
            end = datetime.now() - timedelta(days=days_ago - 1)

            result = await client.execute(
                query,
                variable_values={
                    "input": {
                        "validatorId": validator_id,
                        "segmentId": segment_id,
                        "timeRange": {
                            "start": start.isoformat(),
                            "end": end.isoformat(),
                        },
                    },
                },
            )

            print(f"Fetching metrics between {start.isoformat()} and {end.isoformat()}")

            for data in result["validatorSegmentMetrics"]["values"]:
                # If we haven't seen any result yet, we don't know which fields
                # the result will have. Grab them and write the header for the
                # CSV file.
                if not result_keys:
                    result_keys = data.keys()
                    writer.writerow(result_keys)

                csv_row = data.values()
                writer.writerow(csv_row)
```

## Example response

```json title="JSON" theme={null}
{
  "validatorSegmentMetrics": {
    "values": [
      {
        "startTime": "2024-01-01T12:00:00Z",
        "endTime": "2024-01-02T12:00:00Z",
        "isIncident": true,
        "decisionBoundsType": "UPPER_AND_LOWER",
        "upperBound": 80.0,
        "lowerBound": 60.5,
        "value": 99.9
      }
    ]
  }
}
```
