Abc123
Abc123

Reputation: 45

Python 3 - Flask Restful API to restart another API

I created a python REST web-service, and it will execute a series of subprocess commands to restart another python REST webservice. But the problem is it doesn't really start my other REST service after I call it.

Here is my code for the REST API :

from flask import Flask, jsonify, request, make_response
from flask_restful import fields, reqparse, abort, Api, Resource
import sqlalchemy
from sqlalchemy.sql import table, column, select, update, insert, delete, func
from sqlalchemy.orm import sessionmaker
import requests
import time
import traceback
import subprocess
import os

app = Flask(__name__)
api = Api(app)

class RestartPython(Resource):
    def get(self):

        command1 = 'fuser -k 9876/tcp'
        proc1 = subprocess.Popen(command1, stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, shell=True)
        proc1.wait()

        print('kill python process done')

        command2 = 'source activate envpy3'
        proc2 = subprocess.Popen(command2, stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, shell=True)
        proc2.wait()

        print('switch python env done')

        command3 = 'python ReceiveCall.py'
        print(command3)
        proc3 = subprocess.Popen(command3, stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, shell=True)
        proc3.wait()

        print('ReceiveCall started')

        return make_response(jsonify({'message': 'Python webservice is restarted', 'status': 'Ok'}), 200)

    api.add_resource(RestartPython, '/restart')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8082, debug=True)

This will works if I just run it without wrapping them in web-service

import subprocess

if __name__ == '__main__':
    command1 = 'fuser -k 9876/tcp'
    proc1 = subprocess.Popen(command1, stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, shell=True)
    proc1.wait()

    print('kill python process done')

    command2 = 'source activate envpy3'
    proc2 = subprocess.Popen(command2, stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, shell=True)
    proc2.wait()

    print('switch python env done')

    command3 = 'python ReceiveCall.py'
    print(command3)
    proc3 = subprocess.Popen(command3, stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, shell=True)
    proc3.wait()

    print('ReceiveCall started')

Any ideas?

Upvotes: 0

Views: 748

Answers (1)

pankaj mishra
pankaj mishra

Reputation: 2615

instead of wait() i would recommend to use communicate() . communicate is used to avoid deadlock wherever pipe is used . Let me know if below modification works for you

from flask import Flask, jsonify, request, make_response
from flask_restful import fields, reqparse, abort, Api, Resource
import sqlalchemy
from sqlalchemy.sql import table, column, select, update, insert, delete, func
from sqlalchemy.orm import sessionmaker
import requests
import time
import traceback
import subprocess
from subprocess import PIPE,Popen
import os

app = Flask(__name__)
api = Api(app)

class RestartPython(Resource):
    def get(self):

        command1 = 'fuser -k 9876/tcp'
        proc1 = subprocess.Popen(command1, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        #proc1.wait()
        (stdout, stderr) = proc1.communicate()

        print '.'.join(stdout)
        print '.'.join(stderr)

        print('kill python process done')

        command2 = 'source activate envpy3'
        proc2 = subprocess.Popen(command2, stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, shell=True)
        #proc2.wait()
        proc2.communicate()

        print('switch python env done')

        command3 = 'python ReceiveCall.py'
        print(command3)
        proc3 = subprocess.Popen(command3, stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, shell=True)
        #proc3.wait()
         proc3.communicate()

        print('ReceiveCall started')

        return make_response(jsonify({'message': 'Python webservice is restarted', 'status': 'Ok'}), 200)

    api.add_resource(RestartPython, '/restart')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8082, debug=True)

Upvotes: 1

Related Questions