2015-10-26 12 views
8

自分のFlaskアプリに投稿リクエストを送信しようとしていますが、サーバーを終了するまでハングします。私はJavaScriptで要求を行う場合、それは正常に動作します。なぜPythonコードからはうまくいかないのですか?自分自身にポストリクエストを送信するときにフラスコがハングアップする

from flask import Blueprint, render_template, abort, request, Response, session, url_for 
from jinja2 import TemplateNotFound 

from flask.ext.wtf import Form 
from wtforms import BooleanField, TextField, PasswordField 

import requests 

login = Blueprint('login', __name__, template_folder='templates') 

class LoginForm(Form): 
    email = TextField('Email') 
    password = PasswordField('Password') 

@login.route('/login', methods=['GET', 'POST']) 
    def _login(): 

    form = LoginForm(request.form, csrf_enabled=False) 

    if form.validate_on_submit(): 
     return requests.post(request.url_root + '/api/login', data={"test": True}) 


    return render_template('login.html', form=form) 

答えて

17

Flaskの開発サーバーは、デフォルトではシングルスレッドです。一度に1つの要求しか処理できません。リクエストを作成すると、レスポンスを受信するまでブロックされます。あなたのフラスコのコードは1つのスレッドでリクエストを行い、その後待機します。この2番目の要求を処理する他のスレッドはありません。したがって、要求は完了せず、元の要求は永遠に待機します。

デッドロックを回避し、直接の問題を解決するために、devサーバー上で複数のスレッドまたはプロセスを有効にします。

app.run(threaded=True) 
# or 
app.run(processes=2) 

ただし、アプリ内からアプリに完全なHTTPリクエストを送信する必要はありません。これは深刻な設計上の問題を示しています。たとえば、内部リクエストはクライアントのブラウザ上のセッションにアクセスできないことに注意してください。新しいリクエストを作成するのではなく、共通コードを抽出して内部的に呼び出します。

+1

私はかなり驚いています。どこでも私は行く、私はいつもFlaskはマルチスレッドをサポートしていないと聞きます。アプリケーションには、常にgunicornやnginxを使用してください。レッスンが学んだことは、それらを引き継ぐ前に常にチェックすることになるでしょう:) –

+1

@AbhirathMahipal GunicornとNginxを使うアドバイスは正しいです。 Flaskサーバーは、スレッドをサポートしていますが、本番用ではありません。それは、効率的、安定、または安全であるようには設計されておらず、開発中にのみローカルで使用する必要があります。 – davidism

+0

@ダビデミズムが合意した。私が意味することは、あまりにも多くのことを聞いた後で、フラスコがスレッドオプションを持つ可能性を考慮したことさえありませんでした。 –

0

私はフラスコに精通していません。ただし、コードのこのビット:

if form.validate_on_submit(): 
    return requests.post(request.url_root + '/api/login', data={"test": True}) 

あなたが投稿されたフォームを受け入れ、それを検証してから再び投稿するようです。何度も。

+0

URLが異なるように見えます:2番目には '/ api'という接頭辞があります。これは、スレッドデッドロックによるものであり、無限ループではありません。 – davidism

+0

@ダビデミズムあなたが正しいと確信している間、私はかなり確信しています... 'app.register_blueprint(login、prefix ="/api ")'無限ループを起こすでしょう...しかし、私はあなたが何について問題はOPが見ているということです... –

+0

@JoranBeasley良い点は、opは実際に青写真がどのように登録されたかを示していませんでした。この場合、ブラウザは無限のリダイレクトループについて警告していると思います。 – davidism

関連する問題