【问题标题】:static HTML + Flask + Gunicorn works locally; breaks when pushed to heroku静态 HTML + Flask + Gunicorn 在本地工作;推到heroku时中断
【发布时间】:2013-10-30 16:03:01
【问题描述】:

我刚刚制作了一个小烧瓶应用程序,它可以在本地运行,但是当我尝试将它推送到 heroku 时,在提供静态 HTML 时出现问题(自我诊断,当我让烧瓶返回文本而不是静态 html 文件时一切都按预期进行。)

我尝试遵循本指南.. https://devcenter.heroku.com/articles/getting-started-with-python 这是我目录中的 LS

Procfile        account.pyc     base.pyc        requirements.txt    venv
account.py      base.py         home.html       templates

这里是一些相关文件的代码。

requirements.txt

Flask==0.10.1
Jinja2==2.7.1
MarkupSafe==0.18
Werkzeug==0.9.4
gunicorn==18.0
heroku==0.1.4
httplib2==0.8
itsdangerous==0.23
oauth2==1.5.211
python-dateutil==1.5
requests==2.0.0
wsgiref==0.1.2

gitignore

venv
*.pyc

过程文件

web: gunicorn base:app

account.py(从我的股票经纪人那里获取数据的东西)

 token    = oauth.Token(key=_ACCESS_TOKEN_, secret=_ACCESS_TOKEN_SECRET_)
 consumer = oauth.Consumer(key=_CONSUMER_KEY_, secret=_CONSUMER_SECRET_)
 request_holdings_url = "%s/accounts/%s/holdings.json" % (_BASE_URL_, _ACCOUNT_NUMBER_)
 request_values_url = "%s/market/ext/quotes.xml?" % _BASE_URL_
 #creating the client
 client = oauth.Client(consumer, token=token)

 #making the request via the client

 stocksym = {}


 def urlquery():
 # get all of my tradeking info
     resp, content = client.request(request_holdings_url, "GET")
     content =  json.loads(content)
     return content


 def getstocksym(json):
     # returns the holdings under my TK acct
     allholdings = json[u"response"][u"accountholdings"][u"holding"]
     for stock in allholdings:
         sym = stock[u"instrument"][u"sym"]
         stocksym.update({sym: 0})
     return stocksym


 def stockvalue(stocks):
     # returns a dictionary with stock: price: change:
     stockvalues = {}
     for stock in stocks:
         resp, content = client.request("https://api.tradeking.com/v1/market/ext/quotes.json?symbols=%s" % stock, "GET")
         content = json.loads(content)
         change = content[u"response"][u"quotes"][u"quote"][u"chg_sign"]
         price = content[u"response"][u"quotes"][u"quote"][u"ask"]
         stockvalues.update({stock: {'price':price, 'change':change}})
     return stockvalues

 def parsevalues(stockvalues):
     #parses library, returns whether or not a stock in the dictionary is changing, and what price it is.
     values = []
     for stock in stockvalues:
         price = stockvalues[stock][u"price"]
         if stockvalues[stock][u"change"] == 'u':
             return "%s is going up! and the price is: %s" % (stock, price)
         elif stockvalues[stock][u"change"] == 'd':
            return "%s is going down! and the price is %s" % (stock, price)


 if __name__ == "__main__":
    parsevalues(stockvalue(getstocksym(urlquery())))

base.py

from flask import Flask, jsonify, render_template
import account
app = Flask(__name__)


@app.route("/")
def home():
   values = account.stockvalue(account.getstocksym(account.urlquery()))
   json = jsonify(values)
   json = values
   return render_template('home.html', json=json)

if __name__ == "__main__":
   app.run()

home.html

 <!doctype html>
 <html>
     <head>
         <title> 
            stock app! 
         </title>
     </head>
     <body>
         <ul>
             {% for stock, attr in json.iteritems() %}
                 <li>

                 {{ stock }} - {{attr.price}} <div style="display: inline-block; width: 10px; height: 10px; border-radius: 5px; background-color: {% if attr.    change == 'u' %} green  {% else %} red {% endif %}"></div>

                 </li>

             {% endfor %}
         </ul>
     </body>
 </html>

应用现在在本地成功运行,工头启动。

(venv)Eriks-MacBook-Pro:stockheroku erikmingo$ foreman start
17:57:31 web.1  | started with pid 752
17:57:32 web.1  | 2013-10-21 17:57:32 [752] [INFO] Starting gunicorn 18.0
17:57:32 web.1  | 2013-10-21 17:57:32 [752] [INFO] Listening at: http://0.0.0.0:5000 (752)
17:57:32 web.1  | 2013-10-21 17:57:32 [752] [INFO] Using worker: sync
17:57:32 web.1  | 2013-10-21 17:57:32 [755] [INFO] Booting worker with pid: 755

所以此时我运行:

git add .
git commit -m "this works locally, maybe it will work on heroku!"
git push heroku master

把这个还给我:

Counting objects: 9, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 463 bytes, done.
Total 5 (delta 3), reused 0 (delta 0)

-----> Python app detected
-----> No runtime.txt provided; assuming python-2.7.4.
-----> Using Python runtime (python-2.7.4)
-----> Installing dependencies using Pip (1.3.1)
       Cleaning up...
-----> Discovering process types
       Procfile declares types -> web

-----> Compiled slug size: 29.5MB
-----> Launching... done, v28
       http://still-fortress-2740.herokuapp.com deployed to Heroku

To git@heroku.com:still-fortress-2740.git
   34025ca..ecba67c  master -> master

当我进入 heroku open 我得到一个 500 错误。

这里是heroku日志:

2013-10-22T01:26:32.722581+00:00 heroku[router]: at=info method=GET path=/ host=still-fortress-2740.herokuapp.com fwd="67.176.81.118" dyno=web.1 connect=1ms service=30ms status=500 bytes=135
2013-10-22T01:26:32.723565+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
2013-10-22T01:26:32.723565+00:00 app[web.1]:     reraise(exc_type, exc_value, tb)
2013-10-22T01:26:32.723806+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
2013-10-22T01:26:32.723806+00:00 app[web.1]:     response = self.full_dispatch_request()
2013-10-22T01:26:32.723806+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
2013-10-22T01:26:32.723806+00:00 app[web.1]:     rv = self.handle_user_exception(e)
2013-10-22T01:26:32.723806+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
2013-10-22T01:26:32.723806+00:00 app[web.1]:     reraise(exc_type, exc_value, tb)
2013-10-22T01:26:32.723806+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
2013-10-22T01:26:32.723806+00:00 app[web.1]:     rv = self.dispatch_request()
2013-10-22T01:26:32.723806+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
2013-10-22T01:26:32.723806+00:00 app[web.1]:     return self.view_functions[rule.endpoint](**req.view_args)
2013-10-22T01:26:32.723983+00:00 app[web.1]:   File "/app/base.py", line 8, in home
2013-10-22T01:26:32.723983+00:00 app[web.1]:     values = account.stockvalue(account.getstocksym(account.urlquery()))
2013-10-22T01:26:32.723983+00:00 app[web.1]:   File "/app/account.py", line 28, in urlquery
2013-10-22T01:26:32.723983+00:00 app[web.1]:     resp, content = client.request(request_holdings_url, "GET")
2013-10-22T01:26:32.723983+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/oauth2/__init__.py", line 682, in request
2013-10-22T01:26:32.723983+00:00 app[web.1]:     connection_type=connection_type)
2013-10-22T01:26:32.723983+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/httplib2/__init__.py", line 1570, in request
2013-10-22T01:26:32.723983+00:00 app[web.1]:     (response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
2013-10-22T01:26:32.723983+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/httplib2/__init__.py", line 1317, in _request
2013-10-22T01:26:32.723983+00:00 app[web.1]:     (response, content) = self._conn_request(conn, request_uri, method, body, headers)
2013-10-22T01:26:32.724435+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/httplib2/__init__.py", line 1252, in _conn_request
2013-10-22T01:26:32.724435+00:00 app[web.1]:     conn.connect()
2013-10-22T01:26:32.724435+00:00 app[web.1]:   File "/app/.heroku/python/lib/python2.7/site-packages/httplib2/__init__.py", line 1044, in connect
2013-10-22T01:26:32.724435+00:00 app[web.1]:     raise SSLHandshakeError(e)
2013-10-22T01:26:32.724435+00:00 app[web.1]: SSLHandshakeError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

这是我在 stackoverlow 上的第一篇文章,我尽力遵循发布指南。让我知道您是否有任何其他信息会对您有所帮助...就像我上面提到的,当我将“/”路由的返回更改为字符串时,该应用程序可以在 heroku 上运行。

提前致谢!

编辑:看来问题出在我的 API 调用上……Heroku 说这是一次糟糕的 SSL 握手或其他什么……但这到底是什么意思?这绝对是我的 account.py 文件中的内容,但我不确定是什么。

【问题讨论】:

  • 关于糟糕的 SSL 握手见最新编辑。

标签: python git heroku flask gunicorn


【解决方案1】:

account 模块肯定存在某种问题。当我像这样创建虚拟account 时:

def stockvalue(foo):
    return {'foo': 'bar'}

def getstocksym(foo):
    return None

def urlquery():
    return None

一切顺利。

编辑

尝试用这个替换home,看看你会得到什么:

@app.route("/")
def home():
   try:
       values = account.stockvalue(account.getstocksym(account.urlquery()))
   except Exception as e:
       return jsonify({"error": str(e)})
   return jsonify(values)

或者在app = Flask(__name__) 之后添加app.config['DEBUG'] = True 更好。不要忘记在生产中将其删除。虽然它对调试很有用,但它并不安全

另一个修改

您似乎遇到了缺少证书的问题。它应该有帮助:

  1. 从 curl 站点下载证书:http://curl.haxx.se/ca/cacert.pem
  2. cacert.pem 复制到应用的根目录(account.py 所在的位置)
  3. git add .
  4. 修改account.py
import os
import oauth2 as oauth
# Other imports

token    = oauth.Token(key=_ACCESS_TOKEN_, secret=_ACCESS_TOKEN_SECRET_)
consumer = oauth.Consumer(key=_CONSUMER_KEY_, secret=_CONSUMER_SECRET_)
request_holdings_url = "%s/accounts/%s/holdings.json" % (_BASE_URL_, _ACCOUNT_NUMBER_)
request_values_url = "%s/market/ext/quotes.xml?" % _BASE_URL_

#creating the client
client = oauth.Client(consumer, token=token)
client.ca_certs = os.path.join(os.path.dirname(__file__), 'cacert.pem')

#Rest of your code
... 

提交并推送到 Heroku。

【讨论】:

  • 嗯嗯。当我尝试让 render_template 返回一个 hello world-esque html 文档时,它也不起作用。让我从 account.py 上传一些代码(我不想显示我的令牌等)。
  • 帐户内部发生了很多事情。尝试使用编辑中的代码运行您的应用程序,看看您会得到什么。它应该缩小搜索范围。
  • 在本地工作并给我 "{ "GGG": { "change": "u", "price": "80.8400" }, "ONVO": { "change": "u", "price": "6.2500" } } " 远程中断...将尝试改用您的代码。您认为 heroku 向 tradeking 发出 HTTP 请求可能有问题吗?
  • 在本地工作,在 heroku 上中断....我什至无法获取 html 文件

    嗨,世界!

    可以工作...
  • 你是对的,它与帐户模块有关!哎呀!看看它是否适用于模拟字典still-fortress-2740.herokuapp.com
猜你喜欢
  • 2018-10-18
  • 2021-09-09
  • 1970-01-01
  • 2021-05-12
  • 1970-01-01
  • 2016-09-10
  • 2017-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多