Rails - Sending image using Faraday - ruby-on-rails

I'm trying to make a request to an API sending an image and some other data, and getting the response. That's my code:
file = "assets/images/test.jpg"
conn = Faraday.new(:url => "api_url" ) do |faraday|
faraday.request :multipart
end
payload = { :profile_pic => Faraday::UploadIO.new(file, 'image/jpeg') }
conn.post "/test", payload
My first problem is that I'm always getting the following error:
Errno::ENOENT (No such file or directory - assets/images/test.png)
I've tried all the paths I could imagine. Where should be saved the image in directories to be found by Faraday?
The second question is about the response, how can I get the response and handle it?
The third one is that, I haven't understand what's the utility of the first parameter of the last call:
conn.post "/hello", payload
I've written "/hello" but don't have any idea about what's the real usage.
And the last one. Could I send a raw image saved in a variable instead of sending a path to Faraday?
EDIT
Now it's working, this is the solution:
Be aware that url must be only until .com, the rest of the path must go on conn.post like this example /v1/search.
c.adapter :net_http was needed too.
Message response is correctly handled in json variable.
Solution:
url = 'http://url.com'
file = Rails.root.to_s + "/app/assets/images/test.jpg"
conn = Faraday.new(:url => url ) do |c|
c.request :multipart
c.adapter :net_http
end
payload = { :image => Faraday::UploadIO.new(file, 'image/jpeg'), :token => token}
response = conn.post '/v1/search', payload
json = JSON.parse response.body

You should try this for your first question :
file = Rails.root.to_s + "/app/assets/images/test.jpg"
For your third question, the first parameters allows you to construct the right URL from the base "api_url". Please see the example from the Readme.
## POST ##
conn.post '/nigiri', { :name => 'Maguro' } # POST "name=maguro" to http://sushi.com/nigiri

Related

Use Hash value on url with Nokogiri or RestClient

I have a url like :
http://172.0.0.1:22230/test.action?data={"foo":"bar","joe":"doe"}&sign=x6das
In my browser I can get data from that url, but if I'm use nokogiri
Nokogiri::HTML(open('http://172.0.0.1:22230/test.action?data={"foo":"bar","joe":"doe"}&sign=x6das'))
I get
URI::InvalidURIError: bad URI(is not URI?): http://172.0.0.1:22230/test.action?data={"foo":"bar","joe":"doe"}&sign=x6das
from /home/worka/.rvm/rubies/ruby-2.1.2/lib/ruby/2.1.0/uri/common.rb:176:in `split'
Also with RestClient
RestClient.get 'http://172.0.0.1:22230/test.action?data={"foo":"bar","joe":"doe"}&sign=x6das'
I got same an error.
Encode your url first then use it.
url = 'http://172.0.0:22230/test.action?data={"foo":"bar","joe":"doe"}&sign=x6das'
encoded_url = CGI::escape(url)
Nokogiri::HTML(open(encoded_url))
When dealing with URIs, it's a good idea to use the tools designed for them such as URI, which comes with Ruby.
The URI can't be
http://172.0.0.1:22230/test.action?data={"foo":"bar","joe":"doe"}&sign=x6das
because the data component is invalid. If you are adding data then I'd start with:
require 'uri'
uri = URI.parse('http://172.0.0.1:22230/test.action?sign=x6das')
query = URI.decode_www_form(uri.query).to_h # => {"sign"=>"x6das"}
data = {"foo" => "bar","joe" => "doe"}
uri.query = URI.encode_www_form(query.merge(data)) # => "sign=x6das&foo=bar&joe=doe"
uri.to_s # => "http://172.0.0.1:22230/test.action?sign=x6das&foo=bar&joe=doe"
Your initial example using {"foo":"bar","joe":"doe"} is JSON serialized data, which usually isn't passed in a URL like that. If you need to create JSON, start with the initial hash:
require 'json'
data = {"foo" => "bar","joe" => "doe"}
data.to_json # => "{\"foo\":\"bar\",\"joe\":\"doe\"}"
to_json serializes the hash into a string, which could then be encoded into the URI:
data = {"foo" => "bar","joe" => "doe"}
uri = URI.parse('http://172.0.0.1:22230/test.action?sign=x6das')
query = URI.decode_www_form(uri.query).to_h # => {"sign"=>"x6das"}
uri.query = URI.encode_www_form(query.merge('data' => data.to_json)) # => "sign=x6das&data=%7B%22foo%22%3A%22bar%22%2C%22joe%22%3A%22doe%22%7D"
But again, sending encoded JSON as a query parameter in the URI is not very common or standard since data payload is smaller without the JSON encoding.
Ok I got solved my problem
url = http://172.0.0.1:22230/test.action?data={"foo":"bar","joe":"doe"}&sign=x6das
RestClient.get(URI.encode(url.strip))

The content type 'application/x-www-form-urlencoded' is not supported in Ruby on Rails

So I'm just trying to make a simple post request using httpclient in RoR.
I'm going through a proxy, doing ntlm authentication with the server ( I can make GET requests without a problem).
Now when I try and do a post request, I get the error mentioned in the title...
proxy = ENV['HTTP_PROXY']
client=HTTPClient.new(proxy)
client.set_auth(nil,user,pass)
body= [{'Content-Type' => 'application/atom+xml, :content => ...}]
res = client.post('url',body)
puts res.body
How am i getting this error when I clearly specify the header as atom+xml..?
You should use
res = client.post('url',
:body => "...body content...",
:header => {'Content-Type' => 'application/atom+xml'})

Add parameters to post request with Rest-client rails

I need to make a Post request using Rest-Client in my rails backend. I can successfully do it by the following: rv = RestClient.post URL, id.to_json, :content_type => 'application/json'
I need to add a tag parameter but can't make it work. I've tried different combinations of the following: rv = RestClient.post URL, {:params => {:tag => 'TAG'}}, id.to_json, :content_type => 'application/json' and receive errors about syntax (wrong number of arguments). The params would go on the url, the id.to_json would be part of the body. I can't find documentation that talks about this specific use case.
You can use to_query to convert a hash into a HTTP query string like so:
url_params = {:tag => "TAG"}.to_query
=> "tag=TAG"
Then just use that to construct your entire URL:
rv = RestClient.post "#{URL}?#{url_params}", id.to_json, :content_type => 'application/json'
there is another way to add url parameters to the request, it is notable that you have not sent the post parameters to RestClient in the correct order, which is url , payload, headers. and the headers can include any other tag, like :params.
rv = RestClient.post(URL, id.to_json, {:params => {:tag => 'TAG'},
:content_type => 'application/json' })

post image with faraday as parameter

I have a old service and new service with images on it. I want to migrate the images from old to new. for that I need to get image from my old service and then post it to new sinatra service.
I was able to post image in the format i want using NET::HTTP
url = URI.parse('http://0.0.0.0:9292/')
File.open("./Belgium.png") do |jpg|
req = Net::HTTP::Post::Multipart.new url.path, {"image" => UploadIO.new(jpg, "image/jpeg", "Belgium.jpg"), id:4234}
res = Net::HTTP.start(url.host, url.port) do |http|
http.request(req)
end
end
The params that I get with above post method at my sinatra service are
params = {"image"=>
{:filename=>"Belgium.jpg", :type=>"image/jpeg",:name=>"image",:tempfile=> #<File:/var/folders/h7/f9cvygqs3lg78kwh24v8yzp80000gn/T/RackMultipart20120827-76057-1f3inkn>,
:head=> "Content-Disposition: form-data; name=\"image\";filename=\"Belgium.jpg\"\r\nContent-Length: 28228\r\nContent-Type: image/jpeg\r\nContent-Transfer-Encoding: binary\r\n"},
"id"=>"4234"}
But I wasn't able to get the same result with faraday. I tried using something like:
payload = { :profile_pic => Faraday::UploadIO.new('avatar.jpg', 'image/jpeg') }
Faraday.post 'http://0.0.0.0:9292/', payload
At my service I get something like this:
"#<'UploadIO:0x007fb950373de8>" An object. This is not what i expect at my service.
How can I get the same behaviour as I get with Net::HTTP. I think it has go to do something with middleware, I tried tweaking around but I am still a newbie.
What about:
conn = Faraday.new(:url => 'http://0.0.0.0:9292' ) do |faraday|
faraday.request :multipart
end
payload = { :profile_pic => Faraday::UploadIO.new('avatar.jpg', 'image/jpeg') }
conn.post 'http://0.0.0.0:9292/', payload

http POST error

I'm trying to send the xml to another webserver through Restclient's http POST request.This is the code :
response = RestClient.post 'https://secure.rowebooks.co.uk/testorders/orders.aspx', :content_type => "text/xml", :myfile => File.read("#{Rails.root}/public/shared/#{#book}.xml")
But I'm getting this error
ERROR 2 Data at the root level is invalid. Line 1, position 1.ERROR3 Object reference not set to an instance of an object.
I've been told that I am receiving that error because the XML file is not in the content of the call. It must be in the content. I have no idea what does this mean.
Any suggestion / clue will be greatly appreciated.
Thanks
You should be doing it like this:
response = RestClient.post( 'https://secure.rowebooks.co.uk/testorders/orders.aspx',
File.read("#{Rails.root}/public/shared/#{#book}.xml"), 'Content-Type' => 'text/xml' )

Resources