I get ThrottlingException while using AWS translate api

Viewed 2060

I am running this code to translate

translate = boto3.client(service_name='translate',
    aws_access_key_id="secret",
    aws_secret_access_key="secret",
    region_name='eu-central-1',
    use_ssl=True)

translate.translate_text(Text=data,SourceLanguageCode="de",TargetLanguageCode="en").get("TranslatedText")

Code runs properly for most of the test but suddenly throws the following error:

An error occurred (ThrottlingException) when calling the TranslateText operation (reached max retries: 4): Rate exceeded 

How to handle this exception?

4 Answers

Ran into a similar issue and did not want to use asynchronous batch requests, because I'm using multiple translation APIs and would rather keep the code the same for all.

Here are payload limits for different translation APIs. This may impact throttling (e.g. calling the Amazon Translate API multiple times per second with a small payload worked just fine):

Amazon's limit is clearly the lowest.

Now for the throttling limits on Amazon Translate:

  • Amazon does not indicate what the throttling limit is for the normal API, the docs merely state:

    Amazon Translate scales to serve customer operational traffic. If you encounter sustained throttling, contact AWS Support.

  • But docs for AWS GovCloud do mention:

    The default throttling limits for AWS GovCloud (US) are set to 5000 Bytes per 10 seconds per language pair and 10 transactions per second per language pair. You can request an increase for any of the limits using the Amazon Translate service limits increase form.

For my use case (translating HTML larger than 5,000 bytes after splitting it into chunks), ended up implementing a simple wait of 15 seconds between API calls to avoid hitting the throttling limits. In my tests, translating a payload of 2K to 5K bytes 200 times, with a sleep time of 15 seconds between calls, all ran successfully (whereas with a wait time of just 11 seconds I'd still get some ThrottlingException.)

If I were to code it better, I'd probably implement retries with exponential backoff like Marcin suggested. Or would request a limit increase to make my life easier and my experience more consistent across APIs.

Have you considered using the asynchronous call start_text_translation_job() instead of the synchronous call translate_text()? Then you would have a much higher limit, instead of 5000 bytes, you would have 1,000,000 characters * 1,000,000 documents * 10 batches: https://docs.aws.amazon.com/translate/latest/dg/what-is-limits.html#limits-throttling

Synchronous Real-Time Translation Limits:

Description Limit
Character encoding  UTF-8
Maximum document size (UTF-8 characters)    5,000 bytes

Asynchronous Batch Translation Limits:

Description Limit
Character encoding  UTF-8
Maximum number of characters per document   1,000,000
Maximum size per document   20 MB
Maximum number of documents in batch    1,000,000
Maximum size of total documents in batch    5 GB
Maximum number of parallel batch translation jobs   10

The code for the asynchronous start_text_translation_job() call can be find here: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/translate.html

response = client.start_text_translation_job(
    JobName='string',
    InputDataConfig={
        'S3Uri': 'string',
        'ContentType': 'string'
    },
    OutputDataConfig={
        'S3Uri': 'string'
    },
    DataAccessRoleArn='string',
    SourceLanguageCode='string',
    TargetLanguageCodes=[
        'string',
    ],
    TerminologyNames=[
        'string',
    ],
    ClientToken='string'
)

This question is a few months old now but the solution here worked well for me and let me avoid needing to write my own backoff code:

import boto3
from botocore.config import Config

config = Config(retries=dict(max_attempts=10))
region = "us-east-1"

translate = boto3.client(
    service_name="translate",
    region_name=region,
    use_ssl=True,
    config=config,
)

Even in us-east-1 I seem to hit a few retries, and it's much slower than Google Cloud Translate (which I also hit from Python in the same script), but it works.

Related