-
Notifications
You must be signed in to change notification settings - Fork 0
Using the Web Services: Ruby
Darren Oakley edited this page Jul 4, 2011
·
5 revisions
#! /usr/bin/env ruby -wKU
# Author:: Sébastien Briois (mailto:sebriois@gmail.com)
require "rubygems"
require "rest_client"
require "json"
DOMAIN = RestClient::Resource.new( "http://user:password@localhost:3000" )
# Generic helper method for handling the web calls to the repository.
def request( method, url, data = nil )
response =
case method.upcase
when "GET" then DOMAIN[url].get
when "POST" then DOMAIN[url].post data, :content_type => "application/json"
when "PUT" then DOMAIN[url].put data, :content_type => "application/json"
when "DELETE" then DOMAIN[url].delete
else
raise "Method #{method} unknown when requesting url #{url}"
end
puts "#{method} #{url} - #{response.code} #{RestClient::STATUSES[response.code]}"
return response.body
end
#
# Allele specific methods
#
def find_allele( allele )
params = ""
params << "mgi_accession_id=" + allele[:mgi_accession_id]
params << "&assembly=" + allele[:assembly]
params << "&chromosome=" + allele[:chromosome]
params << "&strand=" + allele[:strand]
params << "&cassette=" + allele[:cassette]
params << "&backbone=" + allele[:backbone]
params << "&homology_arm_start=" + allele[:homology_arm_start]
params << "&homology_arm_end=" + allele[:homology_arm_end]
params << "&cassette_start=" + allele[:cassette_start]
params << "&cassette_end=" + allele[:cassette_end]
# Will find a conditional allele or a non-conditional allele
if ( allele.include? :loxp_start and allele[:loxp_start] ) and ( allele.include? :loxp_end and allele[:loxp_end] )
params += "&loxp_start=#{allele[:loxp_start]}&loxp_end=#{allele[:loxp_end]}"
else
params += "&loxp_start='null'&loxp_end='null'"
end
# Request for all the alleles that match the params.
# The '.json' indicates that we want a JSON string as a response.
response = request( 'GET', "alleles.json?#{params}" )
# This will be a list whether the request returned one allele or more.
allele_list = JSON.parse( response )
# If the search is not specific enough and returns more than 1 allele
if allele_list.length > 1
raise "Your search returned more than one allele, please refine it."
end
if allele_list == 1
return allele_list[0]
end
return nil
end
def create_allele( data )
json = JSON.generate({ :allele => data })
response = request( 'POST', 'alleles.json', json )
allele = JSON.parse( response )
return allele
end
def update_allele( id, data )
json = JSON.generate({ :allele => data })
response = request( 'PUT', "alleles/#{id}.json", json )
allele = JSON.parse( response )
return allele
end
def delete_allele( id )
request( 'DELETE', "alleles/#{id}" )
end
#
# Targeting Vector specific methods
#
def find_targeting_vector( vector )
response = request( 'GET', "targeting_vectors.json?name=#{vector['name']}" )
targeting_vector_list = JSON.parse( response )
if targeting_vector_list == 1
return targeting_vector_list[0]
end
return nil
end
def create_targeting_vector( data )
json = JSON.generate({ :targeting_vector => data })
response = request( 'POST', 'targeting_vectors.json', json )
vector = JSON.parse( response )
return vector
end
def update_targeting_vector( id, data )
json = JSON.generate({ :targeting_vector => data })
response = request( 'PUT', "targeting_vectors/#{id}.json", json )
vector = JSON.parse( response )
return vector
end
def delete_targeting_vector( id )
request( 'DELETE', "targeting_vectors/#{id}" )
end
#
# ES Cell specific methods
#
def find_es_cell( cell )
response = request( 'GET', "es_cells.json?name=#{cell['name']}" )
es_cell_list = JSON.parse( response )
if es_cell_list == 1
return es_cell_list[0]
end
return nil
end
def create_es_cell( cell )
json = JSON.generate({ :es_cell => cell })
response = request( 'POST', 'es_cells.json', json )
cell = JSON.parse( response )
return cell
end
def update_es_cell( id, data )
json = JSON.generate({ :es_cell => data })
response = request( 'PUT', "es_cells/#{id}.json", json )
cell = JSON.parse( response )
return cell
end
def delete_es_cell( id )
request( 'DELETE', "es_cells/#{id}" )
end
##
## Main script scenario:
## - We create a data structure containing all the objects we want to create or update in the database
## - We loop over this data structure and follow this procedure:
## 1- Search the object
## 2- Object found ? Yes: Update; No: Create
##
# We will work with the data linked to the pipeline named "EUCOMM", let's find its ID
response = request( method = 'GET', url = 'pipelines.json' )
pipeline_list = JSON.parse( response )
pipeline = pipeline_list.find { |pipeline| pipeline['name'] == 'EUCOMM' }
# Create our data structure
alleles = [
# First allele
{
:mgi_accession_id => "MGI:123",
:project_design_id => 23640,
:cassette => "L1L2_gt2",
:backbone => "L3L4_pZero_kan",
:assembly => "NCBIM37",
:chromosome => "1",
:strand => "+",
:design_type => "Knock Out",
:design_subtype => "Frameshift",
:homology_arm_start => 10,
:homology_arm_end => 10000,
:cassette_start => 50,
:cassette_end => 500,
:loxp_start => 1000,
:loxp_end => 1500,
# Targeting vectors for the first allele
:targeting_vectors => [
{
:pipeline_id => pipeline['id'],
:name => 'PRPGD001',
:intermediate_vector => 'PGS001',
:ikmc_project_id => 9801
},
{
:pipeline_id => pipeline['id'],
:name => 'PRPGD002',
:intermediate_vector => 'PGS001',
:ikmc_project_id => 9801
}
],
# ES Cells for the first allele
:es_cells => [
{ :pipeline_id => pipeline['id'], :name => 'EPD001', :allele_symbol_superscript => 'tm1a', :targeting_vector => 'PRPGD001' },
{ :pipeline_id => pipeline['id'], :name => 'EPD002', :allele_symbol_superscript => 'tm1a', :targeting_vector => 'PRPGD001' },
{ :pipeline_id => pipeline['id'], :name => 'EPD003', :allele_symbol_superscript => 'tm1a', :targeting_vector => 'PRPGD001' },
{ :pipeline_id => pipeline['id'], :name => 'EPD004', :allele_symbol_superscript => 'tm1a', :targeting_vector => 'PRPGD002' },
{ :pipeline_id => pipeline['id'], :name => 'EPD005', :allele_symbol_superscript => 'tm1a', :targeting_vector => 'PRPGD002' },
{ :pipeline_id => pipeline['id'], :name => 'EPD006', :allele_symbol_superscript => 'tm1a', :targeting_vector => 'PRPGD002' }
]
# Genbank File for the first allele
:genbank_file => {
:escell_clone => "A GENBANK FILE IN PLAIN TEXT",
:targeting_vector => "A GENBANK FILE IN PLAIN TEXT"
}
},
# Second allele
{
:mgi_accession_id => "MGI:456",
:project_design_id => 29871,
:cassette => "L1L2_gt2",
:backbone => "L3L4_pZero_kan",
:assembly => "NCBIM37",
:chromosome => "1",
:strand => "+",
:design_type => "Knock Out",
:design_subtype => "Frameshift",
:homology_arm_start => 10,
:homology_arm_end => 10000,
:cassette_start => 50,
:cassette_end => 500,
:loxp_start => 1000,
:loxp_end => 1500,
# Targeting vectors for the second allele
:targeting_vectors => [
{
:pipeline_id => pipeline['id'],
:name => 'PRPGD003',
:intermediate_vector => 'PGS002',
:ikmc_project_id => 6809480
},
{
:pipeline_id => pipeline['id'],
:name => 'PRPGD004',
:intermediate_vector => 'PGS002',
:ikmc_project_id => 6809480
}
],
# ES Cells for the second allele
:es_cells => [
{ :pipeline_id => pipeline['id'], :name => 'EPD007', :allele_symbol_superscript => 'tm1a', :targeting_vector => 'PRPGD003' },
{ :pipeline_id => pipeline['id'], :name => 'EPD008', :allele_symbol_superscript => 'tm1a', :targeting_vector => 'PRPGD003' },
{ :pipeline_id => pipeline['id'], :name => 'EPD009', :allele_symbol_superscript => 'tm1a', :targeting_vector => 'PRPGD003' },
{ :pipeline_id => pipeline['id'], :name => 'EPD010', :allele_symbol_superscript => 'tm1a', :targeting_vector => 'PRPGD004' },
{ :pipeline_id => pipeline['id'], :name => 'EPD011', :allele_symbol_superscript => 'tm1a', :targeting_vector => 'PRPGD004' },
{ :pipeline_id => pipeline['id'], :name => 'EPD012', :allele_symbol_superscript => 'tm1a', :targeting_vector => 'PRPGD004' }
]
}
]
alleles.each do |allele_hash|
# allele_hash should not contain unknown fields
targeting_vectors = allele_hash.delete( :targeting_vectors )
es_cells = allele_hash.delete( :es_cells )
# Find, Create or Update allele
allele_found = find_allele( allele_hash )
if allele_found.nil?
allele = create_allele( allele_hash )
else
# If allele has been found, it has an "id"
allele = update_allele( allele_found['id'], allele_hash )
end
# Our allele now has an ID
allele_hash[:id] = allele['id']
# Find, Create or Update Targeting Vector
targeting_vectors.each do |vector_hash|
vector_hash[:allele_id] = allele_hash[:id]
vector_found = find_targeting_vector( vector_hash )
if vector_found.nil?
vector = create_targeting_vector( vector_hash )
else
vector = update_targeting_vector( vector_found['id'], vector_hash )
end
vector_hash[:id] = vector['id']
end
# Find, Create or Update ES Cell
es_cells.each do |es_cell_hash|
# ES Cell must be linked to a Molecular Structure
es_cell_hash[:allele_id] = allele_hash[:id]
# If ES Cell is linked to a targeting vector, retrieve its ID
if es_cell_hash.include? :targeting_vector
es_cell_hash[:targeting_vector_id] =
targeting_vectors.find { |v| v[:name] == es_cell_hash[:targeting_vector] }['id']
else
es_cell_hash[:targeting_vector_id] = nil
end
# Find, Create or Update ES Cell
es_cell_found = find_es_cell( es_cell_hash )
if es_cell_found.nil?
es_cell = create_es_cell( es_cell_hash )
else
es_cell = update_es_cell( es_cell_found['id'], es_cell_hash )
end
es_cell_hash[:id] = es_cell['id']
end
end
# DELETE All ES Cells
es_cells.each { |es_cell| delete_es_cell( es_cell[:id] ) }
targeting_vectors.each { |vector| delete_targeting_vector( vector[:id] ) }
alleles.each { |allele| delete_allele( allele[:id] ) }