সিটিআরএল-সি ব্যবহার না করে ফ্ল্যাশ অ্যাপ্লিকেশনটি কীভাবে বন্ধ করবেন


108

আমি একটি কমান্ড প্রয়োগ করতে চাই যা ফ্লাস্ক-স্ক্রিপ্ট ব্যবহার করে ফ্লাস্ক অ্যাপ্লিকেশন বন্ধ করতে পারে। আমি সমাধানটি কিছুক্ষণ অনুসন্ধান করেছি searched ফ্রেমওয়ার্কটি "app.stop ()" এপিআই সরবরাহ করে না, এটি কীভাবে কোড করবেন তা সম্পর্কে আমি আগ্রহী। আমি উবুন্টু 12.10 এবং পাইথন 2.7.3 এ কাজ করছি।


আপনার স্ক্রিপ্ট থেকে আপনার অ্যাপ্লিকেশনটি বন্ধ করতে সক্ষম হওয়া দরকার কেন? (কাজের জন্য সর্বোত্তম সরঞ্জাম আপনি যা করতে চেষ্টা করছেন তার উপর নির্ভর করবে)।
সান ভিইরা

সিরিয়াসলি, আপনি এখানে কি করার চেষ্টা করছেন? আপনি যদি উন্নয়নের জন্য ডেভরভারের কথা বলছেন তবে এটিকে বন্ধ করা পুরোপুরি ঠিক। উত্পাদনে আপনি এর মতো স্থাপনা করেন না এবং আপনি যে কোনও সময় কোনও অনুরোধ থামাতে পারেন, যাতে "অ্যাপটি চলমান বন্ধ করে দেয়"।
Ignas Butėnas

@ সানভিয়েরা আমি এটি জানতে চাইলে এর কোনও সমাধান আছে কিনা তা জানতে চাই।
Vic

@ ইন্নাসবি। আমি এখনই আমার মেশিনে একটি রেস্টস্টুল সার্ভিস বিকাশ করছি। আমি একটি প্রকল্পে কাজ করছি সম্ভবত এটি আমাকে কোন মেশিন মোতায়েন করা উচিত তা চয়ন করতে সহায়তা করবে I কেবলমাত্র প্রক্রিয়াটি হত্যা করে শটডাউন আমি বুঝতে পারি।
Vic

4
@ শ্রুতিক, তবে আপনি প্রযোজনায় অ্যাপ.আরুন () ব্যবহার করবেন না। app.run () কেবল বিকাশের জন্য এবং বিকাশের সময় আপনার অ্যাপ্লিকেশন পরীক্ষা করতে ব্যবহৃত হয়। উত্পাদনে ফ্লাস্ক চালানোর বিভিন্ন উপায় রয়েছে, উদাহরণস্বরূপ এখানে আরও পাওয়া যাবে flask.pocoo.org/docs/quickstart/#deploying-to-a-web-server এবং যদি আপনি ইতিমধ্যে এরকমভাবে কিছু স্থাপন করেন (তাই আমি ভুল বুঝেছি প্রশ্ন), ফ্লাস্কে আসা অনুরোধ পরিবেশন বন্ধ করার উপায়টি হ'ল HTTP সার্ভারটি এটি পরিবেশন করছে stop
Ignas Butėnas

উত্তর:


128

আপনি যদি কেবল আপনার ডেস্কটপে সার্ভার চালাচ্ছেন তবে আপনি সার্ভারটি মেরে ফেলার জন্য একটি শেষ পয়েন্টটি প্রকাশ করতে পারেন ( শিটডাউন দ্য সরল সার্ভারে আরও পড়ুন ):

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()

আমাকে জানতে দা্ও এটা সাহয্য করে কি - না।


18
আপনি কি জানেন যে কোনও অনুরোধের প্রসঙ্গের প্রয়োজন ছাড়াই 'werkzeug.server.shutdown' সম্পত্তি পাওয়ার কোনও উপায় আছে কিনা?
আকাতকিনসন

4
এটি কাজ করতে আমাকে রুট পদ্ধতিটি 'GET' এ পরিবর্তন করতে হয়েছিল।
সিএস

4
সম্পূর্ণতার জন্য এই জবাবটি ফাংশনটি অনুপস্থিত যা আপনি শাটডাউনটি করার জন্য একটি অনুরোধ প্রসঙ্গে বাইরে কল করবেন, যা সার্ভারের কাছে এইচটিটিপি অনুরোধের চেয়ে বেশি কিছু হবে না (যা স্থানীয়ভাবে / স্থানীয়ভাবে যেতে পারে)
জেমস হাচিসন

4
এর সাথে methods='POST', আমি একটি 405 Method not allowedত্রুটি পেয়েছি , যদিও পদ্ধতিগুলি = 'জিইটি'` এর সাথে, এটি @ সিএসসের পরামর্শ অনুসারে কাজ করে।
চটপটি বিন বিন

4
এডাব্লুএস ইলাস্টিক বিয়ানস্টালকের জন্য আমার পক্ষে কাজ হয়নি। স্থানীয়ভাবে ভাল কাজ করেছেন
আন্দ্রে বুলেজিউক

35

আমি থ্রেড ব্যবহার করে কিছুটা আলাদা করেছি

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()

আমি এটি বিশ্রামপ্রাপ্ত এপিআইয়ের শেষ পরীক্ষা শেষ করতে ব্যবহার করি, যেখানে আমি পাইথন রিকোয়েস্টস লাইব্রেরি ব্যবহার করে অনুরোধ পাঠাতে পারি।


4
আমি অন্যান্য জিনিসগুলি কাজ করার ব্যবস্থা করে নি তবে এই সমাধানটি দুর্দান্ত কাজ করে! অসংখ্য ধন্যবাদ! অন্যান্য লোকের জন্য: এটি ফ্লাস্ক বিশ্রামের সাথেও কাজ করে!
জোরিক স্লিজস্টার

আমি অন্য একটি অনুরোধের সাথে এটি আঘাত না করা পর্যন্ত এটি উইন্ডোতে অবরুদ্ধ বলে মনে হচ্ছে ... এর আশপাশে কোনওভাবেই?
ক্লাউডিয়ু

পাইথন ৩.6.২ সহ লিনাক্স বাদে আমার @ ক্লাউডিউর মতো একই সমস্যা রয়েছে
মাইক্রোস্কোপ

আমি জানি না কেন এটি গৃহীত হয়নি, তবে এটি সবচেয়ে পরিষ্কার বলে মনে হয় এবং কোনও অতিরিক্ত নির্ভরতা ছাড়াই দুর্দান্ত কাজ করে। অনেক ধন্যবাদ.
এরিক রিড

21

এটি কিছুটা পুরানো থ্রেড, তবে যদি কেউ ব্যাকগ্রাউন্ডে চলমান কোনও স্ক্রিপ্ট থেকে পরীক্ষা করে, বেসিক ফ্লেস্ক অ্যাপটি পরীক্ষা করে, শিখতে বা পরীক্ষা করে থাকেন, তবে এটি বন্ধ করার দ্রুততম উপায় হ'ল আপনি যে অ্যাপটি চালাচ্ছেন তার বন্দরে চলমান প্রক্রিয়াটি হ্রাস করা to চালু. দ্রষ্টব্য: আমি সচেতন যে লেখক অ্যাপটি হত্যা বা বন্ধ না করার উপায় খুঁজছেন। তবে এটি এমন কাউকে সাহায্য করতে পারে যা শিখছে।

sudo netstat -tulnp | grep :5001

আপনি এই জাতীয় কিছু পাবেন।

tcp 0 0 0.0.0.0:5001 0.0.0.0:* তালিকাভুক্ত 28834 / পাইথন

অ্যাপটি বন্ধ করতে, প্রক্রিয়াটি হত্যা করুন

sudo kill 28834

sudo kill -9 28834প্রক্রিয়াটি মেরে ফেলার আগে আমাকে ব্যবহার করতে হয়েছিল।
উদো ই।

17

আমার পদ্ধতিটি বাশ টার্মিনাল / কনসোলের মাধ্যমে এগিয়ে নেওয়া যেতে পারে

1) চালান এবং প্রক্রিয়া নম্বর পেতে

$ ps aux | grep yourAppKeywords

2 ক) প্রক্রিয়াটি মেরে ফেলুন

$ kill processNum

2 বি) উপরে কাজ না করা হলে প্রক্রিয়াটি মেরে ফেলুন

$ kill -9 processNum

10
আমি প্রায় নিশ্চিত যে প্রশ্নটি "একটি প্রক্রিয়াটি কীভাবে হত্যা করা যায়" নয় এবং সমস্যাটি হ'ল সিটিআরএল + সি করা এটি হত্যা করে না। বিটিডব্লিউ, আমি kill -9 `lsof -i:5000 -t`কেবল ১ টি অ্যাপ ব্যতীত অন্য কোনও পোর্ট ব্যবহার করতে পারি না এবং এটি সহজ হচ্ছে c
এম

10

অন্যরা যেমন নির্দেশ করেছে, আপনি কেবল 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..."

4
এটি কাজ করে কিন্তু অনুভব করে ... খুব হ্যাকি। আমি জানি এটি কিছুক্ষণ হয়ে গেছে, তবে আপনি নিজের কাছে কোনও অনুরোধ না প্রেরণে কি কখনও এইরকম পরিষ্কার উপায় খুঁজে পেয়েছেন?
রসালো

7

এটি একটি পুরানো প্রশ্ন, তবে গুগলিং আমাকে কীভাবে এটি সম্পাদন করতে পারে সে সম্পর্কে কোনও অন্তর্দৃষ্টি দেয়নি।

কারণ আমি এখানে কোডটি সঠিকভাবে পড়িনি ! (দোহ!) এটি যা করে তা হ'ল RuntimeErrorযখন কোনও নেই raisewerkzeug.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) পুনরুদ্ধার ব্যর্থতা: সংযোগটি পুনরায় সেট করা হয়েছে"। ফ্ল্যাশ সমাধান করার জন্য প্রতিক্রিয়া ফিরিয়ে দেওয়ার পরে কোনও ফাংশন কার্যকর করতেও পারে।
samm

@ স্যাম, এই প্রশ্ন থেকে উপসংহারটি কি সম্ভব না যদি আপনি আলাদা থ্রেড শুরু না করেন, তাই না? তারপরে আপনি কীভাবে সেই ভিন্ন থ্রেড থেকে ফ্লাস্ক সার্ভারটি বন্ধ করবেন?
জুরজি


2

আপনি যদি সিএলআই-তে কাজ করছেন এবং কেবলমাত্র একটি ফ্লাস্ক অ্যাপ / প্রক্রিয়া চলছে (বা বরং, আপনি কেবল আপনার সিস্টেমে চলমান যে কোনও ফ্লাস্ক প্রক্রিয়াটি হত্যা করতে চান ), আপনি এটি দিয়ে এটি হত্যা করতে পারেন:

kill $(pgrep -f flask)


1

আপনি যদি অনুরোধ-প্রতিক্রিয়া হ্যান্ডলিংয়ের বাইরে থাকেন তবে আপনি এখনও করতে পারেন:

import os
import signal

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

1

যদি অন্য কেউ যদি উইন 32 পরিষেবাটির মধ্যে ফ্লাস্ক সার্ভারটি বন্ধ করতে চান তবে তা এখানে। এটি বেশ কয়েকটি পদ্ধতির এক বিস্ময়কর সমন্বয়, তবে এটি ভালভাবে কাজ করে। মূল ধারণা:

  1. এগুলি shutdownশেষ বিন্দু যা গ্রেফিউস শাটডাউনের জন্য ব্যবহার করা যেতে পারে। দ্রষ্টব্য : এটি নির্ভর করে request.environ.getযা কেবলমাত্র ওয়েব অনুরোধের প্রসঙ্গে (অভ্যন্তরীণ @app.routeফাংশন) এর মধ্যে ব্যবহারযোগ্য
  2. win32service এর SvcStopপদ্ধতিটি requestsপরিষেবাটিতে নিজেই HTTP অনুরোধ করতে ব্যবহার করে।

myservice_svc.py

import win32service
import win32serviceutil
import win32event
import servicemanager
import time
import traceback
import os

import myservice


class MyServiceSvc(win32serviceutil.ServiceFramework):
    _svc_name_ = "MyServiceSvc"                       # NET START/STOP the service by the following name
    _svc_display_name_ = "Display name"  # this text shows up as the service name in the SCM
    _svc_description_ = "Description" # this text shows up as the description in the SCM

    def __init__(self, args):
        os.chdir(os.path.dirname(myservice.__file__))
        win32serviceutil.ServiceFramework.__init__(self, args)

    def SvcDoRun(self):
        # ... some code skipped
        myservice.start()

    def SvcStop(self):
        """Called when we're being shut down"""
        myservice.stop()
        # tell the SCM we're shutting down
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STOPPED,
                              (self._svc_name_, ''))

if __name__ == '__main__':
    os.chdir(os.path.dirname(myservice.__file__))
    win32serviceutil.HandleCommandLine(MyServiceSvc)

myservice.py

from flask import Flask, request, jsonify

# Workaround - otherwise doesn't work in windows service.
cli = sys.modules['flask.cli']
cli.show_server_banner = lambda *x: None

app = Flask('MyService')

# ... business logic endpoints are skipped.

@app.route("/shutdown", methods=['GET'])
def shutdown():
    shutdown_func = request.environ.get('werkzeug.server.shutdown')
    if shutdown_func is None:
        raise RuntimeError('Not running werkzeug')
    shutdown_func()
    return "Shutting down..."


def start():
    app.run(host='0.0.0.0', threaded=True, port=5001)


def stop():
    import requests
    resp = requests.get('http://localhost:5001/shutdown')

0

গুগল ক্লাউড ভিএম উদাহরণ + ফ্লাস্ক অ্যাপ

আমি গুগল ক্লাউড প্ল্যাটফর্ম ভার্চুয়াল মেশিনে আমার ফ্লাস্ক অ্যাপ্লিকেশনটি হোস্ট করেছি। আমি অ্যাপটি ব্যবহার করে শুরু করেছি python main.pyতবে সমস্যাটি সিটিআরএল + সি সার্ভারটি থামানোর জন্য কাজ করে নি।

এই কমান্ডটি $ sudo netstat -tulnp | grep :5000সার্ভারটি সমাপ্ত করে।

আমার ফ্লাস্ক অ্যাপটি 5000 পোর্টে ডিফল্টরূপে চলে।

দ্রষ্টব্য: আমার ভিএম উদাহরণটি লিনাক্স 9 এ চলছে।

এটি এই জন্য কাজ করে। অন্যান্য প্ল্যাটফর্মের জন্য পরীক্ষা করা হয়নি। এটি আপডেট বা মন্তব্য করতে দ্বিধা বোধ করুন যদি এটি অন্যান্য সংস্করণেও কাজ করে।


0

একটি পাইথন সমাধান

সঙ্গে চালান: python kill_server.py

এটি শুধুমাত্র উইন্ডোজের জন্য । পিআইডি দ্বারা টাস্ককিল দিয়ে সার্ভারদের হত্যা করে, নেটস্ট্যাট সহ একত্রিত।

# kill_server.py

import os
import subprocess
import re

port = 5000
host = '127.0.0.1'
cmd_newlines = r'\r\n'

host_port = host + ':' + str(port)
pid_regex = re.compile(r'[0-9]+$')

netstat = subprocess.run(['netstat', '-n', '-a', '-o'], stdout=subprocess.PIPE)  
# Doesn't return correct PID info without precisely these flags
netstat = str(netstat)
lines = netstat.split(cmd_newlines)

for line in lines:
    if host_port in line:
        pid = pid_regex.findall(line)
        if pid:
            pid = pid[0]
            os.system('taskkill /F /PID ' + str(pid))
        
# And finally delete the .pyc cache
os.system('del /S *.pyc')

যদি আপনার ফেভিকন / সূচী HTML টি লোডিংয়ে পরিবর্তনগুলি সমস্যা হয় (যেমন পুরানো সংস্করণগুলি ক্যাশে করা হয়), তবে ক্রোমেও "ব্রাউজিং ডেটা> চিত্রগুলি এবং ফাইলগুলি সাফ করুন" চেষ্টা করুন

উপরের সমস্তটি করা, এবং শেষ পর্যন্ত আমার ফ্লাস্ক অ্যাপ্লিকেশনটি চালিয়ে যাওয়ার জন্য আমার ফেভিকনটি পেয়ে গেল।


-3

উইন্ডোজের জন্য, ফ্লাস্ক সার্ভারটি বন্ধ / হত্যা করা বেশ সহজ -

  1. গোটো টাস্ক ম্যানেজার
  2. Flask.exe খুঁজুন
  3. প্রক্রিয়া নির্বাচন করুন এবং শেষ করুন

13
আপনার কম্পিউটারের পাওয়ার বোতামটি হাহাহা
মাইকেল গ্রীন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.