{"id":604,"date":"2017-09-24T22:53:09","date_gmt":"2017-09-24T22:53:09","guid":{"rendered":"http:\/\/wiki.thomasandsofia.com\/?p=604"},"modified":"2017-09-26T01:52:11","modified_gmt":"2017-09-26T01:52:11","slug":"using-polly-to-pass-your-exam","status":"publish","type":"post","link":"https:\/\/wiki.thomasandsofia.com\/?p=604","title":{"rendered":"Using Polly to Pass your Exam (50 &#8211; 51)"},"content":{"rendered":"<p>Polly is Amazon&#8217;s text to speech service.<\/p>\n<p>Requires API Gateway and Cross Origin Resource Sharing* Part of the exam!<\/p>\n<p><a href=\"http:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2017\/09\/Screenshot-from-2017-09-24-18-09-41.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-607\" src=\"http:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2017\/09\/Screenshot-from-2017-09-24-18-09-41.png\" alt=\"\" width=\"1259\" height=\"849\" srcset=\"https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2017\/09\/Screenshot-from-2017-09-24-18-09-41.png 1259w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2017\/09\/Screenshot-from-2017-09-24-18-09-41-300x202.png 300w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2017\/09\/Screenshot-from-2017-09-24-18-09-41-768x518.png 768w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2017\/09\/Screenshot-from-2017-09-24-18-09-41-1024x691.png 1024w, https:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2017\/09\/Screenshot-from-2017-09-24-18-09-41-150x101.png 150w\" sizes=\"auto, (max-width: 1259px) 100vw, 1259px\" \/><\/a><\/p>\n<p>Artificial Intelligence &gt; Amazon Polly (was just &#8220;Polly&#8221;)<\/p>\n<p>Create a DynamoDB table<\/p>\n<ul>\n<li>New Table: posts<\/li>\n<li>Partition Key: id<\/li>\n<\/ul>\n<p>Setup S3<\/p>\n<ul>\n<li>Create 2 buckets.\n<ul>\n<li>One for the website (enable static web hosting)<\/li>\n<li>One for the files.\u00a0 (Why shouldn&#8217;t this be the same?)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Setup Messenging<\/p>\n<ul>\n<li>Messaging &gt; Simple Notification Service<\/li>\n<li>Create a topic\n<ul>\n<li>Name: new_posts<\/li>\n<li>Display Name: New Posts<\/li>\n<li>[Create topic]<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Create a Role for the Lambda functions<\/p>\n<ul>\n<li>Security, Identity &amp; Complience &gt; IAM &gt; Roles &gt; [Create role]<\/li>\n<li>Select type of role\n<ul>\n<li>AWS Service &gt; Lambda<\/li>\n<li>[Next: Permissions]<\/li>\n<\/ul>\n<\/li>\n<li>Attach Policy\n<ul>\n<li>Will create a custom role, so we&#8217;ll skip this for now.<\/li>\n<li>[Next: Review]<\/li>\n<\/ul>\n<\/li>\n<li>Review\n<ul>\n<li>Role Name: LambdaPostsReaderRole<\/li>\n<li>Role Description: Allows Lambda Function to call AWS services on your behalf<\/li>\n<li>[Create role]<\/li>\n<\/ul>\n<\/li>\n<li>Assign the policies\n<ul>\n<li>IAM &gt; Roles &gt; LambdaPostsReaderRole<\/li>\n<li>&#8220;Permissions&#8221; tab &gt; Inline Policies &gt; + Add inline policy<\/li>\n<\/ul>\n<\/li>\n<li>Set Permissions\n<ul>\n<li>(*) Custom Policy<\/li>\n<li>[Select]<\/li>\n<\/ul>\n<\/li>\n<li>Review Policy\n<ul>\n<li>Policy Name: LambdaPolicy<\/li>\n<li>Policy Document: Paste the code found <a href=\"http:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2017\/09\/lambdapolicy.txt\" target=\"_blank\" rel=\"noopener\">lambdapolicy.json<\/a>.<\/li>\n<li>[Validate Policy] to see if there are any errors (There is on the video)<\/li>\n<li>[Apply Policy]<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>Create Lambda Functions<\/h3>\n<p>Write text to the DynamoDB Table<\/p>\n<ul>\n<li>Compute &gt; Lambda &gt; [Create a function]<\/li>\n<li>Select Blueprint\n<ul>\n<li>[Author from scratch]<\/li>\n<\/ul>\n<\/li>\n<li>Configure Triggers\n<ul>\n<li>No triggers<\/li>\n<li>[Next]<\/li>\n<\/ul>\n<\/li>\n<li>Configure Function\n<ul>\n<li>Name: PostReader_NewPosts<\/li>\n<li>Description: Lambda function for new posts<\/li>\n<li>Runtime: Python 2.7<\/li>\n<li>Lambda function code\n<ul>\n<li>Insert the code located here: <a href=\"http:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2017\/09\/newposts.py_.txt\" target=\"_blank\" rel=\"noopener\">newposts.py<\/a><\/li>\n<li>Environmental Variables (You can see these in the code.)\n<ul>\n<li>DB_TABLE_NAME = posts<\/li>\n<li>SNS_TOPIC = Get the ARN value for the new_posts topic\n<ul>\n<li>arn:aws:sns:us-east-2:727545344356:new_posts<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>Lambda function handler and role\n<ul>\n<li>Handler: lambda_function.lambda_handler\n<ul>\n<li>This is not explained in the video.<\/li>\n<li>Mine defaulted to index.handler, so I changed it to match his.<\/li>\n<\/ul>\n<\/li>\n<li>Role: Choose and existing role<\/li>\n<li>Existing role: LambdaPostsReaderRole<\/li>\n<li>[Next]<\/li>\n<\/ul>\n<\/li>\n<li>Review\n<ul>\n<li>[Create function]<\/li>\n<\/ul>\n<\/li>\n<li>Test\n<ul>\n<li>&#8220;voice&#8221;: &#8220;Joanna&#8221;<\/li>\n<li>&#8220;text&#8221;: &#8220;This is working!&#8221;<\/li>\n<li>&#8211; Success!<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Create Polly Service<\/p>\n<ul>\n<li>Lambda &gt; Functions &gt; [Create function] &gt; [Author from scratch]<\/li>\n<li>Configure triggers\n<ul>\n<li>Select SNS<\/li>\n<li>Topic = new_posts<\/li>\n<li>[x] Enable trigger<\/li>\n<li>[Next]<\/li>\n<\/ul>\n<\/li>\n<li>Configure function\n<ul>\n<li>Name: PostReader_ConvertToAudio<\/li>\n<li>Description: Convert our posts to audio<\/li>\n<li>Runtime: Python 2.7<\/li>\n<li>Advanced settings\n<ul>\n<li>timeout: 5 minutes 0 seconds (might take a while to convert a lot of text!)<\/li>\n<\/ul>\n<\/li>\n<li>Code: Insert code found here: <a href=\"http:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2017\/09\/convertoaudio.py_.txt\" target=\"_blank\" rel=\"noopener\">convertoaudio.py<\/a><\/li>\n<li>Environmental Variables\n<ul>\n<li>DB_TABLE_NAME = posts<\/li>\n<li>BUCKET_NAME = your_bucket_name (s3.thomasandsofia.com)<\/li>\n<\/ul>\n<\/li>\n<li>Handler: lambda_function.lambda_handler<\/li>\n<li>Role: Choose and existing role<\/li>\n<li>Existing role: LambdaPostsReaderRole<\/li>\n<li>[Next]<\/li>\n<\/ul>\n<\/li>\n<li>Review\n<ul>\n<li>[Create function]<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Get Posts from DynamoDB<\/p>\n<p>(might explain why I didn&#8217;t understand some of the code&#8230;.)<\/p>\n<ul>\n<li>Lambda &gt; Functions &gt; [Create function] &gt; [Author from scratch]<\/li>\n<li>Configure triggers\n<ul>\n<li>Will be triggered by API Gateway, so leave blank<\/li>\n<li>[Next]<\/li>\n<\/ul>\n<\/li>\n<li>Configure function\n<ul>\n<li>Name: PostReader_GetPosts<\/li>\n<li>Desc: PostReader_GetPosts<\/li>\n<li>Runtime: Python 2.7<\/li>\n<li>Code: Insert code found here: <a href=\"http:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2017\/09\/getposts.py_.txt\">getposts.py<\/a><\/li>\n<li>Environmental Variables\n<ul>\n<li>DB_TABLE_NAME = posts<\/li>\n<li>BUCKET_NAME = your_bucket_name (s3.thomasandsofia.com)<\/li>\n<\/ul>\n<\/li>\n<li>Handler: lambda_function.lambda_handler<\/li>\n<li>Role: Choose and existing role<\/li>\n<li>Existing role: LambdaPostsReaderRole<\/li>\n<li>[Next]<\/li>\n<\/ul>\n<\/li>\n<li>Review\n<ul>\n<li>[Create function]<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Configure API Gateway<\/p>\n<ul>\n<li>Application Services &gt; API Gateway<\/li>\n<li>Create new API\n<ul>\n<li>(*) New API<\/li>\n<li>Name and description\n<ul>\n<li>API name: PostReaderAPI<\/li>\n<li>Description: API to read my posts<\/li>\n<\/ul>\n<\/li>\n<li>[Create API]<\/li>\n<\/ul>\n<\/li>\n<li>Resources &#8211; Actions &gt; Create Method\n<ul>\n<li>Blank dropdown: POST<\/li>\n<li>Click the Checkmark Icon<\/li>\n<li>&#8211; POST &#8211; Setup\n<ul>\n<li>Integration type: (*) Lambda Function<\/li>\n<li>Use Lambda Proxy integration [ ] (do not check)<\/li>\n<li>Lambda Region: Select your region (us-east-2)<\/li>\n<li>Lambda Function: click in box, type a character and select &#8216;PostReader_NewPost&#8217;<\/li>\n<\/ul>\n<ul>\n<li>[Save]<\/li>\n<li>&#8220;Add Permission to Lambda Function&#8221;\n<ul>\n<li>[OK]<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>Resources &#8211; Actions &gt; Create Method\n<ul>\n<li>Blank dropdown: GET<\/li>\n<li>Click the Checkmark Icon<\/li>\n<li>&#8211; POST &#8211; Setup\n<ul>\n<li>Integration type: (*) Lambda Function<\/li>\n<li>Use Lambda Proxy integration [ ] (do not check)<\/li>\n<li>Lambda Region: Select your region (us-east-2)<\/li>\n<li>Lambda Function: click in box, type a character and select &#8216;PostReader_GetPost&#8217;<\/li>\n<\/ul>\n<ul>\n<li>[Save]<\/li>\n<li>&#8220;Add Permission to Lambda Function&#8221;\n<ul>\n<li>[OK]<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>&#8220;Cross Origin Resource Sharing&#8221; aka CORS\n<ul>\n<li>Resources &#8211; Actions &gt; Enable CORS<\/li>\n<li>Enable CORS\n<ul>\n<li>This enables you to invoke your API from a website\/domain name that has a different hostname to that API.\u00a0 In this instance, it will be our S3 bucket.<\/li>\n<li>Methods: [x]POST [X]GET [x]Options<\/li>\n<li>[Enable CORS and replace existing CORS headers]<\/li>\n<li>Confirm method changes\n<ul>\n<li>[Yes, replace existing values]<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>Resources &gt; click &#8216;GET&#8217; &gt; Method Request<\/li>\n<li>&#8211; GET &#8211; Method Request &gt; URL Query String Parameters<\/li>\n<li>+ Add query string\n<ul>\n<li>Name: postId (Case sensitive!)<\/li>\n<li>Click the Checkmark Icon<\/li>\n<\/ul>\n<\/li>\n<li>Resources &gt; click &#8216;GET&#8217; &gt; Integration Request<\/li>\n<li>&#8211; GET &#8211; Method Request &gt; Body Mapping Templates<\/li>\n<li>Request body passthrough\n<ul>\n<li>(*) When there are no templates defined (recommended)<\/li>\n<li>+ Add mapping template\n<ul>\n<li>Under &#8216;Content-Type&#8217; (above, I know, strange): application\/json<\/li>\n<li>Click Checkmark<\/li>\n<li>application\/json code: Paste contents found here: <a href=\"http:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2017\/09\/mappings.json_.txt\" target=\"_blank\" rel=\"noopener\">mappings.json<\/a><\/li>\n<li>[Save]<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>Resource &#8211; Actions &gt; Deploy API\n<ul>\n<li>Deployment stage: [New Stage]<\/li>\n<li>Stage name: Dev<\/li>\n<li>Stage description: Dev<\/li>\n<li>Deployment description: Dev<\/li>\n<li>[Deploy]<\/li>\n<\/ul>\n<\/li>\n<li>dev Stage Editor &#8211; Get the URL!!\n<ul>\n<li>Invoke URL:\u00a0 https:\/\/oep9d88gib.execute-api.us-east-2.amazonaws.com\/dev<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Deploy the website<\/p>\n<ul>\n<li>Storage &gt; S3 &gt; Select Bucket &gt; Permissions &gt; Bucket Policy<\/li>\n<li>Insert the JSON code found here: <a href=\"http:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2017\/09\/bucketpolicypermissions.json_.txt\" target=\"_blank\" rel=\"noopener\">bucketpolicypermissions.json<\/a>\n<ul>\n<li>Over-write &#8220;arn:aws:s3:::BUCKET_NAME&#8221; with the actual ARN of the bucket.\u00a0 This is posted above the code window. <span class=\"ng-binding\">arn:aws:s3:::s3.thomasandsofia.com<\/span><\/li>\n<li>[Save]<\/li>\n<\/ul>\n<\/li>\n<li>Edit <a href=\"http:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2017\/09\/scripts.js.txt\" target=\"_blank\" rel=\"noopener\">scripts.js<\/a>\n<ul>\n<li>Replace YOUR-API-GATEWAY-HERE with the URL you saved from the API gateway.<\/li>\n<li>Upload to the bucket<\/li>\n<\/ul>\n<\/li>\n<li>Upload <a href=\"http:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2017\/09\/index.html.txt\">index.html<\/a><\/li>\n<li>Upload <a href=\"http:\/\/wiki.thomasandsofia.com\/wp-content\/uploads\/2017\/09\/styles.css.txt\">styles.css<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Polly is Amazon&#8217;s text to speech service. Requires API Gateway and Cross Origin Resource Sharing* Part of the exam! Artificial Intelligence &gt; Amazon Polly (was just &#8220;Polly&#8221;) Create a DynamoDB table New Table: posts Partition Key: id Setup S3 Create 2 buckets. One for the website (enable static web hosting) One for the files.\u00a0 (Why ..<\/p>\n<div class=\"clear-fix\"><\/div>\n<p><a href=\"https:\/\/wiki.thomasandsofia.com\/?p=604\" title=\"read more...\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18],"tags":[],"class_list":["post-604","post","type-post","status-publish","format-standard","hentry","category-amazon-web-services-aws"],"_links":{"self":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/604","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=604"}],"version-history":[{"count":7,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/604\/revisions"}],"predecessor-version":[{"id":621,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=\/wp\/v2\/posts\/604\/revisions\/621"}],"wp:attachment":[{"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=604"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=604"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wiki.thomasandsofia.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=604"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}