flaskでapiを作ってpyinstallerでexe化
現在pythonのflaskでapiを作ってpyinstallerでexe化しようとしていますが、うまくいきません。
exe化自体はうまくいくのですが、実行するとエラーが出ます。

コンソール側はこんな感じ。
* Serving Flask app 'main' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on all addresses (0.0.0.0)
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://127.0.0.1:5000
* Running on http://192.168.11.22:5000 (Press CTRL+C to quit)
[2022-06-12 09:07:04,173] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
File "flask\app.py", line 2077, in wsgi_app
File "flask\app.py", line 1525, in full_dispatch_request
File "flask\app.py", line 1523, in full_dispatch_request
File "flask\app.py", line 1509, in dispatch_request
File "main.py", line 10, in hello_world
File "flask\templating.py", line 149, in render_template
File "jinja2\environment.py", line 1081, in get_or_select_template
File "jinja2\environment.py", line 1010, in get_template
File "jinja2\environment.py", line 969, in _load_template
File "jinja2\loaders.py", line 126, in load
File "flask\templating.py", line 59, in get_source
File "flask\templating.py", line 95, in _get_source_fast
jinja2.exceptions.TemplateNotFound: index.html
127.0.0.1 - - [12/Jun/2022 09:07:04] "GET / HTTP/1.1" 500 -
127.0.0.1 - - [12/Jun/2022 09:07:04] "GET /favicon.ico HTTP/1.1" 404 -
下から3行目「flask pyinstaller jinja2.exceptions.TemplateNotFound」が出ちゃってます。
ファイル構成はこんな感じ
movConv
├─main.py
└─templates
└─index.html
movConvというプロジェクトフォルダの中にtemplatesフォルダがあるのですが、そこのindex.htmlが見つからないようです。
なんか解決策を探してもいまいちパットしたのが出てこないので、別の方向性に切り替えました。
pythonファイルの中にHTMLベタ書き
index.htmlが見つからないというのであれば、もうmain.pyの中に直接html書き込んでやろうという事です。
改善前
import webbrowser
from flask import Flask
from flask import Flask, render_template, jsonify
from flask import request
app = Flask(__name__)
@app.route("/")
def hello_world():
return render_template("index.html")
@app.route("/syori/", methods=["POST"])
def syori():
if request.method == 'POST':
return jsonify({"language": "python"})
if __name__ == "__main__":
webbrowser.open("http://127.0.0.1:5000", new=0, autoraise=True)
app.run(port=5000, debug=False)
import webbrowser
from flask import Flask
from flask import Flask, render_template, jsonify
from flask import request
app = Flask(__name__)
indexHtml = '''<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/vue@next"></script>
<title>Document</title>
</head>
<body>
<div id="counter">
<p>ごきげんよう</p>
<button v-on:click="handle">ジャンプ</button>
</div>
<script>
const Counter = {
data() {
return {
counter: 0
}
},
methods: {
handle() {
const インスタンス名 = new XMLHttpRequest();
インスタンス名.open('POST', "http://127.0.0.1:5000/syori/");
インスタンス名.setRequestHeader('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
インスタンス名.send('パラメータ=値');
インスタンス名.onreadystatechange = function () {
if (インスタンス名.readyState === 4 && インスタンス名.status === 200) {
//エラーを出さずに通信が完了した時の処理。例↓
console.log(インスタンス名.responseText);
}
}
},
},
}
Vue.createApp(Counter).mount('#counter')
</script>
</body>
</html>'''
@app.route("/")
def hello_world():
return indexHtml
@app.route("/syori/", methods=["POST"])
def syori():
if request.method == 'POST':
return jsonify({"language": "python"})
if __name__ == "__main__":
webbrowser.open("http://127.0.0.1:5000", new=0, autoraise=True)
app.run(port=5000, debug=False)
これで一応動くようになりました。
デメリットは?
このやりかたのデメリットはいろいろありますが、まずはjinja2の機能が死にます。
そもそもまだfalsk触って間もないので、どんな機能があるのかわかってませんが、テンプレートエンジンとしての機能は使えなくなりますね。
まとめ
まぁ背に腹は代えられないってことですぅ
コメント