graphcommons 0.0.5-universal-darwin-15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/graphcommons.rb +381 -0
- metadata +58 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: cde0b484b5fe5f1312d1afb0efc5a82a971db2a1
|
4
|
+
data.tar.gz: 7caf49606f88e2ae7c56b8ee32af03dfb5483fa0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f268db4e190c44310fda1e74cef416358fc8a89f6bd8a6cc65e6b68b1e9a7e49010716597b3ce3550aeb054bfe359f175f5b9b30404eebd82f8126ab9e33ce30
|
7
|
+
data.tar.gz: 6c0a7c41d38ce631226cfe815219c920d0f94e3944c416db8ad2dbfe587c9bfe65ec3e2b433285b90be472b887cbd5de5892d995136d6637e8ab774d5b6122e6
|
data/lib/graphcommons.rb
ADDED
@@ -0,0 +1,381 @@
|
|
1
|
+
#! /bin/ruby
|
2
|
+
|
3
|
+
require 'rest-client'
|
4
|
+
require 'json'
|
5
|
+
require 'pp'
|
6
|
+
|
7
|
+
# Ruby wrapper for Graphcommons REST API that is used
|
8
|
+
# to programmatically make network maps (graphs) and integrate graphs into your
|
9
|
+
# applications.
|
10
|
+
#
|
11
|
+
# To get started, sign up to Graph Commons and get your developer key, which
|
12
|
+
# will be used for authentication in your API calls.
|
13
|
+
#
|
14
|
+
# More info at: http://graphcommons.github.io/api-v1/
|
15
|
+
|
16
|
+
module Graphcommons
|
17
|
+
|
18
|
+
@@verbose = false
|
19
|
+
# Check verbose output. Default is +false+.
|
20
|
+
def self.verbose
|
21
|
+
@@verbose
|
22
|
+
end
|
23
|
+
|
24
|
+
# Switch on verbose output.
|
25
|
+
def self.verbose!
|
26
|
+
@@verbose = true
|
27
|
+
end
|
28
|
+
|
29
|
+
# Switch off verbose output.
|
30
|
+
def self.quiet!
|
31
|
+
@@verbose = false
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
# Custom error class for Graphcommons API.
|
36
|
+
#
|
37
|
+
# Set +Graphcommons.verbose+ to +true+ in order to get stack trace.
|
38
|
+
class APIError < RuntimeError
|
39
|
+
# :nodoc:
|
40
|
+
def backtrace
|
41
|
+
if Graphcommons.verbose
|
42
|
+
caller
|
43
|
+
else
|
44
|
+
[]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Low-level wrapper for API calls.
|
50
|
+
class API
|
51
|
+
|
52
|
+
@@apiurl = "https://graphcommons.com/api/v1"
|
53
|
+
@@apikey ||= ENV["GRAPHCOMMONS_API_KEY"]
|
54
|
+
|
55
|
+
# Handles *GET* requests, returns API response as ruby hash.
|
56
|
+
def self.get endpoint, options = {}
|
57
|
+
uri = self._gd(endpoint, options)
|
58
|
+
puts "GET #{uri}" if Graphcommons.verbose
|
59
|
+
RestClient.get(uri,:authentication=>@@apikey,:content_type=>"application/json") {|data| self._respond data, uri, options}
|
60
|
+
end
|
61
|
+
|
62
|
+
# Handles *DELETE* requests, returns API response as ruby hash.
|
63
|
+
def self.delete endpoint, options = {}
|
64
|
+
uri = self._gd(endpoint, options)
|
65
|
+
puts "DELETE #{uri}" if Graphcommons.verbose
|
66
|
+
RestClient.delete(uri,:authentication=>@@apikey,:content_type=>"application/json") {|data| self._respond data, uri, options}
|
67
|
+
end
|
68
|
+
|
69
|
+
# Handles *POST* requests, returns API response as ruby hash.
|
70
|
+
def self.post endpoint, options = {}
|
71
|
+
uri, query = self._pp endpoint, options
|
72
|
+
puts "POST #{uri} #{query}" if Graphcommons.verbose
|
73
|
+
RestClient.post(uri,query.to_json,:authentication=>@@apikey,:content_type=>"application/json") {|data| self._respond data, uri, query}
|
74
|
+
end
|
75
|
+
|
76
|
+
# Handles *PUT* requests, returns API response as ruby hash.
|
77
|
+
def self.put endpoint, options = {}
|
78
|
+
uri, query = self._pp endpoint, options
|
79
|
+
puts "PUT #{uri} #{query}" if Graphcommons.verbose
|
80
|
+
RestClient.put(uri,query.to_json,:authentication=>@@apikey,:content_type=>"application/json") {|data| self._respond data, uri, query}
|
81
|
+
end
|
82
|
+
|
83
|
+
# Sets API key.
|
84
|
+
#
|
85
|
+
# Returns +true+ if key is changed, +false+ if not changed, raises APIError
|
86
|
+
# if key argument fails /^sk_.\{22\}$/ test.
|
87
|
+
#
|
88
|
+
# To get the key, please visit https://graphcommons.com/me/edit
|
89
|
+
def self.set_key key
|
90
|
+
raise Graphcommons::APIError.new("Invalid API key\nKey should be in following format: sk_XXXXXXXXXXXXXXXXXXXXXX") unless key.match(/^sk_.{22}$/)
|
91
|
+
if @@apikey == key
|
92
|
+
return false
|
93
|
+
else
|
94
|
+
@@apikey = key
|
95
|
+
true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Checks API key to /^sk_.\{22\}$/ test.
|
100
|
+
#
|
101
|
+
# Returns +true+ or +false+.
|
102
|
+
def self.check_key
|
103
|
+
@@apikey and @@apikey.length > 3
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
def self._respond data, uri, query={}
|
108
|
+
begin
|
109
|
+
return JSON.parse(data)
|
110
|
+
rescue
|
111
|
+
if match = data.match(/status[^\w]+\d\d\d[^\w]+status/)
|
112
|
+
code = match.to_s.gsub(/\D/,"")
|
113
|
+
error = ["Not found","Server error"][code[0].to_i-4]+" (#{code})\nURI: #{uri}"
|
114
|
+
error += "\nQUERY: #{query.to_json}" if query.any?
|
115
|
+
raise Graphcommons::APIError.new(error)
|
116
|
+
else
|
117
|
+
return data
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def self._gd endpoint, options
|
123
|
+
raise Graphcommons::APIError.new("API key not set\nHint: use Graphcommons::API.set_key method or GRAPHCOMMONS_API_KEY environment variable.") unless self.check_key
|
124
|
+
ep = endpoint.to_s.gsub /(^\/|\/$)/, ""
|
125
|
+
options[:query] = "*" if (!options.has_key?(:query) or !options.has_key?("query")) and ep.match(/search/)
|
126
|
+
id = options.delete :id if options.has_key? :id
|
127
|
+
id = options.delete "id" if options.has_key? "id"
|
128
|
+
uri = "#{@@apiurl}/#{ep.split(/\//)[0]}/#{id}"
|
129
|
+
uri += "/#{ep.split(/\//)[1..-1].join("/")}" if ep.match /\//
|
130
|
+
uri += "?#{options.map{|k,v| "#{k}=#{v}"}.join("&")}" if options.any?
|
131
|
+
uri = uri.gsub(/\/\//,"/").sub(/\//,"//")
|
132
|
+
end
|
133
|
+
|
134
|
+
def self._pp endpoint, options
|
135
|
+
raise Graphcommons::APIError.new("API key not set\nHint: use Graphcommons::API.set_key method or GRAPHCOMMONS_API_KEY environment variable.") unless self.check_key
|
136
|
+
ep = endpoint.to_s.gsub /(^\/|\/$)/, ""
|
137
|
+
id = options.delete :id if options.has_key? :id
|
138
|
+
id = options.delete "id" if options.has_key? "id"
|
139
|
+
uri = "#{@@apiurl}/#{ep.split(/\//)[0]}/#{id}"
|
140
|
+
uri += "/#{ep.split(/\//)[1..-1].join("/")}" if ep.match /\//
|
141
|
+
uri = uri.gsub(/\/\//,"/").sub(/\//,"//")
|
142
|
+
return uri, options
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Wrapper for *search* endpoints in the API.
|
147
|
+
class Search < API
|
148
|
+
# Search for *graphs*.
|
149
|
+
def self.graphs query={}
|
150
|
+
self.get "graphs/search", query
|
151
|
+
end
|
152
|
+
# Search for *nodes*.
|
153
|
+
def self.nodes query={}
|
154
|
+
self.get "nodes/search", query
|
155
|
+
end
|
156
|
+
# Search through *users*, *graphs* and *nodes*.
|
157
|
+
def self.search query={}
|
158
|
+
self.get "search", query
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# Wrapper for general methods in the API.
|
163
|
+
class Endpoint < API
|
164
|
+
|
165
|
+
# Get API status.
|
166
|
+
# http://graphcommons.github.io/api-v1/#get-status
|
167
|
+
def self.status
|
168
|
+
self.get :status
|
169
|
+
end
|
170
|
+
|
171
|
+
# Create new graph.
|
172
|
+
# Required options: +:name+
|
173
|
+
#
|
174
|
+
# http://graphcommons.github.io/api-v1/#post-graphs
|
175
|
+
def self.new_graph options
|
176
|
+
self.post :graphs, options
|
177
|
+
end
|
178
|
+
|
179
|
+
# Get graph by *:id*.
|
180
|
+
#
|
181
|
+
# http://graphcommons.github.io/api-v1/#get-graphs-id
|
182
|
+
def self.get_graph id
|
183
|
+
self.get :graphs, :id => id
|
184
|
+
end
|
185
|
+
|
186
|
+
# Get node and edge types inside graph with *:id*.
|
187
|
+
#
|
188
|
+
# http://graphcommons.github.io/api-v1/#get-graphs-id-types
|
189
|
+
def self.get_graph_types id
|
190
|
+
self.get "graphs/types", :id => id
|
191
|
+
end
|
192
|
+
|
193
|
+
# Get edges inside graph with *:id*.
|
194
|
+
#
|
195
|
+
# http://graphcommons.github.io/api-v1/#get-graphs-id-edges
|
196
|
+
def self.get_graph_edges id, options
|
197
|
+
options[:id] = id
|
198
|
+
self.get "graphs/edges", options
|
199
|
+
end
|
200
|
+
|
201
|
+
# Query for paths inside graph with *:id*.
|
202
|
+
#
|
203
|
+
# http://graphcommons.github.io/api-v1/#get-graphs-id-paths
|
204
|
+
# http://graphcommons.github.io/api-v1/#paths-endpoint-details
|
205
|
+
def self.get_graph_paths id, options
|
206
|
+
options[:id] = id
|
207
|
+
self.get "graphs/paths", options
|
208
|
+
end
|
209
|
+
|
210
|
+
# Modify attributes of graph with *:id*.
|
211
|
+
#
|
212
|
+
# http://graphcommons.github.io/api-v1/#put-graphs-id
|
213
|
+
def self.update_graph id, options
|
214
|
+
self.put :graphs, :id => id, :graph=> options
|
215
|
+
end
|
216
|
+
|
217
|
+
# Delete graph with *:id*.
|
218
|
+
#
|
219
|
+
# http://graphcommons.github.io/api-v1/#delete-graphs-id
|
220
|
+
def self.delete_graph id
|
221
|
+
self.delete :graphs, :id => id
|
222
|
+
end
|
223
|
+
|
224
|
+
# Get node by *:id*.
|
225
|
+
#
|
226
|
+
# http://graphcommons.github.io/api-v1/#get-nodes-id
|
227
|
+
def self.get_node id
|
228
|
+
self.get :nodes, :id => id
|
229
|
+
end
|
230
|
+
|
231
|
+
# Get hub by *:id*.
|
232
|
+
#
|
233
|
+
# http://graphcommons.github.io/api-v1/#get-hubs-id
|
234
|
+
def self.get_hub id
|
235
|
+
self.get :hubs, :id => id
|
236
|
+
end
|
237
|
+
|
238
|
+
# Get node and edge types in hub with *:id*.
|
239
|
+
#
|
240
|
+
# http://graphcommons.github.io/api-v1/#get-hubs-id-types
|
241
|
+
def self.get_hub_types id
|
242
|
+
self.get "hubs/types", :id => id
|
243
|
+
end
|
244
|
+
|
245
|
+
# Query for paths inside hub with *:id*.
|
246
|
+
#
|
247
|
+
# http://graphcommons.github.io/api-v1/#get-hubs-id-paths
|
248
|
+
# http://graphcommons.github.io/api-v1/#paths-endpoint-details
|
249
|
+
def self.get_hub_paths id, options
|
250
|
+
options[:id] = id
|
251
|
+
self.get "hubs/paths", options
|
252
|
+
end
|
253
|
+
|
254
|
+
# Search for graphs inside hub with *:id*.
|
255
|
+
#
|
256
|
+
# http://graphcommons.github.io/api-v1/#get-hubs-id-graphs
|
257
|
+
def self.get_hub_graphs id, options
|
258
|
+
options[:id] = id
|
259
|
+
self.get "graphs/search", options
|
260
|
+
end
|
261
|
+
|
262
|
+
# Search for nodes inside hub with *:id*.
|
263
|
+
#
|
264
|
+
# http://graphcommons.github.io/api-v1/#get-hubs-id-nodes
|
265
|
+
def self.get_hub_nodes id, options
|
266
|
+
options[:id] = id
|
267
|
+
self.get "nodes/search", options
|
268
|
+
end
|
269
|
+
|
270
|
+
end
|
271
|
+
|
272
|
+
# Changes to the nodes and edges of a graph are carried out by a series of
|
273
|
+
# commands called signals in the request body. With these signals you can
|
274
|
+
# add, update or delete nodes, edges, node types and edge types.
|
275
|
+
#
|
276
|
+
# Mind that +:id+ parameter is required in all calls.
|
277
|
+
class Signal < API
|
278
|
+
|
279
|
+
# This signal type is used for creating nodes. All signals of this type
|
280
|
+
# must define a type and name key. type - name pairs must be unique.
|
281
|
+
#
|
282
|
+
# Upon saving this signal, a new node id is created. The type of the node
|
283
|
+
# is matched with a predefined node type from the hub/graph. If the node
|
284
|
+
# type does not already exist, a node type is created.
|
285
|
+
#
|
286
|
+
# Required options: +:name+, +:type+
|
287
|
+
#
|
288
|
+
# http://graphcommons.github.io/api-v1/#node_create
|
289
|
+
def self.node_create id, options
|
290
|
+
options[:action] = :node_create
|
291
|
+
self._signal id, options
|
292
|
+
end
|
293
|
+
|
294
|
+
# This signal type is used for creating edges. Source and target nodes for
|
295
|
+
# the edge will be created if they don’t already exist. Only one instance
|
296
|
+
# of edgetype is allowed between the same nodes. However, there could be
|
297
|
+
# multiple edges between the same node pair, as long as the their edge
|
298
|
+
# types are different.
|
299
|
+
#
|
300
|
+
# Upon saving this signal a new edge id is created. The type of the edge is
|
301
|
+
# matched with a predefined edge type from the hub/graph. If the edge type
|
302
|
+
# does not already exist, a new edge type is created.
|
303
|
+
#
|
304
|
+
# Required options: +:from_type+, +:from_name+, +:to_type+, +:to_name+, +:name+
|
305
|
+
#
|
306
|
+
# http://graphcommons.github.io/api-v1/#edge_create
|
307
|
+
def self.edge_create id, options
|
308
|
+
options[:action] = :edge_create
|
309
|
+
self._signal id, options
|
310
|
+
end
|
311
|
+
|
312
|
+
# This signal type is used for updating a node. All fields except for id
|
313
|
+
# will be updated in the node.
|
314
|
+
#
|
315
|
+
# http://graphcommons.github.io/api-v1/#node_update
|
316
|
+
def self.node_update id, options
|
317
|
+
options[:action] = :node_update
|
318
|
+
self._signal id, options
|
319
|
+
end
|
320
|
+
|
321
|
+
# This signal type is used for updating an edge. All fields except for id
|
322
|
+
# will be updated in the node.
|
323
|
+
#
|
324
|
+
# Required options: +:from+, +:to+
|
325
|
+
#
|
326
|
+
# http://graphcommons.github.io/api-v1/#edge_update
|
327
|
+
def self.edge_update id, options
|
328
|
+
options[:action] = :edge_update
|
329
|
+
self._signal id, options
|
330
|
+
end
|
331
|
+
|
332
|
+
# This signal type is used for deleting nodes.
|
333
|
+
#
|
334
|
+
# http://graphcommons.github.io/api-v1/#node_delete
|
335
|
+
def self.node_delete id, options
|
336
|
+
options[:action] = :node_delete
|
337
|
+
self._signal id, options
|
338
|
+
end
|
339
|
+
|
340
|
+
# This signal type is used for deleting edges.
|
341
|
+
#
|
342
|
+
# http://graphcommons.github.io/api-v1/#edge_delete
|
343
|
+
def self.edge_delete id, options
|
344
|
+
options[:action] = :edge_delete
|
345
|
+
self._signal id, options
|
346
|
+
end
|
347
|
+
|
348
|
+
# http://graphcommons.github.io/api-v1/#nodetype_update
|
349
|
+
def self.nodetype_update id, options
|
350
|
+
options[:action] = :nodetype_update
|
351
|
+
self._signal id, options
|
352
|
+
end
|
353
|
+
|
354
|
+
# http://graphcommons.github.io/api-v1/#edgetype_update
|
355
|
+
def self.edgetype_update id, options
|
356
|
+
options[:action] = :edgetype_update
|
357
|
+
self._signal id, options
|
358
|
+
end
|
359
|
+
|
360
|
+
# http://graphcommons.github.io/api-v1/#nodetype_delete
|
361
|
+
def self.nodetype_delete id, options
|
362
|
+
options[:action] = :nodetype_delete
|
363
|
+
self._signal id, options
|
364
|
+
end
|
365
|
+
|
366
|
+
# http://graphcommons.github.io/api-v1/#edgetype_delete
|
367
|
+
def self.edgetype_delete id, options
|
368
|
+
options[:action] = :edgetype_delete
|
369
|
+
self._signal id, options
|
370
|
+
end
|
371
|
+
|
372
|
+
private
|
373
|
+
def self._signal id, options
|
374
|
+
options = [options] unless options.is_a? Array
|
375
|
+
self.put "graphs/add", :id => id, :signals => options
|
376
|
+
end
|
377
|
+
|
378
|
+
end
|
379
|
+
|
380
|
+
end
|
381
|
+
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: graphcommons
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
|
+
platform: universal-darwin-15
|
6
|
+
authors:
|
7
|
+
- Yakup Cetinkaya
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.8'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.8'
|
27
|
+
description: 'Ruby wrapper for Graphcommons API. More info at: http://graphcommons.github.io/api-v1/'
|
28
|
+
email: yakup.cetinkaya@gmail.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- lib/graphcommons.rb
|
34
|
+
homepage: https://github.com/graphcommons/graphcommons-ruby
|
35
|
+
licenses:
|
36
|
+
- GPL-3.0
|
37
|
+
metadata: {}
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - '>='
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 2.0.14.1
|
55
|
+
signing_key:
|
56
|
+
specification_version: 4
|
57
|
+
summary: Ruby wrapper for Graphcommons API
|
58
|
+
test_files: []
|