Metadata-Version: 2.5
Name: rashid
Version: 0.3.0
Summary: Validator and linter for Portolan catalogs
Project-URL: Homepage, https://github.com/portolan-sdi/rashid
Author: Portolan contributors
License-Expression: Apache-2.0
License-File: LICENSE
Requires-Python: >=3.10
Requires-Dist: click>=8.4
Requires-Dist: jsonschema-rs>=0.58
Requires-Dist: jsonschema-specifications>=2023.3.6
Requires-Dist: jsonschema>=4.26
Requires-Dist: pyarrow>=21
Requires-Dist: pyproj>=3.7.1
Requires-Dist: rasterio>=1.4.4
Requires-Dist: referencing>=0.30
Requires-Dist: rio-cogeo>=6
Requires-Dist: shapely>=2.1
Provides-Extra: data
Description-Content-Type: text/markdown

# rashid

[![PyPI](https://img.shields.io/pypi/v/rashid.svg)](https://pypi.org/project/rashid/)
[![Python versions](https://img.shields.io/pypi/pyversions/rashid.svg)](https://pypi.org/project/rashid/)
[![CI](https://github.com/portolan-sdi/rashid/actions/workflows/ci.yml/badge.svg)](https://github.com/portolan-sdi/rashid/actions/workflows/ci.yml)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)

rashid checks whether a [Portolan](https://www.portolan-sdi.org/) catalog follows the specification.

Give it a catalog directory, its root `catalog.json`, or the URL of a published catalog. rashid checks the metadata, structure, asset bytes, and hosting. It reports each problem with a stable rule ID.

The name comes from the Arabic root ر ش د. Its participles رَاشِدٌ and رَشِيدٌ mean ["taking, or following, a right way or course or direction"](https://arabiclexicon.hawramani.com/?p=5472#205af1).

## Install

```bash
uv tool install rashid
```

rashid requires Python 3.10 or later.

## Check a Catalog

```bash
rashid check path/to/catalog
```

Exit code `0` means the catalog breaks no MUST requirement. Exit code `1` means it breaks at least one.

By default, rashid checks:

- Portolan metadata requirements.
- STAC 1.1.0 core structure with schemas included in the package.
- Local and remote asset bytes against their metadata and format rules.

Use `--no-data` when you only need a metadata and structure result. Use `--data-scope local` to keep byte checks inside the catalog directory.

```bash
rashid check path/to/catalog --data-scope local
```

## Check a published catalog

Give `rashid check` the URL of the root `catalog.json`, or of the directory that holds it.

```bash
rashid check https://data.example.org/my-catalog/catalog.json
```

rashid fetches the root catalog and follows its `child`, `item`, and JSON `alternate` links. It fetches `AGENTS.md` and `README.md` beside each catalog and collection. It then runs the same passes as for a directory. The URL is the publish base, so the hosting checks run by default: HTTP range support and CORS on the assets, and one HEAD for each link target that the crawl did not fetch. A `child` or `item` link that answers `404` on the host is a `PTL-LIV-006` error. A root `self` link that points to a different location is a `PTL-LIV-007` warning.

A crawl reads only the documents that links point to. rashid reports this limit once as `PTL-GEN-002`. The checks that depend on a full directory listing do not run: `PTL-LNK-002`, for an object without an inbound link, and `PTL-COL-005`, for scene files beside a collection. Sync the tree to disk and check the directory for the full view.

Use `--live` to run the hosting checks on a directory. rashid reads the publish base from the root catalog's absolute `self` link. When the root has no `self` link, pass `--live-base-url`.

```bash
rashid check path/to/catalog --live
rashid check path/to/catalog --live --live-base-url https://data.example.org/my-catalog/
```

Use `--json` for a machine-readable report.

## Read the Report

Each finding contains a rule ID, severity, message, and file path. MUST requirements produce errors, and SHOULD requirements produce warnings.

A catalog can produce thousands of similar findings. After 50 findings, rashid groups results by rule and shows representative examples.

Use `--all` to list every finding. Use `--summary` to group any report by rule. JSON output always contains the complete `findings` array and a `summary.by_rule` object.

## Choose Additional Checks

rashid provides six separate validation passes:

- **Metadata** checks Portolan requirements in catalog JSON.
- **Structural** checks STAC 1.1.0 core structure offline.
- **Extension** checks each object against the schemas of the STAC extensions it declares, offline.
- **Schema** checks each object against the packaged Portolan profile schema.
- **Data** reads asset bytes and verifies checksums, sizes, formats, and extents.
- **Live hosting** checks HTTP range support and CORS on remote servers.

Metadata, structural, extension, and data checks run by default. The live hosting pass also runs by default for a catalog URL. Use `--schema` as a cross-check against the published profile schema. Use `--live` to run the hosting checks on a directory.

The extension pass uses the versions that the profile's extension registry pins. rashid packages those schemas, so a catalog at the pinned versions needs no network. A catalog that declares an older version of a registered extension is checked against that version's schema, which rashid fetches over https. rashid reports an extension outside the registry as an info finding rather than validating it. Use `--schema-allow-network` to fetch and check such a schema.

If a pass cannot run, rashid reports a warning. It does not treat the skipped pass as successful.

For transfer details and every rule ID, see [the rule reference](docs/rules.md).

## Use rashid from Python

```python
from rashid import validate

report = validate("path/to/catalog")
published = validate("https://data.example.org/my-catalog/catalog.json")

for finding in report.errors:
    print(finding.message)
```

`validate()` uses the same default passes as the command-line interface. Set `schema=True` or `live=True` to add those passes. For a URL, `live` is on unless you pass `live=False`. Set `extensions=False` to skip the extension pass.

Use `RulesConfig` to disable rules or change their severity.

```python
from rashid import RulesConfig, Severity, validate

config = RulesConfig(
    disabled=frozenset({"PTL-VIZ-004"}),
    severity_overrides={"PTL-TTL-002": Severity.ERROR},
)

report = validate("path/to/catalog", config=config)
```

The public `rashid.api` module also provides helpers for tools that repair catalogs. Names from this module remain available across 0.x releases. Other internal modules can change in a patch release.

## Documentation

- [Rule reference](docs/rules.md) describes every validation pass, rule group, and degraded-pass code.
- [Contributing guide](docs/contributing.md) covers development setup, tests, and repository checks.
- [Portolan specification](https://github.com/portolan-sdi/portolan-spec) defines the requirements that rashid implements.

## License

rashid is available under the [Apache License 2.0](LICENSE).
