2014-12-14 5 views
17

Il mio obiettivo è ottenere codice arbitrario da eseguire dopo l'avvio dell'applicazione del flask, ecco il mio problema. Ho questo (in cui applicazione è il mio pallone app):Il codice di esecuzione dopo l'applicazione del pallone è stato avviato

def run(): 
    from webapp import app 
    app.run(debug=True, use_reloader=False) 

ho idealmente vorrei solo fare questo

def run(): 
    from webapp import app 
    app.run(debug=True, use_reloader=False) 
    some_code() 

ma il codice non continua app.run passato() fino a quando la uscite server, in modo some_code() non corre

la soluzione su cui sto lavorando in questo momento è quello di eseguire some_code() in un thread separato da app.run(), creare una funzione che imposta before first request questo:

app.is_running = True 

Quindi ottenere some_code() per eseguire una richiesta di base per l'app in modo che venga eseguito il codice "prima della prima richiesta". Questo è abbastanza complicato e sarà difficile scrivere documenti per ... Vorrei piuttosto fare riferimento a un parametro app.is_running già scritto nella beuta, o usare un decoratore @ app.after_server_start, ma a mia conoscenza nessuno dei due esiste:/

Aiutami a migliorare questo codice?


postale humus: ogni volta che penso a questa domanda, mi fa venire voglia di @app.after_server_start decorator

+4

Perché non usare semplicemente '@ app.before_first_request' e * con *. Perché il codice deve essere eseguito prima? –

+2

In altre parole, perché è così importante che il codice venga eseguito * dopo * all'avvio del server (che non è comunque possibile utilizzare in questo modo nel codice di produzione, utilizzare sempre un contenitore WSGI appropriato e non il fragile-per-sviluppo- solo il server Werkzeug è stato avviato con 'app.run()') ma prima che una richiesta sia arrivata? –

+2

Principalmente perché ha più senso eseguire il codice dopo l'avvio del server, ma è giusto che non sia necessario eseguirlo così presto – Cyrin

risposta

8

Usa Flask-Script per eseguire la vostra applicazione, quindi sovrascrivere la classe runserver/metodo come questo

# manage.py 

from flask.ext.script import Manager 

from myapp import app 

manager = Manager(app) 

def crazy_call(): 
    print("crazy_call") 

@manager.command 
def runserver(): 
    app.run() 
    crazy_call() 

if __name__ == "__main__": 
    manager.run() 
+1

Grazie per il tuo post. Quando la nostra app viene esaminata da uwsgi, come possiamo integrare questo gestore? – chefarov

+1

@chefarov ha lasciato il pitone molto tempo fa. Non so – CESCO

+0

Non ha funzionato per me. Ho dovuto scambiare le righe come segue: app.run() e crazy_call(). – jotacor

8

Se è necessario eseguire del codice dopo l'avvio dell'applicazione flask ma rigorosamente prima della prima richiesta, nemmeno essere attivato dall'esecuzione della prima richiesta come @ app.before_first_request può gestire, è necessario utilizzare Flask_Script, come CE SCO ha detto, ma si potrebbe creare una sottoclasse del server di classe e sovrascrivere la chiamata __ __ metodo, invece di sovrascrivere il comando runserver con @ manager.command:

from flask import Flask 
from flask_script import Manager, Server 

def custom_call(): 
    #Your code 
    pass 

class CustomServer(Server): 
    def __call__(self, app, *args, **kwargs): 
     custom_call() 
     #Hint: Here you could manipulate app 
     return Server.__call__(self, app, *args, **kwargs) 

app = Flask(__name__) 
manager = Manager(app) 

# Remeber to add the command to your Manager instance 
manager.add_command('runserver', CustomServer()) 

if __name__ == "__main__": 
    manager.run() 

questo modo non ignorare le opzioni di default di comando runserver.