2015-10-26 13 views
8

Sto tentando di inviare una richiesta di posta all'app Flask da una delle sue viste, ma si blocca fino a quando non uccido il server. Se faccio la richiesta in JavaScript, funziona bene. Perché non funziona dal codice Python?Flask si blocca quando si invia una richiesta di posta a se stesso

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) 

risposta

17

Il server di sviluppo di Flask è a thread singolo per impostazione predefinita. Può gestire solo una richiesta alla volta. Fare una richiesta blocca fino a quando non riceve la risposta. Il tuo codice Flask effettua una richiesta in un thread e quindi attende. Non ci sono altri thread per gestire questa seconda richiesta. Quindi la richiesta non viene mai completata e la richiesta originale attende per sempre.

Abilitare più thread o processi sul server di sviluppo per evitare il deadlock e risolvere il problema immediato.

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

Tuttavia, effettuare una richiesta HTTP completa dell'app dall'interno dell'app non dovrebbe mai essere necessaria e indica un problema di progettazione più approfondito. Ad esempio, osserva che la richiesta interna non avrà accesso alla sessione sul browser del client. Estrai il codice comune e chiamalo internamente, invece di fare una nuova richiesta.

+1

Sono abbastanza sorpreso. Ovunque vada, sento sempre che Flask non supporta il multi-threading. Usa sempre gunicorn e/o nginx per servire la tua applicazione. Lezione appresa, controllerà sempre le cose prima di darle per scontate :) –

+1

@AbhirathMahipal il consiglio di usare Gunicorn e Nginx è corretto. Il server Flask, mentre supporta i thread, non è pensato per la produzione. Non è progettato per essere efficiente, stabile o sicuro, dovrebbe essere usato solo localmente durante lo sviluppo. – davidism

+0

@davidismo concordato. Quello che voglio dire è che dopo aver ascoltato così tanto non ho mai preso in considerazione la possibilità che Flask abbia un'opzione filettata. –

0

Non ho familiarità con Flask. Tuttavia, questo pezzo di codice:

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

Sembra che si sta accettando un modulo pubblicato, la convalida, e poi la pubblicazione di nuovo. Ancora ed ancora.

+0

Gli URL sembrano essere diversi: il secondo ha il prefisso '/ api'. Ciò è dovuto al thread deadlock, non un ciclo infinito. – davidism

+0

@davidism mentre sono abbastanza sicuro che tu abbia ragione ... 'app.register_blueprint (login, prefix ="/api ")' produrrebbe un ciclo infinito ... ma come ho detto sono abbastanza sicuro che tu sia preciso su cosa il problema è che OP sta vedendo ... –

+0

@JoranBeasley buon punto, l'op in realtà non mostra come è stato registrato il progetto. Penso che in questo caso il browser continui ad avvisare di un ciclo di reindirizzamento infinito. – davidism

Problemi correlati