HTTP API¶
The CAS service is a FastAPI application. A running instance serves an
interactive OpenAPI UI at /docs and the raw schema at /openapi.json —
both are generated from the same typed Pydantic models documented here, so they
are always in sync with the deployed version.
pip install "community-attribute-service[api,stac]"
uvicorn cas.api.app:create_app --factory --reload
Endpoints¶
| Method | Path | Purpose |
|---|---|---|
POST |
/api/v1/extract |
Extract attributes for one geometry |
POST |
/api/v1/extract/batch |
Extract attributes for many geometries |
GET |
/api/v1/datasets |
List available datasets (paginated) |
GET |
/api/v1/providers |
List registered providers (paginated) |
GET |
/api/v1/providers/{slug} |
One provider with full dataset metadata |
GET |
/health |
Liveness check + result-cache stats |
GET |
/metrics |
Prometheus metrics exposition |
GET |
/docs |
Interactive OpenAPI (Swagger) UI |
Extract¶
curl -s localhost:8000/api/v1/extract \
-H 'content-type: application/json' -d '{
"geometry": {
"type": "Polygon",
"coordinates": [[[-96.6,39],[-96.5,39],[-96.5,39.1],[-96.6,39.1],[-96.6,39]]]
},
"dataset_ids": ["isric_soilgrids:clay_0-5cm"],
"aggregation": "mean"
}'
Response (AttributeResponse):
{
"request_id": "…",
"geometry_hash": "…",
"results": [
{
"dataset_id": "isric_soilgrids:clay_0-5cm",
"variable": "clay_0-5cm",
"value": 23.4,
"units": "g/kg",
"aggregation": "mean",
"quality": "good",
"coverage_fraction": 1.0,
"pixel_count": 42,
"provider": "isric_soilgrids",
"elapsed_ms": 318,
"provenance": "…"
}
],
"warnings": [],
"elapsed_ms": 320
}
Catalog discovery¶
List every provider, then drill into one for its datasets, resolution, bbox, license, citation, and variables:
curl -s 'localhost:8000/api/v1/providers?limit=1000'
curl -s localhost:8000/api/v1/providers/copernicus_dem
/datasets and /providers accept limit (1–1000, default 100) and offset
and return {total, limit, offset, count, …}. Catalog responses are served from
an in-memory metadata cache (TTL CAS_METADATA_CACHE_TTL_S).
Conventions¶
- Every response carries an
X-Request-IDheader. - Errors use a consistent envelope:
Common type values: validation_error, request_limit, unauthorized,
rate_limited, not_found.
Configuration¶
All runtime config is read from CAS_-prefixed environment variables.
Hardening features are off by default, so the same image runs internal or
public depending only on env.
| Variable | Default | Purpose |
|---|---|---|
CAS_PROVIDER_TIMEOUT_S |
30 |
Per-provider extraction deadline |
CAS_REQUEST_TIMEOUT_S |
120 |
Whole-request backstop deadline |
CAS_MAX_DATASETS_PER_REQUEST |
50 |
Reject oversized requests (422) |
CAS_MAX_POLYGON_VERTICES |
10000 |
Reject overly complex geometries (422) |
CAS_METADATA_CACHE_TTL_S |
3600 |
Catalog cache TTL |
CAS_CORS_ORIGINS |
* |
Allowed origins (CSV or JSON) |
CAS_AUTH_ENABLED / CAS_API_KEYS |
false / — |
Require X-API-Key from an allowlist |
CAS_RATE_LIMIT_ENABLED / CAS_RATE_LIMIT_PER_MINUTE |
false / 60 |
Per-caller fixed-window rate limit |
Deployment (Docker)¶
docker build -t cas-api .
docker run -p 8000:8000 \
-e CAS_AUTH_ENABLED=true -e CAS_API_KEYS=key1,key2 \
-e CAS_RATE_LIMIT_ENABLED=true \
cas-api
The rate limiter is in-memory and per-process; for multi-replica deployments, enforce limits at the ingress/gateway instead.