[英]Heroku works locally but crashes when deployed - Flask
I've made a simple Tic Tac Toe game using flask that I'm trying to deploy to Heroku. I am following the steps outlined in this video, but my app is not working.我使用 flask 制作了一个简单的 Tic Tac Toe 游戏,我正尝试将其部署到 Heroku。我按照此视频中列出的步骤操作,但我的应用程序无法运行。 It works fine locally, but when I test it on Heroku nothing happens when I click "play X here".
它在本地运行良好,但是当我在 Heroku 上测试它时,当我单击“在此处播放 X”时没有任何反应。 If I click again a few times, suddenly the X appears and disappears randomly.
如果我再次点击几次,X 突然随机出现和消失。 If I click reset game either nothing happens or I get "internal server error".
如果我点击重置游戏要么没有任何反应,要么我得到“内部服务器错误”。
https://tictactoe--ai.herokuapp.com/ https://tictactoe--ai.herokuapp.com/
Python code: Python 代码:
from flask import Flask, render_template, session, redirect, url_for
from flask_session import Session
from tempfile import mkdtemp
app = Flask(__name__)
app.config["SESSION_FILE_DIR"] = mkdtemp()
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
def tie(board):
# Returns false if board contains None values and True if all squares on board is full
for row in board:
if None in row:
return False
return True
@app.route("/")
def index():
if "board" not in session:
session["board"] = [[None, None, None], [None, None, None], [None, None, None]]
session["turn"] = "X"
return render_template("game.html", game=session["board"], turn=session["turn"])
@app.route("/play/<int:row>/<int:col>")
def play(row, col):
if session["turn"] == "X":
session["board"][row][col] = "X"
session["turn"] = "O"
else:
session["board"][row][col] = "O"
session["turn"] = "X"
return redirect(url_for("index"))
@app.route("/reset", methods=["POST"])
def reset():
if session["board"]:
session.pop("board")
return redirect(url_for("index"))
@app.context_processor
def winner():
# Columns
left = [ session["board"][0][0], session["board"][1][0], session["board"][2][0] ]
middle = [ session["board"][0][1], session["board"][1][1], session["board"][2][1] ]
right = [ session["board"][0][2], session["board"][1][2], session["board"][2][2] ]
# Rows
top_row = [ session["board"][0][0], session["board"][0][1], session["board"][0][2] ]
middle_row = [ session["board"][1][0], session["board"][1][1], session["board"][1][2] ]
bottom_row = [ session["board"][2][0], session["board"][2][1], session["board"][2][2] ]
# Horizontal = \ and /
horizontal1 = [ session["board"][0][0], session["board"][1][1], session["board"][2][2] ]
horizontal2 = [ session["board"][0][2], session["board"][1][1], session["board"][2][0] ]
check = left, middle, right, horizontal1, horizontal2, top_row, middle_row, bottom_row
for i in check:
if i == ["X", "X", "X"]:
return dict(winner="X is the winner")
if i == ["O", "O", "O"]:
return dict(winner="O is the winner")
full_board = tie(session["board"])
# Returns empty string if board is not full
if not full_board:
return dict(winner="")
# If all squares have values and nobody has won, it is a tie
return dict(winner="Tie!")
if __name__ == "main":
app.debug = True
app.run()
HTML HTML
<!DOCTYPE html>
<html>
<head>
<title>Tic Tac Toe</title>
<style>
table {
border-collapse: collapse;
}
td {
border: 1px solid black;
width: 150px;
height: 150px;
font-size: 30px;
text-align: center;
}
td > a {
font-size: 18px;
}
</style>
</head>
<body>
<table>
{% for i in range(3) %}
<tr>
{% for j in range(3) %}
<td>
{% if game[i][j] %}
{{ game[i][j] }}
{% else %}
<a href="{{ url_for('play', row=i, col=j) }}">Play {{ turn }} here.</a>
{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
{% if winner != 0 %}
{{winner}}
{% endif %}
<form action="/reset" method="post">
<button type="submit">Reset game</button>
</form>
</body>
</html>
Logs:日志:
2020-09-22T06:58:44.453325+00:00 app[web.1]: rv = self.dispatch_request()
2020-09-22T06:58:44.453325+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/flask/app.py", line 1936, in dispatch_request
2020-09-22T06:58:44.453326+00:00 app[web.1]: return self.view_functions[rule.endpoint](**req.view_args)
2020-09-22T06:58:44.453326+00:00 app[web.1]: File "/app/application.py", line 65, in reset
2020-09-22T06:58:44.453327+00:00 app[web.1]: if session["board"]:
2020-09-22T06:58:44.453327+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/werkzeug/local.py", line 377, in <lambda>
2020-09-22T06:58:44.453328+00:00 app[web.1]: __getitem__ = lambda x, i: x._get_current_object()[i]
2020-09-22T06:58:44.454027+00:00 app[web.1]: KeyError: 'board'
2020-09-22T06:58:44.460397+00:00 heroku[router]: at=info method=POST path="/reset" host=tictactoe--ai.herokuapp.com request_id=3384212e-52c7-4a7d-ab32-3ec58c133e29 fwd="178.164.96.83" dyno=web.1 connect=1ms service=13ms status=500 bytes=546 protocol=https
2020-09-22T06:58:44.461261+00:00 app[web.1]: 10.39.211.254 - - [22/Sep/2020:06:58:44 +0000] "POST /reset HTTP/1.1" 500 290 "https://tictactoe--ai.herokuapp.com/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36"
It seems like the problem is KeyErrors with session["board"] and session["turn"].看起来问题是 session["board"] 和 session["turn"] 的 KeyErrors。 When I play a few moves, sometimes it appears on the board, and sometimes not.
当我下几步棋时,棋盘上有时会出现,有时不会。 If I refresh the page a couple of times, it appears to have stored multiple different boards, and loads a different one each time it loads the page again.
如果我刷新页面几次,它似乎存储了多个不同的板,并且每次再次加载页面时加载不同的板。 I am not able to recreate the errors when it run it locally.
当它在本地运行时,我无法重新创建错误。 Any ideas what causes this?
任何想法是什么原因造成的?
Start Flask app binding to the PORT provided by Heroku启动Flask app绑定Heroku提供的PORT
p = int(os.environ.get("PORT", 5000))
app.run(debug=True, port=p, host='0.0.0.0')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.