Class: Kasabi::Sparql::Client

Inherits:
BaseClient show all
Defined in:
lib/kasabi/api/sparql.rb

Overview

A simple SPARQL client that handles the basic HTTP traffic

Constant Summary collapse

VARIABLE_MATCHER =
/(\?|\$)([a-zA-Z]+)/

Instance Attribute Summary

Attributes inherited from BaseClient

#apikey, #client, #endpoint

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from BaseClient

#client_options, #get, #post, #validate_response

Constructor Details

#initialize(endpoint, options = {}) ⇒ Client

Initialize a client for a specific endpoint

endpoint

uri of the SPARQL endpoint

options

hash containing additional configuration options, including :apikey for specifying api key



101
102
103
# File 'lib/kasabi/api/sparql.rb', line 101

def initialize(endpoint, options={} )
 super(endpoint, options)
end

Class Method Details

.apply_initial_bindings(query, bindings = {}) ⇒ Object

Apply some initial bindings to parameters in a query

The keys in the values hash are used to replace variables in a query The values are supplied as is, allowing them to be provided as URIs, or typed literals according to Turtle syntax.

Any keys in the hash that are not in the query are ignored. Any variables not found in the hash remain unbound.

query

the query whose initial bindings are to be set

values

hash of query name to value



118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/kasabi/api/sparql.rb', line 118

def Client.apply_initial_bindings(query, bindings={})
    copy = query.clone()
    copy.gsub!(VARIABLE_MATCHER) do |pattern|
      key = $2
      if bindings.has_key?(key)
        bindings[key].to_s
      else
        pattern
      end              
    end            
    return copy  
end

.result_to_query_binding(result) ⇒ Object

Convert a SPARQL query result binding into a hash suitable for passing to the apply_initial_bindings method.

The result param is assumed to be a Ruby hash that reflects the structure of a binding in a SELECT query result (i.e. the result of parsing the application/sparql-results+json format and extracting an specific result binding.

The method is intended to be used to support cases where an initial select query is performed to extract some variables that can later be plugged into a subsequent query

result

hash conforming to structure of a binding in the SPARQL JSON format



143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/kasabi/api/sparql.rb', line 143

def Client.result_to_query_binding(result)
  hash = {}
  result.each_pair do |key, value|
    if value["type"] == "uri"
      hash[key] = "<#{value["value"]}>"
    elsif (value["type"] == "literal" && !value.has_key?("datatype"))
      hash[key] = "\"#{value["value"]}\""
    elsif (value["type"] == "literal" && value.has_key?("datatype"))
      hash[key] = "\"#{value["value"]}\"^^#{value["datatype"]}"             
    else
      #do nothing for bnodes
    end
  end
  return hash
end

.results_to_query_bindings(results) ⇒ Object

Convert Ruby hash structured according to SPARQL JSON format into an array of hashes by calling result_to_query_binding on each binding into the results.

E.g: results = Sparql::SparqlHelper.select(query, sparql_client) bindings = Sparql::SparqlHelper.results_to_query_bindings(results)

results

hash conforming to SPARQL SELECT structure



167
168
169
170
171
172
173
174
# File 'lib/kasabi/api/sparql.rb', line 167

def Client.results_to_query_bindings(results)
  bindings = []
  
  results["results"]["bindings"].each do |result|
    bindings << result_to_query_binding(result)
  end
  return bindings
end

Instance Method Details

#ask(query) ⇒ Object

Perform a SPARQL ASK query.

query

the SPARQL query

format

the preferred response format



249
250
251
252
# File 'lib/kasabi/api/sparql.rb', line 249

def ask(query)
  json = JSON.parse( query(query, Sparql::SPARQL_RESULTS_JSON) )
  return json["boolean"] == "true"
end

#construct(query) ⇒ Object

Perform a SPARQL CONSTRUCT query.

query

the SPARQL query

format

the preferred response format



238
239
240
241
242
243
# File 'lib/kasabi/api/sparql.rb', line 238

def construct(query)
  response = query(query, "application/json")
  graph = RDF::Graph.new()
  graph.insert( RDF::JSON::Reader.new( StringIO.new( response ) ) )
  return graph                  
end

#describe(query) ⇒ Object

Perform a SPARQL DESCRIBE query.

query

the SPARQL query

format

the preferred response format



211
212
213
214
215
216
# File 'lib/kasabi/api/sparql.rb', line 211

def describe(query)
  response = query(query, "application/json")
  graph = RDF::Graph.new()
  graph.insert( RDF::JSON::Reader.new( StringIO.new( response ) ) )
  return graph                  
end

#describe_uri(uri, type = :cbd) ⇒ Object

Describe a uri, optionally specifying a form of bounded description

uri

the uri to describe

format

mimetype for results

type

symbol indicating type of description, i.e. :cbd, :scbd, :lcbd, or :slcbd



198
199
200
201
202
203
204
205
# File 'lib/kasabi/api/sparql.rb', line 198

def describe_uri(uri, type=:cbd)
  template = Sparql::DESCRIPTIONS[type]
  if template == nil
    raise "Unknown description type"
  end
  query = Client.apply_initial_bindings(template, {"uri" => "<#{uri}>"} )
  return describe(query)
end

#exists?(uri) ⇒ Boolean

Performs an ASK query on the SPARQL endpoint to test whether there are any statements in the triple store about the specified uri.

uri

the uri to test for

sparql_client

a configured Sparql Client object

Returns:

  • (Boolean)


259
260
261
# File 'lib/kasabi/api/sparql.rb', line 259

def exists?(uri)
   return ask("ASK { <#{uri}> ?p ?o }")  
end

#multi_describe(uris) ⇒ Object

DESCRIBE multiple resources in a single query. The provided array should contain the uris that are to be described

This will generate a query like: DESCRIBE <www.example.org> <www.example.com> …

uris

list of the uris to be described

format

the preferred response format. Default is RDF/XML



226
227
228
229
230
231
232
# File 'lib/kasabi/api/sparql.rb', line 226

def multi_describe(uris)
  query = "DESCRIBE " + uris.map {|u| "<#{u}>" }.join(" ")
  response = query(query, "application/json")
  graph = RDF::Graph.new()
  graph.insert( RDF::JSON::Reader.new( StringIO.new( response ) ) )
  return graph                  
end

#query(sparql, format = nil) ⇒ Object

Perform a sparql query.

sparql

a valid SPARQL query

format

specific a request format. Usually a media-type, but may be a name for a type, if not using Conneg

graphs

an array of default graphs

named_graphs

an array of named graphs



182
183
184
185
186
187
188
189
190
191
# File 'lib/kasabi/api/sparql.rb', line 182

def query(sparql, format=nil)          
  headers = {}
  if format != nil            
    headers["Accept"] = format  
  end
  
  response = get( @endpoint, {"query" => sparql}, headers )
  validate_response(response)
  return response.content
end

#select(query) ⇒ Object

Perform a SPARQL SELECT query.

query

the SPARQL query

format

the preferred response format



267
268
269
# File 'lib/kasabi/api/sparql.rb', line 267

def select(query)
  return JSON.parse( query(query, Sparql::SPARQL_RESULTS_JSON) )
end

#select_into_array(query) ⇒ Object

Perform a simple SELECT query and return the results as a simple array of hashes. Each entry in the array will be a row in the results, and each hash will have a key for each variable.

Note that this will lose any type information, only the value of the bindings are returned

Also note that if a row has an empty binding for a given variable, then this variable will not be presented in the hash for that row.

query

the SPARQL SELECT query

sparql_client

a configured Sparql Client object



305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/kasabi/api/sparql.rb', line 305

def select_into_array(query)
  results = select(query)
  rows = []
  results["results"]["bindings"].each do |binding|
    row = {}
    binding.each do |key, value|
      row[key] = value["value"]
    end
    rows << row
  end
  return rows
end

#select_single_value(query) ⇒ Object

Perform a simple SELECT query on an endpoint and return a single result

Will request the results using the SPARQL JSON results format, and parse the resulting JSON results. The assumption is that the SELECT query returns a single value (i.e single variable, with single binding)

Note this will lose any type information, only the value of the binding is returned If additional results are returned, then these are ignored

query

the SPARQL SELECT query

sparql_client

a configured Sparql Client object



329
330
331
332
333
# File 'lib/kasabi/api/sparql.rb', line 329

def select_single_value(query)
  results = select(query)
  v = results["head"]["vars"][0];
  return results["results"]["bindings"][0][v]["value"]           
end

#select_values(query) ⇒ Object

Perform a simple SELECT query on an endpoint and return a simple array of values

Will request the results using the SPARQL JSON results format, and parse the resulting JSON results. The assumption is that the SELECT query contains a single “column” of values, which will be returned as an array

Note this will lose any type information, only the value of the bindings are returned

Also note that if row has an empty binding for the selected variable, then this row will be dropped from the resulting array

query

the SPARQL SELECT query

sparql_client

a configured Sparql Client object



284
285
286
287
288
289
290
291
292
# File 'lib/kasabi/api/sparql.rb', line 284

def select_values(query)
   results = select(query)
   v = results["head"]["vars"][0];
   values = [];
   results["results"]["bindings"].each do |binding|
     values << binding[v]["value"] if binding[v]
   end
   return values           
end