Metadata-Version: 2.4
Name: drb-metadata
Version: 1.4.2
Summary: DRB Metadata Extractor
Author: GAEL Systems
Author-email: drb-python@gael.fr
License: LGPLv3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Environment :: Plugins
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
Requires-Python: <3.14,>=3.11
Description-Content-Type: text/markdown
License-File: LICENCE.txt
Requires-Dist: drb<3,>=2.3.5
Requires-Dist: drb-extractor~=1.3.0
Requires-Dist: rdflib
Dynamic: license-file

# drb-metadata

`drb-metadata` is a DRB `Addon` (`MetadataAddon`) that extracts a product's
metadata according to its topic.  It sits on top of the **drb core** (topic
resolution) and [drb-extractor](https://gitlab.com/drb-python/extractor)
(XQuery evaluation primitives).

## Extracting metadata

```python
from drb.metadata import MetadataAddon
import drb.topics.resolver as resolver

topic, node = resolver.resolve('<my_resource_url>')
metadata = MetadataAddon().apply(node, topic=topic)  # topic optional
for name, md in metadata.items():
    print(name, '--', md.extract())
```

`MetadataAddon().apply(node, topic=…)` returns a `dict[str, DrbMetadata]`.
The `topic` keyword argument is optional; if omitted, the topic is resolved
automatically from `node`.

Call `.extract()` on any `DrbMetadata` value to run its XQuery against the
product and return the result.

## Declaring metadata — the RDF model

Metadata are declared as **RDF triples** in the topic's descriptor graph
using the `metadataset:` vocabulary:

```
namespace: http://knowledge-base.gael.fr/drb/addons/metadataset/
triple:    <topic-uri>  metadataset:<name>  """<xquery>"""
```

The XQuery string is evaluated against the product node at extraction time.

**Inheritance and override.** Topics inherit all `metadataset:` triples from
their `rdfs:subClassOf` parents.  A child topic can override any inherited
metadata by redeclaring a triple with the same `<name>`.

### Example (Turtle)

```turtle
@prefix metadataset: <http://knowledge-base.gael.fr/drb/addons/metadataset/> .

<http://knowledge-base.gael.fr/drb/test/product>
    metadataset:platform_name """'SENTINEL-6'""" ;
    metadataset:filename      """name()""" .
```

## Full TTL workflow

1. **Write or extend a TTL file** with `metadataset:` triples for your topic.

2. **Expose the TTL to drb** — two options:

   - **Packaged descriptor** (recommended for libraries): ship the file as
     `cortex.ttl` inside your Python package and declare a `drb.topic` entry
     point pointing to that package.  drb loads it automatically on import.

   - **Runtime registration** (useful for dynamic or remote graphs): register
     the graph with `ManagerDao` before resolving:

     ```python
     from drb.topics.dao import ManagerDao
     from drb.topics.dao.rdf_dao import RDFDao

     # From a local or remote TTL URL:
     ManagerDao().add_dao('<ttl-url>')

     # From a Fuseki / Graph Store endpoint (with optional auth):
     ManagerDao().add_dao_instance(RDFDao(['<sparql-endpoint-url>'],
                                          auth=('user', 'password')))
     ```

     See the core *Resolution* documentation for details on `ManagerDao`.

3. **Resolve and apply**:

   ```python
   topic, node = resolver.resolve('<my_resource_url>')
   metadata = MetadataAddon().apply(node, topic=topic)
   ```

> **Out of scope.** Server-side ingestion of TTL files into a Fuseki instance
> (e.g. `ingest-kb-addons.sh`) is handled by the `drb-fuseki` project and is
> not covered here.

## `extract_for_class(class_uri, graph)`

When the class is not a resolvable DRB topic (e.g. a derived-table row class
used by the Iceberg add-on), use `extract_for_class` to read `metadataset:`
triples directly from a graph by URI:

```python
from drb.metadata.core import extract_for_class
import rdflib

graph = rdflib.Graph().parse('<my-descriptor.ttl>')
md = extract_for_class('http://example.org/my-class', graph)
# md is a dict[str, DrbMetadata]; bind a node before calling .extract():
md['my_field'].node = some_node
print(md['my_field'].extract())
```

## Migration note

> **The `cortex.yaml` format and the `drb.metadata` Python entry point have
> been removed.**  Metadata are now declared exclusively as `metadataset:`
> triples in the topic's RDF descriptor (TTL file).  Remove any `cortex.yaml`
> files and `drb.metadata` entry points from your packages and replace them
> with `metadataset:` triples in a `cortex.ttl` (or equivalent TTL) exposed
> via a `drb.topic` entry point.
