Skip to content

Releases

ttl3d 0.9.2

Choose a tag to compare

@github-actions github-actions released this 03 Nov 04:04
c1355ef

Dependency updates: the vendored bundle and the PyPI upload action.

  • Vendored bundle: 3d-force-graph 1.80.1 and force-graph 1.52.0 (Dependabot #32). Pages look and
    behave as before.
  • CI: PyPI uploads use pypa/gh-action-pypi-publish 1.14.3, which fixes GHSA-5xjx-3w67-w9x9
    (Dependabot #33).

ttl3d 0.9.1

Choose a tag to compare

@github-actions github-actions released this 21 Oct 20:26
6f9bb2b

The leftovers of the 0.9.0 tables release, and release notes where people look for them.

  • The --columns error names the header as you wrote it: --columns id=Key2 reports 'Key2', not
    'key2' (headers still match in any case).
  • A --columns mapping wins over what the header says of itself: --columns id=key:IGNORE reads the
    ids from that column, as it already did; the README says so and a test pins it.
  • The notebook shows a table: a cell reads the Space missions CSV files into DataFrames
    (dtype=str) and shows the page; its install line now asks for ttl3d>=0.9.0.
  • PyPI lists the changelog, the release notes and the demo site beside the repository, and its
    one-line summary and CITATION.cff's title name SPARQL results and tables as well as RDF.
  • Tests: a CI leg installs pandas, so the real-DataFrame test and the notebook's DataFrame cell run
    there; two more loader tests for ids whose rows say nothing; the tests that prove an option is
    checked before standard input is read write the CLI's output to files, not pipes.

ttl3d 0.9.0

Choose a tag to compare

@github-actions github-actions released this 15 Oct 18:22
ce23ed4

Tables as sources: CSV, TSV and DataFrames. ttl3d nodes.csv edges.csv draws a property graph with no
conversion step: a table with source and target columns is an edge table, one with an id column a node
table, and the other columns are properties. Column roles come from header names (in any case;
Neo4j's import headers, APOC's one-file export and Gephi's edge tables are understood), and
--columns source=from_id,... maps any other header. --format csv or tsv reads any file, and
standard input, as a table. In Python, a DataFrame is a table (read through to_csv; pandas is
never imported), and to_html, write and show take columns= and base=.

An id written as an IRI (<...>, ://) is used as is, ex:Dune resolves when an RDF file of the
same run binds ex, and any other id becomes urn:x-ttl3d:<id> (--base picks the namespace), shown
with the prefix csv. Every table of a run shares the ids, so a node table and an edge table meet,
and tables mix with RDF files and queries.

Edge properties: the other cells of an edge row show on the card under the relation row, at both
ends (kind flyby · year 1979). They travel as RDF reification (rdf:Statement), so an RDF file that
reifies its edges gets the same lines; a link with no such statement is unchanged in the page's data,
which adds a statements key only where there are some. The demo site has a Space missions page built
from examples/missions.csv and examples/mission-links.csv.

ttl3d is on conda-forge: conda install -c conda-forge ttl3d (Python 3.11 or newer there; the
feedstock follows each PyPI release).

ttl3d 0.8.1

Choose a tag to compare

@github-actions github-actions released this 12 Oct 14:29
610f6e4

The default output file name no longer holds a colon. An IPv6 endpoint (--endpoint http://[::1]:8890/sparql with inline query text) named it ::1-3d.html, which Windows refuses (and
its pathlib read the leading :: as a drive, losing the working directory); it is __1-3d.html now.
The rule covers whatever source comes first, so a file a:b.ttl now defaults to a_b-3d.html. The
legend row and the page title still read ::1, and -o is taken as given.

ttl3d 0.8.0

Choose a tag to compare

@github-actions github-actions released this 09 Oct 14:27
99b2a78

The rest of the September review: the design items it left open.

Keyboard and screen readers: Tab reaches the legend rows, which toggle with Enter or Space and say
whether they are pressed; Enter in the search box opens the card of the best match among the lit
nodes (the exact label, then labels starting with the text); Tab and Enter walk the card's relations
to the neighbours' cards, and Esc closes the card and puts the focus back in the search box. The
search box, the card and its close button carry labels, and focused controls show a ring. A card
opened with the pointer leaves the focus where it was.

Names: a type, edge label or property whose local name another one on the page shares shows as
prefix:local (the full IRI when its namespace has no prefix), so FOAF's classes read owl:Class, rdfs:Class rather than Class, Class and dc:title no longer merges with dcterms:title; what the
page never names (rdf:type as a predicate, rdfs:label) clashes with nothing. Pages without such a
clash carry the same data as before; of the demo inputs only FOAF changes.

XML: rdflib's RDF/XML and TriX parsers spent about a minute of CPU on a 1 KB "billion laughs" file
or SPARQL answer before expat's own limit stopped them. Every XML input now passes through bare expat
first, which refuses it in milliseconds at about 1% of a normal load; external entities were and are
never fetched.

Errors: running out of memory is one line (out of memory while building the page; ...) instead of a
traceback, and no longer passes for a syntax error. A file whose guessed parser fails no longer
prints rdflib's "does not look like a valid URI" lines from the Turtle retry before its error.
Endpoint messages and the fetch line name the port when the endpoint's URL gives one
(endpoint h.org:8890/sparql answered 500); source names stay the bare host.

Tests: a TriX fixture loads like its N-Quads twin on rdflib 7.0 and 7.6; a sliced run picks its
layout from the slice and announces the slice before the stress layout; every test subprocess has a
timeout.

ttl3d 0.7.2

Choose a tag to compare

@github-actions github-actions released this 09 Oct 05:32
e5ffcb9

Fixes from three code reviews. A page that built before carries the same data; only the card's
source check in the inlined viewer changed (below).

Errors: --max-mb 1e308 and --endpoint 'http://[bad' were Python tracebacks and are one-line errors
now (--max-mb is too large; ttl3d.Query refuses a malformed endpoint as "the endpoint is not a
well-formed URL"). A directory, a missing file or a pipe given as input says which (X is a directory, not a file, X: no such file, X is not a regular file) instead of printing the bare path; the
exception is still FileNotFoundError. A --focus or --attribute-preds term holding a character
Turtle refuses in an IRI (a space or control character, <, {, |, ...), or an empty term, is an
error naming it, so rdflib no longer logs a warning about it and the Python API stays silent. Terms
may have spaces around their commas (--focus "ex:Dune, ex:Asimov").

SPARQL: an answer without a Content-Length is read a megabyte at a time (the read sized its buffer by
the limit, so a huge max_bytes failed and the default reserved 100 MB for any answer); an HTTP error
whose body timed out or broke off is still "answered 500", and the response is closed; a redirect
message has the request's credentials blanked like any other server text, and no credential stays on
the exception chain (__context__ included, also for a header value http.client refuses).

The node card names the sources of its relations whenever more than one source owns a node or asserts
a link; a source that only adds links owns no node, so the card left them out. A set of sources
raises TypeError, since its order, which names the page and orders the legend, followed the hash seed.
Page's repr counts UTF-8 bytes rather than characters. tools/compare_pages.py masks only the run of
five coordinates each pinned node carries, so no other number can be taken for layout drift, and prints
its usage on bad arguments. New tests cover tools/licenses.py, cyclic and shared blank nodes in a
slice, answers read in many chunks, --max-mb inf/nan and the card's source attribution in the
browser.

ttl3d 0.7.1

Choose a tag to compare

@github-actions github-actions released this 05 Oct 18:56
fb1fce8

Vendored bundle: force-graph 1.51.5 and three.js 0.186.1 (Dependabot #23). Pages look and
behave as before. A browser test that checked the 3D scene straight after a 2D-to-3D switch now
waits for it: the scene is rebuilt a few milliseconds later, so the test failed on fast machines.

ttl3d 0.7.0

Choose a tag to compare

@github-actions github-actions released this 14 Sep 20:53
634a620

SPARQL endpoints as sources: --endpoint URL --query TEXT|@FILE (repeatable) fetches a CONSTRUCT or
DESCRIBE result with one POST at build time and treats it like a file, with its own legend row named
after the query file or the endpoint's host; ttl3d.Query(endpoint, query, auth=, token=, timeout=, max_bytes=) is the same source in Python and checks itself when built. Credentials come from
TTL3D_SPARQL_USER/TTL3D_SPARQL_PASSWORD or TTL3D_SPARQL_TOKEN, never from the command line; an
endpoint URL carrying them is refused, repr never shows them, and server text quoted in an error has
them blanked. The query's PREFIX lines name the page's namespaces; the answer is parsed by its media
type (Turtle, N-Triples, RDF/XML, or a quad format folded into the query's one row) with the endpoint as
base, and a JSON-LD answer is refused, since its parser would fetch a remote @context. One-line errors
cover SELECT, ASK and updates (before anything is sent), HTTP errors, redirects (with the URL to use),
timeouts (--timeout, 60 s per network step), answers over --max-mb (100 MB) and answers that break
off midway. load.load gained a notice callback, and the CLI prints fetched N triples from HOST in S s. Files become optional on the command line. Runs without a query are byte-identical to 0.6.0.
Example: examples/wikidata-moons.rq draws the planets and their moons (916 triples, 308 nodes) from
Wikidata in about a second. The fetch line says when credentials went out, and when over plain http; a
token must be printable ASCII without spaces (a trailing line break in a variable is dropped); a query
file may start with a byte-order mark.

ttl3d 0.6.0

Choose a tag to compare

@github-actions github-actions released this 13 Sep 02:33
720d5aa

Slicing at build time, for graphs too big to draw: --focus IRI --hops N keeps a node's
neighbourhood over link predicates, --schema keeps classes and properties without instances, both
together keep the neighbourhood inside the schema, and ttl3d prints what it kept (kept 12 of 41 nodes (focus :Earth, 2 hops)). The same keyword arguments exist on to_html, write and show.
The slice runs on the RDF before the node/link model, keeps blank-node structure whole, brings each
kept node's classes along under --type-links, and leaves cards, legend and named-graph ownership to
the unchanged model code; an unsliced run is byte-identical to 0.5.0. On a million-triple file the
parse takes about 13 s; a two-hop slice then builds in under 1.5 s and a schema slice in under
1.5 s; the cost follows the surviving triples, not the node count.

ttl3d 0.5.0

Choose a tag to compare

@github-actions github-actions released this 12 Sep 19:27
a8c8fc1

Every source has a legend row, including a file or named graph that only annotates other sources'
nodes (its row is muted and its hover text says why), and selecting a row keeps the endpoints of
every edge that source asserts, not only the edges it asserted first, as the README always said;
the colour ranking past twelve sources counts links the same way, and an annotation-only source
takes no colour. The node card shows the IRI behind a named-graph key under the source name, and
legend rows carry it as hover text (DATA.graphs, one additive key in the page). The demo site
gains the Solar System as one TriG dataset, and CI builds that page on three operating systems.