Getting readable information from Amazon sdk ruby - ruby

Maybe someone could help me with an issue while working with Amazon SDK for Ruby.
When trying to retrieve information with commands like "get_bucket_login" or "get_bucket_location" what I get as a response is:
<Seahorse::Client::Response:....>
According to the documentation, these requests should return strings.
What am I missing? Someone found the same issue?

Seahorse is part of the core of the SDK:
https://github.com/aws/aws-sdk-ruby/tree/master/aws-sdk-core/lib/seahorse
The clients of all the services are modeled to use the Base of this.
Now back to your question:
You get an "empty" response as in it does not conform to what the client base is used to.
=== for get_bucket_location ===
the way to get your bucket location is the following:
resp = s3.get_bucket_location(bucket: "mybucketname")
puts resp.data.location_constraint
empty string means US Standard, per documentation here: http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html
the code that monkey patches this in is here: https://github.com/aws/aws-sdk-ruby/blob/53712d3e4583c982837fb3a301fa2c67226a05ff/aws-sdk-core/lib/aws-sdk-core/plugins/s3_get_bucket_location_fix.rb
== for get_bucket_login ==
I don't see this method on the client. If it's logging instead of login, you can see the response structure in the documentation: http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Client.html#get_bucket_logging-instance_method

Related

Uploading PDF to AWS Lambda via API Gateway mangles the bits...why?

I have deployed an AWS Lambda function, written in Python, and AWS API Gateway structure to cause POST requests to an API endpoint to be redirected to my function. I want to upload a PDF document to my function and have it store the document in a S3 bucket. The problem I have is that the payload of any POST request to my API is being UTF-8 encoded. I don't want that but can't figure out the magic mojo to disable encoding of the request payload.
I am testing using curl, with the following command line:
curl -XPOST https://xxxxxxxxxx.execute-api.us-west-1.amazonaws.com/test -H 'content-type: application/pdf' --data-binary #document.pdf
UPDATE: I just found the following article describing how API Gateway and Lambda support uploading binary data:
https://aws.amazon.com/blogs/compute/handling-binary-data-using-amazon-api-gateway-http-apis/
This article suggests that all of the complexities that I discussed in the initial formation of my question (still provided below) should not be necessary. All I should need to do to upload binary content to my Lambda function is insure that my request includes an appropriate Content-Type header. I was already doing that, but I massaged my Curl command a bit (modified above) to define my request in exactly the way that is done in this article. I still get UTF-8 encoded data and NOT base-64 encoded data. I tried uploading a jpeg file rather than a PDF so I was doing exactly what was done in the article. Still no love. I don't get it. This article demonstrates exactly what I'm doing. But I don't get the result it suggests I should. Ggggrrrr.
ORIGINAL POST:
I am using Terraform to define my deployment. I want to cause the PDF to not be encoded/mangled at all. This is my first time using API Gateway, and I'm obviously missing some bit of config. The one thing I'm doing specifically right now to say that I want incoming payloads to be treated as binary is via the binary_media_types argument to my API definition in Terraform:
resource aws_api_gateway_rest_api proxy {
...
binary_media_types = [
"application/pdf",
"application/octet-stream",
"*/*"
]
This sets the Binary Media Types configuration associated with the API I've defined. I've confirmed via the AWS Console that this setting is having the desired effect...I can see these types in the console. I should need just the first item in the list, but I've added the others while I try to figure out the problem here. By adding that wildcard item, I believe that it shouldn't matter what the incoming Content-Type is...all payloads should be being treated as binary.
The other bit of config that I know about that might be important is the "integration contentHandling property". Here is the key bit of AWS docs that seems to explain all this:
I think the case that applies to me here is the one I've highlighted, per what I say above. This says to me that I shouldn't need to do anything else, per the "unspecified" value in the table for "contentHandling. I've tried setting the "contentHandling" argument on the integration record of my Terraform config, like this:
resource aws_api_gateway_integration proxy {
...
passthrough_behavior = "WHEN_NO_MATCH"
content_handling = "CONVERT_TO_BINARY"
}
I first tried only specifying the content_handling value. I've also tried setting that value to "CONVERT_TO_TEXT", hoping to then get base64-encoded data. Neither of these has any effect. I've tried adding the passthrough_behavior value as shown. I've also tried replacing "WHEN_NO_MATCH" with "WHEN_NO_TEMPLATES". Nothing I do changes the behavior. I haven't been able to figure out where these settings would show up in the AWS console. If I knew they were necessary, I'd explore this further. But I don't think I need to set these.
What am I missing? How can I POST a PDF document to my AWS Lambda function through API Gateway and have the payload of the request not be converted in any way? TIA!
NOTE: I am aware of this Q/A: PDF Uploaded via AWS API Gateway getting corrupted. The answer there doesn't apply to me, as I need to avoid having to form-encode the upload. The client code that will eventually be doing the upload is set in stone and sends a POST request with a payload that is just the bytes of the PDF.

Generating Dynamic SSML from "HTTP Request" to be used on a "Get Input"

I'm wondering if anyone can be of assistance.
I am trying to generate some dynamic Amazon Polly SSML to be used on the Plivo PHLO platform. When someone dials into a particular number, they should be greeted with a custom message (in a particular language) and prompted to enter a number.
I have an HTTP request that hits my API, which receives the request and generates the SSML using Plivo's PHP Server SDK.
$response = new Response();
$speak_elem = $response->addSpeak($result['text'], ['language'=> 'en-US, 'voice'=>"Polly.Joanna"]);
Header('Content-type: text/xml');
die( $response->toXML() );
It seems to me that this HTTP Request is working perfectly and returning perfect SSML. When I copy and hard-code-paste the SSML into the Get Input node, it works OK.
<?xml version="1.0" encoding="utf-8"?>
<Response><Speak language="en-US" voice="Polly.Joanna">Welcome To 101 Broadway. For English, press 1.</Speak></Response>
However, when I try to add a Get Input component and link it's "prompt" audio to the resulting SSML, I am getting an error that says Invalid SSML (See Screenshots at the bottom).
WHAT I'VE TRIED
I've tried returning the SSML in plain XML and using {{HTTP_Welcome.response}}
I've tried returning the SSML as text in a JSON object called SSML and using {{HTTP_Welcome.response.SSML}}
I've tried returning the SSML both with and without the xml tag.
I've tried returning the SSML both with and without the Result tag.
I've tried taking a break and coming back to it. Hey, you never know.
No matter how I return the SSML, and how I try to link it to the Get Input prompt, I am unsuccessful. I'm starting to wonder if this is even possible?
Any help would be immensely appreciated. Thanks!
SCREENSHOT 1
SCREENSHOT 2
My name is Mohammed Huzaif, and I work for Plivo as a Developer Evangelist.
Unfortunately, the "GetInput node" in PHLO does not yet implement the feature you are searching for. The best option is to use a standard speak which is customisable in your way, which may have a less natural feel than SSML.
Currently, I've narrow information about your use case as of now but If you still want to use a custom SSML, I'd recommend utilising a framework instead of PHLO to design your call flow. Here's a tutorial that covers a few use cases by Plivo in several frameworks to help you develop one.
If you experience any problems, please feel free to contact our support team.

How to read a Google People api response object [updated]

I'm new to Google's API and I'm having trouble reading the content of a People contact.
To get the details of a particular contact, references show this code should work [Edit: I updated the personfields]:
profile = service.people().get(resourceName='people/c63810788897573286', personFields='names')
The resourceName is the ID of a particular contact (that ID will only work for someone with access to my account). The server grabs it correctly and returns this:
<googleapiclient.discovery.Resource object at 0x10fd183c8>
How do I read the content of this object? I can't figure out from the documentation
I want to print out the Name. I'm pretty new to APIs, so maybe there is a standard way to read an HTTP object or maybe it's something unique to Google's API. Thanks for any advice
I found an answer in another somewhat related StackOverflow. I needed to the add .execute() to the call
profile = service.people().get(resourceName='people/c63810788897573286', personFields='names').execute()

Reading a Google Spreadsheet into Ruby Objects (or settle for a file download)

I think it's probably simplest to start with my use case:
I'm trying to read the contents of a Google Spreadsheet into ruby, and then use that data for other purposes. This needs to happen server-to-server.
Here's what I've tried:
First I tried to use this google drive gem. Since my interaction needs to be server to server (i.e. a service account), I couldn't get this to work (someone please let me know if they've managed this!)
Next, I tried using the latest google-api-ruby gem, and, following its documentation, was successfully able to authenticate my service account, and have been able to get lists of files, etc. So basically the API is authenticated and working.
The latest issue is that Google Spreadsheets can't be downloaded using the normal download_dest parameter on the get_file method (sorry - would post links to relevant documentation here, but don't have enough rep to do so). So I'm not really sure how to proceed with downloading the relevant file (I understand how to get an export_link), but have no clue how to then prepare the next request).
Any help would be greatly appreciated :)
Here's some basic code for reference -
require 'googleauth'
require 'google/apis/drive_v2'
scopes = ['https://www.googleapis.com/auth/drive']
ENV["GOOGLE_APPLICATION_CREDENTIALS"] = 'path/to/my/creds.json'
auth = Google::Auth.get_application_default(scopes)
drive = Google::Apis::DriveV2::DriveService.new
drive.authorization = auth
ss = drive.get_file('my_spreadsheet_id')
export_url = ss.export_links
# what now?

how to get direct link of folder with Dropbox Ruby SDK?

I'm using Dropbox Ruby SDK, now I want get a full length share url of folder instead of the short url method shares(path) returns. But I couldn't find a way to pass query parameter 'short_url=false'( found on core API) with the method, since it only accepts one argument which is the path to share.
The reason I want the full length url is that I need to provide user a direct link to download the files( by adding 'dl=1'to the full url).
Any suggestion is appreciated.
It doesn't look like the Ruby library currently exposes this. But the source code is here: https://github.com/dropbox/dropbox-sdk-ruby/blob/master/lib/dropbox_sdk.rb#L1222-L1225. If you're up for it, please submit a pull request to add this to the SDK.
In the meantime, here's standalone code to do this:
def long_share_url(access_token, path)
client = DropboxClient.new(access_token)
session = DropboxOAuth2Session.new(access_token, nil)
response = session.do_get "/shares/auto/#{client.format_path(path)}", {"short_url"=>false}
Dropbox::parse_response(response)
end

Resources