2017-03-25 8 views
0

Ich schreibe eine Anwendung, die eine einfache RPC-Schnittstelle, die mit Kolben implementiert ist, freilegen kann. Ich möchte jedoch, dass es möglich ist, diese Schnittstelle zu aktivieren und zu deaktivieren. Außerdem sollte es möglich sein, mehrere Instanzen der Anwendung im selben Python-Interpreter laufen zu lassen, die jeweils ihre eigene RPC-Schnittstelle haben.Starten und Stoppen der Flasche auf Anfrage

Der Dienst ist nur auf localhost ausgesetzt und das ist ein Prototyp, also mache ich mir keine Sorgen um die Sicherheit. Ich suche eine kleine und einfache Lösung. Der offensichtliche Weg scheint hier der Flaschenentwicklungsserver zu sein, aber ich finde keine Möglichkeit, ihn herunterzufahren.

ich einen Kolben Entwurf für die Funktionalität geschaffen habe ich verfügbar machen möchten und jetzt versuche ich, eine Klasse zu schreiben, die RPC-Schnittstelle ähnlich wie diese wickeln:

class RPCInterface: 
    def __init__(self, creating_app, config): 
     self.flask_app = Flask(__name__) 
     self.flask_app.config.update(config) 
     self.flask_app.my_app = creating_app 

     self.flask_app.register_blueprint(my_blueprint) 

     self.flask_thread = Thread(target=Flask.run, args=(self.flask_app,), 
            name='flask_thread', daemon=True) 

    def shutdown(self): 
     # Seems impossible with the flask server 
     raise NotImplemented() 

ich die Variable my_app von der verwende Aktuelle App, um die Instanz meiner Anwendung, mit der diese RPC-Schnittstelle arbeitet, an den Kontext der Anforderungen zu übergeben.

Es kann aus einer Anfrage heraus geschlossen werden (wie hier beschrieben http://flask.pocoo.org/snippets/67/), also wäre eine Lösung, einen Shutdown-Endpunkt zu erstellen und eine Anfrage mit dem Test-Client zu senden, um einen Shutdown zu initiieren. Dies erfordert jedoch einen Kolbenendpunkt nur für diesen Zweck. Das ist alles andere als sauber.

Ich sah in den Quellcode des Kolbens und Werkzeug und rechnete den wichtigen Teil aus (Context bei https://github.com/pallets/werkzeug/blob/master/werkzeug/serving.py#L688) sieht wie folgt aus:

def inner(): 
    try: 
     fd = int(os.environ['WERKZEUG_SERVER_FD']) 
    except (LookupError, ValueError): 
     fd = None 
    srv = make_server(hostname, port, application, threaded, 
         processes, request_handler, 
         passthrough_errors, ssl_context, 
         fd=fd) 
    if fd is None: 
     log_startup(srv.socket) 
    srv.serve_forever() 

make_server eine Instanz von WerkZeugs Serverklasse zurückgibt, die von pythons erbt http.server Klasse. Dies ist wiederum eine Python BaseSocketServer, die eine Shutdown-Methode darstellt. Das Problem ist, dass der hier erstellte Server nur eine lokale Variable ist und somit von nirgendwo zugänglich ist.

Dies ist, wo ich in eine Sackgasse lief. Also meine Frage ist:

  • Hat jemand eine andere Idee, wie man diesen Server leicht herunterfahren?
  • Gibt es einen anderen einfachen Server, um Flask zu betreiben? Etwas, das keinen externen Prozess benötigt und nur in wenigen Codezeilen gestartet und gestoppt werden kann? Alles, was in der Flaschendokumentation aufgelistet ist, scheint ein komplexes Setup zu haben.
+1

Was ist in den Flask-Dokumenten, die eine komplexe Konfiguration haben? Kannst du es teilen?Ich interessiere mich für Ihre Frage – aaossa

+0

Ich bezog sich auf diese Liste: http://flask.pooco.org/docs/0.12/deploying/#deployment Es schien, dass alle von ihnen einen externen Webserver wie Apache oder benötigen nginx. Allerdings habe ich jetzt herausgefunden, dass die gevent Lösung anders ist und keinen externen Server benötigt. Ich arbeite immer noch an diesem Teil. Ich werde aktualisieren, wenn ich Zeit gefunden habe, es zu testen. – Leonidaz0r

Antwort

0

Beantworten Sie meine eigene Frage für den Fall, dass das jemals wieder passiert.

Die erste Lösung umfasste den Wechsel von Kolben zu klein. Klein ist im Grunde ein Kolben mit weniger Merkmalen, der aber auf dem verdrehten Reaktor läuft. Auf diese Weise ist die Integration sehr einfach. Im Grunde funktioniert es wie folgt aus:

from klein import Klein 
from twisted.internet import reactor 

app = Klein() 

@app.route('/') 
def home(request): 
    return 'Some website' 

endpoint = serverFromString(reactor, endpoint_string) 
endpoint.listen(Site(app.resource())) 

reactor.run() 

Nun sind alle Twisted Tools verwendet werden können, um den Server zu starten und stoppen nach Bedarf.

Die zweite Lösung, auf die ich später hinwies, war, HTTP als Transportprotokoll loszuwerden. Ich wechselte zu JSONRPC über das LineReceiver-Protokoll von twisted. Auf diese Weise wurde alles noch einfacher und ich habe sowieso kein HTTP-Material benutzt.

Verwandte Themen