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

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

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

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

Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

Python 3.x

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

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Q&A

解決済

1回答

2097閲覧

herokuでの「Failed to find attribute 'application' in 'app'.」というエラーを解決したい

kashmir

総合スコア10

Flask

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

Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

Python 3.x

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

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

1グッド

0クリップ

投稿2022/01/11 11:49

編集2022/01/17 20:22

前提・実現したいこと

Python・flaskで作ったwebアプリをherokuでデプロイし成功したものの、URLに飛ぶとApplication errorとなってしまう。

プログラミング初心者です。分かりづらい点があるかと思います、ご容赦ください。

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

エラーコードはH10。問題箇所と思われるメッセージはこちらです。

Failed to find attribute 'application' in 'app'.

該当のソースコード

該当ファイルの構成は以下です。

アプリのファイル
|ーーapp.py
|ーーProcfile
|ーーrequirements.txt
|ーーruntime.txt
|ーー__pycache__
|ーーtemplates
|ーーvenv
|ーー.env
|ーー.env.sample

□「heroku logs --tail --app 自分のアプリ名」の実行結果

2022-01-11T11:06:47.556703+00:00 heroku[web.1]: State changed from crashed to starting 2022-01-11T11:06:52.498156+00:00 heroku[web.1]: Starting process with command `gunicorn app : app --log-file -` 2022-01-11T11:06:53.838531+00:00 app[web.1]: [2022-01-11 11:06:53 +0000] [4] [INFO] Starting gunicorn 20.1.0 2022-01-11T11:06:53.838940+00:00 app[web.1]: [2022-01-11 11:06:53 +0000] [4] [INFO] Listening at: http://0.0.0.0:24665 (4) 2022-01-11T11:06:53.838980+00:00 app[web.1]: [2022-01-11 11:06:53 +0000] [4] [INFO] Using worker: sync 2022-01-11T11:06:53.842165+00:00 app[web.1]: [2022-01-11 11:06:53 +0000] [9] [INFO] Booting worker with pid: 9 2022-01-11T11:06:53.853462+00:00 app[web.1]: [2022-01-11 11:06:53 +0000] [10] [INFO] Booting worker with pid: 10 2022-01-11T11:06:54.366422+00:00 heroku[web.1]: State changed from starting to up 2022-01-11T11:06:55.711302+00:00 app[web.1]: Failed to find attribute 'application' in 'app'. 2022-01-11T11:06:55.711529+00:00 app[web.1]: [2022-01-11 11:06:55 +0000] [9] [INFO] Worker exiting (pid: 9) 2022-01-11T11:06:55.711605+00:00 app[web.1]: Failed to find attribute 'application' in 'app'. 2022-01-11T11:06:55.711847+00:00 app[web.1]: [2022-01-11 11:06:55 +0000] [10] [INFO] Worker exiting (pid: 10) 2022-01-11T11:06:56.299718+00:00 app[web.1]: [2022-01-11 11:06:56 +0000] [4] [WARNING] Worker with pid 10 was terminated due to signal 15 2022-01-11T11:06:56.395344+00:00 app[web.1]: [2022-01-11 11:06:56 +0000] [4] [INFO] Shutting down: Master 2022-01-11T11:06:56.395413+00:00 app[web.1]: [2022-01-11 11:06:56 +0000] [4] [INFO] Reason: App failed to load. 2022-01-11T11:06:56.557625+00:00 heroku[web.1]: Process exited with status 4 2022-01-11T11:06:56.610039+00:00 heroku[web.1]: State changed from up to crashed 2022-01-11T11:06:58.000000+00:00 app[api]: Build succeeded 2022-01-11T11:07:02.198343+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=foodbook135.herokuapp.com request_id=fc34bf91-5ec2-44a0-ac3d-fc6e828ba59c fwd="106.154.137.195" dyno= connect= service= status=503 bytes= protocol=https 2022-01-11T11:07:02.822734+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=foodbook135.herokuapp.com request_id=fe1c5296-7855-4f26-b958-f03f77e4fc6d fwd="106.154.137.195" dyno= connect= service= status=503 bytes= protocol=https

Procfile

1web: gunicorn app : app --log-file -

requirements

1beautifulsoup4==4.10.0 2cachetools==4.2.4 3certifi==2021.10.8 4charset-normalizer==2.0.9 5click==8.0.3 6Flask==2.0.2 7google-api-core==2.3.2 8google-api-python-client==2.33.0 9google-auth==2.3.3 10google-auth-httplib2==0.1.0 11googleapis-common-protos==1.54.0 12gunicorn==20.1.0 13httplib2==0.20.2 14idna==3.3 15itsdangerous==2.0.1 16Jinja2==3.0.3 17MarkupSafe==2.0.1 18protobuf==3.19.1 19pyasn1==0.4.8 20pyasn1-modules==0.2.8 21pyparsing==3.0.6 22requests==2.26.0 23rsa==4.8 24six==1.16.0 25soupsieve==2.3.1 26uritemplate==4.1.1 27urllib3==1.26.7 28Werkzeug==2.0.2 29

app.py

1# -*- coding: utf-8 -*- 2from bs4 import BeautifulSoup 3import re 4from flask import Flask, render_template, request, session 5import requests 6import settings 7from requests.exceptions import Timeout 8# 返却された検索結果の読み取りにつかう 9from googleapiclient.discovery import build 10 11# ================================= 12app = Flask(__name__) 13 14# カスタム検索エンジンID 15CUSTOM_SEARCH_ENGINE_ID = "87dabc623cf5e8624" 16# API キー 17API_KEY = settings.AP 18 19# APIにアクセスして結果をもらってくるメソッド 20def get_search_results(query): 21 22 # APIでやりとりするためのリソースを構築 23 search = build( 24 "customsearch", 25 "v1", 26 developerKey = API_KEY 27 ) 28 29 # Google Custom Search から結果を取得 30 result = search.cse().list( 31 q = query, 32 cx = CUSTOM_SEARCH_ENGINE_ID, 33 lr = 'lang_ja', 34 num = 5, 35 start = 1 36 ).execute() 37 38 # 受け取ったjsonをそのまま返却 39 return result 40 41# 検索結果の情報をSearchResultに格納してリストで返す 42def summarize_search_results(result): 43 44 # 結果のjsonから検索結果の部分を取り出しておく 45 result_items_part = result['items'] 46 47 # 抽出した検索結果の情報はこのリストにまとめる 48 result_items = [] 49 50 # 今回は (start =) 1 個目の結果から (num =) 10 個の結果を取得した 51 for i in range(0, 5): 52 # i番目の検索結果の部分 53 result_item = result_items_part[i] 54 # i番目の検索結果からそれぞれの属性の情報をResultクラスに格納して 55 # result_items リストに追加する 56 s_r = SearchResult( 57 title = result_item['title'], 58 url = result_item['link'], 59 snippet = result_item['snippet'] 60 ) 61 62 result_items.append(s_r.Making_d()) 63 64 # 結果を格納したリストを返却 65 return result_items 66 67# 検索結果の情報を格納するクラス 68class SearchResult: 69 def __init__(self, title, url, snippet): 70 self.title = title 71 self.url = url 72 self.snippet = snippet 73 74 def __str__(self): 75 # コマンドライン上での表示形式はご自由にどうぞ 76 return "[title] " + self.title + "\n\t[detail] " + self.snippet + "\n\t[url]" + self.url 77 78 def Making_d(self): 79 d_info = dict(title=self.title, url=self.url, detail=self.snippet) 80 return d_info 81 82# htmlとやり取りするパート 83app = Flask(__name__) 84 85app.secret_key = 'abcdefghijklmn' 86 87@app.route('/', methods=['GET']) 88def get(): 89 return render_template('index.html') 90 91# フォームを読み込んで検索結果を出す =page2 92@app.route('/templates/page2', methods=['POST']) 93def post(): 94 name = request.form.get('name') 95 prefecture = request.form.get('prefectures') 96 query = name 97 query2 = prefecture 98 query3 = '"食べログ"' 99 the_word = query + " " + query2 + " " + query3 100 101 # APIから検索結果を取得 102 result = get_search_results(the_word) 103 # result には 返却されたjsonが入る 104 105 # 検索結果情報からタイトル, URL, スニペット, 検索結果の順位を抽出してまとめる 106 result_items_list = summarize_search_results(result) 107 # result_items_list には SearchResult のリストが入る 108 109 # 他のページへ渡せるようにsessionを使う 110 session['result_items_list'] = result_items_list 111 112 # コマンドラインに検索結果の情報を1個分だけ表示 113 print(result_items_list[0]) 114 # print(query2) 115 # 第2引数で、htmlファイル上の変数にここで用いたリストを代入している 116 return render_template('page2.html', rst_info=result_items_list) 117 118# 1つ目の情報が誤っていたときに2つ目の検索結果を表示する=page3 119@app.route('/templates/page3', methods=["get"]) 120def page3(): 121 # indexからpage2への移動時に作成された検索結果のリストをsessionを使って呼び出す 122 searched_list = session.get('result_items_list', None) 123 124 print(searched_list[1]) 125 return render_template('page3.html', rst_info=searched_list) 126 127# page2での情報でOKだったときに、その店の詳細を表示させる=goal 128@app.route('/templates/goal', methods=["get"]) 129def goal(): 130 131 searched_list = session.get('result_items_list', None) 132 #↓OKが出た店の食べログURLでスクレイピング 133 url_t = searched_list[0]['url'] 134 r = requests.get(url_t) 135 soup = BeautifulSoup(r.text, 'html.parser') 136 name_rst = soup.find('div', class_='rstinfo-table__name-wrap').text 137 station_rst = soup.find('span', class_='linktree__parent-target-text').text 138 tel_rst = soup.find('p', class_='rstdtl-side-yoyaku__tel-number').text 139 140 return render_template('goal.html', searched_list=searched_list, name_rst=name_rst, \ 141 station_rst=station_rst, tel_rst=tel_rst) 142 143# 情報2件が両方とも不適切だった場合、はじめに戻る=fail 144@app.route('/templates/fail', methods=["get"]) 145def fail(): 146 return render_template('fail.html') 147 148# xxxxxxxxxxxxxxxxxxxxxxxxxx 149if __name__ == '__main__': 150 # app.run(debug=True) 151 app.debug = True 152 app.run() 153# xxxxxxxxxxxxxxxxxxxxxxxxxx 154 155 156 157 158 159 160

試したこと

調べる中でProcfileが特にあやしいと感じ、いろいろと英語のサイトなどにも当たりましたが原因がわかりませんでした。

特に参考にしたページ

https://toukei-lab.com/heroku-python
https://creepfablic.site/2019/06/15/heroku-procfile-matome/

よろしくお願いいたします。

AbeTakashiを押しています

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

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

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

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

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

Supernove

2022/01/11 13:45

app.pyも追加してもらってもいいですか?
guest

回答1

0

自己解決

herokuでのアプリ公開をあきらめ、PythonAnywhereを利用した。
無料で公開できたので問題なかった。

投稿2022/01/17 11:22

kashmir

総合スコア10

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問