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.