fluree
======
.. py:module:: fluree
.. autoapi-nested-parse::
Fluree: a graph database with time travel, history, and fine-grained policy.
Open a database with :func:`connect`, create or open a ledger, then write
JSON-LD or Turtle and query it with SPARQL or JSON-LD::
import fluree
with fluree.connect(":memory:") as conn:
people = conn.create("people")
people.insert({
"@context": {"ex": "http://example.org/"},
"@id": "ex:alice", "ex:name": "Alice", "ex:age": 42,
})
for name, age in people.query(
"PREFIX ex: "
"SELECT ?name ?age WHERE { ?s ex:name ?name ; ex:age ?age }"
):
print(name, age)
Submodules
----------
.. toctree::
:maxdepth: 1
/api/fluree/aio/index
/api/fluree/errors/index
Package Contents
----------------
.. py:class:: Connection(native: fluree._fluree.Connection)
A connection to a Fluree database. Create one with :func:`connect`.
.. py:method:: close() -> None
Close the connection. Closing the last open connection to a
directory in this process flushes pending writes and releases the
directory, so another process can open it.
Afterwards the connection, and every ledger, snapshot, transaction
and stream opened through it, raises :class:`InvalidRequestError`;
an open transaction can still be rolled back. Closing again does
nothing.
.. py:method:: create(ledger: str, *, source: str | os.PathLike[str] | None = None) -> Ledger
Create a ledger, optionally bulk-loading RDF files into it.
``source`` is a file or a directory of Turtle, TriG, N-Triples,
N-Quads, or JSON-LD files.
.. py:method:: ledger(ledger: str) -> Ledger
An existing ledger. Raises :class:`NotFoundError` if there is none.
.. py:method:: ledgers() -> list[str]
The ids of every ledger, as ``name:branch``.
.. py:method:: query(query: Query, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: Language | None = None, max_fuel: float | None = None, timeout: float | None = None, **kwparameters: Any) -> Any
Run a query whose ``FROM`` names the ledgers to read.
SPARQL ``FROM `` (and ``FROM NAMED``) or a JSON-LD ``"from"``
picks the ledgers, so one query can span several; a ledger address can
carry a time (````), and SPARQL ``FROM ... TO ...`` reads a
range of history. Results, parameters, ``max_fuel`` and ``timeout`` are
as for :meth:`Snapshot.query`. Cypher has no ``FROM``; run it on a ledger.
.. py:method:: select(query: str, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: SelectLanguage | None = None, max_fuel: float | None = None, timeout: float | None = None, **kwparameters: Any) -> fluree._results.Result
A SPARQL ``SELECT`` whose ``FROM`` names the ledgers, as for
:meth:`query`, returning its :class:`Result`; see
:meth:`Snapshot.select`.
.. py:method:: profile(query: Query, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: Language | None = None, max_fuel: float | None = None, timeout: float | None = None, **kwparameters: Any) -> QueryProfile
Run :meth:`query` and report the fuel and time it took.
.. py:method:: map_iceberg(name: str, mapping: str | os.PathLike[str], *, table_location: str | None = None, catalog_uri: str | None = None, glue: fluree._sources.Glue | None = None, s3_tables: fluree._sources.S3Tables | None = None, table: str | None = None, warehouse: str | None = None, auth: fluree._sources.Auth | None = None, vended_credentials: bool | None = None, s3_region: str | None = None, s3_endpoint: str | None = None, s3_path_style: bool = False, order_by: str | None = None, branch: str | None = None, model: str | None = None, default_allow: bool | None = None) -> fluree._sources.GraphSource
Register Iceberg tables as graph source ``name``, mapped to RDF by
``mapping`` (R2RML, as Turtle text or a path to a Turtle file).
Give exactly one place the tables are found. Read one table directly
from ``table_location`` — an ``s3://`` prefix, or a local ``file://``
path (local paths must lie under a directory named in the
``FLUREE_ICEBERG_LOCAL_ROOTS`` environment variable, set before the
process first reads a table). Or find them through a catalog, where
the mapping's table names (or ``table``) name the tables: a REST
catalog at ``catalog_uri``, with ``warehouse`` and ``auth``
(:class:`Bearer` or :class:`OAuth2`); an AWS Glue Data Catalog
(:class:`Glue`); or an AWS S3 Tables table bucket
(:class:`S3Tables`). A REST catalog's vended credentials are used
unless ``vended_credentials`` is false; otherwise, and always for
Glue and S3 Tables, S3 access uses the usual AWS environment and the
``s3_*`` settings. ``warehouse``, ``auth`` and asking for vended
credentials apply to a REST catalog only, and are refused otherwise.
``order_by`` names the column that orders a key's rows, latest
winning, for :meth:`GraphSource.materialize`. ``model`` names a
ledger whose policies and class hierarchy govern the source.
.. py:method:: map_delta(name: str, mapping: str | os.PathLike[str], *, root: str | None = None, tables: collections.abc.Mapping[str, str] | None = None, unity: fluree._sources.Unity | None = None, s3_region: str | None = None, s3_endpoint: str | None = None, s3_path_style: bool = False, azure: fluree._sources.AzureServicePrincipal | None = None, branch: str | None = None, model: str | None = None, default_allow: bool | None = None) -> fluree._sources.GraphSource
Register Delta Lake tables as graph source ``name``, mapped to RDF
by ``mapping`` (R2RML, as Turtle text or a path to a Turtle file).
Each mapped ``rr:tableName`` is found beneath ``root`` (``a.b`` at
``/a/b``), at its location in ``tables``, or through a
:class:`Unity` catalog. Storage credentials come from the usual AWS or
Azure environment, the ``s3_*`` settings, or ``azure``; local paths
must lie under a directory named in ``FLUREE_ICEBERG_LOCAL_ROOTS``.
``model`` and ``default_allow`` are as for :meth:`map_iceberg`.
.. py:method:: map_sql(name: str, endpoint: str, mapping: str | os.PathLike[str], *, dialect: SqlDialect = 'trino', protocol: Literal['trino', 'presto'] = 'trino', catalog: str | None = None, schema: str | None = None, user: str | None = None, auth: fluree._sources.Auth | None = None, session: collections.abc.Mapping[str, str] | None = None, allow_duplicate_subjects: bool = False, branch: str | None = None, model: str | None = None, default_allow: bool | None = None) -> fluree._sources.GraphSource
Register tables behind a SQL engine that speaks the Trino HTTP
protocol (Trino, Presto, or a bridge to another database) as graph
source ``name``, mapped to RDF by ``mapping``. Queries are pushed down
to ``endpoint`` as SQL in ``dialect``.
A mapped table whose subject key is not unique is reported with a
warning and refused at query time, unless
``allow_duplicate_subjects``. ``model`` and ``default_allow`` are as
for :meth:`map_iceberg`.
.. py:method:: graph_sources() -> list[fluree._sources.GraphSource]
Every graph source, by id.
.. py:method:: graph_source(name: str) -> fluree._sources.GraphSource
Graph source ``name`` (``"name"`` or ``"name:branch"``). Raises
:class:`NotFoundError` if there is none.
.. py:method:: restore(path: str | os.PathLike[str], ledger: str) -> Ledger
Create ``ledger`` from a ``.flpack`` archive (see :meth:`Ledger.archive`).
.. py:method:: drop(ledger: str) -> None
Delete a ledger, every branch and all history (``"people"``), or one
branch (``"people:dev"``).
A ledger's first branch cannot be dropped on its own; drop the ledger.
A branch that other branches were created from is hidden at once but
its storage is kept until they are dropped too.
.. py:class:: Ledger(connection: Connection, ledger_id: str, policy: dict[str, Any] | None = None)
A ledger: write to it, and query its latest state or any past one.
.. py:property:: id
:type: str
The ledger's id, ``name:branch``.
.. py:method:: with_policy(*, identity: str | None = None, policy_class: str | list[str] | None = None, policy: dict[str, Any] | list[Any] | None = None, values: dict[str, Any] | None = None, default_allow: bool | None = None) -> Ledger
This ledger, governed: every read and write through the returned
handle is subject to policy.
- ``identity``: the IRI (often a DID) to evaluate policy as; the
policies attached to it in the ledger apply.
- ``policy_class``: apply the ledger's policies of these classes.
- ``policy``: inline JSON-LD policy documents to apply.
- ``values``: bindings for variables the policies reference,
e.g. ``{"?$dept": "eng"}``.
- ``default_allow``: whether data no policy covers is visible and
writable. ``None`` defers to the ledger's configured default, which
is to deny.
Reads filter out what policy does not allow; a write that policy does
not allow raises :class:`PermissionDeniedError`. So does what policy
cannot filter: the commit log, :meth:`info` and :meth:`graphs`, and
maintenance, branch and export operations.
.. py:method:: insert(data: Data, *, format: Format | None = None, message: str | None = None) -> fluree._records.Commit
Add data: JSON-LD (a dict, list, or JSON text), Turtle, or TriG.
A path is read as a file, its format taken from the extension unless
``format`` is given. ``message`` is recorded with the commit, and
:meth:`log` shows it. Data with nothing to add, such as ``[]``, is
refused.
.. py:method:: upsert(data: Data, *, format: Format | None = None, message: str | None = None) -> fluree._records.Commit
Add data, replacing existing values of the properties it sets.
.. py:method:: insert_rows(rows: Any, *, id: str | None = None, type: str | list[str] | None = None, vocab: str | None = None, columns: collections.abc.Mapping[str, str | None] | None = None, refs: collections.abc.Mapping[str, str] | None = None, message: str | None = None) -> fluree._records.Commit
Add one node per row of ``rows``: a pandas or polars DataFrame, or
an iterable of dicts. Each column becomes a property of its row's
node; a missing value (``None``, ``NaN``, ``NaT``) adds nothing.
- ``id``: the node's IRI, as a template over the row's columns —
``"ex:person/{id}"`` — whose values are percent-escaped. Without
one each row is a new blank node.
- ``type``: the class (or classes) every node gets.
- ``vocab``: an IRI prefix for the column names; otherwise they are
read against the ledger's default context, like JSON-LD keys.
- ``columns``: rename a column's property (full or compact IRI), or
drop the column with ``None``.
- ``refs``: properties whose value is a reference to another node,
each an IRI template — ``{"manager": "ex:person/{manager_id}"}``.
Values convert as in :meth:`insert`, keeping the DataFrame's types:
a pandas integer column with a gap is a float column, unless it has
the nullable ``Int64`` dtype. All rows commit together.
.. py:method:: upsert_rows(rows: Any, *, id: str | None = None, type: str | list[str] | None = None, vocab: str | None = None, columns: collections.abc.Mapping[str, str | None] | None = None, refs: collections.abc.Mapping[str, str] | None = None, message: str | None = None) -> fluree._records.Commit
:meth:`insert_rows`, replacing existing values of the properties
the rows set — to load a table again after it changed.
.. py:method:: update(transaction: str | dict[str, Any] | os.PathLike[str], parameters: collections.abc.Mapping[str, Any] | None = None, *, language: Language | None = None, message: str | None = None, **kwparameters: Any) -> fluree._records.Commit
Apply a SPARQL UPDATE, a Cypher write, or a JSON-LD
``where``/``delete``/``insert``.
The language is told from the text (``language`` overrides it); a
path is read as a file, ``.rq``/``.ru`` as SPARQL and
``.cypher``/``.cyp``/``.cql`` as Cypher. A Cypher write may be a ``;``
script, committed all or nothing — and mixes with the other languages
inside a :meth:`transaction`; its ``$name`` parameters come from
``parameters`` and keyword arguments, and the records a ``RETURN``
produces are the commit's ``result``.
``parameters`` and keyword arguments bind values by name: Cypher
``$name``, and in SPARQL the variable ``?name`` (or ``$name``) wherever
it appears, as if the value were written in its place; see
:meth:`Snapshot.query`.
.. py:method:: sync(data: Data, *, graph: str | None = None, format: Format | None = None, allow_empty: bool = False, dry_run: bool = False, message: str | None = None) -> fluree._records.Commit
Make a graph hold exactly ``data``, committing only the difference:
facts missing from ``data`` are retracted, new ones asserted, and
unchanged ones left alone. History keeps every earlier state.
``graph`` is a named graph's IRI; by default the default graph is
synced. ``data`` is as for :meth:`insert`, and Turtle, N-Triples or
TriG text.
Empty ``data`` would clear the graph, so it is refused unless
``allow_empty`` is set. With ``dry_run`` nothing is committed and the
returned :class:`Commit` (``id`` ``None``) counts what would change.
When ``data`` already matches, no commit is written either.
.. py:method:: transact(fn: collections.abc.Callable[..., _T], /, *args: Any, **kwargs: Any) -> _T
Run ``fn(txn, *args, **kwargs)`` in a :class:`Transaction` and
commit it, running ``fn`` again in a fresh transaction if another
commit lands first. Returns what ``fn`` returns.
The way to read and then write safely: values ``fn`` reads from
``txn`` are re-read on every attempt, so what it writes never rests
on data another writer has since changed. ``fn`` may commit ``txn``
itself (to pass a ``message``); otherwise it is committed when ``fn``
returns. An exception from ``fn`` rolls the transaction back and
propagates.
.. py:method:: transaction(*, message: str | None = None) -> Transaction
Open a :class:`Transaction`: several writes, each seeing the ones
before it, committed together as one commit, with ``message``.
Use it as a context manager to commit on a clean exit and roll back
on an exception::
with ledger.transaction(message="onboard bob") as txn:
txn.insert(...)
txn.update(...)
txn.committed # the Commit
.. py:method:: query(query: Query, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: Language | None = None, max_fuel: float | None = None, timeout: float | None = None, **kwparameters: Any) -> Any
Query the latest state. See :meth:`Snapshot.query`.
.. py:method:: select(query: str, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: SelectLanguage | None = None, max_fuel: float | None = None, timeout: float | None = None, **kwparameters: Any) -> fluree._results.Result
Run a ``SELECT`` on the latest state; see :meth:`Snapshot.select`.
.. py:method:: profile(query: Query, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: Language | None = None, max_fuel: float | None = None, timeout: float | None = None, **kwparameters: Any) -> QueryProfile
Run :meth:`query` and report the fuel and time it took.
.. py:method:: stream(query: Query, parameters: collections.abc.Mapping[str, Any] | None = None, *, max_fuel: float | None = None, timeout: float | None = None, batch_size: int = 1000, **kwparameters: Any) -> fluree._results.RowStream
Run a SELECT and read its rows as they are produced; see
:class:`RowStream`. ``max_fuel`` and ``timeout`` cover the whole stream.
.. py:method:: explain(query: Query, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: Language | None = None, **kwparameters: Any) -> dict[str, Any]
The plan the engine would run ``query`` with, without running it.
.. py:method:: snapshot() -> Snapshot
The latest state, frozen: every query on it sees the same data.
.. py:method:: at(t: int | None = None, *, time: datetime.datetime | str | None = None, commit: str | None = None) -> Snapshot
The ledger as it was at transaction ``t``, a wall-clock ``time``, or
a ``commit``. Give exactly one.
``commit`` is a full commit id (:attr:`Commit.id`), or its hex
:attr:`Commit.digest` or a unique prefix of it (:attr:`Commit.short_id`).
.. py:method:: history(subject: str, predicate: str | None = None, *, from_t: int = 1, to_t: int | None = None) -> list[fluree._records.Change]
Every change to ``subject`` between transactions ``from_t`` and
``to_t`` (default: the latest), oldest first; within one transaction,
retractions come before assertions.
``subject`` and ``predicate`` are full IRIs. Give ``predicate`` to
follow one property.
.. py:method:: log(limit: int | None = None) -> list[fluree._records.Commit]
The ledger's commits, newest first; at most ``limit`` of them.
.. py:method:: changes(commit: CommitRef) -> list[fluree._records.Change]
The facts one commit asserted and retracted.
``commit`` is its ``t``, its id, a prefix of its hex digest
(:attr:`Commit.short_id`), or a :class:`Commit`. Under :meth:`with_policy`, facts the policy
hides are left out.
.. py:method:: branch(name: str) -> Ledger
Create branch ``name`` from this ledger's latest state and return
it. Branch from a past state with ``ledger.at(...).branch(name)``.
The new branch shares this one's history up to that point; from then
on each changes independently, until :meth:`merge` brings one's
commits into the other.
.. py:method:: branches() -> list[fluree._records.Branch]
Every branch of this ledger, by name.
.. py:method:: merge(source: str | Ledger, *, strategy: MergeStrategy = 'take-both') -> fluree._records.MergeResult
Bring the commits of branch ``source`` (a name like ``"dev"``, or
its :class:`Ledger`) into this branch.
If this branch has no commits of its own since ``source`` was created
from it, it moves forward to ``source``'s latest commit. Otherwise one
merge commit applies ``source``'s changes, and ``strategy`` settles
properties both branches changed:
- ``"take-both"``: keep both values.
- ``"abort"``: change nothing and raise :class:`ConflictError`.
- ``"take-source"``: ``source``'s value wins.
- ``"take-branch"``: this branch's value wins.
Preview a merge with :meth:`merge_preview`.
.. py:method:: merge_preview(source: str | Ledger, *, strategy: MergeStrategy = 'take-both', details: bool = False, changes: bool = False, changes_after: str | None = None, validate: bool = True, conflicts: bool = True, max_commits: int | None = 500, max_conflicts: int | None = 200, max_changes: int | None = 500) -> fluree._records.MergePreview
What :meth:`merge` of ``source`` would do, without doing it.
- ``strategy``: the one to judge ``mergeable`` by.
- ``details``: include what each side wrote to each conflict.
- ``changes``: include the net facts the merge would bring in, at most
``max_changes`` of them per call; pass the result's
``changes_after`` back to read the next page.
- ``validate=False`` skips checking the merged state against the
ledger's SHACL shapes.
- ``conflicts=False`` skips finding conflicts, the costly part on
branches that have drifted far apart.
- ``max_commits`` and ``max_conflicts`` cap the lists returned, not the
work; ``None`` lifts a cap.
.. py:method:: rebase(*, strategy: RebaseStrategy = 'take-both') -> fluree._records.RebaseResult
Replay this branch's own commits on top of the latest commit of the
branch it was created from, as if it had been created from there.
``strategy`` settles properties both branches changed: ``"take-both"``
keeps both values, ``"abort"`` changes nothing and raises
:class:`ConflictError`, ``"take-source"`` lets the source branch's
value win, ``"take-branch"`` lets this branch's win, and ``"skip"``
drops each of this branch's commits that conflicts.
.. py:method:: revert(commits: CommitRef | list[CommitRef], *, strategy: RevertStrategy = 'abort') -> fluree._records.RevertResult
Undo one commit or several, in one new commit.
A commit is named by its ``t``, its id, a prefix of its hex digest, or
a :class:`Commit`. ``strategy`` settles properties that later commits
changed again: ``"abort"`` changes nothing and raises
:class:`ConflictError`, ``"take-source"`` undoes them anyway, and
``"take-branch"`` keeps the later values. Merge commits cannot be
reverted.
Preview a revert with :meth:`revert_preview`.
.. py:method:: revert_preview(commits: CommitRef | list[CommitRef], *, strategy: RevertStrategy = 'abort', validate: bool = True, conflicts: bool = True, max_commits: int | None = 500, max_conflicts: int | None = 200) -> fluree._records.RevertPreview
What :meth:`revert` would do, without doing it. ``strategy`` is the
one to judge ``revertable`` by; the other options are as for
:meth:`merge_preview`.
.. py:method:: validate(shapes: Data | None = None, *, shapes_graph: str | None = None, graph: str | None = None, include_attached: bool = False, format: Format | None = None, max_fuel: float | None = None, timeout: float | None = None) -> fluree._records.ValidationReport
Check the data against SHACL shapes, without changing anything.
By default the shapes are the ledger's own — the ones its writes are
checked against. Give ``shapes`` (JSON-LD, Turtle, or a path, as for
:meth:`insert`) to check against other shapes, or ``shapes_graph``,
the IRI of a named graph that holds them; ``include_attached`` adds
the ledger's own shapes to either. ``graph`` validates a named graph
rather than the default graph. ``max_fuel`` and ``timeout`` bound the
work, as for :meth:`query`.
.. py:method:: index_status() -> fluree._records.IndexStatus
How far indexing has caught up with the ledger's commits.
.. py:method:: index(*, timeout: float | None = None) -> int
Index everything committed so far, waiting up to ``timeout``
seconds; returns the indexed ``t``. Queries do not need this — they
read unindexed commits too — but it makes them faster sooner.
Needs a connection with background indexing.
.. py:method:: reindex() -> int
Rebuild the index from scratch from the commit history; returns the
indexed ``t``.
.. py:method:: verify(*, max_commits: int | None = None) -> fluree._records.VerifyReport
Check that every commit, back to the first (or the last
``max_commits``), and the index root are present and readable.
.. py:method:: sweep(*, dry_run: bool = False) -> fluree._records.SweepResult
Delete index files that no index of any branch of this ledger
references any more — left behind as indexing replaces old index
files. ``dry_run`` counts them without deleting.
.. py:method:: export(path: str | os.PathLike[str] | None = None, *, format: ExportFormat | None = None, graph: str | None = None, all_graphs: bool = False, context: dict[str, Any] | None = None) -> str | None
Export the ledger's current data as RDF.
Writes to ``path`` and returns ``None``, or returns the text when no
path is given. ``format`` is ``"turtle"``, ``"trig"``, ``"ntriples"``,
``"nquads"``, or ``"jsonld"``; by default it follows the path's
extension, else Turtle. The default graph is exported unless ``graph``
names one or ``all_graphs`` asks for every named graph too (use TriG
or N-Quads for that). ``context`` supplies prefixes for Turtle and
JSON-LD. Export the past with ``ledger.at(...).export(...)``.
.. py:method:: archive(path: str | os.PathLike[str], *, include_indexes: bool = True) -> None
Write the whole ledger, every commit, to a ``.flpack`` archive that
:meth:`Connection.restore` loads back. Without indexes the archive is
smaller but the restored ledger must reindex before it is fast.
.. py:property:: context
:type: dict[str, Any] | None
The ledger's default JSON-LD context, or ``None``.
Queries that omit ``@context`` (JSON-LD) or ``PREFIX`` (SPARQL) resolve
their prefixes against it. Replace it with :meth:`set_context`.
.. py:method:: set_context(context: dict[str, Any]) -> None
Replace the ledger's default JSON-LD context: a ``{prefix: IRI}`` map.
.. py:method:: info() -> dict[str, Any]
Ledger metadata and statistics.
.. py:method:: graphs() -> list[fluree._terms.IRI]
The IRIs of the ledger's named graphs, in the order they were first
written to. The default graph and Fluree's own graphs (commit
metadata, configuration) are left out.
A graph is created by writing to it — TriG, SPARQL ``GRAPH``, or a
JSON-LD node's ``"@graph"`` — and queried with SPARQL ``GRAPH`` or
JSON-LD ``["graph", iri, pattern]``.
.. py:method:: drop_graph(graph: str) -> fluree._records.Commit
Retract everything in named graph ``graph`` (its full IRI) in one
commit. History keeps it, and the graph can be written to again. The
default graph and Fluree's own graphs cannot be dropped.
.. py:method:: set_full_text(properties: collections.abc.Iterable[str], *, language: str = 'en', reindex: bool = True) -> None
Make the plain-string values of ``properties`` searchable with
``fulltext()``, analyzed in ``language`` (a BCP-47 tag; values tagged
with their own language use it instead).
``properties`` are IRIs, full or compact against the ledger's default
context; they replace the ones configured before, and an empty list
turns the configuration off. The data itself is not changed.
``reindex`` rebuilds the index so values already in the ledger are
searchable. From then on, a property is searchable as values commit
once an index build has seen values of it: a property configured
before the ledger holds any of its values is searchable after the
next index build (background indexing, or :meth:`reindex`). Pass
``reindex=False`` to defer the rebuild, for instance before a bulk
load, and call :meth:`reindex` when ready.
.. py:method:: full_text() -> fluree._records.FullText | None
The ledger's full-text configuration, or ``None`` without one.
.. py:class:: QueryProfile
A query's result with what it cost: ``fuel`` (the engine's unit of
work, the unit ``max_fuel`` limits) and wall-clock ``time``.
.. py:attribute:: result
:type: Any
.. py:attribute:: fuel
:type: float | None
.. py:attribute:: time
:type: datetime.timedelta | None
.. py:class:: Snapshot(native: fluree._fluree.Snapshot, ledger: Ledger)
A ledger frozen at one point in time.
Get one from :meth:`Ledger.snapshot` or :meth:`Ledger.at`.
.. py:method:: export(path: str | os.PathLike[str] | None = None, *, format: ExportFormat | None = None, graph: str | None = None, all_graphs: bool = False, context: dict[str, Any] | None = None) -> str | None
Export the data as of this snapshot; see :meth:`Ledger.export`.
.. py:method:: branch(name: str) -> Ledger
Create branch ``name`` from this past state; see :meth:`Ledger.branch`.
.. py:property:: ledger
:type: str
The id of the ledger this is a snapshot of, ``name:branch``.
.. py:property:: t
:type: int
The transaction this snapshot reflects.
.. py:method:: query(query: Query, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: Language | None = None, max_fuel: float | None = None, timeout: float | None = None, **kwparameters: Any) -> Any
Run a SPARQL, Cypher, or JSON-LD query.
The language is told from the query — a dict or JSON text is
JSON-LD, text that opens like SPARQL (``PREFIX``, ``SELECT``, ...) is
SPARQL, and text that opens like Cypher (``MATCH``, ``UNWIND``, ...)
is Cypher — or set with ``language``.
- SPARQL ``SELECT`` and every Cypher query return a :class:`Result`;
Cypher nodes, relationships and paths come back as :class:`Node`,
:class:`Relationship` and :class:`Path`.
- SPARQL ``ASK`` returns a ``bool``; ``CONSTRUCT``/``DESCRIBE`` the
constructed graph as a JSON-LD document.
- A JSON-LD query returns its JSON result as Python objects.
``parameters`` and keyword arguments bind values by name. In Cypher
they are the ``$name`` parameters. In SPARQL each names a variable —
``?name`` or ``$name``, the same variable — and the value stands in
for it wherever it appears, as if written there: ``query("SELECT ?s
WHERE { ?s ex:name $name }", name="Alice")``. A value is an
:class:`IRI`, :class:`BlankNode`, :class:`LangString` or
:class:`Literal`, or a Python ``str``, ``int``, ``float``, ``bool``,
``Decimal``, ``datetime``, ``date`` or ``time``; a :class:`Node` stands
for its ``element_id``. A SPARQL parameter the query never mentions is
an error, since its misspelt variable would otherwise match anything;
a JSON-LD query takes no parameters.
A Cypher write is refused here; run it with :meth:`Ledger.update`.
``max_fuel`` caps the work the query may do (see :meth:`profile` for
what a query costs); past it the query stops with
:class:`ResourceLimitError`. ``timeout`` is in seconds; past it the
query is cancelled with :class:`QueryTimeoutError`.
.. py:method:: select(query: str, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: SelectLanguage | None = None, max_fuel: float | None = None, timeout: float | None = None, **kwparameters: Any) -> fluree._results.Result
Run a SPARQL ``SELECT`` or a Cypher query and return its
:class:`Result` — :meth:`query` for the queries whose result is a
table, typed as one. Anything else (``ASK``, ``CONSTRUCT``, JSON-LD)
raises :class:`InvalidRequestError` without running. Parameters,
``max_fuel`` and ``timeout`` are as for :meth:`query`.
.. py:method:: profile(query: Query, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: Language | None = None, max_fuel: float | None = None, timeout: float | None = None, **kwparameters: Any) -> QueryProfile
Run :meth:`query` and report the fuel and time it took.
.. py:method:: stream(query: Query, parameters: collections.abc.Mapping[str, Any] | None = None, *, max_fuel: float | None = None, timeout: float | None = None, batch_size: int = 1000, **kwparameters: Any) -> fluree._results.RowStream
Run a SELECT and read its rows as they are produced; see
:class:`RowStream`.
.. py:method:: explain(query: Query, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: Language | None = None, **kwparameters: Any) -> dict[str, Any]
The plan the engine would run ``query`` with, without running it.
.. py:class:: Transaction(ledger: Ledger, native: fluree._fluree.Transaction, message: str | None)
Writes staged one at a time and committed together as one commit.
Get one from :meth:`Ledger.transaction`. Each write applies over the ones
before it — an ``update``'s ``WHERE`` sees an earlier ``insert`` — and is
checked as it is staged, so a write that is invalid or that policy does
not allow raises at once and is left out; the transaction carries on
without it. Queries on the transaction read the staged state; nothing is
visible on the ledger until :meth:`commit`.
A fact that one write adds and a later one removes (or the reverse) is
left out of the commit, so the commit holds only the net change.
The writes stage against the ledger as it was when the transaction
began. If another commit lands first:
- a transaction that was only written to is staged again on top of it —
each update's ``WHERE`` matches the new data;
- a transaction that was also *read* (``query``, ``explain``, or the
``RETURN`` records of a Cypher write) raises :class:`ConflictError` on
:meth:`commit`, since what was read may have decided what was written. Run it again, or use
:meth:`Ledger.transact`, which does.
As a context manager it commits on a clean exit and rolls back on an
exception; :attr:`committed` holds the resulting :class:`Commit`.
.. py:attribute:: committed
:type: fluree._records.Commit | None
:value: None
.. py:method:: insert(data: Data, *, format: Format | None = None) -> None
Stage an insert; see :meth:`Ledger.insert`.
.. py:method:: upsert(data: Data, *, format: Format | None = None) -> None
Stage an upsert; see :meth:`Ledger.upsert`.
.. py:method:: insert_rows(rows: Any, *, id: str | None = None, type: str | list[str] | None = None, vocab: str | None = None, columns: collections.abc.Mapping[str, str | None] | None = None, refs: collections.abc.Mapping[str, str] | None = None) -> None
Stage :meth:`Ledger.insert_rows`.
.. py:method:: upsert_rows(rows: Any, *, id: str | None = None, type: str | list[str] | None = None, vocab: str | None = None, columns: collections.abc.Mapping[str, str | None] | None = None, refs: collections.abc.Mapping[str, str] | None = None) -> None
Stage :meth:`Ledger.upsert_rows`.
.. py:method:: update(transaction: str | dict[str, Any] | os.PathLike[str], parameters: collections.abc.Mapping[str, Any] | None = None, *, language: Language | None = None, **kwparameters: Any) -> fluree._results.Result | None
Stage an update — SPARQL UPDATE, a Cypher write, or JSON-LD; see
:meth:`Ledger.update`. A Cypher write returns the records of its
``RETURN`` (``None`` without one); receiving them counts as reading
the transaction.
.. py:method:: query(query: Query, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: Language | None = None, max_fuel: float | None = None, timeout: float | None = None, **kwparameters: Any) -> Any
Query the staged state; see :meth:`Snapshot.query`.
.. py:method:: select(query: str, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: SelectLanguage | None = None, max_fuel: float | None = None, timeout: float | None = None, **kwparameters: Any) -> fluree._results.Result
Run a ``SELECT`` on the staged state; see :meth:`Snapshot.select`.
.. py:method:: explain(query: Query, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: Language | None = None, **kwparameters: Any) -> dict[str, Any]
The plan ``query`` would run with over the staged state.
.. py:method:: commit(*, message: str | None = None) -> fluree._records.Commit
Commit the staged writes as one commit, recording ``message`` (by
default the one the transaction was opened with). The transaction is
closed afterwards, even if the commit fails.
.. py:method:: rollback() -> None
Discard the staged writes and close the transaction.
.. py:function:: connect(path: str | os.PathLike[str] | None = None, *, config: dict[str, Any] | None = None, indexing: bool = True) -> Connection
Open a Fluree database, creating it if needed.
Give a directory ``path``, or ``":memory:"`` for a database that lives
only as long as the connection. ``indexing=False`` turns off background
indexing in this process.
Connections in one process to the same directory share one engine, so
threads may each open their own; they must agree on ``indexing``. While
any of them is open, another process that opens the directory raises
:class:`DatabaseInUseError`: run ``fluree server`` on it to share it
across processes. A ``config`` connection to file storage is not shared:
while it is open, opening that storage again raises
:class:`DatabaseInUseError`, in this process too.
For anything else — S3 or split commit/index storage, a DynamoDB
nameservice, encryption at rest, values read from environment variables —
pass a JSON-LD connection ``config`` instead of a path; it is the same
document ``fluree server`` takes with ``--connection-config``.
The connection is a context manager that closes it on exit::
with fluree.connect("./data") as conn:
ledger = conn.create("people")
.. py:class:: Node(element_id: fluree._terms.IRI | fluree._terms.BlankNode, labels: frozenset[str], properties: dict[str, Any])
Bases: :py:obj:`collections.abc.Mapping`\ [\ :py:obj:`str`\ , :py:obj:`Any`\ ]
A node: its properties (read like a dict), its ``labels`` — the
node's classes — and ``element_id``, its identity: the same
:class:`IRI` (or :class:`BlankNode`) a SPARQL query returns for it.
.. py:attribute:: element_id
.. py:attribute:: labels
.. py:class:: Path(nodes: tuple[Node, ...], relationships: tuple[Relationship, ...])
A walk through the graph: ``nodes`` and the ``relationships``
between them, in order. Iterating a path yields its relationships.
.. py:attribute:: nodes
.. py:attribute:: relationships
.. py:property:: start_node
:type: Node
The node the path starts at.
.. py:property:: end_node
:type: Node
The node the path ends at.
.. py:class:: Relationship(element_id: fluree._terms.IRI | fluree._terms.BlankNode | None, type: str, start_node: Node, end_node: Node, properties: dict[str, Any])
Bases: :py:obj:`collections.abc.Mapping`\ [\ :py:obj:`str`\ , :py:obj:`Any`\ ]
A relationship: its properties (read like a dict), its ``type``, and
the nodes it runs from and to. ``element_id`` is its identity when it
has one (every relationship a Cypher ``CREATE`` makes does).
``start_node`` and ``end_node`` carry their properties and labels when
the same result returned those nodes; otherwise only their
``element_id``.
.. py:attribute:: element_id
.. py:attribute:: type
.. py:attribute:: start_node
.. py:attribute:: end_node
.. py:property:: nodes
:type: tuple[Node, Node]
``(start_node, end_node)``.
.. py:class:: Branch
A branch of a ledger. Open it with ``conn.ledger(branch.id)``.
``source`` is the branch it was created from, ``None`` for the ledger's
first branch. ``t`` and ``head`` are its latest commit's ``t`` and id.
.. py:attribute:: name
:type: str
.. py:attribute:: id
:type: str
.. py:attribute:: source
:type: str | None
.. py:attribute:: t
:type: int
.. py:attribute:: head
:type: str | None
.. py:class:: Change
One fact asserted or retracted at transaction ``t``: ``subject``'s
``predicate`` gained (``op == "assert"``) or lost (``op == "retract"``)
``value``, in the default graph or the named ``graph``.
``t`` is ``None`` for the net changes a merge preview reports, which span
several commits.
.. py:attribute:: t
:type: int | None
.. py:attribute:: op
:type: Literal['assert', 'retract']
.. py:attribute:: subject
:type: fluree._terms.IRI | fluree._terms.BlankNode
.. py:attribute:: predicate
:type: fluree._terms.IRI
.. py:attribute:: value
:type: Any
.. py:attribute:: graph
:type: fluree._terms.IRI | None
:value: None
.. py:class:: Commit
The outcome of a transaction.
``id`` is the commit's content id (a CID). ``digest`` is its hex hash, the
form ``fluree log`` shows: like a git SHA, a unique prefix of it
(``short_id``, say) identifies the commit. A prefix of ``id`` does not,
since every CID starts with the same header characters.
``id`` and ``digest`` are ``None`` when the transaction changed nothing, in
which case no commit was written and ``t`` is the ledger's unchanged ``t``.
``time`` and ``message`` are filled in for commits read from
:meth:`Ledger.log` and the previews. ``result`` holds the records a
Cypher write's ``RETURN`` produced.
.. py:attribute:: t
:type: int
.. py:attribute:: id
:type: str | None
.. py:attribute:: digest
:type: str | None
.. py:attribute:: asserts
:type: int
.. py:attribute:: retracts
:type: int
.. py:attribute:: time
:type: datetime.datetime | None
:value: None
.. py:attribute:: message
:type: str | None
:value: None
.. py:attribute:: result
:type: fluree._results.Result | None
:value: None
.. py:property:: short_id
:type: str | None
The first 12 hex digits of ``digest``, as ``fluree log`` prints them.
.. py:class:: Conflict
A property of a subject that both sides changed.
``source`` and ``target`` are what each side wrote to it, when the preview
was asked for ``details``; otherwise ``None``.
.. py:attribute:: subject
:type: fluree._terms.IRI | fluree._terms.BlankNode
.. py:attribute:: predicate
:type: fluree._terms.IRI
.. py:attribute:: graph
:type: fluree._terms.IRI | None
.. py:attribute:: source
:type: list[Change] | None
:value: None
.. py:attribute:: target
:type: list[Change] | None
:value: None
.. py:class:: FullText
A ledger's full-text configuration (see :meth:`Ledger.set_full_text`):
the properties whose plain-string values ``fulltext()`` scores, and the
language untagged values are analyzed in.
.. py:attribute:: properties
:type: tuple[fluree._terms.IRI, ...]
.. py:attribute:: language
:type: str | None
.. py:class:: IndexStatus
Where indexing of a ledger stands. Commits after ``index_t`` (up to
``commit_t``) are queryable but not yet indexed. ``phase`` is ``"idle"``,
``"pending"`` or ``"in_progress"``; ``enabled`` is false on a connection
without background indexing (``":memory:"``, or ``indexing=False``).
.. py:attribute:: index_t
:type: int
.. py:attribute:: commit_t
:type: int
.. py:attribute:: enabled
:type: bool
.. py:attribute:: phase
:type: str
.. py:attribute:: error
:type: str | None
.. py:class:: MergePreview
What merging ``source`` into ``target`` would do, without doing it.
- ``ahead``: commits on ``source`` that ``target`` lacks, newest first;
``behind``: the reverse. Each list may be capped; ``ahead_count`` and
``behind_count`` are the full counts.
- ``ancestor_t``: the ``t`` of the last commit the two share.
- ``fast_forward``: ``target`` has no commits of its own since, so the
merge just moves it forward.
- ``conflicts``: properties both sides changed (may be capped;
``conflict_count`` is the full count).
- ``mergeable``: the merge would succeed under the previewed strategy,
including the ledger's SHACL shapes; when it would fail validation,
``violations`` holds the report.
- ``changes``: the net facts the merge would bring in, when asked for. Pass
``changes_after`` back as ``changes_after=`` to read the next page.
.. py:attribute:: source
:type: str
.. py:attribute:: target
:type: str
.. py:attribute:: fast_forward
:type: bool
.. py:attribute:: mergeable
:type: bool
.. py:attribute:: ancestor_t
:type: int | None
.. py:attribute:: ahead
:type: list[Commit]
.. py:attribute:: ahead_count
:type: int
.. py:attribute:: behind
:type: list[Commit]
.. py:attribute:: behind_count
:type: int
.. py:attribute:: conflicts
:type: list[Conflict]
.. py:attribute:: conflict_count
:type: int
.. py:attribute:: violations
:type: str | None
.. py:attribute:: changes
:type: list[Change] | None
.. py:attribute:: changes_after
:type: str | None
.. py:class:: MergeResult
The outcome of :meth:`Ledger.merge`.
A ``fast_forward`` merge moved ``target`` to ``source``'s latest commit
without writing one; otherwise ``id`` is the new merge commit. ``t`` is
``target``'s ``t`` afterwards. ``conflicts`` counts the properties
``strategy`` resolved.
.. py:attribute:: source
:type: str
.. py:attribute:: target
:type: str
.. py:attribute:: fast_forward
:type: bool
.. py:attribute:: t
:type: int
.. py:attribute:: id
:type: str
.. py:attribute:: digest
:type: str
.. py:attribute:: conflicts
:type: int
.. py:attribute:: strategy
:type: str | None
.. py:class:: RebaseResult
The outcome of :meth:`Ledger.rebase`.
Of the branch's ``total`` own commits, ``replayed`` were rewritten on top
of its source's latest commit (``source_t``) and ``skipped`` were dropped
by the ``"skip"`` strategy. ``conflicts`` lists ``(t, properties,
resolution)`` for each commit that conflicted, ``t`` being the commit's
original ``t``; ``failures`` lists ``(t, error)`` for commits that failed
validation once replayed. A ``fast_forward`` rebase had no commits of its
own to replay.
.. py:attribute:: fast_forward
:type: bool
.. py:attribute:: replayed
:type: int
.. py:attribute:: skipped
:type: int
.. py:attribute:: total
:type: int
.. py:attribute:: source_t
:type: int
.. py:attribute:: conflicts
:type: list[tuple[int, int, str]]
.. py:attribute:: failures
:type: list[tuple[int, str]]
.. py:class:: RevertPreview
What reverting would do, without doing it.
``commits`` are the commits that would be undone, newest first (may be
capped; ``commit_count`` is the full count). ``conflicts`` are properties
changed again since those commits. ``revertable`` says whether the revert
would succeed under the previewed strategy and the ledger's SHACL shapes;
when validation would fail, ``violations`` holds the report.
.. py:attribute:: revertable
:type: bool
.. py:attribute:: commits
:type: list[Commit]
.. py:attribute:: commit_count
:type: int
.. py:attribute:: conflicts
:type: list[Conflict]
.. py:attribute:: conflict_count
:type: int
.. py:attribute:: violations
:type: str | None
.. py:class:: RevertResult
The outcome of :meth:`Ledger.revert`.
``reverted`` holds the ids of the undone commits, newest first. When
``committed`` is false the commits had nothing left to undo, no commit was
written, and ``t``/``id`` describe the unchanged head. ``conflicts`` counts
the properties changed since that ``strategy`` resolved.
.. py:attribute:: committed
:type: bool
.. py:attribute:: t
:type: int
.. py:attribute:: id
:type: str
.. py:attribute:: digest
:type: str
.. py:attribute:: reverted
:type: list[str]
.. py:attribute:: conflicts
:type: int
.. py:attribute:: strategy
:type: str
.. py:class:: SweepResult
The outcome of :meth:`Ledger.sweep`: ``orphans`` index files no longer
referenced, of which ``reclaimed`` were deleted (none on a dry run);
``failures`` lists ``(file, error)`` for those that could not be.
.. py:attribute:: dry_run
:type: bool
.. py:attribute:: orphans
:type: int
.. py:attribute:: reclaimed
:type: int
.. py:attribute:: failures
:type: list[tuple[str, str]]
.. py:class:: ValidationReport
The outcome of :meth:`Ledger.validate`. ``conforms`` is false when any
result is a violation. ``shape_count`` is how many shapes were checked —
``0`` means no shapes were found, so the data trivially conforms. ``t`` is
the state that was validated.
.. py:attribute:: conforms
:type: bool
.. py:attribute:: results
:type: list[ValidationResult]
.. py:attribute:: shape_count
:type: int
.. py:attribute:: t
:type: int
.. py:class:: ValidationResult
One way the data fails a SHACL shape.
``focus`` is the node that failed and ``path`` the property, when the
constraint is on one; ``value`` is the offending value, when there is
one. ``severity`` is ``"violation"``, ``"warning"`` or ``"info"``.
``shape`` is the node shape and ``component`` the SHACL constraint
component (``sh:MinCountConstraintComponent``, ...) that produced it.
.. py:attribute:: focus
:type: Any
.. py:attribute:: path
:type: fluree._terms.IRI | None
.. py:attribute:: message
:type: str
.. py:attribute:: severity
:type: str
.. py:attribute:: value
:type: Any
.. py:attribute:: shape
:type: fluree._terms.IRI | fluree._terms.BlankNode
.. py:attribute:: component
:type: fluree._terms.IRI
.. py:class:: VerifyReport
The outcome of :meth:`Ledger.verify`.
``severity`` is ``"healthy"``, ``"provenance"`` (a raw transaction is
missing: the data is intact) or ``"chain"`` (a commit or the index root is
missing or unreadable). ``problems`` describes each one, as a dict with a
``kind``. ``truncated`` means ``max_commits`` stopped the check early.
.. py:attribute:: severity
:type: str
.. py:attribute:: head_t
:type: int
.. py:attribute:: index_t
:type: int
.. py:attribute:: commits_checked
:type: int
.. py:attribute:: truncated
:type: bool
.. py:attribute:: problems
:type: list[dict[str, Any]]
.. py:property:: healthy
:type: bool
Whether nothing was found missing or unreadable.
.. py:function:: set_log_level(level: str | int) -> None
Send the engine's log events at ``level`` and above to the
``fluree.engine`` logger: a :mod:`logging` level (``"INFO"``,
``logging.DEBUG``), ``"TRACE"`` for the most detail, or ``"OFF"``.
Warnings and errors are sent by default.
This sets what the engine produces; the logger's own level and handlers
still decide what is shown. Below the level, the engine skips the events
entirely.
.. py:class:: Record
Bases: :py:obj:`tuple`
One result row: a tuple in the query's column order that can also be
read by column name — ``record["name"]`` or ``record.name`` — with
``get``, ``keys``, ``values``, ``items`` and ``data``.
Attribute access gives way to the methods: a column named ``data`` or
``count`` is read as ``record["data"]``. Unbound values are ``None``.
.. py:method:: get(key: str, default: Any = None) -> Any
The value of column ``key`` (``None`` when unbound), or ``default``
when the result has no column ``key``.
.. py:method:: index(key: str | int) -> int
The position of column ``key``.
.. py:method:: keys() -> list[str]
The column names, in order.
.. py:method:: values(*keys: str | int) -> list[Any]
The values of columns ``keys`` (names or positions), or of every column.
.. py:method:: items(*keys: str | int) -> list[tuple[str, Any]]
``(column, value)`` pairs for columns ``keys``, or for every column.
.. py:method:: data(*keys: str | int) -> dict[str, Any]
The record as a dict of plain values: nodes become their property
dicts, relationships ``(start properties, type, end properties)``.
.. py:class:: Result(keys: list[str], records: list[Record])
Bases: :py:obj:`collections.abc.Sequence`\ [\ :py:obj:`Record`\ ]
The records a SPARQL ``SELECT`` or a Cypher statement returned, in
order. Iterate it, index it, or read it as a whole: ``single()`` for
the one record, ``first()`` for the first, ``value()`` for one column, ``data()`` for dicts,
``to_pandas()`` for a DataFrame.
.. py:method:: keys() -> list[str]
Column names in projection order (SPARQL variables without ``?``).
.. py:property:: columns
:type: list[str]
The same as :meth:`keys`.
.. py:method:: single() -> Record
The one record; :class:`InvalidRequestError` unless there is
exactly one. For "the first record, if any", use :meth:`first`.
.. py:method:: first() -> Record | None
The first record, or ``None`` when there are none.
.. py:method:: value(key: str | int = 0, default: Any = None) -> list[Any]
One column's values, ``default`` where a record lacks it.
.. py:method:: values(*keys: str | int) -> list[list[Any]]
Every record's values, as lists; see :meth:`Record.values`.
.. py:method:: data(*keys: str | int) -> list[dict[str, Any]]
Every record as a dict of plain values; see :meth:`Record.data`.
.. py:method:: to_pandas() -> pandas.DataFrame
The records as a pandas DataFrame, one column per key. Nodes and
relationships stay objects.
.. py:attribute:: to_df
.. py:method:: to_polars() -> polars.DataFrame
The records as a polars DataFrame, one column per key. Nodes and
relationships become object columns.
.. py:class:: RowStream(native: fluree._fluree.RowStream, batch_size: int)
Bases: :py:obj:`collections.abc.Iterator`\ [\ :py:obj:`Record`\ ]
The records of a SELECT, read as the query produces them.
Iterate it like a :class:`Result`; memory stays flat however many records
the query returns. The query runs until the stream ends, :meth:`close`
is called, or the stream is garbage-collected — so when reading may stop
early, use it as a context manager, which closes it at the end of the
block::
with ledger.stream(query) as rows:
for row in rows:
if done(row):
break
.. py:method:: keys() -> list[str] | None
Column names in projection order (for ``SELECT *``, known once the
first record is read).
.. py:property:: columns
:type: list[str] | None
The same as :meth:`keys`.
.. py:method:: close() -> None
Stop the query; the stream yields nothing more.
.. py:class:: AzureServicePrincipal
Microsoft Entra service-principal credentials for Delta tables in
ADLS Gen2 or OneLake.
.. py:attribute:: tenant_id
:type: str
.. py:attribute:: client_id
:type: str
.. py:attribute:: client_secret
:type: Secret
.. py:class:: Bearer
Authenticate with a static bearer token.
.. py:attribute:: token
:type: Secret
.. py:class:: EnvVar
A secret read from environment variable ``name`` where the source is
read, so the secret itself is never stored with the graph source.
.. py:attribute:: name
:type: str
.. py:class:: Glue
An AWS Glue Data Catalog that Iceberg tables are found through: each
mapped ``rr:tableName`` is a Glue ``.``, whose current
metadata file Glue names. The catalog call and the S3 reads use the usual
AWS environment, never vended credentials. ``region`` is the catalog's
region (else ``s3_region``, else the AWS region chain); ``catalog_id``
reads another account's catalog.
.. py:attribute:: region
:type: str | None
:value: None
.. py:attribute:: catalog_id
:type: str | None
:value: None
.. py:class:: GraphSource(connection: fluree._connection.Connection, raw: collections.abc.Mapping[str, Any])
A graph source: tables mapped to RDF and queried in place.
Create one with :meth:`Connection.map_iceberg`, :meth:`Connection.map_delta`
or :meth:`Connection.map_sql`, or look one up with
:meth:`Connection.graph_source`. Query it on its own here, or with other
graph sources and ledgers through :meth:`Connection.query`, naming it in
``FROM `` (SPARQL) or ``"from"`` (JSON-LD).
``id`` is ``name:branch``, and ``kind`` the kind of source, such as
``"iceberg"``, ``"delta"`` or ``"sql"``.
.. py:attribute:: id
:type: str
.. py:attribute:: name
:type: str
.. py:attribute:: branch
:type: str
.. py:attribute:: kind
:type: str
.. py:method:: query(query: fluree._connection.Query, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: fluree._connection.Language | None = None, max_fuel: float | None = None, timeout: float | None = None, **kwparameters: Any) -> Any
Run a SPARQL or JSON-LD query of this source; see
:meth:`Snapshot.query`. Cypher reads ledgers only.
.. py:method:: select(query: str, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: fluree._connection.SelectLanguage | None = None, max_fuel: float | None = None, timeout: float | None = None, **kwparameters: Any) -> fluree._results.Result
Run a SPARQL ``SELECT`` of this source; see :meth:`Snapshot.select`.
.. py:method:: profile(query: fluree._connection.Query, parameters: collections.abc.Mapping[str, Any] | None = None, *, language: fluree._connection.Language | None = None, max_fuel: float | None = None, timeout: float | None = None, **kwparameters: Any) -> fluree._connection.QueryProfile
Run :meth:`query` and report the fuel and time it took.
.. py:method:: materialize(into: str, *, full: bool = False) -> MaterializeResult
Copy this source's rows into ledger ``into`` (created if missing)
as ordinary ledger data, so they gain history, policy and indexes.
Each pass reads only what the source has added since the last pass
into ``into``, where the table's history allows; ``full`` re-reads
everything. A row whose subject reappears replaces it. Iceberg
sources only.
.. py:method:: drop() -> None
Remove this graph source. The tables themselves are not touched.
.. py:class:: MaterializeResult
One :meth:`GraphSource.materialize` pass.
``snapshot`` is the source snapshot now reflected in the ledger (``None``
for a table with no snapshots yet). ``incremental`` says whether only
what the source added since the last pass was read; ``committed`` whether
anything changed in the ledger.
.. py:attribute:: snapshot
:type: int | None
.. py:attribute:: incremental
:type: bool
.. py:attribute:: committed
:type: bool
.. py:attribute:: rows_read
:type: int
.. py:attribute:: subjects_upserted
:type: int
.. py:attribute:: subjects_retracted
:type: int
.. py:class:: OAuth2
Authenticate with OAuth2 client credentials, fetching (and refreshing)
a token from ``token_url`` (which a :class:`Unity` catalog can leave to
its default).
.. py:attribute:: token_url
:type: str | None
.. py:attribute:: client_id
:type: str
.. py:attribute:: client_secret
:type: Secret
.. py:attribute:: scope
:type: str | None
:value: None
.. py:attribute:: audience
:type: str | None
:value: None
.. py:class:: S3Tables
An AWS S3 Tables table bucket that Iceberg tables are found in, named by
its ARN (``arn:aws:s3tables:::bucket/``): each
mapped ``rr:tableName`` is a ``.`` in the bucket. The
region defaults to the ARN's. Reads use the usual AWS environment.
.. py:attribute:: table_bucket_arn
:type: str
.. py:attribute:: region
:type: str | None
:value: None
.. py:class:: Unity
A Databricks Unity Catalog that Delta tables are found and read
through. ``catalog`` and ``schema`` complete table names of fewer than
three parts. An :class:`OAuth2` ``token_url`` defaults to the
workspace's own endpoint.
.. py:attribute:: uri
:type: str
.. py:attribute:: catalog
:type: str | None
:value: None
.. py:attribute:: schema
:type: str | None
:value: None
.. py:attribute:: auth
:type: Auth | None
:value: None
.. py:class:: IRI
Bases: :py:obj:`str`
An IRI. Compares equal to the same IRI as a plain ``str``.
.. py:class:: BlankNode
Bases: :py:obj:`str`
A blank node, by its label (without the ``_:`` prefix).
.. py:class:: LangString
Bases: :py:obj:`str`
A language-tagged string: a ``str`` with a ``language`` tag.
It compares like a string: equal to a plain ``str`` with the same text,
and to another ``LangString`` with the same text and the same tag
(compared case-insensitively, as BCP 47 tags are).
.. py:attribute:: language
:type: str
.. py:class:: Literal
A literal with no lossless Python type, as lexical form and datatype.
.. py:attribute:: value
:type: str
.. py:attribute:: datatype
:type: str
.. py:class:: Vector
Bases: :py:obj:`tuple`
An embedding vector: a tuple of floats, stored as ``f:embeddingVector``.
Build one from any sequence of numbers or a numpy array. Insert it as a
property value, pass it as a query parameter, and read it back from
queries; ``numpy.asarray(vector)`` gives a ``float32`` array. Values are
stored at ``float32`` precision. A one-dimensional numpy array is taken as
a vector wherever a ``Vector`` is.
.. py:exception:: ConflictError
Bases: :py:obj:`FlureeError`
A concurrent change won; retrying against the new state may succeed.
When a commit lost a race, ``expected_t`` is the ledger ``t`` it was
built on and ``head_t`` the ``t`` another commit had moved it to; both
are ``None`` for other conflicts.
.. py:attribute:: expected_t
:type: int | None
:value: None
.. py:attribute:: head_t
:type: int | None
:value: None
.. py:exception:: DatabaseInUseError
Bases: :py:obj:`FlureeError`
The database directory is open in another process.
One process opens a directory at a time, and its threads share that
connection. To use the same data from several processes, run
``fluree server`` on the directory and send requests to it. ``pid`` is
the other process's id, or ``None`` when it could not be read.
.. py:attribute:: pid
:type: int | None
:value: None
.. py:exception:: FlureeError
Bases: :py:obj:`Exception`
Base class for all Fluree errors.
``status`` is the HTTP-style status code the engine assigned the error,
or ``None`` when the error did not come from the engine.
.. py:attribute:: status
:type: int | None
:value: None
.. py:exception:: InvalidRequestError
Bases: :py:obj:`FlureeError`, :py:obj:`ValueError`
The query, transaction, or argument is malformed or invalid.
.. py:exception:: NotFoundError
Bases: :py:obj:`FlureeError`, :py:obj:`LookupError`
A ledger, branch, commit, or graph does not exist.
.. py:exception:: PermissionDeniedError
Bases: :py:obj:`FlureeError`, :py:obj:`PermissionError`
Policy denied the operation.
.. py:exception:: QueryTimeoutError
Bases: :py:obj:`FlureeError`, :py:obj:`TimeoutError`
The operation ran past its time limit.
.. py:exception:: ResourceLimitError
Bases: :py:obj:`FlureeError`
The operation exceeded a fuel, memory, or size limit.
.. py:exception:: ShaclViolationError
Bases: :py:obj:`InvalidRequestError`
A write that would leave data breaking the ledger's SHACL shapes.
``violations`` lists each way it would, as the same
:class:`ValidationResult` objects :meth:`Ledger.validate` reports, so a
rejected write is handled like a failed validation.
.. py:property:: violations
:type: list[fluree._records.ValidationResult]
Each way the write breaks the shapes, as :class:`ValidationResult` objects.
.. py:exception:: UniqueConstraintError
Bases: :py:obj:`InvalidRequestError`
A write that would give two subjects the same value of a property the
ledger requires to be unique (``f:enforceUnique``).
``value`` is the value as text; ``graph`` is the named graph's IRI, or
``None`` for the default graph.
.. py:attribute:: property
:type: fluree._terms.IRI
.. py:attribute:: value
:type: str
.. py:attribute:: graph
:type: fluree._terms.IRI | None
.. py:attribute:: existing_subject
:type: fluree._terms.IRI
.. py:attribute:: new_subject
:type: fluree._terms.IRI