arash ajam
arash ajam

Reputation: 31

flask+react website using App Engine, url not found

A simple flask+ react website that i have deployed to App Engine works fine locally. When I serve main.py locally and go to /hello it returns "hello world" as it should. However when deployed to app engine and using the provided URL with /hello it returns "The requested URL /hello was not found on this server."

below is main.py

from flask import Flask, render_template
app = Flask(__name__, static_folder="./build/static", template_folder="./build")
 @app.route("/")
 def index():
     return render_template("index.html")
@app.route("/hello")
def hello():
    return "Hello World!"
if __name__ == "__main__":
    app.run(host='127.0.0.1', port=8080, debug=True)

here's my app.yaml

runtime: python37
entrypoint: gunicorn -b :$PORT main:app

handlers:
- url: /
  static_files: build/index.html
  upload: build/index.html
- url: /
  static_dir: build
- url: /(.*)
  script: auto
project_root/
build/
   static/
   index.html
app.yaml
main.py

It also returns index.html fine on app engine when entering [provided-url].com/

Upvotes: 2

Views: 615

Answers (2)

arash ajam
arash ajam

Reputation: 31

So after messing around with my code for days the problem was with the handlers. With runtime:python37 you shouldn’t use the handlers. Not sure why but when I removed the handlers from app.yaml it all worked.

Upvotes: 0

GAEfan
GAEfan

Reputation: 11360

Your url handlers in app.yaml are short-circuiting. The first / matches, and it never gets to the 2nd / handler. I think you want something like:

handlers:
- url: /static
  static_dir: build/static/
- url: /(.*)
  script: auto

then let your Flask handlers do all the work. Then, send all your calls to static files to /static/somefile.jpg etc.

EDIT: If you want to make your life easier, don't serve index.html as a static file. Serve it from main.py, as you have that set up. All of your React urls get handled in main.py, and all separately render index.html. All of your React routing and components get called from inside index.html. Your API calls get handled in main.py as well.

@app.route("/")
def index():
    template_context = {
        'msg'      : "you are on my home page",
    }
    return render_template("index.html", **template_context)

@app.route("/profile")
def profile():
    template_context = {
        'msg'      : "this is your user profile",
    }
    return render_template("index.html", **template_context)

@app.route("/hello")
def hello():
    return "Hello World!"

EDIT #2: If you insist on serving index.html as a static file, you could set up your app.yaml like this:

handlers:
- url: /
  static_files: build/index.html
  upload: build/index.html
- url: /static
  static_dir: build/static/
- url: /(.*)
  script: auto

and you would delete the @app.route("/") handler from main.py, as it will never get there.

Upvotes: 1

Related Questions