# Python API

Import `Assessor` from `fair_offline_assessor`. Choose an assessor once, then call
`assess()` for each dataset.

## Select an assessor

`Assessor(name, version=...)` chooses an assessor and a version included in the
installed library.

**`name`** — `str`

Assessor name: `FUJI` or `FAIR_CHAMPION`. Uppercase and lowercase are accepted.

**`version`** — `str | None`

The version to use. This determines how the assessor maps metadata fields and
which checks and scoring rules it applies. If omitted, the library uses its
default: `3.5.1` for F-UJI, or `0.5.12` for Champion's FAIR Core Tests.
An existing `Assessor` keeps its selected version across calls.

An unknown name or unavailable version raises `ProfileError` before the assessment
starts. Its `code` explains which selection failed.

**Use the default version**

```python
from fair_offline_assessor import Assessor

assessor = Assessor("FUJI")
```

**Choose a specific version**

```python
assessor = Assessor("FUJI", version="3.5.1")
```

## Assess a dataset

`assessor.assess(...)` runs the checks and returns an
[`AssessmentResult`](/local-offline-assessor-for-fair-loaf/results). Pass arguments by name, as in the example.

**`metadata`** — `dict | list[dict] | str`

The metadata to check. Supply a Python dictionary, a list of dictionaries, or
the text of a document. The supported formats depend on the assessor; see
[F-UJI metadata](/local-offline-assessor-for-fair-loaf/assessors/fuji#metadata) or [Champion metadata](/local-offline-assessor-for-fair-loaf/assessors/champion#metadata).

**`metadata_format`** — `str | None`

The format of the supplied metadata. F-UJI defaults to `json-ld`; other options
include `datacite-json`, `xml`, `html`, `turtle` and `rdfxml`. Pass the document's
contents in `metadata`; the library does not open file paths or URLs for you.
Champion accepts only the default JSON-LD format or explicit `json-ld`.

**`subject`** — `str | None`

For F-UJI with JSON-LD or other RDF formats, the identifier of the dataset you
expect it to assess. This verifies F-UJI's choice; it does not change the choice.
If the choice cannot be confirmed, affected checks return `indeterminate` with
`subject_not_selected`. Omit this argument for XML, DataCite JSON and HTML.

For Champion, selects the entire RDF graph containing that node's outgoing
statements. It does not set the identifier being assessed. See
[Champion graph selection](/local-offline-assessor-for-fair-loaf/assessors/champion#metadata).

**`metadata_url`** — `str | None`

The metadata document's original URL or identifier. In JSON-LD it provides the
base for relative identifiers. F-UJI also uses it for identifier and protocol
checks. Champion uses it as the metadata origin when checking outward links;
its assessment target is separate. The library never opens this URL.

**`target_identifier`** — `str | None`

For Champion, the identifier being assessed, such as `10.1234/example`.
It is not inferred from `@id`, `subject` or `metadata_url`. Missing or invalid
targets leave dependent checks `indeterminate`; graph-only checks can still run.
Omit this argument for F-UJI.

**`local_contexts`** — `dict[str, dict] | None`

JSON-LD context documents: definitions of what field names mean. Dictionary keys
are context URLs; values are the corresponding documents, each containing
`@context`. The bundled Schema.org context works for both assessors. Other remote
contexts must be supplied locally; they are never downloaded. See
[contexts](/local-offline-assessor-for-fair-loaf/assessors/fuji#contexts) for the argument format.

Use `model_dump()` to get a dictionary or `model_dump_json()` to get a JSON string.

**Assess metadata**

```python
from fair_offline_assessor import Assessor

result = Assessor("FUJI", version="3.5.1").assess(
    metadata={
        "@context": "https://schema.org",
        "@type": "Dataset",
        "@id": "https://example.org/datasets/1",
        "name": "Example dataset",
        "license": "https://creativecommons.org/licenses/by/4.0/",
    }
)

print(result.coverage.model_dump_json(indent=2))
```

**How many checks could run**

```json
{
  "evaluated": 15,
  "indeterminate": 16,
  "errors": 0,
  "not_applicable": 0,
  "total": 31
}
```

**Save the result**

```python
from pathlib import Path

Path("assessment.json").write_text(
    result.model_dump_json(indent=2),
    encoding="utf-8",
)
```

## Problems with metadata

`result.diagnostics` contains messages about invalid or unsupported metadata.
Checks that cannot use that information remain `indeterminate`; other checks
can still run. A missing field can cause a failure or an indeterminate result,
depending on what the check requires.

Read each check's `reason_code` and `message` alongside the diagnostics.
[F-UJI troubleshooting](/local-offline-assessor-for-fair-loaf/assessors/fuji#troubleshooting) lists common problems and fixes.
For Champion, see [input problems](/local-offline-assessor-for-fair-loaf/assessors/champion#input-problems).

## Select by profile

A profile is the stored configuration selecting an assessor's code and resources.
The lower-level API accepts an exact `id@version` and either a dictionary or a
typed input. It uses the same checks as `Assessor`:

```python
from fair_offline_assessor import ChampionInput, assess, list_profiles

result = assess(
    ChampionInput(metadata={}, target_identifier="10.1234/example"),
    profile="fair-champion-offline@0.5.12",
)
print([f"{profile.id}@{profile.version}" for profile in list_profiles()])
```

F-UJI uses `AssessmentInput` and `fusji-offline@3.5.1`.
