Skip to content

JSON-LD

JSON-LD processing and examples for Blacklake metadata.

Overview

JSON-LD (JSON for Linked Data) provides a way to express linked data in JSON format, enabling semantic interoperability and web integration.

JSON-LD Context

Blacklake Context

{
  "@context": {
    "dcterms": "http://purl.org/dc/terms/",
    "foaf": "http://xmlns.com/foaf/0.1/",
    "owl": "http://www.w3.org/2002/07/owl#",
    "bl": "https://sempervent.github.io/blacklake/ns#",
    "id": "@id",
    "type": "@type",
    "created": {"@id": "dcterms:created", "@type": "xsd:dateTime"},
    "modified": {"@id": "dcterms:modified", "@type": "xsd:dateTime"},
    "size": {"@id": "dcterms:extent", "@type": "xsd:integer"},
    "checksum": "bl:checksum",
    "algo": "bl:algo",
    "mime": "dcterms:format",
    "title": "dcterms:title",
    "description": "dcterms:description",
    "keyword": "dcterms:subject",
    "creator": "dcterms:creator",
    "rights": "dcterms:rights",
    "license": "dcterms:license",
    "partOf": "dcterms:isPartOf",
    "relation": "dcterms:relation",
    "Agent": "foaf:Agent",
    "Person": "foaf:Person",
    "Organization": "foaf:Organization",
    "name": "foaf:name",
    "mbox": {"@id": "foaf:mbox", "@type": "@id"},
    "homepage": {"@id": "foaf:homepage", "@type": "@id"},
    "Object": "bl:Object",
    "Commit": "bl:Commit"
  }
}

Object Metadata Examples

Basic Object

{
  "@context": "../contexts/blacklake.context.jsonld",
  "id": "bl:obj:sha256:abc123...",
  "type": ["Object", "dcterms:Dataset"],
  "title": "Sales Data 2024",
  "description": "Q1-Q4 sales data for North America",
  "mime": "text/csv",
  "size": 1024000,
  "checksum": "abc123...",
  "algo": "sha256",
  "created": "2024-01-15T10:30:00Z",
  "creator": {
    "id": "urn:uuid:550e8400-e29b-41d4-a716-446655440000",
    "type": "Person",
    "name": "Data Team",
    "mbox": "mailto:data@company.com"
  },
  "rights": "CC BY 4.0",
  "license": {
    "id": "https://creativecommons.org/licenses/by/4.0/"
  },
  "keyword": ["sales", "revenue", "2024", "north-america"],
  "relation": ["bl:commit:def456..."]
}

Scientific Dataset

{
  "@context": "../contexts/blacklake.context.jsonld",
  "id": "bl:obj:sha256:def456...",
  "type": ["Object", "dcterms:Dataset"],
  "title": "Climate Data 2023",
  "description": "Daily temperature and precipitation data for North America",
  "mime": "application/netcdf",
  "size": 52428800,
  "checksum": "def456...",
  "algo": "sha256",
  "created": "2024-01-15T10:30:00Z",
  "creator": {
    "id": "urn:uuid:550e8400-e29b-41d4-a716-446655440001",
    "type": "Person",
    "name": "Dr. Jane Smith",
    "mbox": "mailto:jane@university.edu"
  },
  "rights": "CC BY 4.0",
  "license": {
    "id": "https://creativecommons.org/licenses/by/4.0/"
  },
  "keyword": ["climate", "temperature", "precipitation", "2023"],
  "relation": ["bl:commit:ghi789..."]
}

Commit Metadata Examples

Basic Commit

{
  "@context": "../contexts/blacklake.context.jsonld",
  "id": "bl:commit:sha256:abc123...",
  "type": "Commit",
  "title": "Add sales data",
  "description": "Added Q1-Q4 sales data with metadata",
  "created": "2024-01-15T10:30:00Z",
  "creator": {
    "id": "urn:uuid:550e8400-e29b-41d4-a716-446655440000",
    "type": "Person",
    "name": "Data Team",
    "mbox": "mailto:data@company.com"
  },
  "relation": [
    "bl:tree:sha256:def456...",
    "bl:commit:sha256:ghi789..."
  ],
  "keyword": ["commit", "blacklake"]
}

Merge Commit

{
  "@context": "../contexts/blacklake.context.jsonld",
  "id": "bl:commit:sha256:jkl012...",
  "type": "Commit",
  "title": "Merge feature branch",
  "description": "Merged feature/new-analysis into main",
  "created": "2024-01-15T10:30:00Z",
  "creator": {
    "id": "urn:uuid:550e8400-e29b-41d4-a716-446655440000",
    "type": "Person",
    "name": "Data Team",
    "mbox": "mailto:data@company.com"
  },
  "relation": [
    "bl:tree:sha256:mno345...",
    "bl:commit:sha256:pqr678...",
    "bl:commit:sha256:stu901..."
  ],
  "keyword": ["commit", "merge", "blacklake"]
}

Agent Examples

Person

{
  "@context": "../contexts/blacklake.context.jsonld",
  "id": "urn:uuid:550e8400-e29b-41d4-a716-446655440000",
  "type": "Person",
  "name": "John Doe",
  "mbox": "mailto:john@company.com",
  "homepage": "https://company.com/~john"
}

Organization

{
  "@context": "../contexts/blacklake.context.jsonld",
  "id": "urn:uuid:550e8400-e29b-41d4-a716-446655440001",
  "type": "Organization",
  "name": "Acme Corporation",
  "homepage": "https://acme.com"
}

JSON-LD Processing

Compact and Expand

from pyld import jsonld

# Compact JSON-LD
context = {
    "@context": "../contexts/blacklake.context.jsonld"
}

expanded = jsonld.expand(metadata)
compacted = jsonld.compact(expanded, context)

Example Processing

# Original metadata
metadata = {
    "id": "bl:obj:sha256:abc123...",
    "type": "Object",
    "title": "Sales Data 2024",
    "creator": {
        "name": "Data Team",
        "email": "data@company.com"
    }
}

# Expand to full RDF
expanded = jsonld.expand(metadata)
# Result: Full RDF triples

# Compact using context
compacted = jsonld.compact(expanded, context)
# Result: Compact JSON-LD

Serialization Formats

Turtle (TTL)

@prefix bl: <https://sempervent.github.io/blacklake/ns#> .
@prefix dct: <http://purl.org/dc/terms/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

bl:obj:sha256:abc123... a dct:Dataset ;
  dct:title "Sales Data 2024" ;
  dct:creator [ a foaf:Person ;
    foaf:name "Data Team" ;
    foaf:mbox <mailto:data@company.com> ] .

N-Quads

<bl:obj:sha256:abc123...> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/dc/terms/Dataset> .
<bl:obj:sha256:abc123...> <http://purl.org/dc/terms/title> "Sales Data 2024" .
<bl:obj:sha256:abc123...> <http://purl.org/dc/terms/creator> _:b1 .
_:b1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .
_:b1 <http://xmlns.com/foaf/0.1/name> "Data Team" .
_:b1 <http://xmlns.com/foaf/0.1/mbox> <mailto:data@company.com> .

API Integration

Content Negotiation

# Request JSON-LD
curl -H "Accept: application/ld+json" \
  http://localhost:8000/metadata/objects/abc123

# Request standard JSON
curl -H "Accept: application/json" \
  http://localhost:8000/metadata/objects/abc123

Response Formats

JSON-LD Response:

{
  "@context": "https://sempervent.github.io/blacklake/ns#",
  "@id": "bl:obj:sha256:abc123...",
  "@type": "Object",
  "title": "Sales Data 2024",
  "creator": {
    "@type": "Person",
    "name": "Data Team",
    "mbox": "mailto:data@company.com"
  }
}

Standard JSON Response:

{
  "id": "bl:obj:sha256:abc123...",
  "title": "Sales Data 2024",
  "creator": {
    "name": "Data Team",
    "email": "data@company.com"
  }
}

Validation

SHACL Validation

from pyshacl import validate

# Validate JSON-LD against SHACL shapes
conforms, results, text = validate(
    data_graph=metadata_graph,
    shacl_graph=shacl_shapes
)

if not conforms:
    print(f"Validation errors: {text}")

Example Validation

# Load metadata
with open("metadata.jsonld", "r") as f:
    metadata = json.load(f)

# Validate
conforms, results, text = validate_metadata(metadata, "object")

if conforms:
    print("✓ Metadata is valid")
else:
    print(f"✗ Validation errors: {text}")

Best Practices

Consistent Structure

{
  "@context": "../contexts/blacklake.context.jsonld",
  "id": "bl:obj:sha256:abc123...",
  "type": ["Object", "dcterms:Dataset"],
  "title": "Consistent Title",
  "description": "Clear description",
  "creator": {
    "id": "urn:uuid:...",
    "type": "Person",
    "name": "Creator Name",
    "mbox": "mailto:creator@example.com"
  }
}

Reusable Agents

{
  "@context": "../contexts/blacklake.context.jsonld",
  "@graph": [
    {
      "id": "urn:uuid:550e8400-e29b-41d4-a716-446655440000",
      "type": "Person",
      "name": "Data Team",
      "mbox": "mailto:data@company.com"
    },
    {
      "id": "urn:uuid:550e8400-e29b-41d4-a716-446655440001",
      "type": "Organization",
      "name": "Company Inc",
      "homepage": "https://company.com"
    }
  ]
}

Next Steps