1

nginx + gunicorn + フラスコを実行しています

私のnginx設定は次のようになります:

...

        proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header            Host $http_host;
        proxy_set_header            Stage "development";

        proxy_redirect off;

...

私のフラスコアプリは次のようになります:

from flask import Flask, request

from werkzeug.contrib.fixers import ProxyFix

app = Flask(__name__)

# configuration settings

if request.headers.get('Stage') == 'production':
    app.config.from_object('config.production_config')
else:
    app.config.from_object('config.development_config')

@app.route('/')
def index():
    return "hello"

app.wsgi_app = ProxyFix(app.wsgi_app)

でも、

それはうまくいかないようです。

私は得る:RuntimeError:リクエストコンテキストの外で働いている

私のnginxは開発/運用環境を持つことができるように設定されていますが、この「サーバーの場所」は開発環境であると言え、Flaskに適切な構成を使用してもらいたいです。

4

2 に答える 2

4

アプリケーション構成はアプリケーション全体を対象としていますが、リクエスト ヘッダーは 1 つのリクエストのみを対象としています。通常、同じアプリケーションが多くの要求を処理します。したがって、リクエスト ヘッダーに基づいて構成を設定することはできません。

モジュール レベルのコードは、アプリケーションにまだリクエストが届いていないときにサーバーの起動時に実行されるため、現在のリクエストはありません。これが、「リクエスト コンテキスト外で動作しています」というメッセージの意味です。

あなたがやろうとしていること (prod vs. dev config) は、gunicorn サーバーを起動するスクリプトで環境変数を使用する方が適切です。両方が同時に必要な場合は、2 つの gunicorn サーバーを実行するのが最も簡単です。

または、2 つのアプリケーション オブジェクトを作成し、両方を同じプロセスで実行し、次のような WSGI ミドルウェアでディスパッチします: http://flask.pocoo.org/docs/patterns/appdispatch/

于 2012-08-03T09:00:59.507 に答える
1

これは少し古いですが、フラスコでこれを実現する方法を追加したいと思います。これの大部分はhttp://flask.pocoo.org/docs/config/から採用されています。

config.pyでは、複数のクラス(環境ごとに1つ)を定義します。

class Config(object):
    FOO = 1
    BAR = 2

class Development(Config):
    BAR = 3

次に、各アプリケーションノードでgunicorn initスクリプトに環境変数を設定します(私たちにとって、これはスーパーバイザー構成内にありますが、そうである必要はありません)。

APPLICATION_ENV='Development'

次に、初期化中のフラスコアプリケーション内(サーバーの起動時にのみ実行され、リクエストコンテキスト内では実行されません):

try:
    env = os.environ['APPLICATION_ENV']
except KeyError as e:
    logging.error('Unknown environment key, defaulting to Development')
    env = 'Development'
    app.config.from_object('config.%s' % env)

これで、app.config['BAR']は3になります。

また、ローカル構成ファイルのサポートも必要でした(たとえば、開発者のマシンや、chefから直接マシンにデプロイされ、gitに保存されていないパスワード)。これを行うために、上記を拡張して、app.config['LOCAL_CONFIG']パラメーターに基づいてローカル構成もロードしました。

class Development(Config):
    BAR = 3
    LOCAL_CONFIG = '/etc/localConfig.py'

そして/etc/localConfig.pyに

BAR = 4

また、上記のコードが環境の初期app.configをロードした後のアプリ初期化コードでは、次のようになります。

if 'LOCAL_CONFIG' in app.config:
    #try to load the local configuration overrides
    if app.config.from_pyfile(app.config['LOCAL_CONFIG'], silent=True):
        logging.info('Loaded local config file at %s' % app.config['LOCAL_CONFIG'])
    else:
        logging.warning('Failed to load local config file at %s - does it exist?' % app.config['LOCAL_CONFIG'])

この時点で、app.config['BAR']は4です。

構成にdictがある場合、その中のキーではなく、dict全体のみをオーバーライドできるため、これは完全ではありません。しかし、それは私たちが必要とすることのほとんどを達成します。

于 2013-01-05T14:17:57.990 に答える