aws-sam-cli icon indicating copy to clipboard operation
aws-sam-cli copied to clipboard

Unable to Retrieve Bot Response: ERR_NAME_NOT_RESOLVED and 403 Forbidden Error in Flask Application

Open Hafsa-221 opened this issue 10 months ago • 10 comments

Description: I'm encountering an issue with my Flask application where I'm unable to retrieve a response from the bot when sending a query through the index.html page. Here are the details:

Problem: When I enter a query in the input field on the index.html page and click "Send," the request is made to the "/get" endpoint in my Flask application, but I'm not receiving any response from the bot.

Steps to reproduce: Open the index.html page in a browser. Enter a query in the input field. Click "Send." Check the browser console for any errors.

Error messages: Failed to load resource: net::ERR_NAME_NOT_RESOLVED Failed to load resource: the server responded with a status of 403 (Forbidden)

Code snippets:

flask route:

@app.route("/get") def get_bot_response(): print("Inside get_bot_response function") # Add this line user_text = request.args.get('msg') print("Received message:", user_text) # Print the user's message bot_response = get_query_reply(user_text) print("Bot's response:", bot_response) # Print the bot's response headers = get_headers() # Get the headers return jsonify(bot_response), 200, headers

Expected behavior: After sending a query, I should receive a response from the bot displayed in the chat area on the index.html page.

Environment details: Operating system: Windows Browser: Google Python version: 3.12

I would appreciate any assistance in resolving this issue. Thank you!

Hafsa-221 avatar Apr 08 '24 21:04 Hafsa-221

Thanks for opening this issue. This is the repository for AWS SAM CLI, a command line tool to manage AWS Cloudformation resources.

Can you provide a project where we can reproduce this if this is a SAM CLI issue?

lucashuy avatar Apr 08 '24 22:04 lucashuy

The problem I'm facing involves running a Flask application on AWS Lambda with API Gateway integration. Specifically, I'm encountering errors related to loading resources (ERR_NAME_NOT_RESOLVED) and receiving a 403 Forbidden error.

Would you still like me to provide a project to reproduce the issue, or do you have any suggestions on how I can resolve these errors within the context of deploying a Flask application on AWS Lambda with API Gateway?

Thank you for your assistance

Hafsa-221 avatar Apr 09 '24 07:04 Hafsa-221

Hi, could you provide the project please? It would be useful to help figuring out the root cause of your issue.

jysheng123 avatar Apr 09 '24 16:04 jysheng123

Here are the main project files: app.py

import constants
import nltk
import ssl
import tempfile
import random
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import string
import sys
import warnings
import requests
import awsgi
import json
from flask import Flask, render_template,jsonify

try:
    _create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
    pass
else:
    ssl._create_default_https_context = _create_unverified_https_context

# Use a temporary directory for NLTK data
temp_dir = tempfile.mkdtemp()
nltk.data.path.append(temp_dir)

# Download necessary NLTK resources
nltk.download('punkt', download_dir=temp_dir)



def get_formalities_reply(formality):
    if any(remove_punctuation_marks(formality).lower() in remove_punctuation_marks(greet).lower() for greet in constants.GREETING_INPUTS):
        return random.choice(constants.GREETING_REPLIES)
    elif any(remove_punctuation_marks(formality).lower() in remove_punctuation_marks(thanks).lower() for thanks in constants.THANKS_INPUTS):
        return random.choice(constants.THANKS_REPLIES)

def get_lemmatized_tokens(text):
    normalized_tokens = nltk.word_tokenize(remove_punctuation_marks(text.lower()))
    return [nltk.stem.WordNetLemmatizer().lemmatize(normalized_token) for normalized_token in normalized_tokens]

corpus = open('corpus.txt', 'r', errors='ignore').read().lower()
documents = nltk.sent_tokenize(corpus)

def get_query_reply(query):    
    documents.append(query)
    tfidf_results = TfidfVectorizer(tokenizer=get_lemmatized_tokens, stop_words='english').fit_transform(documents)
    cosine_similarity_results = cosine_similarity(tfidf_results[-1], tfidf_results).flatten()
    best_index = cosine_similarity_results.argsort()[-2]
    documents.remove(query)
    if cosine_similarity_results[best_index] == 0:
        return "I am sorry! I don't understand you..."
    else:
        return documents[best_index]

def remove_punctuation_marks(text):
    punctuation_marks = dict((ord(punctuation_mark), None) for punctuation_mark in string.punctuation)
    return text.translate(punctuation_marks)



app = Flask(__name__)
#app.static_folder = 'static'
def get_headers():
    return {
        "Access-Control-Allow-Credentials": "true",
        "Access-Control-Allow-Origin": "*",
        "Content-Type": "application/json"
    }



@app.route("/")
def home():
    print("Attempting to render index.html")  # Debugging statement
    return render_template("index.html")
    #return "<!doctype html>\n<html lang=en>\n<title>Test TIle</title>\n<h1>Test heading</h1>\n<p>Test message</p>\n"
 


@app.route("/get")
def get_bot_response():
    print("Inside get_bot_response function")  # Add this line
    user_text = request.args.get('msg')
    print("Received message:", user_text)  # Print the user's message
    bot_response = get_query_reply(user_text)
    print("Bot's response:", bot_response)  # Print the bot's response
    headers = get_headers()  # Get the headers
    return jsonify(bot_response), 200, headers 


  
def lambda_handler(event, context):
    print("Event is: ",event)
    print("Context is: ",context)
    if event == {}:
        #event = {}
        #event['httpMethod'] = 'GET'
        #event['path'] = '/'
        #event['queryStringParameters'] = {}
        #event_data=json.dumps(event)
        #print("Event_data is: ",event_data)
        #event = {'httpMethod':'GET','path':'/','queryStringParameters':{}}
        
        print("Event now is: ",event)
        print("App is: ",app)
        return awsgi.response(app, event, context)
        headers = get_headers()
        response['headers'] = get_headers()  # Add headers to the response
        return response
        
    else:
        event = {'httpMethod':'GET','path':'/','queryStringParameters':{}}
        return awsgi.response(app, event, context)
        headers = get_headers()
        response['headers'] = get_headers()  # Add headers to the response
        return response

Main file index.html :

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Payactiv</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="shortcut icon" href="#" />
<style>
:root {
    --body-bg: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
    --msger-bg: #fff;
    --border: 2px solid #ddd;
    --left-msg-bg: #ececec;
    --right-msg-bg: #579ffb;
  }
  
  html {
    box-sizing: border-box;
  }
  
  *,
  *:before,
  *:after {
    margin: 0;
    padding: 0;
    box-sizing: inherit;
  }
  
  body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    background-image: var(--body-bg);
    font-family: Helvetica, sans-serif;
  }
  
  .msger {
    display: flex;
    flex-flow: column wrap;
    justify-content: space-between;
    width: 100%;
    max-width: 867px;
    margin: 25px 10px;
    height: calc(100% - 50px);
    border: var(--border);
    border-radius: 5px;
    background: var(--msger-bg);
    box-shadow: 0 15px 15px -5px rgba(0, 0, 0, 0.2);
  }
  
  .msger-header {
    /* display: flex; */
    font-size: medium;
    justify-content: space-between;
    padding: 10px;
    text-align: center;
    border-bottom: var(--border);
    background: #eee;
    color: #666;
  }
  
  .msger-chat {
    flex: 1;
    overflow-y: auto;
    padding: 10px;
  }
  .msger-chat::-webkit-scrollbar {
    width: 6px;
  }
  .msger-chat::-webkit-scrollbar-track {
    background: #ddd;
  }
  .msger-chat::-webkit-scrollbar-thumb {
    background: #bdbdbd;
  }
  .msg {
    display: flex;
    align-items: flex-end;
    margin-bottom: 10px;
  }
  
  .msg-img {
    width: 50px;
    height: 50px;
    margin-right: 10px;
    background: #ddd;
    background-repeat: no-repeat;
    background-position: center;
    background-size: cover;
    border-radius: 50%;
  }
  .msg-bubble {
    max-width: 450px;
    padding: 15px;
    border-radius: 15px;
    background: var(--left-msg-bg);
  }
  .msg-info {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
  }
  .msg-info-name {
    margin-right: 10px;
    font-weight: bold;
  }
  .msg-info-time {
    font-size: 0.85em;
  }
  
  .left-msg .msg-bubble {
    border-bottom-left-radius: 0;
  }
  
  .right-msg {
    flex-direction: row-reverse;
  }
  .right-msg .msg-bubble {
    background: var(--right-msg-bg);
    color: #fff;
    border-bottom-right-radius: 0;
  }
  .right-msg .msg-img {
    margin: 0 0 0 10px;
  }
  
  .msger-inputarea {
    display: flex;
    padding: 10px;
    border-top: var(--border);
    background: #eee;
  }
  .msger-inputarea * {
    padding: 10px;
    border: none;
    border-radius: 3px;
    font-size: 1em;
  }
  .msger-input {
    flex: 1;
    background: #ddd;
  }
  .msger-send-btn {
    margin-left: 10px;
    background: #579ffb;
    color: #fff;
    font-weight: bold;
    cursor: pointer;
    transition: background 0.23s;
  }
  .msger-send-btn:hover {
    background: rgb(0, 180, 50);
  }
  
  .msger-chat {
    background-color: #fcfcfe;
     }

</style>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
</head>

<body>
  <!-- partial:index.partial.html -->
  <section class="msger">
    <header class="msger-header">
      <div class="msger-header-title">
        </i> Chat </i>
      </div>
    </header>

    <main class="msger-chat">
      <div class="msg left-msg">
        <div class="msg-img" style="background-image: url(https://image.flaticon.com/icons/svg/327/327779.svg)"></div>

        <div class="msg-bubble">
          <div class="msg-info">
            <div class="msg-info-name">Marty</div>
            <div class="msg-info-time"></div>
          </div>

          <div class="msg-text">
            Hi, I am Marty.          </div>
          <div class="msg-text">
           How may I help you?          </div>
        </div>
      </div>

    </main>

    <form class="msger-inputarea">
      <input type="text" class="msger-input" id="textInput" placeholder="Enter your message...">
      <button type="submit" class="msger-send-btn">Send</button>
    </form>
  </section>
  <!-- partial -->
  <script src='https://use.fontawesome.com/releases/v5.0.13/js/all.js'></script>
  <script>
    const msgerForm = get(".msger-inputarea");
    const msgerInput = get(".msger-input");
    const msgerChat = get(".msger-chat");


    // Icons made by Freepik from www.flaticon.com
    const BOT_IMG = "https://image.flaticon.com/icons/svg/327/327779.svg";
    const PERSON_IMG = "https://image.flaticon.com/icons/svg/145/145867.svg";
    const BOT_NAME = "Marty";
    const PERSON_NAME = "You";

    msgerForm.addEventListener("submit", event => {
      event.preventDefault();

      const msgText = msgerInput.value;
      if (!msgText) return;

      appendMessage(PERSON_NAME, PERSON_IMG, "right", msgText);
      msgerInput.value = "";
      botResponse(msgText);
    });

    function appendMessage(name, img, side, text) {
           const msgHTML = `
<div class="msg ${side}-msg">
  <div class="msg-img" style="background-image: url(${img})"></div>

  <div class="msg-bubble">
    <div class="msg-info">
      <div class="msg-info-name">${name}</div>
      <div class="msg-info-time">${formatDate(new Date())}</div>
    </div>

    <div class="msg-text">${text}</div>
  </div>
</div>
`;

      msgerChat.insertAdjacentHTML("beforeend", msgHTML);
      msgerChat.scrollTop += 500;
    }

    function botResponse(rawText) {
    // Bot Response
    $.get("/get", { msg: rawText }).done(function (data) {
        console.log(rawText);
        console.log(data);
        const msgText = data;
        appendMessage(PERSON_NAME, PERSON_IMG, "right", rawText); // Append user's message
        appendMessage(BOT_NAME, BOT_IMG, "left", msgText); // Append bot's response
    });

    }


    // Utils
    function get(selector, root = document) {
      return root.querySelector(selector);
    }

    function formatDate(date) {
      const h = "0" + date.getHours();
      const m = "0" + date.getMinutes();

      return `${h.slice(-2)}:${m.slice(-2)}`;
    }



  </script>

</body>

</html>

Hafsa-221 avatar Apr 15 '24 04:04 Hafsa-221

Could you add the commands of sam-cli that you use to deploy this? Have you tried sam remote invoke? If so, what is its output?

merajhasan88 avatar Apr 15 '24 09:04 merajhasan88

It works fine on SAM remote invoke, but when I entered the URL provided by sam deploy --guided after building it using sam build to get the page displayed on the browser, the page displays the user-entered message appropriately. However, there is no response. I get the following error: Sam-cli commands: sam build sam deploy --guided sam remote invoke error

Hafsa-221 avatar Apr 15 '24 11:04 Hafsa-221

It is still not clear to me, can you provide more information?

As far as I understand, you are trying to serve a Flask application inside your lambda function, but you are facing issues with it, is that correct?

What is the reason that you are using sam remote invoke, to get the response from Flask server or something else?

mndeveci avatar May 16 '24 23:05 mndeveci

Yes, you are understanding it correctly. I am using sam remote invoke to test whether the issue is related to a library or if it's specifically due to permissions and policies. When I use the link provided by the deployment, I get the response, but if I use the same link with the get route in an AJAX call, I get a CORS error. When I try to enable CORS from AWS, I get an exception stating "Failed to update on header." here is what i get when i provided the link provided by deployment: Deployment link in ajax call : https://w1wp4zon03.execute-api.me-south-1.amazonaws.com/Prod/hello/
Response : image

Link with get route in ajax call : https://w1wp4zon03.execute-api.me-south-1.amazonaws.com/Prod/hello/get Response: image

Trying to enable Cors origin: image

Hafsa-220 avatar Jun 10 '24 04:06 Hafsa-220

Any one who can help please.

Hafsa-221 avatar Sep 03 '24 13:09 Hafsa-221

Hello, I faced similar issues recently. I did not use SAM, but I did deploy a Flask app on AWS lambda with API gateway. The only difference was I used a proxy integration ({+proxy}) to not bother with specifying every route of my Flask App.

Here is a list of blocking points I faced, and that may help you.

1/ CORS Issues :

  • Your route need to send a response with the appropriate headers (as you do with get_headers). If you do not use proxy integration in API gateway, this can be done in the "Integration response" section of your method.
  • Your API Gateway method should integrate these headers. This has to be done in the "Method response" of your method. You need to specify the headers that will specifically be kept by API Gateway when sending back the response to the client (you just have to list the name of the headers).
  • You have enabled CORS on your method, that results in AWS creating automatically an OPTIONS method (you should see a pre-flight request on your network). You may take inspiration on this OPTIONS method configuration (for "Integration response" and "Method response")
  • Don't forget to click "Deploy API" once updated

2/ Forbidden Error 403 (https://w1wp4zon03.execute-api.me-south-1.amazonaws.com/prod/)

  • Troubleshooting with AWS : https://repost.aws/knowledge-center/api-gateway-troubleshoot-403-forbidden. I see that the x-amzn-errortype is ForbiddenException, so you can start looking at the related issues ?
  • It might be related to the fact that the route "/" (before /hello) has nothing configured ? IDK

3/ Favicon not found : when deploying static files on AWS Lambda, the stage name is not taken into account. For instance, you may use an image like <img src="/assets/..." />. Deployed, it will look at url-of-my-api-gateway/assets/... while it is hosted at url-of-my-api-gateway/stage-name/assets/...

Here is a quick tuto I followed, and may help you : https://www.youtube.com/watch?v=2Jvzc4Q4Ky0. You could also look at your Cloudwatch logs if configured (from AWS Lambda > your lambda > Configuration > Monitoring and operations tools > Logging configuration).

Good luck

david-bretaud-dev avatar Sep 05 '24 20:09 david-bretaud-dev