1

I have an html page, custom.html, and a python script, test.py (both screenshotted below). The html page only has a button that should trigger the python script to print a line (in my next python script I'd like it to do more but this is my starting point).

Under Chrome's developer tools, once I click the button, I receive a GET 404 error, initiated by Jquery. Any advice on successfully activating the python script from my html button is greatly appreciated.

enter image description here enter image description here

My test.py script is simply

print("Successful line print")

Here is my custom.html document

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

  <head>
    <meta charset="utf-8">
    <title>Page Title</title>
    <link rel="stylesheet" type="text/css" href="../static/css/style2.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>


  </head>
  <pre>

  </pre>

  <body>
    <div>
      <div>
        <button style="text-align: center; margin-bottom: 150px" class="search-btn" type="button" value=" Run Script " onclick="goPython()">Trigger Python
          <script>
            function goPython() {
              $.ajax({
                url: "../folder/test.py",
                context: document.body
              }).done(function() {
                alert('finished python script');;
              });
            }
          </script>
        </button>
      </div>
    </div>
  </body>

  </html>

EDIT: I am adding the code to my main.py script required for Google App Engine to handle URL calls and importing Flask.

from flask import Flask, request, render_template

app = Flask(__name__)

@app.route("/")
def index():
    return render_template('index.html')

@app.route("/learn.html")
def learn():
    return render_template('learn.html')

@app.route("/custom.html")
def custom():
    return render_template('custom.html')

if __name__ == "__main__":
    app.run()

EDIT 2, after attempting @Dustin Ingram's answer:

Here is the new code to my custom.html

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

  <head>
    <meta charset="utf-8">
    <title>Page Title</title>
    <link rel="stylesheet" type="text/css" href="../static/css/style2.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>


  </head>

  <body>
    <div>
      <div>
        <button style="text-align: center; margin-bottom: 150px" class="search-btn" type="button" value=" Run Script " onclick="goPython()">Click Here
          <script>
            function goPython() {
              $.ajax({
                url: "/trigger-python",
                context: document.body
              }).done(function() {
                alert('finished python script');;
              });
            }
          </script>
        </button>
      </div>
    </div>
  </body>

  </html>

And I made a simple test.py just to test the ability for the html button click to activate the python script

from flask import Flask

app = Flask(__name__)

@app.route("/trigger-python")
def print_something():
    print("Successful line print")
    return 'OK'

print_something()

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=8080, debug=True)

After fixing the URL called in AJAX, I'm still getting the same 404 error when clicking the button. Below is an updated Chrome Developer Tool screenshot.

enter image description here enter image description here

Henrik
  • 191
  • 1
  • 17

1 Answers1

2

You can't call a Python script via an AJAX request like that. You'll need to call a URL that corresponds to an endpoint of a Python web application.

So, for example, on the frontend:

$.ajax({
  url: "/do-something",
  context: document.body
})

and then on the backend there is a corresponding route:

@app.route("/do-something")
def do_something():
    print("Successful line print")
    return 'OK'

See https://cloud.google.com/appengine/docs/standard/python3/quickstart for details on getting started with Python web applications on App Engine.

EDIT: Here's exactly what I've tested and confirmed works:

app.yaml:

runtime: python37

requirements.txt:

Flask==1.1.2

main.py:

from flask import Flask, render_template

app = Flask(__name__)


@app.route('/custom.html')
def custom():
    return render_template('custom.html')

@app.route("/trigger-python")
def print_something():
    print("Successful line print")
    return 'OK'

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=8080, debug=True)

templates/custom.html

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

  <head>
    <meta charset="utf-8">
    <title>Page Title</title>
    <link rel="stylesheet" type="text/css" href="../static/css/style2.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>


  </head>

  <body>
    <div>
      <div>
        <button style="text-align: center; margin-bottom: 150px" class="search-btn" type="button" value=" Run Script " onclick="goPython()">Click Here
          <script>
            function goPython() {
              $.ajax({
                url: "/trigger-python",
                context: document.body
              }).done(function() {
                alert('finished python script');;
              });
            }
          </script>
        </button>
      </div>
    </div>
  </body>

  </html>

You can see it working here: https://stackoverflow-61195723.uc.r.appspot.com/custom.html

Dustin Ingram
  • 20,502
  • 7
  • 59
  • 82
  • Thank you for the advice, I've added my code to main.py, a script used next to my app.yaml script, static, and templates subdirectories to call URLs for various pages of the website. Are you suggesting a separate URL is needed when the button is clicked and the python script is linked to that separate URL, just as 'index', 'learn', and 'custom ' have their own URLs? – Henrik Apr 14 '20 at 14:12
  • This is where I found the use of AJAX for this purpose, but assumed it would be safer as I'm running through Google App Engine: https://stackoverflow.com/questions/48552343/how-can-i-execute-a-python-script-from-an-html-button/48552490 . So this is incorrect for my case? – Henrik Apr 14 '20 at 18:51
  • @Henrik I've updated my answer to add more details. – Dustin Ingram Apr 15 '20 at 01:17
  • perfect, thank you for the update. I'll give this a go first thing in the morning and keep you posted. – Henrik Apr 15 '20 at 04:14
  • I've been implementing your answer all morning and am still getting the same issues (I've updated my original post with new code and errors at the bottom). I'm sure it's an implementation error and I'm missing something small, but looking up the problem is just leading me to the same sites I've already visited. Do you have any suggestions? – Henrik Apr 15 '20 at 15:07
  • @Henrik I see no reason why this wouldn't be working. I've added the exact files that I've tested with and can confirm is working to my answer. – Dustin Ingram Apr 15 '20 at 19:44
  • Yes! That did the trick, thank you @Dustin. I'm using Flask, which looks for a particular folder structure, in particular a 'main.py' script to call various URLs, etc, so my 'test.py' wasn't being recognized within the Flask framework I believe. This has cleared up a lot, I appreciate it. – Henrik Apr 15 '20 at 20:25
  • Sorry, I missed that in your question! Yes, you'll want to have everything in the `main.py` file. Glad to help! – Dustin Ingram Apr 16 '20 at 01:04