{"id":177,"date":"2020-09-02T18:25:59","date_gmt":"2020-09-02T18:25:59","guid":{"rendered":"https:\/\/machine-learning.webcloning.com\/2020\/09\/02\/getting-a-batch-job-completion-message-from-amazon-translate\/"},"modified":"2020-09-02T18:25:59","modified_gmt":"2020-09-02T18:25:59","slug":"getting-a-batch-job-completion-message-from-amazon-translate","status":"publish","type":"post","link":"https:\/\/salarydistribution.com\/machine-learning\/2020\/09\/02\/getting-a-batch-job-completion-message-from-amazon-translate\/","title":{"rendered":"Getting a batch job completion message from Amazon Translate"},"content":{"rendered":"<div id=\"\">\n<p><a href=\"https:\/\/aws.amazon.com\/translate\/\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon Translate<\/a> is a neural machine translation service that delivers fast, high-quality, and affordable language translation. Neural machine translation is a form of language translation automation that uses deep learning models to deliver more accurate and natural-sounding translation than traditional statistical and rule-based translation algorithms. The translation service is trained on a wide variety of content across different use cases and domains to perform well on many kinds of content.<\/p>\n<p>The Amazon Translate <a href=\"https:\/\/docs.aws.amazon.com\/translate\/latest\/dg\/async.html\" target=\"_blank\" rel=\"noopener noreferrer\">asynchronous <\/a><a href=\"https:\/\/docs.aws.amazon.com\/translate\/latest\/dg\/async.html\" target=\"_blank\" rel=\"noopener noreferrer\">batch processing<\/a> capability enables organizations to translate a large collection of text or HTML documents. They can translate the collection of documents from one language to another with just a single API call. The ability to process data at scale is becoming important to organizations across all industries. In this blog post, we are going to demonstrate how you can build a notification mechanism to message you when a batch translation job is complete. This can enable end-end automation by triggering other Lambda functions or integrate with SQS for any post processing steps.<\/p>\n<h2>Solution overview<\/h2>\n<p>The following diagram illustrates the high-level architecture of the solution.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-14815 size-full\" title=\"Architecture diagram\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/08\/13\/translatebatchpoller_arch.png\" alt=\"Architecture diagram depicting polling mechanism for batch translation job\" width=\"842\" height=\"342\"><\/p>\n<p>The solution contains the following steps:<\/p>\n<ol>\n<li>A user starts a batch translation job.<\/li>\n<li>An <a href=\"http:\/\/aws.amazon.com\/cloudwatch\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon CloudWatch Events<\/a> rule picks up the event and triggers the <a href=\"http:\/\/aws.amazon.com\/step-functions\" target=\"_blank\" rel=\"noopener noreferrer\">AWS Step Functions<\/a>\n<\/li>\n<li>The Job Poller <a href=\"http:\/\/aws.amazon.com\/lambda\" target=\"_blank\" rel=\"noopener noreferrer\">AWS Lambda<\/a> function polls the job status every 5 minutes.<\/li>\n<li>When the Amazon Translate batch job is complete, an email notification is sent via an <a href=\"http:\/\/aws.amazon.com\/sns\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon Simple Notification Service<\/a> (Amazon SNS) topic.<\/li>\n<\/ol>\n<p>To implement this solution, you must create the following:<\/p>\n<ol>\n<li>An SNS topic<\/li>\n<li>An <a href=\"http:\/\/aws.amazon.com\/iam\" target=\"_blank\" rel=\"noopener noreferrer\">AWS Identity and Access Management<\/a> (IAM) role<\/li>\n<li>A Lambda function<\/li>\n<li>A Step Functions state machine<\/li>\n<li>A CloudWatch Events rule<\/li>\n<\/ol>\n<h2>Creating an SNS topic<\/h2>\n<p>To create an SNS topic, complete the following steps:<\/p>\n<ol>\n<li>On the <a href=\"https:\/\/console.aws.amazon.com\/sns\/\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon SNS console<\/a>, create a new topic.<\/li>\n<li>For <strong>Topic name<\/strong>, enter a name (for example, <code>TranslateJobNotificationTopic<\/code>).<\/li>\n<li>Choose <strong>Create topic<\/strong>.<\/li>\n<\/ol>\n<p>You can now see the TranslateJobNotificationTopic page. The <strong>Details<\/strong> section displays the topic\u2019s name, ARN, display name (optional), and the AWS account ID of the Topic owner.<\/p>\n<ol start=\"4\">\n<li>In the <strong>Details<\/strong> section, copy the topic ARN to the clipboard (<code>arn:aws:sns:us-east-1:<em>123456789012<\/em>:TranslateJobNotificationTopic<\/code>).<\/li>\n<li>On the left navigation pane, choose <strong>Subscriptions<\/strong>.<\/li>\n<li>Choose <strong>Create subscription<\/strong>.<\/li>\n<li>On the <strong>Create subscription<\/strong> page, enter the topic ARN of the topic you created earlier (<code>arn:aws:sns:us-east-1:<em>123456789012<\/em>:TranslateJobNotificationTopic<\/code>).<\/li>\n<li>For <strong>Protocol<\/strong>, select <strong>Email<\/strong>.<\/li>\n<li>For <strong>Endpoint<\/strong>, enter an email address that can receive notifications.<\/li>\n<li>Choose <strong>Create subscription<\/strong>.<\/li>\n<\/ol>\n<p>For email subscriptions, you have to first confirm the subscription by choosing the <strong>confirm subscription<\/strong> link in the email you received.<\/p>\n<h3>Creating an IAM role for the Lambda function<\/h3>\n<p>To create an IAM role, complete the following steps. For more information, see <a href=\"https:\/\/docs.aws.amazon.com\/AWSEC2\/latest\/UserGuide\/iam-roles-for-amazon-ec2.html#create-iam-role\" target=\"_blank\" rel=\"noopener noreferrer\">Creating an IAM Role<\/a>.<\/p>\n<ol>\n<li>On the <a href=\"https:\/\/console.aws.amazon.com\/iam\/\" target=\"_blank\" rel=\"noopener noreferrer\">IAM console<\/a>, choose <strong>Policies<\/strong>.<\/li>\n<li>Choose <strong>Create Policy<\/strong>.<\/li>\n<li>On the <strong>JSON<\/strong> tab, enter the following IAM policy:<\/li>\n<\/ol>\n<pre><code class=\"lang-json\">{    \"Version\": \"2012-10-17\",\r\n    \"Statement\": [\r\n        {\r\n            \"Sid\": \"VisualEditor0\",\r\n            \"Effect\": \"Allow\",\r\n            \"Action\": \"translate:DescribeTextTranslationJob\",\r\n            \"Resource\": \"*\"\r\n        },\r\n        {\r\n            \"Effect\": \"Allow\",\r\n            \"Action\": [\r\n                \"logs:CreateLogGroup\",\r\n                \"logs:CreateLogStream\",\r\n                \"logs:PutLogEvents\"\r\n            ],\r\n            \"Resource\": \"arn:aws:logs:us-east-1:123456789012:log-group:\/aws\/lambda\/TranslateJobStatusPoller:*\"\r\n        }\r\n    ]\r\n}<\/code><\/pre>\n<p>Update the resource property for CloudWatch Logs permission to reflect your configuration for Region, AWS account ID, and the Lambda function name.<\/p>\n<ol start=\"4\">\n<li>Choose <strong>Review policy<\/strong>.<\/li>\n<li>Enter a name (MyLambdaPolicy) for this policy and choose <strong>Create policy<\/strong>.<\/li>\n<li>Record the name of this policy for later steps.<\/li>\n<li>On the left navigation pane, choose <strong>Roles<\/strong>.<\/li>\n<li>Choose <strong>Create role<\/strong>.<\/li>\n<li>On the <strong>Select role type<\/strong> page, choose <strong>Lambda<\/strong> and the <strong>Lambda<\/strong> use case.<\/li>\n<li>Choose <strong>Next: Permissions<\/strong>.<\/li>\n<li>Filter policies by the policy name that you just created, and select the check-box.<\/li>\n<li>Choose <strong>Next: Tags<\/strong>.<\/li>\n<li>Add an appropriate tag.<\/li>\n<li>Choose <strong>Next: Review<\/strong>.<\/li>\n<li>Give this IAM role an appropriate name, and note it for future use.<\/li>\n<li>Choose <strong>Create role<\/strong>.<\/li>\n<\/ol>\n<h3>Creating a Lambda function<\/h3>\n<p>To create a Lambda function, complete the following steps. For more information, see <a href=\"https:\/\/docs.aws.amazon.com\/lambda\/latest\/dg\/getting-started-create-function.html\" target=\"_blank\" rel=\"noopener noreferrer\">Create a Lambda Function with the Console<\/a>.<\/p>\n<ol>\n<li>On the <a href=\"https:\/\/console.aws.amazon.com\/lambda\/home\" target=\"_blank\" rel=\"noopener noreferrer\">Lambda console<\/a>, choose <strong>Author from scratch<\/strong>.<\/li>\n<li>For <strong>Function Name<\/strong>, enter the name of your function (for example, <strong>TranslateJobStatusPoller<\/strong>).<\/li>\n<li>For <strong>Runtime<\/strong>, choose <strong>Python 3.8<\/strong>.<\/li>\n<li>For <strong>Execution role<\/strong>, select <strong>Use an existing role<\/strong>.<\/li>\n<li>Choose the IAM role you created in the previous step.<\/li>\n<li>Choose <strong>Create Function<\/strong>.<\/li>\n<li>Remove the default function and enter the following code into the <strong>Function Code<\/strong> window:<\/li>\n<\/ol>\n<pre><code class=\"lang-python\"># Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.\r\n# Licensed under the Apache License, Version 2.0 (the \"License\").\r\n# You may not use this file except in compliance with the License.\r\n# A copy of the License is located at## http:\/\/aws.amazon.com\/apache2.0\/\r\n# or in the \"license\" file accompanying this file.\r\n# This file is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\r\n# either express or implied. See the License for the specific language governing permissions\r\n# and limitations under the License.\r\n# Description: This Lambda function is part of the a step function that checks the status of Amazon translate batch job. \r\n# Author: Sudhanshu Malhotra\r\nimport boto3\r\nimport logging\r\nimport os\r\n\r\nfrom botocore.exceptions import ClientError\r\n\r\nlogging.basicConfig(level=logging.DEBUG)\r\nlogger = logging.getLogger(__name__)\r\n\r\ndef msgpublish(jobid):\r\n    client = boto3.client('translate')\r\n    try:\r\n        response = client.describe_text_translation_job(JobId=jobid)\r\n        logger.debug('Job Status is: {}' .format(response['TextTranslationJobProperties']['JobStatus']))\r\n        return(response['TextTranslationJobProperties']['JobStatus'])\r\n    \r\n    except ClientError as e:\r\n        logger.error(\"An error occured: %s\" % e)\r\n    \r\ndef lambda_handler(event, context):\r\n    logger.setLevel(logging.DEBUG)\r\n    logger.debug('Job ID is: {}' .format(event))\r\n    return(msgpublish(event))\r\n<\/code><\/pre>\n<ol start=\"8\">\n<li>Choose <strong>Save<\/strong>.<\/li>\n<\/ol>\n<h3>Creating a state machine<\/h3>\n<p>To create a state machine, complete the following steps. For more information, see <a href=\"https:\/\/docs.aws.amazon.com\/step-functions\/latest\/dg\/getting-started.html#create-state-machine\" target=\"_blank\" rel=\"noopener noreferrer\">Create a State Machine<\/a>.<\/p>\n<ol>\n<li>On the <a href=\"https:\/\/console.aws.amazon.com\/states\/home?#\/statemachines\/create\" target=\"_blank\" rel=\"noopener noreferrer\">Step Functions console<\/a>, on the <strong>Define state machine<\/strong> page, choose <strong>Start with a template<\/strong>.<\/li>\n<li>Choose <strong>Hello world<\/strong>.<\/li>\n<li>Under <strong>Type<\/strong>, choose <strong>Standard.<\/strong>\n<\/li>\n<li>Under <strong>Definition, <\/strong>enter the following <a href=\"https:\/\/docs.aws.amazon.com\/step-functions\/latest\/dg\/concepts-amazon-states-language.html\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon States Language<\/a>. Make sure to replace the Lambda function and SNS topic ARN.<\/li>\n<\/ol>\n<pre><code class=\"lang-json\">{\r\n\"Comment\": \"Polling step function for translate job complete\",\r\n\"StartAt\": \"LambdaPoll\",\r\n\"States\": {\r\n\"LambdaPoll\": {\r\n\"Type\": \"Task\",\r\n\"Resource\": \"&lt;ARN of the Lambda Function created in step 3&gt;\",\r\n\"InputPath\": \"$.detail.responseElements.jobId\",\r\n\"ResultPath\": \"$.detail.responseElements.jobStatus\",\r\n\"Next\": \"Job Complete?\",\r\n\"Retry\": [\r\n{\r\n\"ErrorEquals\": [\r\n\"States.ALL\"\r\n],\r\n\"IntervalSeconds\": 1,\r\n\"MaxAttempts\": 3,\r\n\"BackoffRate\": 2\r\n}\r\n]\r\n},\r\n\"Job Complete?\": {\r\n\"Type\": \"Choice\",\r\n\"Choices\": [\r\n{\r\n\"Variable\": \"$.detail.responseElements.jobStatus\",\r\n\"StringEquals\": \"IN_PROGRESS\",\r\n\"Next\": \"Wait X Seconds\"\r\n},\r\n{\r\n\"Variable\": \"$.detail.responseElements.jobStatus\",\r\n\"StringEquals\": \"SUBMITTED\",\r\n\"Next\": \"Wait X Seconds\"\r\n},\r\n{\r\n\"Variable\": \"$.detail.responseElements.jobStatus\",\r\n\"StringEquals\": \"COMPLETED\",\r\n\"Next\": \"Notify\"\r\n},\r\n{\r\n\"Variable\": \"$.detail.responseElements.jobStatus\",\r\n\"StringEquals\": \"FAILED\",\r\n\"Next\": \"Notify\"\r\n},\r\n{\r\n\"Variable\": \"$.detail.responseElements.jobStatus\",\r\n\"StringEquals\": \"STOPPED\",\r\n\"Next\": \"Notify\"\r\n}\r\n],\r\n\"Default\": \"Wait X Seconds\"\r\n},\r\n\"Wait X Seconds\": {\r\n\"Type\": \"Wait\",\r\n\"Seconds\": 60,\r\n\"Next\": \"LambdaPoll\"\r\n},\r\n\"Notify\": {\r\n\"Type\": \"Task\",\r\n\"Resource\": \"arn:aws:states:::sns:publish\",\r\n\"Parameters\": {\r\n\"Subject\": \"Translate Batch Job Notification\",\r\n\"Message\": {\r\n\"JobId.$\": \"$.detail.responseElements.jobId\",\r\n\"S3OutputLocation.$\": \"$.detail.requestParameters.outputDataConfig.s3Uri\",\r\n\"JobStatus.$\": \"$.detail.responseElements.jobStatus\"\r\n},\r\n\"MessageAttributes\": {\r\n\"JobId\": {\r\n\"DataType\": \"String\",\r\n\"StringValue.$\": \"$.detail.responseElements.jobId\"\r\n},\r\n\"S3OutputLocation\": {\r\n\"DataType\": \"String\",\r\n\"StringValue.$\": \"$.detail.requestParameters.outputDataConfig.s3Uri\"\r\n}\r\n},\r\n\"TopicArn\": \"&lt;ARN of the SNS topic created in step 1&gt;\"\r\n},\r\n\"End\": true\r\n}\r\n}\r\n}\r\n<\/code><\/pre>\n<ol start=\"5\">\n<li>Use the graph in the <strong>Visual Workflow<\/strong> pane to check that your Amazon States Language code describes your state machine correctly. You should see something like the following screenshot.<br \/><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-14817 alignnone\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/08\/13\/translatebatchpoller_ASL.png\" alt=\"Amazon State machine depicting various states of batch translation job\" width=\"350\" height=\"405\">\n<\/li>\n<\/ol>\n<ol start=\"6\">\n<li>Choose <strong>Next<\/strong>.<\/li>\n<li>For <strong>Name<\/strong>, enter a name for the state machine.<\/li>\n<li>Under <strong>Permissions<\/strong>, select <strong>Create new role<\/strong>.<\/li>\n<\/ol>\n<p>You now see an info block with the details of the role and the associated permissions.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-14820\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/08\/13\/translatebatchpoller_policytemplate.png\" alt=\"IAM policy screenshot for State machine\" width=\"500\" height=\"300\"><\/p>\n<ol start=\"9\">\n<li>Choose <strong>Create state machine.<\/strong>\n<\/li>\n<\/ol>\n<h3>Creating a CloudWatch Events rule<\/h3>\n<p>To create a CloudWatch Events rule, complete the following steps. This rule catches when a user performs a StartTextTranslationJob API event and triggers the step function (set as a target).<\/p>\n<ol>\n<li>On the <a href=\"https:\/\/console.aws.amazon.com\/cloudwatch\/\" target=\"_blank\" rel=\"noopener noreferrer\">CloudWatch console<\/a>, choose <strong>Rules<\/strong>.<\/li>\n<li>Choose <strong>Create rule<\/strong>.<\/li>\n<li>On the <strong>Step 1: Create rule <\/strong>page, under <strong>Event Source<\/strong>, select <strong>Event Pattern<\/strong>.<\/li>\n<li>Choose <strong>Build custom event pattern<\/strong> from the drop-down menu.<\/li>\n<li>Enter the following code into the preview pane:<\/li>\n<\/ol>\n<pre><code class=\"lang-json\">{ \r\n    \"source\": [ \"aws.translate\" ], \r\n    \"detail-type\": [ \"AWS API Call via CloudTrail\" ], \r\n    \"detail\": { \r\n            \"eventSource\": [ \"translate.amazonaws.com\" ], \r\n            \"eventName\": [ \"StartTextTranslationJob\" ] \r\n            } \r\n }<\/code><\/pre>\n<ol start=\"6\">\n<li>For <strong>Targets<\/strong>, select <strong>Step Functions state machine<\/strong>.<\/li>\n<li>Select the state machine you created earlier.<\/li>\n<li>For permission to send events to Step Functions, select <strong>Create a new role for this specific resource<\/strong>.<\/li>\n<li>Choose <strong>Configure details<\/strong>.<\/li>\n<li>On the <strong>Step 2: Configure rule details<\/strong> page, enter a name and description for the rule.<\/li>\n<li>For <strong>State<\/strong>, select <strong>Enabled<\/strong>.<\/li>\n<li>Choose <strong>Create rule<\/strong>.<\/li>\n<\/ol>\n<h2>Validating the solution<\/h2>\n<p>To test this solution, I first create an Amazon Translate batch job and provide the input text <a href=\"http:\/\/aws.amazon.com\/s3\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon Simple Storage Service<\/a> (Amazon S3) location, output Amazon S3 location, target language, and the data access service role ARN. For instructions on creating a batch translate job, see <a href=\"https:\/\/docs.aws.amazon.com\/translate\/latest\/dg\/async.html\" target=\"_blank\" rel=\"noopener noreferrer\">Asynchronous Batch Processing<\/a> or <a href=\"https:\/\/aws.amazon.com\/blogs\/machine-learning\/translating-documents-with-amazon-translate-aws-lambda-and-the-new-batch-translate-api\/\" target=\"_blank\" rel=\"noopener noreferrer\">Translating documents with Amazon Translate, AWS Lambda, and the new Batch Translate API<\/a>.<\/p>\n<p>The following screenshot shows my batch job on the <strong>Translation jobs<\/strong> page.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-14821 size-full\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/08\/13\/translatebatchpoller_Solutionval1.png\" alt=\"Amazon translate job start screenshot of Translate console\" width=\"842\" height=\"212\"><\/p>\n<p>The CloudWatch Events rule picks up the StartTextTranslationJob API and triggers the state machine. When the job is complete, I get an email notification via Amazon SNS.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-14822 size-full\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/08\/13\/translatebatchpoller_Solutionval2.png\" alt=\"Translate job complete notification email screenshot showing job status, job name and output location of the translated job\" width=\"842\" height=\"248\"><\/p>\n<h2>Conclusion<\/h2>\n<p>In this post, we demonstrated how you can use Step Functions to poll for an Amazon Translate batch job. For this use case, we configured an email notification to send when a job is complete; however, you can use this framework to trigger other Lambda functions or integrate with <a href=\"http:\/\/aws.amazon.com\/sqs\" target=\"_blank\" rel=\"noopener noreferrer\">Amazon Simple Queue Service<\/a> (Amazon SQS) for any postprocessing automated steps, enabling you to build an end-to-end automated workflow. For further reading, see the following:<\/p>\n<h2>About the Authors<\/h2>\n<hr>\n<p><em><img decoding=\"async\" loading=\"lazy\" class=\"alignleft wp-image-14826 size-thumbnail\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/08\/13\/Phonetool_sid-150x150.png\" alt=\"\" width=\"150\" height=\"150\"><\/em>Sudhanshu Malhotra is a Boston-based Enterprise Solutions Architect for AWS. He is a technology enthusiast who enjoys helping customers find innovative solutions to complex business challenges. His core areas of focus are DevOps, Machine Learning, and Security. When he\u2019s not working with customers on their journey to the cloud, he enjoys reading, hiking, and exploring new cuisines.<\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<p><span><em><img decoding=\"async\" loading=\"lazy\" class=\"alignleft wp-image-14823 size-thumbnail\" src=\"https:\/\/d2908q01vomqb2.cloudfront.net\/f1f836cb4ea6efb2a0b1b99f41ad8b103eff4b59\/2020\/08\/13\/Phonetool_sivarajamani-150x150.png\" alt=\"\" width=\"150\" height=\"150\"><\/em><\/span>Siva Rajamani is a Boston-based Enterprise Solutions Architect for AWS. He enjoys working closely with customers, supporting their digital transformation and AWS adoption journey. His core areas of focus are Serverless, Application Integration, and Security. Outside of work, he enjoys outdoor activities and watching documentaries.<\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>https:\/\/aws.amazon.com\/blogs\/machine-learning\/getting-a-batch-job-completion-message-from-amazon-translate\/<\/p>\n","protected":false},"author":0,"featured_media":178,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts\/177"}],"collection":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/comments?post=177"}],"version-history":[{"count":0,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/posts\/177\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/media\/178"}],"wp:attachment":[{"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/media?parent=177"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/categories?post=177"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/salarydistribution.com\/machine-learning\/wp-json\/wp\/v2\/tags?post=177"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}