# Polars functions that answer questions about text

A Polars frame goes in. Read the frame with its new columns from `Call.value`.

## Install

| Channel |
| --- |
| `pip install thinkthen[polars]` |

Set `THINKTHEN_API_KEY` in the environment.

## A first call

*form.json, a file the sample reads*

```
{
  "version": 1,
  "questions": {
    "steps": {
      "decide": "Does the report give steps to reproduce?"
    },
    "area": {
      "choose": "Which part of the app is this?",
      "options": [
        "export",
        "login",
        "billing"
      ]
    },
    "impact": {
      "score": "How much does this block the user?",
      "levels": [
        "None.",
        "Slows them.",
        "Blocks work."
      ]
    }
  }
}
```

```
import polars as pl
import thinkthen as tt

reports = pl.DataFrame({
    "body": [
        (
            "CSV export fails every time. "
            "Steps: open a report,\n"
            "click Export, pick CSV. "
            "My month-end numbers are stuck.\n"
        ),
        (
            "Steps: open the login page, enter a password, "
            "press Enter. The page spins and "
            "nobody can sign in."
        ),
        (
            "The Pay button on the billing page "
            "is a slightly "
            "different blue. No steps, I just noticed it."
        ),
    ],
})
triage = tt.annotate("form.json", reports, on="body").value
assert triage.select("steps", "area", "impact").rows() == [
    (True, "export", 1.99),
    (True, "login", 2.0),
    (False, "billing", 0.01),
]
assert triage["failed"].to_list() == [None, None, None]
```

Not sure comes back as `None`. Branch on it and send those cases to a person. Each [function page](/functions/) shows its Polars call.

## Run facts

`Call.facts` counts the whole frame call. The new columns hold only the answers.

## Errors

Every failure raises a `ThinkThenError`, as in Python. A failed row in a column call ends the call with `BackendError`.

## Settings and recording

`tt.Engine` takes each setting as a keyword, as in Python. `record=` writes a recording to a folder. `replay=` answers from that recording with no connection. The [Settings](/install/settings/) page lists every setting.

## Backends

Polars runs on the Python engine, so it reaches each backend the same way. The [Python page](/install/python/#backends) shows Jev, Liquid d1 and Ollama.

## What is different in Polars

- `decide`, `choose`, `score`, and `tag` send a whole column to the engine in one call.
- `on=` names the column the questions read.

On GitHub: [github.com/botassembly/thinkthen](https://github.com/botassembly/thinkthen)
