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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/graphcommons.rb +381 -0
  3. 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
@@ -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: []