DataDungeon::API
Inherits HTTP::Handler < Reference < Object
A JSON API over a DB, for tools that browse and curate a store from
elsewhere, such as an asset browser. Mount it in an application's HTTP
server (it's an HTTP::Handler, under prefix), or run it alone next to
the database with dd-serve.
Tokens go in Authorization: Bearer <token>. Reads need read_token,
or nothing when it's nil (for a server only this machine can reach).
Writes need write_token; with none, there are no writes. The write
token reads too. A read-only DB refuses writes whatever the token.
GET /types types, counts (current and retired), registrations
and every consumer's indexes
GET /types/:type/tags tag names and how many assets carry each
GET /types/:type/tags/:key a tag's values, most frequent first (?limit=)
GET /types/:type/views how many pictures are seen from each named direction
GET /assets a page of assets with their tags, newest first:
?type= &q= (whole words, catt* for a start)
&tag.<key>= &link.<rel>=<name> (or <name>.*
for it and the names under it, <start>*)
&unlinked=<rel> &file_hash=<sha-256>
&description_hash=<sha-256> (every asset sharing
a description) &text.<kind>=<owner:name> (a
wording a recipe used; @<version> for one wording)
&limit= &page=<n> or &before=<id>
&count=1 (a total), &meta=1 (each picture's fields,
and its view readably)
picture fields: &field.<name>=<low>..<high> (either
end open), &view=<named direction>, &view.side=
&view.yaw= &view.pitch= &view.within=<degrees>,
and the same for light
Listings and counts take current assets, or with
?retired=only retired ones, =include both
GET /assets/:id an asset, its tags, custom tags, metadata (with a
picture's view and light readably) and links
GET /assets/:id/object its bytes, streamed from the storage
GET /assets/:id/recipe how it was made (DB#recipe): what was sent, the
wordings it used (owner:name@version),
steps included; 404 when it has none
GET /assets/:id/links its links, and the links to it
GET /assets/:id/tracks what tools measured of a sound or video over time
(DB#tracks): each track's name, tool, made_at and
cues [{start_ms, end_ms, value}]
GET /assets/:id/tracks/:name one track; 404 when it has none of that name
POST /maintenance/check check_consistency's report
GET /objects every object key the store's rows use (object_keys),
for clearing a shared bucket
GET /vocabulary the shared tags and their values, with their titles
(DB#vocabulary), each rating with DataDungeon's
words for it; DataDungeon's asset types
(DB::STANDARD_TYPES); and the shared tracks
(DB::STANDARD_TRACKS)
GET /types/:type/matches best matches, given a matcher (MatchIndex):
?trait.<k>=<v> &field.<f>=<v> (view=back-left,
dominant-color=#aa3311) &require=a,b &weight.<k>=<n> &limit=
GET /assets/:id/similar the assets closest to this one: ?require= &weight.<k>= &limit=
GET /search assets by meaning, given a searcher (SemanticIndex), best
first with their scores: ?q= &type= &media= &tag.<k>=
&key= &key_prefix= &facet= (one facet of type) &limit=
&min_score=; or one query per facet, &facet.<name>=<q>
with type: each asset scores its weakest
GET /search/status the store's embedding model, and how many texts wait
to be embedded or failed
POST /assets a file added by hand, as multipart/form-data: file
(its Content-Type the asset's) and asset, JSON
{type, tags, custom, description, permanent,
made_at, supersedes, image}; stored as not generated,
with no recipe; image as PATCH takes it, plus how
to store the file ({compression: "normalize",
target_format: "tiff"} for 8-bit 64x64 tiles); 409
with asset_id when its type already holds the bytes;
413 for a file over max_upload (256 MiB)
POST /assets/:id/webp {tags, quality}: a picture's WebP as an asset of its
own, its tags with these over them, linked
derived-from it (DB#store_webp); 409 as above
PATCH /assets/:id {tags, description, everywhere, flagged, rating,
permanent, image}: update_asset;
image holds the fields an application sets, view
and light as {side, yaw, pitch, roll}
DELETE /assets/:id
POST /assets/:id/links {rel, to (an asset id) or name, data}: link
(rel supersedes: supersede)
DELETE /assets/:id/links ?rel= &to= or &name=: unlink
POST /assets/:id/retire retire: hidden, kept, reversible
POST /assets/:id/reinstate reinstate
POST /maintenance/prune {type, keep_last, retired_before}: delete retired assets
POST /maintenance/measure {type, all}: measure_images
PUT /assets/:id/keyframes [{at_ms, held, view, light, anchor_x, anchor_y}]:
set_keyframes (view and light readably)
PUT /assets/:id/tracks/:name {tool, cues}: set_track, replacing the track
POST /types/:type/promote {trait, value}: promote
POST /maintenance/vacuum {delete_missing_rows, delete_orphan_objects}
Constants
MAX_ASSET_PART = (1_i64 * 1024) * 1024
MAX_PAGE = 500
MAX_UPLOAD = (256_i64 * 1024) * 1024
The most an upload's file may hold unless max_upload: says otherwise,
and its asset part (JSON): read no further than that, so a body of any
size can't fill the server's memory.
PAGE = 50