# Metric Job Management

!!! note
    **Performance Tuning**: You can improve evaluation speed by passing `RunConfig(parallelism=...)` in `config=...`. Adjust parallelism based on your model capacity and rate limits.

## Submit a Job

Submit a metric evaluation with the Evaluator plugin SDK. The `submit` method returns an `EvaluatorJobResource` that you can use to monitor the job and download results.

{% raw %}
```python
import os

from nemo_evaluator.sdk import Evaluator
from nemo_platform import NeMoPlatform
from nemo_evaluator_sdk import RunConfig
from nemo_evaluator_sdk import ExactMatchMetric

sdk = NeMoPlatform(
    base_url=os.environ.get("NMP_BASE_URL", "http://localhost:8080"),
    workspace="default",
)
evaluator: Evaluator = sdk.evaluator  # this object is an Evaluator resource

metric = ExactMatchMetric(reference="{{item.expected}}", candidate="{{item.output}}")

job = evaluator.submit(
    metric=metric,
    dataset=[
        {"expected": "Paris", "output": "Paris"},
        {"expected": "Berlin", "output": "Munich"},
    ],
    config=RunConfig(parallelism=4),
)
print("Submitted job:", job.name)

job.wait_until_done()
result = job.get_result()
```
{% endraw %}

## Monitor Job

Monitor job status with the returned job resource. Use `wait_until_done()` when you want the SDK to poll until the job reaches a terminal state.

```python
job_status = job.get_job_status()
print("status:", job_status.status, job_status.status_details)

if not job.check_if_complete():
    job.wait_until_done()
```

`wait_until_done()` raises if the job reaches a terminal failure status or times out.

Refer to [Evaluator Troubleshooting](../../troubleshooting/evaluator.md) for help troubleshooting job failures.

## Reconnect to a Job

If you already know a job name, get a job resource for it and continue monitoring.

```python
job = evaluator.get_job_resource("my-job-name")
job.wait_until_done()
```

## View Evaluation Results

Evaluation results are available after the evaluation job successfully completes. Use `get_result()` to retrieve aggregate scores and row-level scores as an `EvaluationResult`.

```python
result = job.get_result()

for score in result.aggregate_scores.scores:
    print(f"{score.name}: mean={score.mean}")

for row in result.row_scores:
    print(row.item, row.metrics)
```

See [Evaluation Results](results.md) for details on aggregate and row-level result fields.

## Download Job Artifacts

Download the full artifacts directory when you need the raw files generated during job execution. The `path`
argument sets the base output directory; artifacts are extracted under a job-specific subdirectory.

```python
job.wait_until_done()
artifacts_dir = job.download_artifacts(path="evaluation_artifacts")
print(f"Saved artifacts under {artifacts_dir}")
```
