Ctrl-c का उपयोग किए बिना फ्लास्क एप्लिकेशन को कैसे रोकें


104

मैं एक कमांड लागू करना चाहता हूं जो फ्लास्क-स्क्रिप्ट का उपयोग करके फ्लास्क एप्लिकेशन को रोक सकता है। मैंने कुछ समय के लिए समाधान खोजा है। क्योंकि फ्रेमवर्क "app.stop ()" API प्रदान नहीं करता है, मैं इसे कोड करने के तरीके के बारे में उत्सुक हूं। मैं Ubuntu 12.10 और पायथन 2.7.3 पर काम कर रहा हूं।


आपको अपने एप्लिकेशन को स्क्रिप्ट से रोकने में सक्षम होने की आवश्यकता क्यों है? (नौकरी के लिए सबसे अच्छा उपकरण इस बात पर निर्भर करेगा कि आप क्या करने की कोशिश कर रहे हैं)।
सीन विएरा

गंभीरता से, आप यहाँ क्या करने की कोशिश कर रहे हैं? यदि आप विकास के लिए डेसरवर के बारे में बात कर रहे हैं, तो इसे उस तरह से रोकना पूरी तरह से ठीक है। उत्पादन में आप इस तरह की तैनाती नहीं करते हैं और आप किसी भी समय अनुरोध को रोक सकते हैं, इसलिए "ऐप चलना बंद हो जाता है"।
इग्नास बुटानास

@ सीनवीरा मैं जानना चाहता हूं कि क्या ऐसा करने का कोई समाधान है।
vic

@IgnasB। मैं अभी अपनी मशीन पर एक RESTful सेवा विकसित कर रहा हूं। मैं एक परियोजना पर काम कर रहा हूं, शायद इससे मुझे यह चुनने में मदद मिलेगी कि मुझे किन मशीनों को तैनात करना चाहिए। जिस तरह से मैं यह पता लगा सकता हूं कि इस प्रक्रिया को मारने से शटडाउन हो सकता है।
vic

3
@vrootic, लेकिन आप वैसे भी उत्पादन में app.run () का उपयोग नहीं करेंगे। app.run () का उपयोग केवल विकास के लिए और विकास करते समय अपने आवेदन का परीक्षण करने के लिए किया जाता है। उत्पादन में फ्लास्क को चलाने के अलग-अलग तरीके हैं, उदाहरण के लिए यहां और अधिक पाया जा सकता है। फ्लास्क.पोकू.ओआर / डॉक्स / क्विकस्टार्ट /#deploying-to-a-web-server और यदि आप किसी भी तरह से पहले से ही तैनात हैं (तो मुझे गलत समझा गया प्रश्न), फ्लास्क में आने वाले अनुरोध को रोकने का तरीका http सर्वर को बंद करना है जो इसे सेवा दे रहा है।
इग्नास बुटानास

जवाबों:


125

यदि आप सर्वर को अपने डेस्कटॉप पर चला रहे हैं, तो आप सर्वर को मारने के लिए एक समापन बिंदु को उजागर कर सकते हैं ( शटडाउन पर अधिक पढ़ें। अन्य सर्वर ):

from flask import request
def shutdown_server():
    func = request.environ.get('werkzeug.server.shutdown')
    if func is None:
        raise RuntimeError('Not running with the Werkzeug Server')
    func()

@app.route('/shutdown', methods=['POST'])
def shutdown():
    shutdown_server()
    return 'Server shutting down...'

यहाँ एक और दृष्टिकोण है जो अधिक निहित है:

from multiprocessing import Process

server = Process(target=app.run)
server.start()
# ...
server.terminate()
server.join()

मुझे बताएं क्या इससे मदद मिलती है।


16
क्या आपको पता है कि अनुरोध के संदर्भ की आवश्यकता के बिना 'werkzeug.server.shutdown' संपत्ति प्राप्त करने का कोई तरीका है?
akatkinson

5
मुझे इसे प्राप्त करने के लिए मार्ग विधि को 'GET' में बदलना पड़ा।
सीएस

5
पूर्णता के लिए यह उत्तर उस फ़ंक्शन को याद कर रहा है जिसे आप शटडाउन करने के लिए अनुरोध के संदर्भ के बाहर कहेंगे, जो कि सर्वर के लिए HTTP अनुरोध (जो / स्थानीय से उत्पन्न हो सकता है) के अलावा और कुछ नहीं होगा
JamesHutchison

1
के साथ methods='POST', मुझे एक 405 Method not allowedत्रुटि मिलती है , जबकि विधियों = 'GET'` के साथ, यह @CS के रूप में काम करता है।
एजिल बीन

1
AWS इलास्टिक बीनस्टॉक पर मेरे लिए काम नहीं किया। स्थानीय रूप से अच्छी तरह से काम किया
एंड्री बुलेज़ुक

34

मैंने थ्रेड्स का उपयोग करके इसे थोड़ा अलग किया

from werkzeug.serving import make_server

class ServerThread(threading.Thread):

    def __init__(self, app):
        threading.Thread.__init__(self)
        self.srv = make_server('127.0.0.1', 5000, app)
        self.ctx = app.app_context()
        self.ctx.push()

    def run(self):
        log.info('starting server')
        self.srv.serve_forever()

    def shutdown(self):
        self.srv.shutdown()

def start_server():
    global server
    app = flask.Flask('myapp')
    ...
    server = ServerThread(app)
    server.start()
    log.info('server started')

def stop_server():
    global server
    server.shutdown()

मैं इसका इस्तेमाल आराम करने वाली आपी के लिए अंत में परीक्षण करने के लिए करता हूं, जहां मैं अजगर अनुरोध पुस्तकालय का उपयोग करके अनुरोध भेज सकता हूं।


2
मैंने काम करने के लिए अन्य सामान प्राप्त करने का प्रबंधन नहीं किया, लेकिन यह समाधान बहुत अच्छा काम करता है! अनेक अनेक धन्यवाद! अन्य लोगों के लिए: यह फ्लास्क रेस्टफुल के साथ भी काम करता है!
जोरिक स्लीजस्टर

यह विंडोज़ पर तब तक अवरुद्ध लगता है जब तक कि मैं इसे एक और अनुरोध के साथ नहीं मारता ... किसी भी तरह से?
क्लाउडीउ

मुझे @Claudiu के समान ही मुद्दा मिल रहा है, सिवाय Linux पर अजगर के साथ 3.6.2
miccscopes

मुझे नहीं पता कि यह क्यों स्वीकार नहीं किया गया है, लेकिन यह सबसे साफ लगता है और बिना किसी अतिरिक्त निर्भरता के महान काम करता है। बहुत बहुत धन्यवाद।
एरिक रीड

17

यह थोड़ा पुराना धागा है, लेकिन अगर कोई व्यक्ति मूल फ्लास्क ऐप का प्रयोग, सीखना, या परीक्षण करना शुरू कर रहा है, तो पृष्ठभूमि में चलने वाली स्क्रिप्ट से शुरू होता है, इसे रोकने का सबसे तेज़ तरीका उस पोर्ट पर चलने वाली प्रक्रिया को मारना है जिसे आप अपना ऐप चला रहे हैं। पर। नोट: मुझे पता है कि लेखक ऐप को मारने या बंद नहीं करने का एक तरीका ढूंढ रहा है। लेकिन यह सीखने वाले किसी व्यक्ति की मदद कर सकता है।

sudo netstat -tulnp | grep :5001

आपको कुछ ऐसा मिलेगा।

tcp 0 0 0.0.0.0:5001 0.0.0.0:* LISTEN 28834 / अजगर

एप्लिकेशन को रोकने के लिए, प्रक्रिया को मार डालो

sudo kill 28834

15

मेरी पद्धति को बैश टर्मिनल / कंसोल के माध्यम से आगे बढ़ाया जा सकता है

1) रन करें और प्रक्रिया संख्या प्राप्त करें

$ ps aux | grep yourAppKeywords

2 ए) प्रक्रिया को मार डालो

$ kill processNum

2 बी) अगर काम नहीं कर रहा है तो प्रक्रिया को मार दें

$ kill -9 processNum

9
मुझे लगभग यकीन है कि सवाल "कैसे एक प्रक्रिया को मारने के लिए नहीं है", और समस्या यह है कि ctrl + c इसे नहीं मारता है। Btw, मैं kill -9 `lsof -i:5000 -t`cuz का उपयोग नहीं करता है सिर्फ 1 ऐप के अलावा पोर्ट का उपयोग कर सकता है और आसान हो रहा है।
m3nda

9

जैसा कि दूसरों ने बताया है, आप केवल werkzeug.server.shutdownएक अनुरोध हैंडलर से उपयोग कर सकते हैं । जिस तरह से मैंने एक और समय में सर्वर को बंद करने के लिए पाया है वह खुद को एक अनुरोध भेजने के लिए है। उदाहरण के लिए, /killइस स्निपेट में हैंडलर देव सर्वर को तब तक मार देगा, जब तक कि अगले सेकंड के दौरान कोई अन्य अनुरोध न आए:

import requests
from threading import Timer
from flask import request
import time

LAST_REQUEST_MS = 0
@app.before_request
def update_last_request_ms():
    global LAST_REQUEST_MS
    LAST_REQUEST_MS = time.time() * 1000


@app.route('/seriouslykill', methods=['POST'])
def seriouslykill():
    func = request.environ.get('werkzeug.server.shutdown')
    if func is None:
        raise RuntimeError('Not running with the Werkzeug Server')
    func()
    return "Shutting down..."


@app.route('/kill', methods=['POST'])
def kill():
    last_ms = LAST_REQUEST_MS
    def shutdown():
        if LAST_REQUEST_MS <= last_ms:  # subsequent requests abort shutdown
            requests.post('http://localhost:5000/seriouslykill')
        else:
            pass

    Timer(1.0, shutdown).start()  # wait 1 second
    return "Shutting down..."

2
यह काम करता है, लेकिन लगता है ... बहुत हैकरी। मुझे पता है कि यह एक समय हो गया है, लेकिन क्या आपने कभी खुद को एक अनुरोध भेजे बिना, ऐसा करने का एक साफ तरीका पाया?
रसदार

7

यह एक पुराना सवाल है, लेकिन इसे पूरा करने के तरीके में गुग्लिंग ने मुझे कोई जानकारी नहीं दी।

क्योंकि मैंने यहाँ कोड ठीक से नहीं पढ़ा ! (दोह!) क्या करना है RuntimeErrorजब कोई werkzeug.server.shutdownमें नहीं है request.environ...

तो जब हम requestउठाने के लिए नहीं है तो हम क्या कर सकते हैंRuntimeError

def shutdown():
    raise RuntimeError("Server going down")

और जब पकड़ता है कि app.run()रिटर्न:

...
try:
    app.run(host="0.0.0.0")
except RuntimeError, msg:
    if str(msg) == "Server going down":
        pass # or whatever you want to do when the server goes down
    else:
        # appropriate handling/logging of other runtime errors
# and so on
...

अपने आप को एक अनुरोध भेजने की आवश्यकता नहीं है।


4

आपको "CTRL-C" नहीं दबाना है, लेकिन आप एक समापन बिंदु प्रदान कर सकते हैं जो आपके लिए है:

from flask import Flask, jsonify, request
import json, os, signal

@app.route('/stopServer', methods=['GET'])
def stopServer():
    os.kill(os.getpid(), signal.SIGINT)
    return jsonify({ "success": True, "message": "Server is shutting down..." })

अब आप बस इस समापन बिंदु को शालीनतापूर्वक सर्वर को बंद करने के लिए कह सकते हैं:

curl localhost:5000/stopServer

मैंने आपके कोड का परीक्षण किया है, लेकिन उसके बाद os.kill, ग्राहक द्वारा दी गई प्रतिक्रिया प्राप्त नहीं की जा सकती है। के लिए curl, यह "कर्ल: (56) Recv विफलता: कनेक्शन रीसेट किया गया था" आउटपुट। फ्लास्क की प्रतिक्रिया के बाद इसे हल करने के लिए एक समारोह भी देखें ।
samm

@samm, उस प्रश्न से निष्कर्ष यह है कि जब तक आप एक अलग धागा शुरू नहीं करते हैं, संभव नहीं है? तो फिर आप उस अलग धागे से फ्लास्क सर्वर को कैसे बंद करते हैं?
जूरगी


2

यदि आप सीएलआई पर काम कर रहे हैं और केवल एक फ्लास्क ऐप / प्रक्रिया चल रही है (या इसके बजाय, आप बस अपने सिस्टम पर चलने वाली किसी भी फ्लास्क प्रक्रिया को मारना चाहते हैं ), तो आप इसे मार सकते हैं:

kill $(pgrep -f flask)


1

यदि आप अनुरोध-प्रतिसाद हैंडलिंग से बाहर हैं, तो आप अभी भी कर सकते हैं:

import os
import signal

sig = getattr(signal, "SIGKILL", signal.SIGTERM)
os.kill(os.getpid(), sig)

0

Google क्लाउड VM उदाहरण + फ्लास्क ऐप

मैंने अपने फ्लास्क एप्लिकेशन को Google क्लाउड प्लेटफ़ॉर्म वर्चुअल मशीन पर होस्ट किया। मैंने ऐप का उपयोग करना शुरू कर दिया python main.pyथा लेकिन समस्या ctrl + c सर्वर को रोकने के लिए काम नहीं करती थी।

यह कमांड $ sudo netstat -tulnp | grep :5000सर्वर को समाप्त करता है।

मेरा फ्लास्क ऐप डिफ़ॉल्ट रूप से पोर्ट 5000 पर चलता है।

नोट: मेरा VM उदाहरण Linux 9 पर चल रहा है।

इसके लिए काम करता है। अन्य प्लेटफार्मों के लिए परीक्षण नहीं किया गया है। यदि यह अन्य संस्करणों के लिए भी काम करता है तो अपडेट या टिप्पणी करने के लिए स्वतंत्र महसूस करें।


-1

विंडोज के लिए, फ्लास्क सर्वर को रोकना / मारना काफी आसान है -

  1. गोटो टास्क मैनेजर
  2. फ्लास्क ask१ ask
  3. चयन करें और प्रक्रिया समाप्त करें

10
आपके कंप्यूटर पर पावर बटन काफी प्रभावी है और साथ ही साथ हाहा
माइकल ग्रीन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.