Dan
Dan

Reputation: 4329

How do I post JSON via HTTP in Ruby after conversion from Python?

I yield - I've tried for hours to crack this nut but can't figure it out. I'm too new to Ruby (and have no Python background!) to translate this and then post my JSON data to a site that requires user/pass, and then get the response data.

This is the Python code:

r = requests.post('https://keychain.oneid.com/validate/', json.dumps(data), auth=('username', 'password'))
r.json()

where data is:

{"some" => "data", "fun" => "times"}

I'm trying to replicate the functionality of this code in Ruby for use with a Rails application, but between figuring out how the Python requests.post() function operates and then writing the Ruby code for POST and GET, I've become totally lost.

I tried Net::HTTP but I'm not clear if I should be putting the username/pass in the body or use the basic_auth method -- basic_auth seems to only work inside Net::HTTP.get ... and Net::HTTP doesn't seem to easily handle JSON, but again, I could be totally out to lunch at this point.

Any suggestions or help would be greatly appreciated!

Upvotes: 6

Views: 12774

Answers (2)

zhongguoa
zhongguoa

Reputation: 336

Use the rest-client gem or just use Net::HTTP.

Ruby code(version 1.9.3):

require 'net/http'
require 'json'
require 'uri'

uri = URI('https://keychain.oneid.com/validate/')
req = Net::HTTP::Post.new uri.path
# ruby 2.0: req = Net::HTTP::Post.new uri
req.basic_auth 'username', 'password'
req.body = {:some => 'data', :fun => 'times'}.to_json

res = Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  http.ssl_version = :SSLv3
  http.request req
end

puts res.body
# => {"errorcode": -99, "error": "Invalid API credentials. Please verify and try again"}

json = JSON.parse res.body
puts json['errorcode']
# => -99

Upvotes: 16

the Tin Man
the Tin Man

Reputation: 160631

I'd recommend taking a look at the RestClient gem. It makes it easy to deal with GET/POST, plus all the rest of the REST calls. It also has an IRB-based shell called restclient available from the command-line, making it easier to experiment with your connection settings.

From the documentation:

RestClient.post "http://example.com/resource", { 'x' => 1 }.to_json, :content_type => :json, :accept => :json

Looking at it you can see similarities with the Python code.

You can add the authentication info to the hash:

require 'restclient'
require 'json'
require 'base64'

RestClient.post(
  'https://keychain.oneid.com/validate/',
  {
    :authentication => 'Basic ' + Base64.encode64(name + ':' + password),
    'some' => 'data',
    'fun' => 'times'
  }.to_json,
  :content_type => :json,
  :accept => :json
)

Alternately, you could use the Curb gem. Curb used libcurl, which is an industry standard tool for web connectivity. The documentation shows several ways to send POST requests.

Upvotes: 3

Related Questions