How to access AWS Comprehend using aws-sdk-comprehend gem?

230 views Asked by At

I'm working on getting my Rails app interacting with the AWS Comprehend service for text entity extraction. I'm using the aws-sdk-comprehend gem. I have successfully gotten my app working with the AWS Rekognition service for image analysis using the aws-sdk-rekognition gem.

I can't seem to get the AWS Comprehend authentication correct as all of my calls result in an Aws::Comprehend::Errors::InvalidRequestException.

I have all of the following ENV variables set:

  • AWSAccessKeyId
  • AWSSecretKey
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

My code looks something like this:

class MyApp::Aws::ComprehendService < MyApp::ServiceBase 

  def call
    @credentials = Aws::Credentials.new(ENV['AWSAccessKeyId'], ENV['AWSSecretKey'])
    @client = Aws::Comprehend::Client.new(region: "us-west-1", credentials: credentials)
    @client.detect_entities({text: "this is a simply little blob of text", language_code: "en"})
  end

end

This resulted in Aws::Comprehend::Errors::InvalidRequestException. So I also tried:

class MyApp::Aws::ComprehendService < MyApp::ServiceBase 

  def call
    # use ENV credential format I've seen in examples...
    @credentials = Aws::Credentials.new(ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'])
    @client = Aws::Comprehend::Client.new(region: "us-west-1", credentials: credentials)
    @client.detect_entities({text: "this is a simply little blob of text", language_code: "en"})
  end

end

I found an example that didn't use the @credential approach. The example claimed "The initialize method will load the credentials environment variables by itself". So I tried this:

class MyApp::Aws::ComprehendService < MyApp::ServiceBase 

  def call
    # ignore setting the credentials
    @client = Aws::Comprehend::Client.new(region: "us-west-1")
    @client.detect_entities({text: "this is a simply little blob of text", language_code: "en"}).
  end

end

This also resulted in Aws::Comprehend::Errors::InvalidRequestException.

Can you see anything I'm doing wrong? Has anyone had success in using this gem to interact with the Comprehend API?

1

There are 1 answers

2
engineersmnky On

Per the Documentation for Aws::Comprehend::Client#detect_entities

If the system detects a document-level error in your input document, the API returns an InvalidRequestException error response. For details about this exception, see Errors in semi-structured documents in the Comprehend Developer Guide.

So it appears your usage is not necessarily the issue but rather the input documents themselves.

The response however should include what the actual issue is according to the Developer Guide:

Document-level errors

If the ClassifyDocument or DetectEntities API operation detects a document-level error in your input document, the API returns an InvalidRequestException error response.

In the error response, the Reason field contains the value INVALID_DOCUMENT.

The Detail field contains one of the following values:

  • DOCUMENT_SIZE_EXCEEDED – Document size is too large. Check the size of your file and resubmit the request.

  • UNSUPPORTED_DOC_TYPE – Document type is not supported. Check the file type and resubmit the request.

  • PAGE_LIMIT_EXCEEDED – Too many pages in the document. Check the number of pages in your file and resubmit the request.

  • TEXTRACT_ACCESS_DENIED_EXCEPTION – Access denied to Amazon Textract. Verify that your account has permission to use the Amazon Textract DetectDocumentText and AnalyzeDocument API operations and resubmit the request.

The Aws::Comprehend::Errors::InvalidRequestException object is documented so it appears you could potentially figure out what is wrong via

def call
    # use ENV credential format I've seen in examples...
    @credentials = Aws::Credentials.new(ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'])
    @client = Aws::Comprehend::Client.new(region: "us-west-1", credentials: credentials)
    begin
      @client.detect_entities({text: "this is a simply little blob of text", language_code: "en"})
    rescue Aws::Comprehend::Errors::InvalidRequestException => e
      # interrogate the error object here e.g. 
      puts {reason: e.reason, detail: e.detail} 
    end 
  end