Gunicorn: v20の問題「app」でアプリケヌションオブゞェクト「create_app」が芋぀かりたせんでした

䜜成日 2019幎11月09日  Â·  47コメント  Â·  ゜ヌス: benoitc/gunicorn

私は自分のバヌゞョンのgunicornを固定するのを怠っおいたしたが、今朝、アプリを再デプロむするず実行コマンドが壊れ始め、自動的に20.0にアップグレヌドされたした。

私のバヌゞョンのgunicornを19.9にダりングレヌドするず、問題が修正されたした。

これは、アプリを実行するために䜿甚しおいるコマンドです。

gunicorn 'app:create_app()' --workers 4 --threads 4 --bind 0.0.0.0:$PORT

゚ラヌは次のずおりです。

Failed to find application object 'create_app()' in 'app'
( Feedback Requested FeaturApp Investigation

最も参考になるコメント

マスタヌで修正されたした。 パッチをありがずう@davidism 

凊理されるすべおのケヌスはこのテストに含たれたす https 

党おのコメント47件

私もこの問題を経隓したした、すなわち
Failed to find application object 'create_app()' in 'app'
バヌゞョン19.9.0に固定するず、問題が解決したす。

私は圓初、修正はgunicornコマンドを次のように倉曎するこずでしたが
gunicorn --bind 0.0.0.0:$PORT app:create_app()
に
gunicorn --bind 0.0.0.0:$PORT app:create_app
create_appの埌の角かっこがなくなったこずに泚意しおください。 最初は、すべおが順調に芋えたす。

website_1 | [2019-11-10 19:18:54 +0000] [1] [INFO] gunicorn20.0.0を開始しおいたす
website_1 | [2019-11-10 19:18:54 +0000] [1] [情報]リスニング http 
website_1 | [2019-11-10 19:18:54 +0000] [1] [情報]ワヌカヌの䜿甚同期
website_1 | [2019-11-10 19:18:54 +0000] [11] [INFO] pidでワヌカヌを起動しおいたす11

しかし、残念ながら、フラスコのWebサむト/゚ンドポむントをロヌドしようずするず、次のように衚瀺されるため、これは蜃気楌にすぎたせん。

[2019-11-10 19:20:28 +0000] [11] [゚ラヌ]リク゚ストの凊理䞭に゚ラヌが発生したした/
website_1 | トレヌスバック最埌の最埌の呌び出し
website_1 | ファむル「/usr/local/lib/python3.7/site-packages/gunicorn/workers/sync.py」、134行目、ハンドル
website_1 | self.handle_requestlistener、req、client、addr
website_1 | ファむル「/usr/local/lib/python3.7/site-packages/gunicorn/workers/sync.py」、175行目、handle_request
website_1 | respiter = self.wsgienviron、resp.start_response
website_1 | TypeErrorcreate_appは0個の䜍眮匕数を取りたすが、2個が指定されたした

これは明らかにgunicornバヌゞョン20.0.0の問題です。

この倉曎に関連しおいる必芁がありたす https 

あなたの偎でそれを修正する1぀の方法は、メむンモゞュヌルでmyapp = create_app()を゚クスポヌトし、10個をapp:myapp開始するこずです。 これは機胜するはずです。機胜しない堎合はお知らせください。

そこで䜕かする必芁があるかどうか調べたす。 @berkerpeksagなぜevalの削陀が必芁だったのですか

これは、この倉曎に関連しおいる必芁がありたす 3701ad9diff-0b90f794c3e9742c45bf484505e3db8dR377 via2043。

あなたの偎でそれを修正する1぀の方法は、メむンモゞュヌルでmyapp = create_app()を゚クスポヌトし、10個をapp:myapp開始するこずです。 これは機胜するはずです。機胜しない堎合はお知らせください。

そこで䜕かする必芁があるかどうか調べたす。 @berkerpeksagなぜevalの削陀が必芁だったのですか

アプリケヌションでこの倉曎を行い、クラッシュを修正したした。Gunicornは、 create_app()の結果を倉数に保存し、Gunicornの実行コマンドで䜿甚できるように゚クスポヌトするこずで、アプリケヌションを実行できるようになりたした。

# app.py
def create_app():
    ...

my_app = create_app()

gunicorn "app:my_app" --workers 8

@benoitcず@ jrusso1020が䞊蚘で提案したこずを実行するず、問題が修正されるこずを確認できたす。 皆さんありがずう

次のように起動時にパラメヌタヌの受け枡しが必芁な堎合、修正が機胜しおいないようです。

gunicorn --chdir hcli_core path "hcli_ coreHCLI " hcli_core sample hfm ".connector"。

パラメヌタの受け枡しは19.9.0で機胜したすが、20.0.0では倱敗したす。

@benoitc知っおおくず䟿利な堎合に備えお、フラスコのドキュメントでは、gunicornを䜿甚するずきにapp:create_app()パタヌンを掚奚しおいたす。 新しいナヌザヌの䞭には、フラスコアプリを䜜成した結果、最初にgunicornを詊しおみる人もいるず思いたす。圌らは、これらのドキュメントからの珟圚壊れおいる掚奚事項を䜿甚しようずしたす少なくずも私の経隓ではありたす。

そのチヌムに連絡しお曎新を䟝頌するこずはできたすが、 @ berkerpeksagがexecのドロップを怜蚎するのを埅っお、それを元に戻すこずが理にかなっおいる堎合に備えたす。

@ tjwaterman99ええず、この方法でアプリに匕数を枡すのが奜きかどうかは

Flaskの䜿甚法の私たち自身の

cc @tilgovi @berkerpeksag ^^

FWIW私たちもこれに遭遇しおいたす。

「アプリケヌションファクトリ」のFlaskパタヌンに埓う人はかなり倚いず思いたす。
確かに回避策はありたすが、少なくずも倉曎ログには、これを重倧な倉曎ずしお蚘茉する必芁がありたす。

app:callable()やapp:callable(some, args)などの䜿甚法を意図的にサポヌトしたこずはないず思いたす。 以前の実装でeval()を䜿甚したこずによる䞍幞な副䜜甚だったず思いたす。

珟圚の実装は、Djangoのimport_string()機胜にかなり近いものです。

https://github.com/django/django/blob/master/django/utils/module_loading.py#L7 -L24

ドキュメントを改善し、リリヌスノヌトを远加し、より説明的な゚ラヌメッセヌゞを衚瀺させおいただきたす。

appcallable やappcallable some、argsなどの䜿甚法を意図的にサポヌトしたこずはないず思いたす。 以前の実装でevalを䜿甚したこずによる䞍幞な副䜜甚だったず思いたす。

はい私は同意する。 私が芋おいる限り、アプリケヌションを起動するそのような方法をサポヌトしたこずはありたせん。

より明確な゚ラヌのために私は+1です。 アプリケヌション名が単玔な名前でない堎合は、゚ラヌが発生する可胜性がありたすか

これは、䞻芁なwsgiフレヌムワヌクの1぀フラスコの公開ドキュメントに蚘茉されおいる明瀺的な動䜜であり、以前はプロゞェクトでサポヌトされおいたこずを芚えおおいおください。 evalを削陀するず、アプリケヌションの遅延開始が防止されたす。これは、アプリケヌションが1ラむブラリによっお提䟛され、2重芁なセットアップコストが発生する堎合に問題になりたす。 evalが䞍適切であるずいうセキュリティやその他の理由がない堎合、既存の動䜜をサポヌトし続けるこずは簡単ではないでしょうか。

誰かが同様のケヌスに遭遇した堎合、Python 3.7以降の適切な回避策は、このPEPに埓っお、モゞュヌルレベルの__getattr__䜜成するこずにより、モゞュヌルレベルの倉数を停造するこずです。 これにより、gunicorn 20.0.0の重倧な倉曎にぶ぀かるこずなく、怠惰な開始アプリケヌションファクトリが可胜になりたす。

たあ、私たちはそのような振る舞いを実際にサポヌトしたこずはありたせん、私たちのドキュメントや䟋のどれもそれを䜿甚しおいたせん。 それはコマンドラむンに適合したせん。

しかし、これは本圓に重倧な倉曎であり、予期しないものです。 その埌、 evalを元に戻し、非掚奚の動䜜に぀いおナヌザヌに譊告するこずに賛成です。 たぶんそれを眮き換えお、人々が「ファクトリ」デザむンパタヌンを䜿甚できるようにするために、蚭定を远加するこずができたす--init-args 

gunicorn -b :8000 --init-args="arg1,arg2"  app:factory_method

たたはそれのようなもの。 考え

@benoitc明瀺的なコマンドラむンフラグでファクトリメ゜ッドをサポヌトするのは玠晎らしいでしょう😄倚分次のようなものです

$ gunicorn -b :8000 \
  --callable \
  --callable-arg "abc" \
  --callable-arg "xyz" \
  --callable-kwarg "key" "value" \
  app:factory_method

たたは、 --factoryなどの別のベヌス名

テストを簡単に実行する方法がなくなったため、この倉曎で問題が発生したした。 i私のアプリは環境倉数に䟝存しおいるため、iiテストコレクションはすべおのモゞュヌルをロヌドしdoctestsの堎合、iiiむンポヌト埌たでアプリの構築を延期できないため、長い文字列を远加せずにプロゞェクトをテストするこずはできたせんすべおのテストコマンドの前に環境倉数を入力し、テストに以前よりも時間がかかりたす。

私はPython3.7を䜿甚しおいるので、モゞュヌルレベルの__getattr__でこれを回避できるず思いたすが、3.7より前の堎合、ダりングレヌド以倖にこの問題の解決策はないず思いたす。

コマンドラむンフラグでファクトリメ゜ッドをサポヌトするこずで、この問題を解決できるず思いたす。 しかし、明らかな解決策がない堎合は、他の提案もいただければ幞いです🙃

@ tjwaterman99ええず、この方法でアプリに匕数を枡すのが奜きかどうかは

Flaskの䜿甚法の私たち自身の

私は同意したす。環境を介しお匕数を枡す方が盎感的であり、ナヌザヌが構成を1か所にたずめるこずを奚励するず思いたす。 ただし、呌び出し可胜なオブゞェクト/ファクトリをサポヌトするこずは、少なくずもFlaskにずっお、そしおおそらく他のフレヌムワヌクにずっおも重芁です。

exec次のリリヌスを廃止する前に、譊告を発し、工堎でGunicornを䜿甚する方法を説明するための+1。

これが起こったのは残念です。 応答方法には2぀の遞択肢がありたす。 動䜜を元に戻すこずも、党員の移行を支揎するこずもできたす。

動䜜を元に戻す堎合は、PyPIからリリヌスをプルするのが理にかなっおいるかもしれたせんが、これはあたりにも培底的だず思いたす。 Gunicornは、この䜿甚法を文曞化たたは提案したこずはありたせん。

したがっお、皆様のご䞍䟿をお詫び申し䞊げたす。

ドキュメントを曎新するには、PRでFlaskに連絡する必芁がありたす。 私はそれをしおうれしいです。 他の人はすでにここで移行パスを文曞化しおいるず思いたす。

アプリケヌションファクトリをむンポヌトし、呌び出し、゚クスポヌトする_separate_モゞュヌルたたはスクリプトがあるず䟿利な堎合があるずいう提案を远加したす。 これはGunicornの゚ントリポむントずしお機胜し、doctestやその他のツヌルから省略しお、開発䞭にこれらのツヌルを実行するずきに䞍芁なむンポヌトがトリガヌされないようにするこずができたす。 __main__.pyたたはweb.pyスクリプトのようなものがこれに䜿甚できたす。

将来的には、リリヌスが安党であるず考えられる堎合でも、リリヌス候補を利甚できるようにする必芁がありたす。 これをリリヌス候補で捉えお、リリヌスノヌトの重倧な倉曎を文曞化するか、サむクルで非掚奚にする機䌚があった可胜性がありたす。

コマンドラむンで初期化匕数のサポヌトを远加するこずは意味がないず思いたす。 このリリヌスには遅すぎたす。 高床なナヌスケヌス向けのカスタムアプリケヌションはすでにサポヌトされおいたす。 たた、倚くのフレヌムワヌクには、アプリケヌションに蚭定を枡すための独自の掚奚方法がありたす。 Gunicornは独自のものを提䟛する必芁はありたせん。 この問題を修正するために匕数を远加しようずするず、将来この皮の重倧な倉曎の衚面積が拡倧したす。 GunicornのCLIサヌフェスを可胜な限り最小化するこずを目指す必芁がありたす。

ドキュメントを曎新するには、PRでFlaskに連絡する必芁がありたす。 私はそれをしおうれしいです。 他の人はすでにここで移行パスを文曞化しおいるず思いたす。

@ bilalshaikh42はすでにhttps://github.com/pallets/flask/pull/3421でこれを行っおいるようです

ここのFlaskメンテナの1人

そこでevalを取り陀くこずに完党に同意したすが、アプリファクトリを明瀺的にサポヌトする必芁があるず思いたす。 アプリファクトリの芁点は、むンポヌト可胜なappオブゞェクトを䜿甚しないようにするこずですこれを䜿甚するず、埪環䟝存関係地獄が発生するこずが倚いため。

flask run cli開発甚のみでは、アプリファクトリが非垞に䞀般的であるため、実際に明瀺的なサポヌトを远加したした。

もちろん、 wsgi.pyを含むfrom myapp. import make_app; app = make_app() wsgi.pyを䜜成するのは簡単です。 しかし、私はこのファむルを個別に維持する必芁がありたすこれは、 pip install myappが実行するために必芁なすべおをむンストヌルしないため、䞍䟿です、たたはパッケヌゞに入れる぀たり、内郚からむンポヌトできるようになりたした。間違っおいるアプリ自䜓

Flaskでは、呌び出し可胜なアプリファクトリをチェックし、 eval頌らずに呌び出す明瀺的な方法を採甚したした。おそらく、このようなものも怜蚎できたすか 魔法を枛らしたい堎合は、アプリケヌションを指すためずアプリファクトリを指すために異なるCLI匕数を䜿甚するこずもできたす。

将来的には、リリヌスが安党であるず考えられる堎合でも、リリヌス候補を利甚できるようにする必芁がありたす。 これをリリヌス候補で捉えお、リリヌスノヌトの重倧な倉曎を文曞化するか、サむクルで非掚奚にする機䌚があった可胜性がありたす。

RCが本圓に圹立぀かどうかはわかりたせん-䞀般的に人々は--preむンストヌル/アップグレヌドしたせんこれがどれほどひどく機胜するためでもありたす-それは明瀺的に指定されたパッケヌゞだけでなく、どんなに深くおもすべおのネストされた䟝存関係に圱響したす、したがっお、䟝存関係の䟝存関係によっお壊れたプレリリヌスが取り蟌たれるのは非垞に簡単です。そのため、バヌゞョンを固定しなかった人は、実際にリリヌスされるたで砎損を芋぀けるこずはありたせん。

zope.hookableは、オプションのC拡匵機胜により本質的にオヌバヌヘッドのない、怠惰なファクトリのようなアプロヌチを実装する簡単な方法を提䟛したす。 ただし、远加の匕数を枡すこずに぀いおは䜕もしたせん。

# app.py
from zope.hookable import hookable

def make_app():
    def _(environ, start_response, value=b'Hello'):
        start_response('200 OK',
                       [('Content-Type', 'text/plain')])
        return [value]
    return _

<strong i="8">@hookable</strong>
def app(environ, start_response):
    real_app = make_app()
    app.sethook(real_app)
    return real_app(environ, start_response, b"First time")
$ gunicorn app:app
[2019-11-12 05:53:47 -0600] [12457] [INFO] Starting gunicorn 20.0.0
[2019-11-12 05:53:47 -0600] [12457] [INFO] Listening at: http://127.0.0.1:8000 (12457)
[2019-11-12 05:53:47 -0600] [12457] [INFO] Using worker: sync
[2019-11-12 05:53:47 -0600] [12460] [INFO] Booting worker with pid: 12460
...
% http localhost:8000
HTTP/1.1 200 OK
Connection: close
Content-Type: text/plain
Date: Tue, 12 Nov 2019 11:53:49 GMT
Server: gunicorn/20.0.0
Transfer-Encoding: chunked

First time

% http localhost:8000
HTTP/1.1 200 OK
Connection: close
Content-Type: text/plain
Date: Tue, 12 Nov 2019 11:53:51 GMT
Server: gunicorn/20.0.0
Transfer-Encoding: chunked

Hello

もちろん、 wsgi.pyを含むfrom myapp. import make_app; app = make_app() wsgi.pyを䜜成するのは簡単です。 しかし、私はこのファむルを個別に維持する必芁がありたすこれは、 pip install myappが実行するために必芁なすべおをむンストヌルしないため、䞍䟿です、たたはパッケヌゞに入れる぀たり、内郚からむンポヌトできるようになりたした。間違っおいるアプリ自䜓

プロゞェクトのwsgi.pyが間違っおいるもう1぀の理由は、プロゞェクト内のすべおのモゞュヌルをむンポヌトするツヌルがあるこずです。 䟋えば。 pytestは、doctestを探すずきに実行したす。

ここに別のフラスコメンテナ。 @ThiefMasterは私が蚀いたいこずをすべお蚀ったので、私は䞻にこの機胜のサポヌトを繰り返しおいたす。

私は取り払うに同意eval 、ず私はそれを回避flask run 。 以前の動䜜のより制玄されたバヌゞョンを远加できたす。 コマンドラむンオプションに芪が含たれおいる堎合は、実際のアプリを返すファクトリであるず想定したす。 literal_evalを䜿甚しお芪の内容を解析しおから、解析されたパラメヌタヌを䜿甚しおファクトリを呌び出したす。

wsgi.pyファむルのないファクトリパタヌンはかなり䟡倀があるず思いたす。 Gunicornでそれを維持する方法を芋぀けるのを手䌝いたいです。

工堎のようなアプリケヌション文字列のliteral_evalのPRをたずめたいず思いたせんか これはgunicorn.util.import_appたす。

テストを远加する必芁がありたすが、Gunicornに移怍されたFlaskのコヌドは次のずおりです https //github.com/benoitc/gunicorn/compare/master ... davidismimport-factory

@davidism興味がある堎合は、アプリファクトリからアプリを読み蟌むのに圹立぀可胜性のある関数をast.parseずast.literal_evalを䜿甚しお評䟡されるため、 eval呌び出しはありたせん。

import ast
from types import ModuleType
from typing import Any


def get_app(module: ModuleType, obj: str) -> Any:
    """
    Get the app referenced by ``obj`` from the given ``module``.

    Supports either direct named references or app factories, using `ast.literal_eval` for safety.

    Example usage::

        >>> import collections
        >>> get_app(collections, 'Counter')
        <class 'collections.Counter'>
        >>> get_app(collections, 'Counter()')
        Counter()
        >>> get_app(collections, 'import evil_module')  # doctest: +ELLIPSIS
        Traceback (most recent call last):
          ...
        ValueError: Could not parse 'import evil_module' as a reference to a module attribute or app factory.
        >>> get_app(collections, '(lambda: sys.do_evil)()')
        Traceback (most recent call last):
            ...
        ValueError: App factories must be referenced by a simple function name
        >>> get_app(collections, '(1, 2, 3)')
        Traceback (most recent call last):
            ...
        ValueError: Could not parse '(1, 2, 3)' as a reference to a module attribute or app factory.
    """
    # Parse `obj` to an AST expression, handling syntax errors with an informative error
    try:
        # Note that mode='eval' only means that a single expression should be parsed
        # It does not mean that `ast.parse` actually evaluates `obj`
        expression = ast.parse(obj, mode='eval').body
    except SyntaxError as syntax_error:
        raise ValueError("Could not parse '{}' as a reference to a module attribute or app factory.".format(obj)) from syntax_error

    # Handle expressions that just reference a module attribute by name
    if isinstance(expression, ast.Name):
        # Expression is just a name, attempt to get the attribute from the module
        return getattr(module, expression.id)

    # Handle expressions that make a function call (factory)
    if isinstance(expression, ast.Call):
        # Make sure the function name is just a name reference
        if not isinstance(expression.func, ast.Name):
            raise ValueError("App factories must be referenced by a simple function name")

        # Extract the function name, args and kwargs from the call
        try:
            name = expression.func.id
            args = [ast.literal_eval(arg) for arg in expression.args]
            kwargs = {keyword.arg: ast.literal_eval(keyword.value) for keyword in expression.keywords}
        except ValueError as value_error:
            raise ValueError("Could not evaluate factory arguments, please ensure that arguments include only literals.") from value_error

        # Get and call the function, passing in the given arguments:
        return getattr(module, name)(*args, **kwargs)

    # Raise an error, we only support named references and factory methods
    raise ValueError("Could not parse '{}' as a reference to a module attribute or app factory.".format(obj))

匕数なしのアプリファクトリのみをサポヌトするこずを決定した堎合は、すべおの匕数凊理コヌドを削陀できたす。 名前ずファクトリ呌び出しを安党に区別するこずは䟝然ずしおうたく機胜したすそしお、ナヌザヌがファクトリに匕数を枡そうずしたずきに特定の゚ラヌメッセヌゞをナヌザヌに䞎えるのに圹立ちたす

@ThiefMaster私はただそのようなパタヌンをサポヌトすべきだず確信しおいたせん。 それはどのように圹立ちたすか 本圓に必芁な堎合は、環境倉数を䜿甚しおカスタム匕数たたは構成を枡さないのはなぜですか

確かに、myappからを含むwsgi.pyを䜜成したす。 make_appをむンポヌトしたす。 app = make_appは簡単です。 しかし、私はこのファむルを個別に維持する必芁がありたすこれは、pip install myappが実行に必芁なすべおをむンストヌルしないため、䞍䟿です、たたはパッケヌゞに入れる぀たり、アプリ自䜓からむンポヌトできるようになりたした。これは間違っおいるでしょう

私はそれを理解しおいたせん、なぜそのようなファむルを別々に維持しなければならないのですか

パッケヌゞに含たれおいる堎合は、むンポヌト可胜です。 したがっお、より倧きなプロゞェクトがある堎合、誰かがcurrent_appなどを䜿甚する代わりに、最終的にはそれをむンポヌトするだけです。぀たり、この皮の間違いを含むPRを凊理する堎合は、より倚くの䜜業が必芁になりたす。

パッケヌゞの倖にある堎合、 pip install実行しおも取埗できたせん。


FWIW、私は匕数を枡すこずを本圓に気にしたせん。 通垞、それらは必芁ありたせんenv varsは確かに行く方法です。 しかし、少なくずもアプリオブゞェクトの代わりに呌び出し可胜なアプリファクトリを指すこずができるこずは非垞に䟿利です

本圓に必芁な堎合は、環境倉数を䜿甚しおカスタム匕数たたは構成を枡さないのはなぜですか

pytestは、テストを芋぀けるためにプロゞェクト内のすべおのモゞュヌルをロヌドしたす。 環境倉数たたは構成ファむルに䟝存するグロヌバルapp=Flask()オブゞェクトがある堎合、そのオブゞェクトはテストの実行時にロヌドされたす。 環境倉数や構成ファむルを蚭定せずにテストを実行できるず䟿利です。 アプリのファクトリパタヌンはこれに最適です。

いく぀かの人気のあるFlaskチュヌトリアルがあるため、匕数パタヌンのあるファクトリはやや䞀般的です。そのため、 flask runサポヌトしたした。 私は、環境を䜿甚しおアプリを構成するこずが望たしいこずに同意したす。そのため、匕数なしでファクトリの呌び出しをサポヌトする、より瞮小されたバヌゞョンで問題ありたせん。

# an app is a name only
$ gunicorn module:app

# a factory has (), but no args allowed
$ gunicorn module:factory()

@tilgovi同意したす。 私の䞻な問題は、それが誰かを壊すずは思っおいなかったずいうこずです。それゆえ、なぜ私は評䟡たたはより安党なものを元に戻しお非掚奚にするこずを提案したした。 䞀方、はい、その動䜜はサポヌトされおおらず、 evalを䜿甚したこずによる䞍幞な圱響

@davidismおもしろい。 しかし、呌び出し可胜なオブゞェクトをアプリケヌションずしお䜿甚するのずどう違うのでしょうか。

どういう意味かわかりたせんが、もっず具䜓的な䟋を挙げおいただけたすか ファクトリはWSGIアプリケヌションを返したすが、それ自䜓はWSGIアプリケヌションではありたせん。

@davidism私は䜕かがこれを


def make_app():
  from mymodule.application import MainApp
  return MainApp()

application = make_app()

次に誰かがgunicorn -b :8000 somemodule:application実行したす

これにより、コヌドをむンポヌトするずきにapplicationが垞に評䟡され、ファクトリの目的が損なわれたす。

WSGI呌び出し可胜オブゞェクトはクラスむンスタンスにするこずもできるため、おそらくこれが意図されたものです。

class Application:
    _app = None
    def __call__(self, environ, start_response):
        if self._app is None:
            from wherever import make_app
            self._app = make_app()
        return self._app(environ, start_response)

application = Application()

 zope.hookable䟋は基本的に同じですが、定垞状態でのオヌバヌヘッドが少なくなりたす。

実際のWSGIアプリを䜜成するWSGIアプリを持぀こずは理想的ではありたせん。 これは、実際の゚ントリポむントにプロキシするすべおのリク゚ストに察する远加の関数呌び出しになりたした。 セットアップは最初のリク゚ストの前に行う必芁がありたすが、珟圚はそれたで延期されおいるため、最初のリク゚ストには堎合によっおはかなり時間がかかりたす。

ここで問題ずなっおいる機胜は、ランタむム/環境構成に基づいおそのオブゞェクトを䜜成するファクトリ関数です。これは、アプリケヌションパヌツを分離し、埪環むンポヌトを回避し、テストの分離を容易にするのに圹立ちたす。 ファクトリを明瀺的に呌び出すコヌドのどこかに、デカップリングの目的が無効になりたす。ナヌザヌが代わりにFlaskで䜿甚できる機胜を䜿甚する必芁があるずきに、「ああ、このアプリオブゞェクトを今すぐむンポヌトする必芁がある」ず思うこずを保蚌したす。

この時点で、私たちが求めおいるのは、「むンポヌト文字列がparensで終わっおいる堎合は、むンポヌトされた名前を呌び出しおアプリを取埗する」こずだけです。

これを回避する方法はたくさんあるず思いたすが、それは単に私たちがタヌゲットオヌディ゚ンスではないこずを意味したす。 パッケヌゞの倖郚にあるスクリプトをコンテナの゚ントリポむントずしお出荷したり、それを無芖するようにpytestを構成したりするなどのこずができるこずは知っおいたすが、チュヌトリアルをフォロヌしおいる可胜性のある、これが壊れた人を気にかけたいず思いたす。トレヌスバックを理解しおいたせん。

非垞に限定された「アプリオブゞェクトが匕数なしで呌び出し可胜である堎合は、ファクトリずしお呌び出す」パタヌンは機胜する可胜性がありたすが、呌び出し可胜オブゞェクトが実際には装食が䞍十分で、むントロスペクションから匕数を簡単に明らかにしないWSGIアプリケヌションである堎合は倱敗したす。 寛倧になりたいのなら、 evalを避けながら、これたでのすべおをサポヌトする必芁があるので、それが私たちのすべき道だず思いたす。

私は本圓にすべおの提案に感謝し、これを解決するのを手䌝いたす、皆さん。

literal_evalを䜿甚した@davidismず@connorbrintonの䞡方の提案が奜きです。

これにより、コヌドをむンポヌトするずきにアプリケヌションが垞に評䟡され、ファクトリの目的が損なわれたす。

実行時にアプリを初期化し、ワヌカヌが䜿甚する呌び出し可胜オブゞェクトを返したす。 それはそれほど違いはありたせん。

そのパタヌンに぀いおの私の䞻な予備は、HUPたたはUSR2の期埅を砎るこずができるいく぀かのコヌドを事前に生成するこずを人々に奚励するこずです。 たた、珟圚のUIを壊したす。 gunicornの将来の䜿甚法で機胜したすか

ずにかく、遞択肢は次のずおりです。

  1. この動䜜はサポヌトされおおらず、文曞化されおいなかったず芋なすこずができたすgunicornで。 それに基づいお行われた倉曎。
  2. 䞀郚のナヌザヌはそれに䟝存しおいたしたが、今はその動䜜をサポヌトしたいず考えおいたす

1は難しいこずですが、サポヌトしたこずがないこずを考えるず、論理的なパスでもありたす。
2ある皮の矎的感芚があり、コマンドラむンUIが壊れおいたす。gunicornでテストするには、いく぀かのテスト/䟋が必芁です。literal_evalsのようなものを䜿甚しおください。

2はサポヌトできたすが、テストをお願いしたす。 たた、それを文曞化する必芁がありたすか

@tilgovi @jamadden @berkerpeksag @sirkonstあなたの奜みは䜕ですか

別の重倧なですが、これはliteral_eval解決されたせん。

たずえば、Plotly Dashでは、 Dashオブゞェクトを䜿甚したす。このオブゞェクトは、内郚的にserver属性ずしおFlaskむンスタンスを持っおいたす。 䞀郚の人々は䜿甚しおいたした

gunicorn "module:app.server"

しかし、これがサポヌトされるべきかどうかはわかりたせん。 flask runもそれをサポヌトしおいたせん。 Dashオブゞェクトには、 __call__に枡されるFlask.__call__ __call__メ゜ッドが必芁なようです。 さらに、 Dashのドキュメントでは、 server = app.serverを実行し、Gunicornにそのこずを指摘しおいるため、これはほずんどの堎合、誀った情報が枡された堎合のようです。

@davidism今日は病気ですが、月曜日のリリヌスのために、この日曜日にそれに぀いお芋おいきたす。 @tilgoviからの提案は適切であり、䞀般的な蚈画は、叀い評䟡を安党な評䟡に眮き換えるこずです。

そのような初期化を䜿甚しおいるナヌザヌに譊告する必芁があるず思いたす。 考え cc @tilgovi

別の実装を䜜成したい堎合を陀いお、䞊蚘でリンクしたブランチを土曜日にテストを行うPRに倉換しようずしたす。

@davidism先に進みたす。 私は日曜日に戻っおきお、必芁に応じおレビュヌしたす:)ありがずう

少し遅れお、今これに取り組んでいたす。

@connorbrinton ast.parseを䜿甚するずいうクヌルなアむデアです。詊しおみお、䞀緒に行く堎合は、コミットの共著者ずしおあなたを含めたす。

やや人気のあるそしおかなり叀いStack Overflowの回答があり、ナヌザヌをv19の動䜜に誘導しおいるずいう点でチャむムを鳎らしたかっただけです。これは、遞択内容によっおは曎新が必芁になる堎合がありたす 8495367 / using-additional-command-line-arguments-with-gunicorn

マスタヌで修正されたした。 パッチをありがずう@davidism 

凊理されるすべおのケヌスはこのテストに含たれたす https 

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡