2015-10-26 20 views
8

Próbuję wysłać prośbę o dodanie do mojej aplikacji Flask z jednego z jej własnych widoków, ale zawiesza się, dopóki nie zabiję serwera. Jeśli wykonam żądanie w JavaScript, działa dobrze. Dlaczego nie działa z kodu Python?Flask zawiesza się podczas wysyłania żądania do siebie

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) 

Odpowiedz

17

Serwer rozwoju Flask jest domyślnie ustawiony jako jeden wątek. Może obsłużyć tylko jedną prośbę naraz. Złożenie wniosku blokuje, dopóki nie otrzyma odpowiedzi. Twój kod Flask wysyła żądanie w jednym wątku, a następnie czeka. Nie ma innych wątków do obsłużenia tego drugiego żądania. Tak więc prośba nigdy się nie kończy, a pierwotna prośba czeka na zawsze.

Włącz wiele wątków lub procesów na serwerze, aby uniknąć zakleszczenia i naprawić natychmiastowy problem.

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

Jednak wykonanie pełnego żądania HTTP do aplikacji z poziomu aplikacji nie powinno być konieczne i wskazuje na głębszy problem z projektowaniem. Na przykład zauważ, że wewnętrzne żądanie nie będzie miało dostępu do sesji w przeglądarce klienta. Wyodrębnij wspólny kod i wywołaj go wewnętrznie, zamiast składać nowe żądanie.

+1

Jestem całkiem zaskoczony. Gdziekolwiek pójdę, zawsze słyszę, że Flask nie obsługuje wielowątkowości. Zawsze używaj gunicorn i/lub nginx do obsługi aplikacji. Lekcja, której się nauczyłeś, zawsze będzie sprawdzać rzeczy, zanim je przyjmą za pewnik :) –

+1

@AhhirathMahipal rada do korzystania z Gunicorn i Nginx jest poprawna. Serwer Flask, gdy obsługuje wątki, nie jest przeznaczony do produkcji. Nie jest zaprojektowany tak, aby był wydajny, stabilny lub bezpieczny, powinien być używany lokalnie tylko podczas programowania. – davidism

+0

@davidism agreed. Chodzi mi o to, że po usłyszeniu tak wielu rzeczy nigdy nie brałem pod uwagę możliwości, że Flask ma opcję gwintowania. –

0

Nie jestem zaznajomiony z Flask. Jednak ten kawałek kodu:

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

Wygląda jakbyś przyjmując formę zamieszczonych, sprawdzania go, a następnie umieszczenie go ponownie. Raz po raz.

+0

Adresy URL wyglądają inaczej: drugi ma przedrostek '/ api'. Jest to spowodowane zakleszczeniem wątku, a nie nieskończoną pętlą. – davidism

+0

@Davidism, a ja jestem całkiem pewien, że masz rację ... 'app.register_blueprint (login, prefix ="/api ")' dałaby nieskończoną pętlę ... ale jak powiedziałem jestem dość pewny, że jesteś na miejscu o czym Problem polega na tym, że OP widzi ... –

+0

@JoranBeasley dobry punkt, operacja nie pokazała, w jaki sposób został zarejestrowany projekt. Myślę, że przeglądarka nadal ostrzegałaby o nieskończonej pętli przekierowań w tym przypadku. – davidism

Powiązane problemy