【问题标题】:AWS Textract InvalidParameterExceptionAWS 文本无效参数异常
【发布时间】:2022-01-26 07:45:39
【问题描述】:

我有一个 .Net 核心客户端应用程序,根据 AWS 文档使用带有 S3、SNS 和 SQS 的 amazon Textract,检测和分析多页文档中的文本 (https://docs.aws.amazon.com/textract/latest/dg/async.html)

使用 AmazonTextractServiceRole 策略创建了一个 AWS 角色,并根据文档 (https://docs.aws.amazon.com/textract/latest/dg/api-async-roles.html) 添加了以下信任关系 { “版本”:“2012-10-17”, “陈述”: [ { “效果”:“允许”, “主要的”: { “服务”:“textract.amazonaws.com” }, “动作”:“sts:AssumeRole” } ] }

订阅 SQS 到该主题并根据 aws 文档授予 Amazon SNS 主题向 Amazon SQS 队列发送消息的权限。

所有资源,包括 S3 Bucket、SNS、SQS 都在同一个 us-west2 区域中

以下方法显示一般错误“InvalidParameterException” 请求的参数无效

但如果 NotificationChannel 部分被注释,则代码工作正常并返回正确的作业 ID。

错误消息没有给出关于参数的清晰图片。非常感谢任何帮助。

public async Task<string> ScanDocument()
{
            string roleArn = "aws:iam::xxxxxxxxxxxx:instance-profile/MyTextractRole";
            string topicArn = "aws:sns:us-west-2:xxxxxxxxxxxx:AmazonTextract-My-Topic";
            string bucketName = "mybucket";
            string filename = "mytestdoc.pdf";

            var request = new StartDocumentAnalysisRequest();
            var notificationChannel = new NotificationChannel();
            notificationChannel.RoleArn = roleArn;
            notificationChannel.SNSTopicArn = topicArn;

            var s3Object = new S3Object
            {
                Bucket = bucketName,
                Name = filename
            };
            request.DocumentLocation = new DocumentLocation
            {
                S3Object = s3Object
            };
            request.FeatureTypes = new List<string>() { "TABLES", "FORMS" };
            request.NotificationChannel = channel; /* Commenting this line work the code*/
            var response = await this._textractService.StartDocumentAnalysisAsync(request);
            return response.JobId;

        }

【问题讨论】:

    标签: amazon-web-services .net-core amazon-textract


    【解决方案1】:

    调试无效的 AWS 请求

    AWS 开发工具包会在本地验证您的请求对象,然后再将其分派到 AWS 服务器。此验证将失败,并出现无用的不透明错误,例如 OP。

    由于 SDK 是开源的,您可以检查源代码以帮助缩小无效参数的范围。

    在我们查看代码之前:SDK(和文档)实际上是从描述 API、其要求以及如何验证它们的特殊 JSON 文件生成的。实际代码是根据这些 JSON 文件生成的。

    我将使用 Node.js SDK 作为示例,但我确信类似的方法可能适用于其他 SDK,包括 .NET

    在我们的例子中(AWS Textract),最新的 Api 版本是2018-06-27。果然,JSON源文件在GitHub上,here

    就我而言,实验将问题缩小到ClientRequestToken。错误是不透明的InvalidParameterException。我在 SDK 源 JSON 文件中搜索了它,果然在line 392

    "ClientRequestToken": {
      "type": "string",
      "max": 64,
      "min": 1,
      "pattern": "^[a-zA-Z0-9-_]+$"
    },
    

    一大堆未记录的需求!

    就我而言,我使用的令牌违反了正则表达式(上述源代码中的pattern)。更改我的令牌代码以满足正则表达式解决了这个问题。

    对于这类不透明的类型错误,我推荐这种方法。

    【讨论】:

    • “一大堆未记录的需求!”这是现场!
    【解决方案2】:

    经过漫长的一天分析问题。我能够解决它.. 根据文档主题,只需要将 SendMessage 操作发送到 SQS 。但是在将其更改为 All SQS Action 后,它开始工作。但是仍然 AWS 错误消息确实具有误导性和混淆性

    【讨论】:

      【解决方案3】:

      您需要将权限更改为 All SQS Action,然后使用以下代码

      
      def startJob(s3BucketName, objectName):
          response = None
          response = textract.start_document_text_detection(
          DocumentLocation={
              'S3Object': {
                  'Bucket': s3BucketName,
                  'Name': objectName
              }
          })
      
          return response["JobId"]
      
      def isJobComplete(jobId):
          # For production use cases, use SNS based notification 
          # Details at: https://docs.aws.amazon.com/textract/latest/dg/api-async.html
          time.sleep(5)
          response = textract.get_document_text_detection(JobId=jobId)
          status = response["JobStatus"]
          print("Job status: {}".format(status))
      
          while(status == "IN_PROGRESS"):
              time.sleep(5)
              response = textract.get_document_text_detection(JobId=jobId)
              status = response["JobStatus"]
              print("Job status: {}".format(status))
      
          return status
      
      def getJobResults(jobId):
      
          pages = []
      
          response = textract.get_document_text_detection(JobId=jobId)
          
          pages.append(response)
          print("Resultset page recieved: {}".format(len(pages)))
          nextToken = None
          if('NextToken' in response):
              nextToken = response['NextToken']
      
          while(nextToken):
      
              response = textract.get_document_text_detection(JobId=jobId, NextToken=nextToken)
              pages.append(response)
              print("Resultset page recieved: {}".format(len(pages)))
              nextToken = None
              if('NextToken' in response):
                  nextToken = response['NextToken']
      
          return pages
      

      【讨论】:

      • 请记住,Stack Overflow 不仅仅是为了解决眼前的问题,而是为了帮助未来的读者找到类似问题的解决方案,这需要了解底层代码。这对于我们社区的初学者和不熟悉语法的成员来说尤其重要。鉴于此,您能否edit 您的答案包括对您正在做什么的解释以及为什么您认为这是最好的方法?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-17
      • 2012-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-12
      • 1970-01-01
      相关资源
      最近更新 更多