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

# Accessing log attachments in Python scorers

export const plans_0 = "Any"

export const deployments_0 = "Any"

export const data_plane_version_0 = undefined

export const use_case_0 = undefined

<Note>
  **Applies to:**

  * Plan - {plans_0}
  * Deployment - {deployments_0}
  * {data_plane_version_0}
  * {use_case_0}
</Note>

## Summary

**Goal:** Access log attachment data within Python custom scorers using the ReadonlyAttachment class.

**Features:** Custom scorers, ReadonlyAttachment class, attachment data retrieval methods.

## Configuration Steps

### Step 1: Import ReadonlyAttachment

Import the ReadonlyAttachment class from the Braintrust logger module.

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
from braintrust.logger import ReadonlyAttachment

```

### Step 2: Access attachment in scorer

Attachment objects in scorer parameters contain metadata only; use ReadonlyAttachment methods to retrieve actual data.

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
def score_image_response(input: Any, output: str) -> dict:
    """
    Scorer that accesses an image attachment and returns metadata.
    """
    image_attachment = input.get("image")

    if image_attachment is None:
        return {"score": 0.0, "metadata": {"error": "No image attachment found"}}

    # Handle both hydrated ReadonlyAttachment and raw reference dicts
    if isinstance(image_attachment, dict):
        if image_attachment.get("type") in ("braintrust_attachment", "external_attachment"):
            image_attachment = ReadonlyAttachment(image_attachment)
        else:
            return {"score": 0.0, "metadata": {"error": "Invalid attachment format"}}

    try:
        # Download the image bytes
        image_bytes = image_attachment.data

        # Access attachment metadata
        content_type = image_attachment.reference.get("content_type", "unknown")
        filename = image_attachment.reference.get("filename", "unknown")

        # Your scoring logic here - this is just an example
        # You could use PIL, cv2, or other libraries to analyze the image
        has_content = len(image_bytes) > 0

        return {
            "score": 1.0 if has_content else 0.0,
            "metadata": {
                "file_size": len(image_bytes),
                "content_type": content_type,
                "filename": filename,
            }
        }
    except Exception as e:
        return {"score": 0.0, "metadata": {"error": str(e)}}

```

## Step 3: Test

![](https://assets.usepylon.com/f9e0f7c8-a513-475d-93fb-43d7cd5de18e%2F1770053626728-Screenshot2026-02-02at11.33.42AM.png?Expires=253370764800\&Signature=MJztUR~j-5Lc4SjB~t1szHxEksiHikEA4sC8ViSxMooCEngLk--rxyOe1Qe6n-UZs3WOrHFWAf8e1rw3yT22oxo8ibllC1~Gy4xsvTg3rTKERizNs6q1WOZBGGG~7sYPyxB1IF0AoYqREXntLLfQ2wRq8fECFcGhYph-2XDoJNjl8kgGij~g6Qen4C~-g1cc7qFEuhNr788rhHo4~E3P1lpU6aj2s3uh87415J76Z3bPs9j8r5EwmVzb6OqCS9KHz67nhzFYUVu1BGBT465WV~mTUP3Xiu3azAJPxlGYwmhlvLQwpfZNudbiYicGrMQiSik2lTKIo8p42JoZ7HGckg__\&Key-Pair-Id=K3NV4LZ47N8M46)
