Skip to main content

DaFab Client

The Python client for the DaFab catalogue.

DaFab processes Copernicus Sentinel-2 imagery into AI-generated water-analysis and field-delineation products on European HPC systems, and publishes the images and the products as STAC items in a Rucio catalogue hosted at CERN. This client reads that catalogue, searches it with typed metadata filters, follows the lineage between a product and the image it was derived from, and downloads assets. It works out of the box with a shared read profile, no configuration needed.

You can also browse the same catalogue without code, on the discovery site or through its STAC root.

Install

pip install dafab-client

Python 3.10 or newer. The client talks to dafab.cern.ch over HTTPS and downloads assets from the project's object store. For the notebook, install the notebooks extra described below.

First call

import dafab_client as dc

dc.ping()    # the server version
dc.whoami()  # the shared read profile, account user_dafab

The package ships the profile user_dafab, meant for reading the public catalogue, together with the TLS trust bundle it uses. Publication needs a personal account, see Publishing below.

What the catalogue holds

DaFab's images and products live in the scope dafab as STAC 1.1 items, each stored as a Rucio container that carries its full JSON document.

Collection Content Example item
sentinel_2_l2a Sentinel-2 L2A source images and their previews S2A_MSIL2A_20160229T032652_N0500_R018_T48QUH_20231011T191655
water_analysis water maps, excess and deficit polygons, previews the image id followed by _water_analysis_300
smart_agriculture field boundaries and previews the image id followed by _smart_agriculture_300

A product carries a derived_from link to its source image, and the catalogue attaches each product below its source image and its facet catalogue, so lineage can be followed both ways. Facet catalogues such as agriculture_season, water_anomaly and water_basin group products by season, by flood, drought or normal conditions, and by river basin.

Reference collections from other providers live in their own scopes beside dafab, one collection each. Their documents keep the metadata and the links of their providers.

Scope Collection Content
hand glo-30-hand Height Above Nearest Drainage, 1 degree tiles at 30 m
worldcover esa-worldcover-map-10m-2021-v2 ESA WorldCover 2021 land cover, 3 degree tiles at 10 m
gfm GFM reference water masks of the Copernicus Global Flood Monitoring
fiboa fiboa open field boundary datasets published by fiboa

The helpers read the scope dafab unless you pass scope=. The STAC root covers dafab, and the discovery site shows all five scopes.

dc.list_stac_scopes()                       # prints the scopes visible to the profile
dc.get_catalogs_and_collections()           # collections and facet catalogues of dafab, as {"scope", "id"} rows
dc.get_catalogs_and_collections(scope="hand")                    # [{"scope": "hand", "id": "glo-30-hand"}]
dc.get_items(filters={"name": "S2A_MSIL2A_20160229T032652_N0500_R018_T48QUH*"}, long=False)   # one tile and date, the image and its two products
dc.get_items_by_bbox(-17.5, 15.2, -17.4, 15.3, scope="hand")     # the HAND tile under a small box

get_items returns every item of the scope without a filter, which in dafab is more than 17,000 ids and takes about 20 seconds, since the server answers in pages of 100. Narrow it with name patterns (* or % match any sequence) or use the searches below.

Searches are JSON filters made of comparison nodes, each with a path into the document, a comparator, a value and a valueType, combined by logical nodes with and, or and not. The server evaluates any path of the stored documents, and the paths that the catalogue declares, such as collection, properties.datetime and properties.eo:cloud_cover, have indexes and answer fastest.

clear_images_2016 = {
    "type": "logical", "combinator": "and", "filters": [
        {"type": "comparison", "comparator": "equals", "path": ["collection"], "value": "sentinel_2_l2a", "valueType": "string"},
        {"type": "comparison", "comparator": "lessThanOrEqual", "path": ["properties", "eo:cloud_cover"], "value": 20, "valueType": "number"},
        {"type": "comparison", "comparator": "greaterThanOrEqual", "path": ["properties", "datetime"], "value": "2016-01-01T00:00:00Z", "valueType": "date"},
        {"type": "comparison", "comparator": "lessThan", "path": ["properties", "datetime"], "value": "2017-01-01T00:00:00Z", "valueType": "date"},
    ],
}
ids = dc.get_items_by_enhanced_filter(clear_images_2016, return_mode="ids")
items = dc.get_items_by_enhanced_filter(clear_images_2016, return_mode="metadata")   # full documents

A group marked "inherited": true is evaluated against the ancestors of each candidate, so a search can select products by properties of their source image. This finds field-delineation products whose source image had at most 20 percent cloud cover.

fields_from_clear_images = {
    "type": "logical", "combinator": "and", "filters": [
        {"type": "comparison", "comparator": "equals", "path": ["collection"], "value": "smart_agriculture", "valueType": "string"},
        {"type": "logical", "combinator": "and", "inherited": True, "filters": [
            {"type": "comparison", "comparator": "equals", "path": ["collection"], "value": "sentinel_2_l2a", "valueType": "string"},
            {"type": "comparison", "comparator": "lessThanOrEqual", "path": ["properties", "eo:cloud_cover"], "value": 20, "valueType": "number"},
        ]},
    ],
}
product_ids = dc.get_items_by_enhanced_filter(fields_from_clear_images)
Comparators Meaning
equals, notEquals equality, or inequality
lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual ordered comparison of numbers, dates or strings
in the value is one of a list
like, notLike text pattern, * or % for any sequence and ? for one character
contains, containsAny, containsAll array membership
isNull, isNotNull, isEmpty, isNotEmpty null and empty-array checks, written without a value member

Value types are string, number, integer, boolean, date and array. A document that lacks the field matches neither a typed comparison nor its negation, nor isNull or isNotNull, so incomplete metadata is left out rather than silently included.

Three helpers build the common spatial and temporal searches for you, and return ids or full documents with return_mode. A time range matches an item whose properties.datetime falls in it, or whose start_datetime to end_datetime span overlaps it, such as a HAND tile, as the discovery site does.

dc.get_items_by_timerange("2016-02-01T00:00:00Z", "2016-03-01T00:00:00Z")
dc.get_items_by_bbox(103.5, 19.8, 104.2, 20.8)                    # west, south, east, north
dc.get_items_by_bbox_and_timerange([103.5, 19.8, 104.2, 20.8], ["2016-02-01T00:00:00Z", "2016-03-01T00:00:00Z"])

Lineage and facets have their own helpers.

image = "S2A_MSIL2A_20160229T032652_N0500_R018_T48QUH_20231011T191655"
product = image + "_smart_agriculture_300"

dc.get_source_original_item_ids_from_derived_item(product)      # the image the product came from
dc.get_related_item_ids_from_original_item(image)                # every product of the image
dc.get_sibling_derived_item_ids(image, collection_id="smart_agriculture")
dc.get_item_ids_by_top_facet_catalog("water_basin")              # products placed under any river basin
dc.get_item_ids_by_facet_value_catalog("water_basin_mekong")     # products in one basin
dc.get_item_facet_placements(product, collection_id="smart_agriculture")

Project members find the full reference of comparators, types, null handling, sorting and paging in the repository's docs/enhanced-filtering.md.

Read metadata

document = dc.get_bulk_metadata(product)                          # the whole STAC item
subset = dc.get_bulk_metadata(product, paths=["/collection", "/properties/datetime", "/assets"])
dc.extract_metadata_value("/properties/datetime", pname=image)     # one value by JSON pointer, as text
report = dc.list_item_asset_entries(product, check_storage=True)  # every asset and whether its file is in storage

dc.as_json(document) formats any of these for display.

Download assets

dc.download_item_asset(product, "dafab-field-boundaries-thumbnail", destination_dir="downloads")
href = dc.build_stable_asset_href(image, "TCI_20m")               # the permanent URL of an asset
dc.download_asset_from_stable_href(href, destination_dir="downloads")
dc.download_all_derived_item_assets(product, destination_dir="downloads", overwrite=True)   # the thumbnail above again, with the other assets

Downloads go to destination_dir, the current directory by default, and refuse to replace an existing file unless overwrite=True. Where a local copy of the storage is mounted, download_item_asset uses it and reports mode == "local_posix".

dc.get_map(items, output_path="map.html") renders the footprints of a list of documents to an interactive HTML map.

Notebook

The packaged notebook walks through most of the above against the live catalogue, the reference collections included, and runs unchanged with the shared profile. It takes about three minutes, and its download cells write about 175 MB under demo-data/ in the current directory.

pip install "dafab-client[notebooks]"
python -c "import dafab_client as dc; print(dc.get_example('user'))"
jupyter notebook dafab_simple_user_workflows.ipynb

Validate a document

The validators check an item against the schemas shipped with the client, either a local file or the stored copy on the server, without changing anything.

dc.validate_original_item(source="server", expected_item_id=image, expected_collection_id="sentinel_2_l2a")
dc.validate_derived_item(source="local", item_path="my_product.json")   # a product document of your own

Configuration

Nothing is required for reading. These variables change the defaults.

Variable Effect
DAFAB_PROFILE the account whose profile to load, default user_dafab
DAFAB_PROFILE_PATH an explicit profile file
DAFAB_PROFILE_DIR the directory holding <account>/config, default ~/.config/dafab/credentials/profiles or $XDG_CONFIG_HOME/dafab/credentials/profiles
DAFAB_DEMO_DATA_DIR the folder under which get_map writes filters/bbox_map.html when it gets no output_path, default ./demo-data

Set them before importing the client. A profile is a JSON file with the connection and the credentials of one account.

{
  "rucio_host": "https://dafab.cern.ch",
  "auth_host": "https://dafab.cern.ch",
  "auth_type": "userpass",
  "account": "my_account",
  "creds": {"username": "my_account", "password": "..."},
  "ca_cert": "$client_path/_rucio/secrets/user_dafab/rucio_ca_bundle.pem",
  "vo": "def"
}

ca_cert names the TLS trust bundle. $client_path is the installed package, $client_account the account name, and $profile_path the directory of the profile file, so a personal profile can reuse the shipped bundle as above. Keep profile files private.

Publishing

Publishing images and products, attaching them to their collections and facets, and repairing collection extents are done by DaFab's processing pipelines with the publication helpers of this package, ensure_item, set_metadata, publish_original_asset, publish_derived_asset and the sync_*_collection_extent family. They write to the catalogue and need an account with write access. prepare_original_item_metadata, which makes the thumbnail and overview previews of an image, needs the previews extra, pip install "dafab-client[previews]". Project members find the procedures in the repository's docs/. To request an account, contact the project through dafab-ai.eu.

Licence

Apache License 2.0. The package bundles the Rucio client modules, which are also Apache 2.0.

Metadata

Release files for dafab-client 4.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dafab-client 4.0.0
File Size Uploaded Provenance
dafab_client-4.0.0.tar.gz 243.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for dafab-client 4.0.0
File Interpreter ABI Platform
dafab_client-4.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 539.0 kB

Release files / dafab_client-4.0.0.tar.gz

Download URL dafab_client-4.0.0.tar.gz
Size 243.7 kB
Tags Source
SHA-256 checksum
How to use checksums
b711460f721929d450b3aa2159e20ad9e670eeafb3372a86b8b29d41721b25f4
BLAKE2b-256 checksum
How to use checksums
29182fafc8e83dfe25efeb9d254b614c1f0ce79b3618d811e9d88c5205714034
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.11

Release files / dafab_client-4.0.0-py3-none-any.whl

Download URL dafab_client-4.0.0-py3-none-any.whl
Size 295.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
af527c64b99b4b3d54f9830d2df7c9a0f6704e5b57ba81d3ab44f654f72e887f
BLAKE2b-256 checksum
How to use checksums
950f4a1cd868b648002e2964f4749c962a26719917eb90150758863eaf60f5d6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.11

Security for dafab-client 4.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

4.0.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page