Heroku上的Flask-Firebase应用程序未获取环境变量

时间:2019-12-04 14:23:13

标签: python firebase heroku flask environment-variables

我在制作使用Firebase来运行的Flask应用时遇到了麻烦。 似乎Firebase Credentials api即使打印后也不会接受env变量!

此处是应用程序代码:

#!/usr/bin/env python3
""" PixelCode PDF generation application"""

from io import BytesIO
from os import environ
from flask import Flask, render_template_string, send_file, abort, jsonify
from flask_cors import CORS
from dotenv import load_dotenv
from weasyprint import HTML, CSS
import firebase_admin
from firebase_admin import firestore, credentials

load_dotenv()

APP = Flask(__name__)
CORS(APP)

ENV_KEYS = {
    "type": "service_account",
    "private_key_id": environ["FIREBASE_PRIVATE_KEY_ID"],
    "private_key": environ["FIREBASE_PRIVATE_KEY"],
    "client_email": environ["FIREBASE_CLIENT_EMAIL"],
    "client_id": environ["FIREBASE_CLIENT_ID"],
    "token_uri": environ["FIREBASE_TOKEN_URI"],
    "project_id": environ["FIREBASE_PROJECT_ID"],
}

print("ENV KEYS:", ENV_KEYS)

CREDENTIALS = credentials.Certificate(ENV_KEYS)

firebase_admin.initialize_app(
    CREDENTIALS, {'databaseURL': environ["FIREBASE_DATABASE_URL"]}
)

DB = firestore.client()

# Trimmed for brevity...

@APP.route('/', methods=["GET"])
def get_home():
    return render_template_string("<h2>PixelCode GoDocu Services</h2>")


if __name__ == '__main__':
    # This is used when running locally only. When deploying to Google App
    # Engine, a webserver process such as Gunicorn will serve the app. This
    # can be configured by adding an `entrypoint` to app.yaml.
    # Flask's development server will automatically serve static files in
    # the "static" directory. See:
    # http://flask.pocoo.org/docs/1.0/quickstart/#static-files. Once deployed,
    # App Engine itself will serve those files as configured in app.yaml.
    APP.run(host='0.0.0.0', port=environ.get('PORT', 8080), debug=True)

在开发人员/本地环境(我的电脑)上,该应用程序可以使用 .env 文件正常运行。 我也在heroku上设置了环境变量。

在部署应用程序后, print 语句可以很好地打印所有环境变量。 之后,该应用程序因以下错误而崩溃:

  

2019-12-04T14:11:33.349817 + 00:00 app [web.1]:[2019-12-04 14:11:33 +0000] [11] [ERROR]辅助进程异常

     

2019-12-04T14:11:33.349821 + 00:00 app [web.1]:追溯(最近一次拨打电话):

     

2019-12-04T14:11:33.349824 + 00:00 app [web.1]:文件“ /app/.heroku/python/lib/python3.7/site-packages/firebase_admin/credentials.py”,第97行,初始化

     

2019-12-04T14:11:33.349826 + 00:00 app [web.1]:json_data,scopes = _scopes)

     

2019-12-04T14:11:33.349829 + 00:00 app [web.1]:文件“ /app/.heroku/python/lib/python3.7/site-packages/google/oauth2/service_account.py ”,第193行,位于from_service_account_info

     

2019-12-04T14:11:33.349832 + 00:00 app [web.1]:信息,require = ['client_email','token_uri'])

     

2019-12-04T14:11:33.349834 + 00:00 app [web.1]:文件“ /app/.heroku/python/lib/python3.7/site-packages/google/auth/_service_account_info.py “,位于from_dict

中的第54行      

2019-12-04T14:11:33.349836 + 00:00 app [web.1]:签名者= crypt.RSASigner.from_service_account_info(数据)

     

2019-12-04T14:11:33.349838 + 00:00 app [web.1]:文件“ /app/.heroku/python/lib/python3.7/site-packages/google/auth/crypt/base .py”,第115行,位于from_service_account_info

     

2019-12-04T14:11:33.349840 + 00:00 app [web.1]:info.get(_JSON_FILE_PRIVATE_KEY_ID))

     

2019-12-04T14:11:33.349842 + 00:00 app [web.1]:文件“ /app/.heroku/python/lib/python3.7/site-packages/google/auth/crypt/_python_rsa .py“,第174行,位于from_string

     

2019-12-04T14:11:33.349844 + 00:00 app [web.1]:提高ValueError('无法检测到密钥。')

     

2019-12-04T14:11:33.349847 + 00:00 app [web.1]:ValueError:无法检测到密钥。

     

2019-12-04T14:11:33.349849 + 00:00 app [web.1]:

     

2019-12-04T14:11:33.349851 + 00:00 app [web.1]:在处理上述异常期间,发生了另一个异常:

     

2019-12-04T14:11:33.349858 + 00:00 app [web.1]:

     

2019-12-04T14:11:33.349860 + 00:00 app [web.1]:追溯(最近一次通话为最后):

     

2019-12-04T14:11:33.349862 + 00:00 app [web.1]:文件“ /app/.heroku/python/lib/python3.7/site-packages/gunicorn/arbiter.py”,第583行,在spawn_worker中

     

2019-12-04T14:11:33.349864 + 00:00 app [web.1]:worker.init_process()

     

2019-12-04T14:11:33.349866 + 00:00 app [web.1]:文件“ /app/.heroku/python/lib/python3.7/site-packages/gunicorn/workers/base.py “,第129行,位于init_process

     

2019-12-04T14:11:33.349868 + 00:00 app [web.1]:self.load_wsgi()

     

2019-12-04T14:11:33.349871 + 00:00 app [web.1]:文件“ /app/.heroku/python/lib/python3.7/site-packages/gunicorn/workers/base.py ”,在load_wsgi中的第138行

     

2019-12-04T14:11:33.349873 + 00:00 app [web.1]:self.wsgi = self.app.wsgi()

     

2019-12-04T14:11:33.349875 + 00:00 app [web.1]:文件“ /app/.heroku/python/lib/python3.7/site-packages/gunicorn/app/base.py “,第67行,在wsgi中

     

2019-12-04T14:11:33.349877 + 00:00 app [web.1]:self.callable = self.load()

     

2019-12-04T14:11:33.349879 + 00:00 app [web.1]:文件“ /app/.heroku/python/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py “,第52行,处于加载状态

     

2019-12-04T14:11:33.349881 + 00:00 app [web.1]:返回self.load_wsgiapp()

     

2019-12-04T14:11:33.349883 + 00:00 app [web.1]:文件“ /app/.heroku/python/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py ”,在load_wsgiapp中的第41行

     

2019-12-04T14:11:33.349885 + 00:00 app [web.1]:返回util.import_app(self.app_uri)

     

2019-12-04T14:11:33.349887 + 00:00 app [web.1]:文件“ /app/.heroku/python/lib/python3.7/site-packages/gunicorn/util.py”,第350行,位于import_app

     

2019-12-04T14:11:33.349889 + 00:00 app [web.1]:导入(模块)

     

2019-12-04T14:11:33.349891 + 00:00 app [web.1]:文件“ /app/app.py”,第30行,位于

     

2019-12-04T14:11:33.349893 + 00:00 app [web.1]:凭据=凭据。证书(ENV_KEYS)

     

2019-12-04T14:11:33.349895 + 00:00 app [web.1]:文件“ /app/.heroku/python/lib/python3.7/site-packages/firebase_admin/credentials.py”,第100行,在 init

中      

2019-12-04T14:11:33.349897 + 00:00 app [web.1]:'由以下原因引起:“ {0}”'。format(error))

     

2019-12-04T14:11:33.349900 + 00:00 app [web.1]:ValueError:无法初始化证书凭据。原因:“无法检测到任何键。”

     

2019-12-04T14:11:33.350466 + 00:00 app [web.1]:[2019-12-04 14:11:33 +0000] [11] [INFO]工人退出(pid:11)

     

2019-12-04T14:11:33.625273 + 00:00 app [web.1]:[2019-12-04 14:11:33 +0000] [4] [INFO]正在关机:大师

提前谢谢!

1 个答案:

答案 0 :(得分:2)

对于偶然发现类似问题的人(不仅限于heroku和firebase), 当shell(某些)解析环境变量时,它们会转义特殊字符,因此将它们作为文字传递。 对于上述情况,执行命令heroku config -s时,您会注意到对于FIREBASE_PRIVATE_KEY字符,\n\\n替换。

要解决此问题,只需在代码中将\\n替换为\n。见下文

ENV_KEYS = {
"type": "service_account",
"private_key_id": environ["FIREBASE_PRIVATE_KEY_ID"],
"private_key": environ["FIREBASE_PRIVATE_KEY"].replace("\\n", "\n"),
"client_email": environ["FIREBASE_CLIENT_EMAIL"],
"client_id": environ["FIREBASE_CLIENT_ID"],
"token_uri": environ["FIREBASE_TOKEN_URI"],
"project_id": environ["FIREBASE_PROJECT_ID"],
}