I’ve been playing with the Titan graph database lately; it’s hella cool, super powerful, and has a great ecosystem. One tool in the Titan toolbox is a REST interface called Rexster.
You can check to see that it’s up and what it’s serving up by curl-ing one of its endpoints.
# curl localhost:8182/graphs/graph
{"version":"2.5.0","name":"graph","graph":"titangraph[cassandrathrift:[127.0.0.1]]","features":{"isWrapper":false,"supportsVertexProperties":true,"supportsMapProperty":true,"supportsUniformListProperty":true,"supportsIndices":false,"ignoresSuppliedIds":true,"supportsFloatProperty":true,"supportsPrimitiveArrayProperty":true,"supportsEdgeIndex":false,"supportsKeyIndices":true,"supportsDoubleProperty":true,"isPersistent":true,"supportsVertexIteration":true,"supportsEdgeProperties":true,"supportsSelfLoops":true,"supportsDuplicateEdges":true,"supportsSerializableObjectProperty":true,"supportsEdgeIteration":true,"supportsVertexIndex":false,"supportsIntegerProperty":true,"supportsBooleanProperty":true,"supportsMixedListProperty":true,"supportsEdgeRetrieval":true,"supportsTransactions":true,"supportsThreadedTransactions":true,"supportsStringProperty":true,"supportsVertexKeyIndex":false,"supportsEdgeKeyIndex":false,"supportsLongProperty":true},"readOnly":false,"type":"com.thinkaurelius.titan.graphdb.database.StandardTitanGraph","queryTime":0.213622,"upTime":"0[d]:00[h]:28[m]:25[s]","extensions":[{"op":"GET","namespace":"tp","name":"gremlin","description":"evaluate an ad-hoc Gremlin script for a graph.","href":"http://localhost:8182/graphs/graph/tp/gremlin","title":"tp:gremlin","parameters":[{"name":"rexster.showTypes","description":"displays the properties of the elements with their native data type (default is false)"},{"name":"language","description":"the gremlin language flavor to use (default is groovy)"},{"name":"params","description":"a map of parameters to bind to the script engine"},{"name":"load","description":"a list of 'stored procedures' to execute prior to the 'script' (if 'script' is not specified then the last script in this argument will return the values"},{"name":"returnTotal","description":"when set to true, the full result set will be iterated and the results returned (default is false)"},{"name":"rexster.returnKeys","description":"an array of element property keys to return (default is to return all element properties)"},{"name":"rexster.offset.start","description":"start index for a paged set of data to be returned"},{"name":"rexster.offset.end","description":"end index for a paged set of data to be returned"},{"name":"script","description":"the Gremlin script to be evaluated"}]},{"op":"POST","namespace":"tp","name":"gremlin","description":"evaluate an ad-hoc Gremlin script for a graph.","href":"http://localhost:8182/graphs/graph/tp/gremlin","title":"tp:gremlin","parameters":[{"name":"rexster.showTypes","description":"displays the properties of the elements with their native data type (default is false)"},{"name":"language","description":"the gremlin language flavor to use (default is groovy)"},{"name":"params","description":"a map of parameters to bind to the script engine"},{"name":"load","description":"a list of 'stored procedures' to execute prior to the 'script' (if 'script' is not specified then the last script in this argument will return the values"},{"name":"returnTotal","description":"when set to true, the full result set will be iterated and the results returned (default is false)"},{"name":"rexster.returnKeys","description":"an array of element property keys to return (default is to return all element properties)"},{"name":"rexster.offset.start","description":"start index for a paged set of data to be returned"},{"name":"rexster.offset.end","description":"end index for a paged set of data to be returned"},{"name":"script","description":"the Gremlin script to be evaluated"}]}
Ugly. Python to the rescue.
#!/usr/bin/env python import simplejson import sys import yaml print yaml.dump(simplejson.loads(str(sys.stdin.read())), default_flow_style=False)
Basically a one-liner.
# curl localhost:32791/graphs/graph | python json2yaml.py
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3581 0 3581 0 0 552k 0 --:--:-- --:--:-- --:--:-- 582k
extensions:
- description: evaluate an ad-hoc Gremlin script for a graph.
href: http://localhost:8182/graphs/graph/tp/gremlin
name: gremlin
namespace: tp
op: GET
parameters:
- description: displays the properties of the elements with their native data type
(default is false)
name: rexster.showTypes
- description: the gremlin language flavor to use (default is groovy)
name: language
- description: a map of parameters to bind to the script engine
name: params
- description: a list of 'stored procedures' to execute prior to the 'script' (if
'script' is not specified then the last script in this argument will return
the values
name: load
- description: when set to true, the full result set will be iterated and the results
returned (default is false)
name: returnTotal
- description: an array of element property keys to return (default is to return
all element properties)
name: rexster.returnKeys
- description: start index for a paged set of data to be returned
name: rexster.offset.start
- description: end index for a paged set of data to be returned
name: rexster.offset.end
- description: the Gremlin script to be evaluated
name: script
title: tp:gremlin
- description: evaluate an ad-hoc Gremlin script for a graph.
href: http://localhost:8182/graphs/graph/tp/gremlin
name: gremlin
namespace: tp
op: POST
parameters:
- description: displays the properties of the elements with their native data type
(default is false)
name: rexster.showTypes
- description: the gremlin language flavor to use (default is groovy)
name: language
- description: a map of parameters to bind to the script engine
name: params
- description: a list of 'stored procedures' to execute prior to the 'script' (if
'script' is not specified then the last script in this argument will return
the values
name: load
- description: when set to true, the full result set will be iterated and the results
returned (default is false)
name: returnTotal
- description: an array of element property keys to return (default is to return
all element properties)
name: rexster.returnKeys
- description: start index for a paged set of data to be returned
name: rexster.offset.start
- description: end index for a paged set of data to be returned
name: rexster.offset.end
- description: the Gremlin script to be evaluated
name: script
title: tp:gremlin
features:
ignoresSuppliedIds: true
isPersistent: true
isWrapper: false
supportsBooleanProperty: true
supportsDoubleProperty: true
supportsDuplicateEdges: true
supportsEdgeIndex: false
supportsEdgeIteration: true
supportsEdgeKeyIndex: false
supportsEdgeProperties: true
supportsEdgeRetrieval: true
supportsFloatProperty: true
supportsIndices: false
supportsIntegerProperty: true
supportsKeyIndices: true
supportsLongProperty: true
supportsMapProperty: true
supportsMixedListProperty: true
supportsPrimitiveArrayProperty: true
supportsSelfLoops: true
supportsSerializableObjectProperty: true
supportsStringProperty: true
supportsThreadedTransactions: true
supportsTransactions: true
supportsUniformListProperty: true
supportsVertexIndex: false
supportsVertexIteration: true
supportsVertexKeyIndex: false
supportsVertexProperties: true
graph: titangraph[cassandrathrift:[127.0.0.1]]
name: graph
queryTime: 0.31277
readOnly: false
type: com.thinkaurelius.titan.graphdb.database.StandardTitanGraph
upTime: 0[d]:00[h]:31[m]:27[s]
version: 2.5.0
I love Python. YAML ain’t bad, either.