Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

[Documentation](https://digitalbazaar.github.io/pyld/) |
[Installation](#installation) | [Usage](#usage) | [Advanced
Topics](#advanced-topics) | [Contributing](./CONTRIBUTING.md) |
Topics](#advanced-topics) | [What's new in version 4](#whats-new-in-version-4) |
[Contributing](./CONTRIBUTING.md) |
[Changelog](./CHANGELOG.md)

## Introduction
Expand Down Expand Up @@ -45,6 +46,27 @@ memory footprint in order to operate.
* [Requests](http://docs.python-requests.org/) (optional)
* [aiohttp](https://aiohttp.readthedocs.io/) (optional)

## What's new in version 4

PyLD 4 moves RDF handling to [RDFLib](https://rdflib.readthedocs.io/) and adds
RDF Dataset Canonicalization 1.0 support.

The main developer-facing changes are:

* `jsonld.to_rdf()` returns an `rdflib.Dataset` by default when no output
`format` is requested.
* `jsonld.to_rdf(doc, {'legacyMode': True})` returns the RDF.js-like dataset
`dict` used by PyLD versions lower than 4.
* `jsonld.from_rdf()` accepts `rdflib.Dataset`, N-Quads strings, and the legacy
dataset `dict`.
* `jsonld.normalize()` defaults to `RDFC10`; pass `{'algorithm': 'URDNA2015'}`
if older canonicalization output must remain stable.
* The internal `pyld.nquads` parser/serializer module has been removed. Use the
JSON-LD APIs with `format: 'application/n-quads'` or RDFLib directly.

See the full [version 4 upgrade notes](https://digitalbazaar.github.io/pyld/whats-new-version-4/)
and the [`4.0.0` changelog entry](./CHANGELOG.md#400---unreleased).

## Installation

PyLD can be installed with a [pip](http://www.pip-installer.org/)
Expand Down Expand Up @@ -121,10 +143,10 @@ flattened = jsonld.flatten(doc)
framed = jsonld.frame(doc, frame)
# document transformed into a particular tree structure per the given frame

# normalize a document using the RDF Dataset Normalization Algorithm
# (URDNA2015), see: https://www.w3.org/TR/rdf-canon/
# normalize a document using RDF Dataset Canonicalization 1.0
# (RDFC10), see: https://www.w3.org/TR/rdf-canon/
normalized = jsonld.normalize(
doc, {'algorithm': 'URDNA2015', 'format': 'application/n-quads'})
doc, {'algorithm': 'RDFC10', 'format': 'application/n-quads'})
# normalized is a string that is a canonical representation of the document
# that can be used for hashing, comparison, etc.
```
Expand Down
3 changes: 3 additions & 0 deletions docs/.pages
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
nav:
- Quickstart:
- index.md
- whats-new-version-4.md
- installation.md
- conformance.md
- Tutorials:
- tutorials
- Reference:
- reference
- Project:
Expand Down
21 changes: 21 additions & 0 deletions docs/examples/context_resolver_sqlite_cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import json
from pathlib import Path

from cachetools import LRUCache

from pyld import ContextResolver, SqliteCacheRequestsDocumentLoader, jsonld

loader = SqliteCacheRequestsDocumentLoader(
sqlite_file_path=Path("/tmp/pyld_example_context_cache.sqlite"),
)
resolver = ContextResolver(LRUCache(maxsize=1000), loader)

doc = {
"@context": "https://schema.org/",
"name": "Example Person",
}
options = {"documentLoader": loader, "contextResolver": resolver}

expanded = jsonld.expand(doc, options=options)

print(json.dumps(expanded, indent=2))
31 changes: 31 additions & 0 deletions docs/examples/document_loaders/caching_modes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import json
import tempfile
from pathlib import Path
from uuid import uuid4

from requests_cache import CachedSession

from pyld import (
RequestsDocumentLoader,
SqliteCacheRequestsDocumentLoader,
jsonld,
)

doc = {
"@context": {"name": "https://schema.org/name"},
"name": "Earth",
}

no_cache_loader = RequestsDocumentLoader()

memory_cache_loader = RequestsDocumentLoader(
session=CachedSession(backend="memory", cache_control=True),
)

persistent_cache_loader = SqliteCacheRequestsDocumentLoader(
sqlite_file_path=Path(tempfile.gettempdir()) / f"pyld-{uuid4()}.sqlite",
)

result = jsonld.expand(doc, options={"documentLoader": persistent_cache_loader})

print(json.dumps(result, indent=2))
15 changes: 15 additions & 0 deletions docs/examples/from_rdf_dataset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import json

from rdflib import Dataset

from pyld import jsonld

nquads = (
'<http://dbpedia.org/resource/Earth> '
'<http://schema.org/name> "Earth" .\n'
)
dataset = Dataset().parse(data=nquads, format="nquads")

doc = jsonld.from_rdf(dataset)

print(json.dumps(doc, indent=2))
16 changes: 16 additions & 0 deletions docs/examples/inject_context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import json

from pyld import jsonld

doc = {
"name": "Ada Lovelace",
"homepage": "https://example.com/ada",
}
context = {
"name": "http://schema.org/name",
"homepage": {"@id": "http://schema.org/url", "@type": "@id"},
}

expanded = jsonld.expand(doc, {"expandContext": context})

print(json.dumps(expanded, indent=2))
24 changes: 24 additions & 0 deletions docs/examples/inject_context_compact.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import json

from pyld import jsonld

doc = {
"name": "Ada Lovelace",
"homepage": "https://example.com/ada",
}
source_context = {
"name": "http://schema.org/name",
"homepage": {"@id": "http://schema.org/url", "@type": "@id"},
}
output_context = {
"name": "http://schema.org/name",
"url": {"@id": "http://schema.org/url", "@type": "@id"},
}

compacted = jsonld.compact(
doc,
output_context,
{"expandContext": source_context},
)

print(json.dumps(compacted, indent=2))
20 changes: 20 additions & 0 deletions docs/examples/legacy_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import json

from pyld.util import from_legacy_dataset, to_legacy_dataset

legacy_dataset = {
'http://example.org': [
{
'subject': {'type': 'blank node', 'value': '_:s1'},
'predicate': {'type': 'IRI', 'value': 'p1'},
'object': {'type': 'literal', 'value': 'o1'},
}
]
}


rdflib_dataset = from_legacy_dataset(legacy_dataset)
print(rdflib_dataset.serialize(format="nquads"))

legacy_dataset = to_legacy_dataset(rdflib_dataset)
print(json.dumps(legacy_dataset, indent=2))
9 changes: 9 additions & 0 deletions docs/examples/normalize.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
},
}

# Normalize with RDFC10
normalized = jsonld.normalize(
doc,
{"format": "application/n-quads"},
)

print(normalized)

# Normalize with URDNA2015
normalized = jsonld.normalize(
doc,
{"algorithm": "URDNA2015", "format": "application/n-quads"},
Expand Down
19 changes: 19 additions & 0 deletions docs/examples/normalize_output_map.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import json

from pyld import jsonld

doc = {
"@type": "http://schema.org/Person",
"http://schema.org/name": "Manu Sporny",
"http://schema.org/url": {"@id": "http://manu.sporny.org/"},
"http://schema.org/image": {
"@id": "http://manu.sporny.org/images/manu.png"
},
}

identifier_map = jsonld.normalize(
doc,
{"algorithm": "RDFC10", "outputMap": True},
)

print(json.dumps(identifier_map, indent=2))
11 changes: 11 additions & 0 deletions docs/examples/open_jsonld_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import json
from pathlib import Path

from pyld import jsonld

path = Path(__file__).resolve().parent / "data" / "person.jsonld"
doc = json.loads(path.read_text())

expanded = jsonld.expand(doc)

print(json.dumps(expanded, indent=2))
11 changes: 11 additions & 0 deletions docs/examples/open_jsonld_file_to_rdf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import json
from pathlib import Path

from pyld import jsonld

path = Path(__file__).resolve().parent / "data" / "person.jsonld"
doc = json.loads(path.read_text())

nquads = jsonld.to_rdf(doc, {"format": "application/n-quads"})

print(nquads)
18 changes: 18 additions & 0 deletions docs/examples/persistent_document_loader_cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import json
import tempfile
from pathlib import Path
from uuid import uuid4

from pyld import SqliteCacheRequestsDocumentLoader, jsonld

cache_path = Path(tempfile.gettempdir()) / f"pyld-{uuid4()}.sqlite"
loader = SqliteCacheRequestsDocumentLoader(sqlite_file_path=cache_path)

doc = {
"@context": {"name": "https://schema.org/name"},
"name": "Earth",
}

expanded = jsonld.expand(doc, options={"documentLoader": loader})

print(json.dumps(expanded, indent=2))
16 changes: 16 additions & 0 deletions docs/examples/rdflib_parse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import json

from rdflib import Dataset

from pyld import jsonld

nquads = (
'<http://dbpedia.org/resource/Earth> '
'<http://schema.org/name> "Earth" .\n'
)
dataset = Dataset().parse(data=nquads, format="nquads")

doc = jsonld.from_rdf(dataset)
compacted = jsonld.compact(doc, {"name": "http://schema.org/name"})

print(json.dumps(compacted, indent=2))
28 changes: 28 additions & 0 deletions docs/examples/rdflib_processing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import json

from rdflib import Namespace, URIRef

from pyld import jsonld

SCHEMA = Namespace("http://schema.org/")
subject = URIRef("http://dbpedia.org/resource/Earth")

doc = {
"@context": {"name": str(SCHEMA.name)},
"@id": str(subject),
"name": "Earth",
}

dataset = jsonld.to_rdf(doc)
dataset.add((subject, SCHEMA.url, URIRef("https://example.com/earth")))

jsonld_doc = jsonld.from_rdf(dataset)
compacted = jsonld.compact(
jsonld_doc,
{
"name": str(SCHEMA.name),
"homepage": {"@id": str(SCHEMA.url), "@type": "@id"},
},
)

print(json.dumps(compacted, indent=2))
19 changes: 19 additions & 0 deletions docs/examples/rdflib_query.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import json

from rdflib import Namespace, URIRef

from pyld import jsonld

SCHEMA = Namespace("http://schema.org/")
subject = URIRef("http://dbpedia.org/resource/Earth")

doc = {
"@context": {"name": str(SCHEMA.name)},
"@id": str(subject),
"name": "Earth",
}

dataset = jsonld.to_rdf(doc)
names = [str(value) for value in dataset.objects(subject, SCHEMA.name)]

print(json.dumps(names, indent=2))
14 changes: 14 additions & 0 deletions docs/examples/to_rdf_dataset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from pyld import jsonld

doc = {
"@context": {
"name": "http://schema.org/name",
},
"@id": "http://dbpedia.org/resource/Earth",
"name": "Earth",
}

dataset = jsonld.to_rdf(doc)

print(type(dataset).__name__)
print(dataset.serialize(format="nquads"))
15 changes: 15 additions & 0 deletions docs/examples/to_rdf_legacy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import json

from pyld import jsonld

doc = {
"@context": {
"name": "http://schema.org/name",
},
"@id": "http://dbpedia.org/resource/Earth",
"name": "Earth",
}

legacy_dataset = jsonld.to_rdf(doc, {"legacyMode": True})

print(json.dumps(legacy_dataset, indent=2))
9 changes: 9 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ applications add meaning to existing JSON documents with in-band or out-of-band
contexts, while keeping the document shape practical for web APIs, JavaScript,
and JSON document stores.

## :material-new-box: What's new in version 4

PyLD 4 uses [:material-library: RDFLib](https://rdflib.readthedocs.io/)
`rdflib.Dataset` as the native RDF dataset representation, adds `RDFC10`
canonicalization, and removes the internal `pyld.nquads` parser/serializer
module.

[Read the version 4 upgrade notes :octicons-arrow-right-24:](whats-new-version-4.md)

## :material-lightning-bolt: Quick Examples

=== "jsonld.compact()"
Expand Down
Loading
Loading