Using ruby curb gem to access paypal api - ruby

Follow the instruction in Paypal Developer 'make your first call':
curl https://api.sandbox.paypal.com/v1/oauth2/token \
-H "Accept: application/json" \
-H "Accept-Language: en_US" \
-u "EOJ2S-Z6OoN_le_KS1d75wsZ6y0SFdVsY9183IvxFyZp:EClusMEUk8e9ihI7ZdVLF5cZ6y0SFdVsY9183IvxFyZp" \
-d "grant_type=client_credentials"
It is working and get the expected result like the instruction states, but I prefer to use ruby curb gem:
require 'curl'
paypal_result = Curl::Easy.http_post("https://api.sandbox.paypal.com/v1/oauth2/token", "grant_type=client_credentials") do |http|
http.headers['Accept'] = "application/json"
http.headers['Accept-Language'] = "en_US"
http.username = "EOJ2S-Z6OoN_le_KS1d75wsZ6y0SFdVsY9183IvxFyZp:EClusMEUk8e9ihI7ZdVLF5cZ6y0SFdVsY9183IvxFyZp"
end
puts paypal_result.body_str
However I got the following:
{"error":"invalid_client","error_description":"The basic auth authorization header cannot be decoded"}
It is an error for sure, but what's wrong with my curb syntax? Any idea?

I can't tell you exactly what's wrong, but I can tell you how to see what's happening. Try putting it into verbose mode, so you can see what data and headers are actually being sent:
curl = Curl::Easy.new
# Make it verbose, prints to stderr
curl.verbose = true
paypal_result = curl.http_post("https://api.sandbox.paypal.com/v1/oauth2/token", "grant_type=client_credentials") do |http|
# etc.
end
You can compare with the CLI version by using the -v flag.
Hope that helps you discover the difference.

Related

curl type and ruby rest client

I am not able to translate the curl command into ruby rest-client
curl 'http://localhost:8080/../attachments' -H "Content-Type: multipart/form-data" -H "CMD-Authorization: xxxx" -X POST -F attachment='{"_description":"this is test";type=application/json' -F file=#/root/Desktop/rest/saturn.bin
The main problem regards the "type=application/json" in the form attachment.
My code is:
require 'base64'
require 'rest-client'
require 'json'
....
file1=File.new('/root/Desktop/rest/saturn.bin','rb')
response =RestClient.post("#{uri}",
{
:attachment=>'{"_description":"this is test";"type"=>"application/json"}',
:file=>file1,
},{:cmd_authorization=>"#{#session_id}"})`
I tried other code combination adding for example :content_type=>"application/json" in the header unsuccessfully. Thanks for the support.

Ruby GET request with headers and data?

This is a cUrl command I want to do in Ruby
curl --get 'https://api.twitter.com/1.1/statuses/user_timeline.json' --data 'screen_name=example' --header 'Authorization: OAuth oauth_consumer_key="example", oauth_version="1.0"' --verbose
So far I only know how to GET requests using Net::HTTP but these don't have headers and data like the cUrl command above.
It would be great if someone could tell me how to GET in Ruby with headers and data.
If you don't mind using additional GEMS, try UniRest

From Ruby to Perl, Post data is disappearing

I'm trying to mimic the following curl command that works perfectly:
curl -k -i -d #content.json -H "Content-Type: application/json" -H "Accept: applicaztion/json" https://localhost:909/api/authenticateUser
I'm mimicking the curl command in Ruby/rails. I'm using the rest-client gem. The target is an API written in old-style Perl. The problem is that the API does NOT "see" the payload that is sent in the new ruby code:
pload = '<string>'.to_json
response = RestClient::Request.execute(url: 'https://localhost:909/api/authenticateUser', method: :post, payload: pload, accept: :json, content_type: :json, verify_ssl: false)
What is going wrong? Is my Ruby code bad or is the Perl code "too stupid/old" to pick up the payload from ruby. This is the Perl code:
my $data = $cgi->param('POSTDATA') || "";
I tend to think the problem is with my ruby code since the old Perl code receives the payload properly from the curl command above and from some other old Perl code.
Thanks for the help.
For POSTDATA to be populated,
The request must have a Content-Length header
The value of the request's Content-Length header must be non-zero.
The request method must be POST.
The request must have a Content-Type header.
The value of the request's Content-Type header must not include any of the following:
application/x-www-form-urlencoded
multipart/form-data
application/xml
multipart/related

Unable to invoke Rally LBAPI WS from ruby rest-client program. Any

I have been able to query rally analytics API using DHC(Dev HTTP Client) with the following POST request
http://rally1.rallydev.com/analytics/v2.0/service/rally/workspace/1234/artifact/snapshot/query.js&API_Key=key123
and body
{
"find": {
"ObjectID": 4321
}
}
Is there any way I can do this from Ruby? I have using 'rest-client' but am only getting errors endlessly (400, 403, ....)
Has anyone been able to do this ?
Is this possible using curl?
It's possible using both curl and ruby. You need to set a ZSESSIONID header value equal to your API Key. Curl example here (randomized Workspace OID and API Key):
curl -X POST \
'https://rally1.rallydev.com/analytics/v2.0/service/rally/workspace/12345678910/artifact/snapshot/query' \
-H 'content-type: application/json' \
-H 'accept: application/json' \
-H 'ZSESSIONID: _m31qjdm43Ou74h0cACk28zgBUOPm50Xtna2PhQ2L22' \
--data '{"find":{"FormattedID": "DE9", "__At": "current"},"fields":true,"start":0,"pagesize":10,"removeUnauthorizedSnapshots":true}' \
--compressed
It is fairly straightforward to do in Ruby also. The following Gists:
Rally Lookback Connection Helper
Rally Lookback Query Example
Contain a Ruby connection helper for connecting to Rally's Lookback API. The second Gist contains an example of using the connection helper along with a hash representing a find query object. The Ruby example uses httpclient gem as opposed to rest-client gem, but the concept is the same.
Has this API changed ? We had a change in our username recently and since then, running the Query example returns {"_rallyAPIMajor":"2","_rallyAPIMinor":"0","Errors":["Not Found"],"Warnings":[]}
for all the queries.

How to update a TeamCity build parameter using REST+cURL

I have a configuration parameter called "testing" in one of my build configurations in TeamCity. After taking a look at the TeamCity REST API doc here I could get information about this parameter using the following cURL command line commands on Windows:
(1) curl -X GET -H "Authorization: Basic (...)" http://teamcity:8080/httpAuth/app/rest/buildTypes/id:bt7/parameters
(2) curl -X GET -H "Authorization: Basic (...)" http://teamcity:8080/httpAuth/app/rest/buildTypes/id:bt7/parameters/testing
Response:
(1) <?xml version="1.0" encoding="UTF-8" standalone="yes"?><property name="testing" value="11"/></properties>
(2) 11
But then, when I try to update this "testing" build parameter using the following command, I get an error message:
curl -X PUT -d "1" -H "Authorization: Basic (...)" http://teamcity:8080/httpAuth/app/rest/buildTypes/id:bt7/parameters/testing
Response:
Error has occurred during request processing (Unsupported Media Type).
Error: javax.ws.rs.WebApplicationException
Not supported request. Please check URL, HTTP method and transfered data are correct.
I already successfully use a similar command to update the buildNumberCounter setting of the same build configuration:
curl -X PUT -d "1" -H "Authorization: Basic (...)" http://teamcity:8080/httpAuth/app/rest/buildTypes/id:bt7/settings/buildNumberCounter
That's why I thought I can do the same with a build parameter in a similar way. What am I missing here?
UPDATE:
I managed to update the "testing" build parameter with value "1" using Fiddler. The request I composed had the following content:
Request: PUT
URL: http://teamcity:8080/httpAuth/app/rest/buildTypes/id:bt7/parameters/testing
Request headers: Authorization: Basic (...)
Request body: 1
So the problem with my cURL command above is probably somewhere around the -d "1" option. But where?
UPDATE 2:
I'm not sure if that makes any difference, but I use this cURL build on Windows 7.
Instead of fixing the failing cURL command, as a workaround, we use now Node.js to compose and send the REST request to TeamCity.
The script that needs to be fed to node.exe is as follows:
// Equivalent cURL command:
// curl -X PUT -d "1" -H "Authorization: Basic (...)" http://teamcity:8080/httpAuth/app/rest/buildTypes/id:bt7/parameters/testing
var http = require('http'),
options = {
hostname: 'teamcity',
port: 8080,
path: '/httpAuth/app/rest/buildTypes/id:bt7/parameters/testing',
method: 'PUT',
headers: { 'Authorization': 'Basic (...)' }
},
req;
req = http.request(options, function(res) { });
// write data to request body
req.write('1');
req.end();
Although the workaround works perfectly, I would still like to know what's wrong with the above cURL command?
For parameters that are non-XML like the one you are asking about, just add:
--Header "Content-Type: text/plain"
For parameters that are XML then you'll want to switch that to:
--Header "Content-Type: application/xml"
I was having a hard time figuring this out too but I found the answer. Instead of using -d and -H at the front. Use --data and --header at the end as shown below . I found this in the TeamCity docs buried in a "click to expand" example.
Set build number counter:
curl -v --basic --user <username>:<password> --request PUT http://<teamcity.url>/app/rest/buildTypes/<buildTypeLocator>/settings/buildNumberCounter --data <new number> --header "Content-Type: text/plain"
Set build number format:
curl -v --basic --user <username>:<password> --request PUT http://<teamcity.url>/app/rest/buildTypes/<buildTypeLocator>/settings/buildNumberPattern --data <new format> --header "Content-Type: text/plain"
I guess the REST API expect XML as input, add
-H "Content-type:text/xml"
and put XML as input. If you have a XML file file.xml :
curl -d "#/path/to/file.xml" -H "Content-type:text/xml" (...)

Resources