Files

225 lines
8.3 KiB
Plaintext

/graph
GET (Accept: application/json, application/x-msgpack)
Can be filtered by supplying query parameters 'user' and 'role' - see below
If no queries ('q') are supplied:
returns listing of available graphs, including a the contents of 'meta' and a few other magic fields
Else, iterates over list of graphs and executes queries - see below:
returns a list such that the first entry is:
[query patterns]
and subsequent entries are:
[<graph>, <query index>, chain]
POST (Accept: application/json, application/x-msgpack)
(Content-Type: application/json, application/x-msgpack)
body should be object w/ the optional kv pairs below
{
"seed": true, // mark any referenced nodes/edges as seeds (nodes are assigned depth=0)
"meta": {}, // same structure as POST /graph, merges graph-level kv pairs
'chains': [], // list of node[->edge->node]* object chains
'nodes': [], // list of nodes
'edges': [], // list of edges
}
all node objects must have:
a) type/value combo
all edge objects referenced in chains must have:
a) type[/value] (optional value defaults to empty string)
all edge objects referenced in edges must have:
a) type[/value] (optional value defaults to empty string)
b) src and tgt attributes, with node objects as values (as above, must have type/value attributes)
Nodes and edges will be created as necessary if type/value or type/value/src/tgt combos do not already exist
Any supplied 'depth' property on a node is silently ignored (use seed flag to set node depth=0).
Any supplied 'cost' property on an edge is silently ignored if either is true:
a) cost < 0 or cost > 1
b) cost > target edge's current cost
/graph/<uuid>
HEAD
GET (Accept: application/json, application/x-msgpack, application/octet-stream)
if application/octet-stream:
dumps binary lemongraph snapshot, ignores QUERY_STRING parameters
elif application/x-msgpack or application/json:
QUERY_STRING parameters:
q=<pattern> (see LemonGraph/MatchLGQL.py for query pattern docs)
crawl=<string> ('0' or not '0')
start=<x> (x > 0)
stop=<y> (y > 0)
limit=<z> (z >= 0)
w/out supplied q, the other options are meaningless
without supplied q:
return a full graph dump - only valid for application/json
(I have not settled on a streaming format for application/x-msgpack)
only other param employed is 'stop' - dumped graph will include
changes up to and including supplied ID
with both q and crawl supplied, and crawl is not '0':
return sub-graph[s] - only valid for application/json
traverse graph, using chain data returned from queries as starting points
only other param employed is 'stop' - dumped sub-graph[s] will include
changes up to and including supplied ID
otherwise:
if limit:
limit all query responses to that many chains
if start && stop:
evaluate streaming query over ID range [start, stop]
elif start:
evaluate streaming query over ID range [start, inf)
eilf stop:
evaluate ad-hoc query as of position
streams a single lists of lists:
first entry is a sorted list of the requested query patterns
remaining entries are tuples of query pattern index and matching chain
POST (Content-Type: application/json, application/x-msgpack)
target graph must exist already, unless 'create' is in the query parameters (no value required)
body should be object w/ the optional kv pairs below
{
"seed": true, // mark any referenced nodes/edges as seeds (nodes are assigned depth=0)
"meta": {}, // same structure as POST /graph, merges graph-level kv pairs
'chains': [], // list of node[->edge->node]* object chains
'nodes': [], // list of nodes
'edges': [], // list of edges
}
all node objects must have at minimum either of:
a) type/value combo
b) ID (node must exist already)
all edge objects referenced in chains must have at minimum either of:
a) type[/value] (optional value defaults to empty string)
b) ID (edge must exist already)
all edge objects referenced in edges must have at minimum either of:
a) type[/value] (optional value defaults to empty string), along with:
1) src and tgt attributes, with node objects as values (as above, must have ID or type/value attributes)
b) ID (edge must exist already)
When not referenced by ID, nodes and edges will be created as necessary if type/value or type/value/src/tgt combos do not already exist
Any supplied 'depth' property on a node is silently ignored (use seed flag to set node depth=0).
Any supplied 'cost' property on an edge is silently ignored if either is true:
a) cost < 0 or cost > 1
b) cost > target edge's current cost
PUT (application/octet-stream)
expects graph binary as input
DELETE
Deletes given graph.
/graph/<uuid>/meta
GET (Accept: application/json, application/x-msgpack)
PUT (Content-Type: application/json, application/x-msgpack)
/graph/<uuid>/status
HEAD
GET (Accept: application/json, application/x-msgpack)
/reset/<uuid>
PUT
Clears entire graph db and re-inserts the first POST marked as seed data, if present.
Payload should be empty.
/graph/<uuid>/node/<id>
GET (Accept: application/json, application/x-msgpack)
PUT (Content-Type: application/json, application/x-msgpack)
/graph/<uuid>/edge/<id>
GET (Accept: application/json, application/x-msgpack)
PUT (Content-Type: application/json, application/x-msgpack)
/graph/exec
POST (Content-Type: application/python)
Post python script body that at minimum defines a handler function like so:
def handler(txns_uuids, headers, **kwargs):
pass
After loading, it will be called with:
* a generator that yields tuples of read-only transaction handle and matching uuid
* the response headers object
* and any supplied QUERY_STRING parameters as named parameters
Optionally filter graphs by supplying user and role parameters (they will be excluded from the kwargs fed to the handler)
/graph/<uuid>/exec
POST (Content-Type: application/python)
Post python script body that at minimum defines a handler function like so:
def handler(txn, uuid, headers, **kwargs):
pass
After loading, it will be called with:
* a read-only transaction handle
* the graph uuid
* the response headers object
* and any supplied QUERY_STRING parameters as named parameters
/graph/<uuid>/seeds
GET (Accept: application/json, application/x-msgpack)
Returns ordered list of posted payloads that were marked as seeds.
/kv/<uuid> - non-logged key/value pairs
GET (Accept: application/json, application/x-msgpack)
Retrieves dictionary
PUT (Content-Type: application/json, application/x-msgpack)
Overwrites dictionary
POST (Content-Type: application/json, application/x-msgpack)
Merges dictionary
DELETE
Deletes dictionary
/kv/<uuid>/<key> - non-logged key/value pairs
GET (Accept: application/json, application/x-msgpack)
Retrieves specific dictionary key
PUT (Content-Type: application/json, application/x-msgpack)
Overwrites specific dictionary key
POST (Content-Type: application/json, application/x-msgpack)
Merges specific dictionary key
DELETE
Deletes specific dictionary key
/view/<uuid>
GET
Returns html that presents a graph using D3
/d3/<uuid>
GET
Streams D3-friendly json dump of graph
Magic Meta Keys:
If present, several meta keys are harvested, transformed, and cached
by the top-level graph tracking layer:
'enabled':
bool(value) is cached, defaulting: true
'priority':
clamped to be in numeric range [0-255], default: 100
'roles':
if dictionary:
keys are users
values can be either:
a) strings of one or more words
b) dictionaries of:
role: boolean
For example, here are the two styles:
{
"alice" : "reader writer",
"bob": { "reader": true, "writer": false }
}
This data is indexed such that you can pull:
* a list of graphs that Alice has any active role:
/graph?user=alice
* a list of graphs that Bob is either a reader or a writer for:
/graph?user=bob&role=reader&role=writer
In addition, if user & optionally role arguments are supplied, any HTTP request to /graph/<uuid>
or deeper will enforce either:
a) if specified, that the supplied user is a member of at least one of the supplied roles
b) else if no roles are supplied, that the supplied user is a member of at least one role