質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Jinja2

Jinja2は、Python用のテンプレートエンジンです。テンプレートファイルの読込や文字列の埋込、分岐/ループの制御文のサポートなどの機能を持ちます。HTMLやXML生成によく使用されますが、どのような文書でも生成することが可能です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

1705閲覧

Flaskのwebアプリの起動ができない

lilliveon

総合スコア9

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Jinja2

Jinja2は、Python用のテンプレートエンジンです。テンプレートファイルの読込や文字列の埋込、分岐/ループの制御文のサポートなどの機能を持ちます。HTMLやXML生成によく使用されますが、どのような文書でも生成することが可能です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2023/05/10 07:07

編集2023/05/10 07:11

実現したいこと

Flaskを用いたWebアプリの起動

前提

PythonのFlaskでWebアプリを作っています。
初めにWebアプリの起動及び画面遷移を試すべくコードを書いてみたのですが、エラーが発生して起動できません。何かアドバイスいただけると嬉しいです。

発生している問題・エラーメッセージ

No module named minhaya_reviewer.__main__; 'minhaya_reviewer' is a package and cannot be directly executed

フォルダの構造(Visual Studio Code)
イメージ説明
「python」というフォルダに「minhaya_reveiwer」というフォルダが入っており、起動する時は

...\python> python3 -m minhaya_reviewer run

というコマンドを使用しています。
(WindowsのPowerShellです)

該当のソースコード

index.html

1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>QuizReviewer</title> 6 </head> 7 <body> 8 <h1>QuizReviewer</h1> 9 <a href="{{ url_for('solve') }}">クイズを解く</a> 10 <a href="{{ url_for('manage') }}">クイズの管理</a> 11 </body> 12</html>

manage.html

1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>QuizReviewer</title> 6 </head> 7 <body> 8 <h1>QuizReviewer</h1> 9 <a>クイズ管理画面</a> 10 </body> 11</html>

solve.html

1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>QuizReviewer</title> 6 </head> 7 <body> 8 <h1>QuizReviewer</h1> 9 <a>クイズを解く画面</a> 10 </body> 11</html>

__init__.py

1from flask import Flask 2app = Flask(__name__) 3import minhaya_reviewer.main

main.py

1from minhaya_reviewer import app 2from flask import render_template, request, redirect, url_for 3import sqlite3 4 5@app.route("/") 6def index(): 7 return render_template( 8 "index.html" 9 ) 10 11@app.route("/solve") 12def solve(): 13 return render_template( 14 "solve.html" 15 ) 16 17@app.route("/manage") 18def manage(): 19 return render_template( 20 "manage.html" 21 ) 22

試したこと

https://qiita.com/xu1718191411/items/96dda3d6cf2ab11ae1b3
上記のサイトを見てフォルダの構造の問題かなと思ったのですが、特に僕の場合は問題がないように感じます。

補足情報(FW/ツールのバージョンなど)

Flask==2.3.2
Jinja2==3.1.2

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lilliveon

2023/05/10 07:26

コメントありがとうございます。エラー文を見るに minhaya_reviewer.__main__ が見つからないと言われているのは分かるのですが、「minhaya_reviewer」の中に「main.py」はちゃんとあるのでなぜそうなっているのかが分からない状態です。 プログラミングの経験が非常に浅いため、もし見当違いな返答をしていましたら申し訳ないです。
dameo

2023/05/10 07:33 編集

経験が浅いという認識があるなら、経験を積んでください。 自分でモジュールを書いてimportすればいいだけです。 例えばこんなの [main.py] # subのインポート文 func() [sub.py] def func(): print('func()')
lilliveon

2023/05/10 07:45

例を挙げて説明してくださりありがとうございます。 main.pyにて関数で処理を書き、__init__.pyでmain.pyモジュールをimportしているつもりなのですが、できていませんでしょうか?
dameo

2023/05/10 07:46

別に丁寧に話す必要はないので、書いたことをやってください。
lilliveon

2023/05/10 08:42

書いてくださったことをやってみた結果、ちゃんと"func()"がprintされました。 質問したコードでなぜ同様にできないのか分からないままですが、コメントくださったことを踏まえてもう一度考えてみます。 お時間いただきありがとうございました。
quickquip

2023/05/10 09:08

どうして python3 -m minhaya_reviewer run というコマンドで起動しようと考えたんでしょうか。 何かの例をみないとこれはやらないように感じて気になりました。 このように起動するのに必要なことは No module named minhaya_reviewer.__main__; 'minhaya_reviewer' is a package and cannot be directly executed というメッセージにそのままズバリ書いてあります。
lilliveon

2023/05/10 09:24

コメントありがとうございます。 python3 -m minhaya_reviewer run というコマンドを使用した理由は、 Youtubeで公開されているFlask入門の動画で勉強してサンプルコードを入力した際に flask run と入力すると flask : 用語 'flask' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されません。名前が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいことを確認してから 、再試行してください。 というエラーが発生してしまってWebアプリを起動できなかったからです。対処法を調べた結果 python3 -m ~ run と入力すると無事Webアプリを立ち上げることができましたので、以後このコマンドを使用して起動しています。 念のためもう一度 flask run というコマンドで実行してみたのですが、同様のエラーが発生してしまいました。
quickquip

2023/05/10 09:29

これは質問の前提として必要不可欠な情報だと思うので、この欄ではなくて質問に記載してください
quickquip

2023/05/10 09:56 編集

python3 -m ~ run と書いてますが python3 -m flask run もしくは python -m flask --app minhaya_reviewer run じゃないですか?
dameo

2023/05/10 11:08

一応書いておくと、__init__.pyの3行目、エラーになりますよ。 まずなぜこのような構成にしているのか? が、完全におかしいので、起動方法にはあえて触れずに、importの理解度を確認させてもらいました。 結局何も答えを書かず、「main.pyにて関数で処理を書き、__init__.pyでmain.pyモジュールをimportしているつもり」と、不思議なことを書いているところから、初心者ではなく意図的に変な質問をしているだけと判断し、そこで放置させてもらった次第です。 普通の初心者であればチュートリアル風の記事から始めて、いきなり__init__.pyを書くことはありません。もちろん意味不明なimportをする理由もありません。この手の質問者に回答をすることは誤った知見を広めるだけになるので、回答すべきではないと思いますよ。
lilliveon

2023/05/10 11:16

僕の方では__init__.pyの3行目は変えなくてもエラーは発生しませんでした。 不思議なことを書いていることに関しては、敢えて変な質問をしていると判断されるくらいおかしな返答をしてしまったと捉えさせていただき、自身の未熟さを再認識した上で今後とも精進してまいります。 一応僕がチュートリアルとして見た動画のURLを貼っておきます。 https://www.youtube.com/watch?v=EQIAzH0HvzQ&t=749s ここではいきなり__init__.pyを使用しており、僕にはハードルが高かったのかもしれません。 ご意見ありがとうございました。
dameo

2023/05/10 11:41

参考にしたチュートリアル動画が中途半端に詰め込みすぎてるということですか・・・ https://flask.palletsprojects.com/en/2.3.x/quickstart/ にあるとおり、最小のコードだと from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): return "<p>Hello, World!</p>" となります。このコードはコマンドラインから flask --app hello run とかで実行することもできますが、最終行に app.run() を追記して、python hello.py しても(簡易)実行できます。 チュートリアル風の記事として動画を選択するのであれば、紹介された内容をきちんと1つ1つ理解してから使ってください。コピペではいけません。どこまで100%理解できていて、どこから100%まで理解できていないのかを明確にしてください。100%理解した、以外は使い物になりません。網羅的に理解する必要はないので、今のコードに必要な部分だけ100%理解するようにすればOKです。あと穴は空いていてもいいので、体系的にどの辺を理解できているのか、位置は把握しておいた方がいいですね。
quickquip

2023/05/10 11:50

ごく普通のFlaskのディレクトリ構造だと思います。
lilliveon

2023/05/10 12:02

コードとコマンドに加え、正しい学習方法まで解説していただきありがとうございます。 仰る通り、チュートリアルで何となく理解して作ったサンプルのWebアプリをコピペした部分が多く、紹介された内容を完全に理解していないままにしていました。dameoさんのアドバイスを踏まえ、もう一度動画及び自分のコードを100%理解できるまで見直して、ちゃんと自分のスキルとして身に付くようにします。
dameo

2023/05/10 12:36

普通の簡単なアプリなら__init__.pyを入れないと思いますが。。。主観なので置いておきますか importでエラーになるかと思ったら、ルートから書いてることになってエラーにならないんですね from . import main よく考えずにこんなのでなかったのでエラーだと思い込んでました そこは私の勘違いです 実際動かしたところ main.py に以下は足りないようですね。 from flask import render_template
lilliveon

2023/05/10 13:12 編集

最後の文章は、main.pyに from flask import render_template が書かれていないというご指摘でお間違い無いですかね? それでしたら質問文で貼らせていただきましたmain.pyのコードにて from flask import render_template, request, redirect, url_for と書いており、そこでimportしています。 後々実装するつもりだったとは言え、まだ実装していない request, redirect, url_for も書いている部分がややこしかったと思います、申し訳ありません。
dameo

2023/05/10 15:33

何かの操作でうっかり消えてたみたいですね ややこしくはないですが、不要なものは消しましょう
guest

回答2

0

ベストアンサー

https://docs.python.org/ja/3.9/using/cmdline.html#cmdoption-m

パッケージ名 (名前空間パッケージも含む) でも構いません。通常のモジュールの代わりにパッケージ名が与えられた場合、インタプリタは <pkg>.__main__ を main モジュールとして実行します。

をしようとしているのに__main__がないと言われています。そういうエラーです。

コードに間違いがあるのではなくて、「必要なファイルがない」もしくは「起動の仕方を勘違いしている」という感じです。

投稿2023/05/10 09:18

編集2023/05/10 09:24
quickquip

総合スコア11038

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lilliveon

2023/05/10 09:42

仰る通り起動の仕方が間違っており、python3 -m (フォルダ名) run だと勘違いしていました。 python3 -m flask run コマンドを実行した結果、無事解決することができ、画面遷移もちゃんとできました。 解決方法に加え、エラーの原理の説明及び質問の仕方まで親切にアドバイスしてくださり本当にありがとうございました🙇
quickquip

2023/05/10 09:59

python3 -m flask run で実行できたということは FLASK_APP 環境変数に minhaya_reviewer がセットしてあったということですかね……
lilliveon

2023/05/10 10:09

仰る通りです。起動方法の問題であったのが僕としては盲点であり、質問した際もそこをもっと詳しく書くべきだったと反省しています。 とても参考になりました。
guest

0

回答ではありません

とりあえず現状の問題点とその対応について、環境構築スクリプトも含めて展開します。

現状の問題点

  1. 起動方法が不自然な点
  2. 不思議な構成になっている点

原因

  1. (推測)policy未設定により、無署名スクリプト実行が出来ない
  2. __init__.py, main.pyが相互importになっている点と、なぜか相対指定されておらず不思議な位置からimportしている点

2.についてはコメントにある動画内容からそうなっているため

対策

1. power shellのポリシーチェックをバイバスする

元のポリシーを変更せず、一時的にポリシーをバイパスするにはコマンドプロンプトから以下のようにpowershellを起動する

cmd

1C:\python\hoge>powershell -executionpolicy bypass 2PS C:\python\hoge> .\env\Scripts\Activate.ps1 3(env) PS C:\python\hoge> flask 4Usage: flask [OPTIONS] COMMAND [ARGS]... 5...

about_Execution_Policies
https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_execution_policies

2. blueprintを使用する

普通は意味もなく分けるのではなく、ある程度以上のページセットを塊としてルーティングやその内部処理を記述するために、モジュール分割する。flaskではこの塊をblueprintと呼ぶ。逆に言えばblueprintを使うほどでなければ__init__.pyを使っても汚れるだけ。

Blog Blueprint
https://flask.palletsprojects.com/en/2.3.x/tutorial/blog/

対策後ファイル

最後に構築用スクリプトがあるのでコピペは不要
記載のないファイルは変更していない

minhaya_reveiwer/__init__.py

python

1from flask import Flask 2def create_app(): 3 app = Flask(__name__) 4 from . import main 5 app.register_blueprint(main.bp) 6 return app

minhaya_reveiwer/main.py

python

1from flask import Blueprint, render_template 2bp = Blueprint('main', __name__) 3@bp.route("/") 4def index(): 5 return render_template("index.html") 6@bp.route("/solve") 7def solve(): 8 return render_template("solve.html") 9@bp.route("/manage") 10def manage(): 11 return render_template("manage.html")

minhaya_reveiwer/templates/index.html

html

1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>QuizReviewer</title> 6 </head> 7 <body> 8 <h1>QuizReviewer</h1> 9 <a href="{{ url_for('.solve') }}">クイズを解く</a> 10 <a href="{{ url_for('.manage') }}">クイズの管理</a> 11 </body> 12</html>

環境構築スクリプト

venv構築からflaskインストールもまとめて実施。空のディレクトリで実行する

python

1import os 2import venv 3import subprocess 4ENV = 'env' 5if os.name == 'posix': 6 BIN = 'bin' 7else: 8 BIN = 'Scripts' 9builder = venv.EnvBuilder(with_pip=True) 10builder.create(ENV) 11cwd = os.getcwd() 12python = os.path.join(cwd, ENV, BIN, 'python') 13os.environ['VIRTUAL_ENV'] = os.path.join(cwd, ENV) 14os.environ['PATH'] = os.path.join(cwd, ENV, BIN) + os.pathsep + os.environ['PATH'] 15p = subprocess.run([python, '-m', 'pip', 'install', '--upgrade', 'pip', 'setuptools']) 16p = subprocess.run([python, '-m', 'pip', 'install', 'Flask==2.3.2', 'Jinja2==3.1.2']) 17app_dir = os.path.join(cwd, 'minhaya_reveiwer') 18templates_dir = os.path.join(app_dir, 'templates') 19os.makedirs(templates_dir, exist_ok=True) 20with open(os.path.join(app_dir, '__init__.py'), 'wt', encoding='utf8') as f: 21 f.write("""\ 22from flask import Flask 23def create_app(): 24 app = Flask(__name__) 25 from . import main 26 app.register_blueprint(main.bp) 27 return app 28""") 29with open(os.path.join(app_dir, 'main.py'), 'wt', encoding='utf8') as f: 30 f.write("""\ 31from flask import Blueprint, render_template 32bp = Blueprint('main', __name__) 33@bp.route("/") 34def index(): 35 return render_template("index.html") 36@bp.route("/solve") 37def solve(): 38 return render_template("solve.html") 39@bp.route("/manage") 40def manage(): 41 return render_template("manage.html") 42""") 43with open(os.path.join(templates_dir, 'index.html'), 'wt', encoding='utf8') as f: 44 f.write("""\ 45<!DOCTYPE html> 46<html lang="ja"> 47 <head> 48 <meta charset="UTF-8"> 49 <title>QuizReviewer</title> 50 </head> 51 <body> 52 <h1>QuizReviewer</h1> 53 <a href="{{ url_for('.solve') }}">クイズを解く</a> 54 <a href="{{ url_for('.manage') }}">クイズの管理</a> 55 </body> 56</html> 57""") 58with open(os.path.join(templates_dir, 'manage.html'), 'wt', encoding='utf8') as f: 59 f.write("""\ 60<!DOCTYPE html> 61<html lang="ja"> 62 <head> 63 <meta charset="UTF-8"> 64 <title>QuizReviewer</title> 65 </head> 66 <body> 67 <h1>QuizReviewer</h1> 68 <a>クイズ管理画面</a> 69 </body> 70</html> 71""") 72with open(os.path.join(templates_dir, 'solve.html'), 'wt', encoding='utf8') as f: 73 f.write("""\ 74<!DOCTYPE html> 75<html lang="ja"> 76 <head> 77 <meta charset="UTF-8"> 78 <title>QuizReviewer</title> 79 </head> 80 <body> 81 <h1>QuizReviewer</h1> 82 <a>クイズを解く画面</a> 83 </body> 84</html> 85""") 86p = subprocess.run([python, '-m', 'flask', '--app', 'minhaya_reveiwer', 'run'])

投稿2023/05/10 18:28

編集2023/05/10 18:34
dameo

総合スコア943

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

lilliveon

2023/05/11 10:31

物凄く丁寧に説明してくださり本当にありがとうございます🙇 自分が気づけていない問題まで分かって本当に助かりました。 いただいた回答を参考にしつつ、加えてアドバイス通りに別のもっと解説が充実した動画で勉強して、自分のコードを全てちゃんと説明できるように理解した結果、作業効率の向上及び自身の成長が感じられました。 今後ともちゃんとスキルとして身に付くように経験を積むことを意識して精進してまいります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問