2

Am currently implementing a REST interface to my web application from a desktop application that compliments the service. We are using Python with Flask for the REST server implementation.

We have a situation where the Java client will request a POST and the python server-side will process the post just fine up until it needs to connect to the MySQL database.

Here is the python/flask code:

@app.route("/update_project/<project_data>", methods=['GET','POST'])
def updateWPProject(project_data):
    """project_data = user+++++pw+++++pj_jsondoc.
    This will update an existing project data or insert a non-existant project data item."""
    usrpw = project_data.split("+++++")
    dblogin = wplogin(usr=usrpw[0], pw=usrpw[1])
    if dblogin[0] == 'SUCCESS':
        db_name = dblogin[1][0].strip()
        db_user = dblogin[1][1].strip()
        db_pw = dblogin[1][2].strip()
        if flask.request.method == 'POST':
            fname = flask.request.form['fName']
            if fname:
                pj = Project()
                try:
                    pj = json.loads(fname)
                except TypeError:
                    sys.stdout.write("JSON conversion error...%s" % sys.exc_info()[0])
                except AttributeError:
                    sys.stdout.write("JSON conversion error...%s" % sys.exc_info()[0])

                updateProject(db_name,db_user,db_pw,pj)
                #return redirect(url_for('/'))
    else:
        return 'Login failure.'
    pass

This works just fine up until it gets to the 'updateProject(db_name,db_user,db_pw,pj)' line. It will then go to that function, and return a 500 at 'cursor=conn.cursor()' without finishing the function.

    def updateProject(dbname, dbuser, dbpw, pj):
        """Updates or inserts a project record is not exists. PJ passed as an argument is a Project object."""

        try:
            conn = getConnection(dbuser, dbpw, dbname)
            cursor = conn.cursor()
        except:
            sys.stdout.write("MySQL connection error...%s" % sys.exc_info()[0])

        sql_stmt = """INSERT INTO projects( projNo, projName, worksteplabel, workstep1label, workstep2label, workstep3label, resultlabel, result1label, result2label, result3label, projectowner, dbname, dblogin, dbpw, role, preference1, preference2, preference3 )
VALUES (
'projNo', 'projName', 'wslabel', 'wslabel', 'wslabel', 'wslabel', 'rlabel', 'rlabel', 'rlabel', 'rlabel', 'pjowner', 'dbname', 'dblogin', 'dbpw', 'role', 'pref1', 'pref2', 'pref3'
) ON DUPLICATE
KEY UPDATE projName = 'projName',
worksteplabel = 'wslabel',
workstep1label = 'wslabel',
workstep2label = 'wslabel',
workstep3label = 'wslabel',
resultlabel = 'rlabel',
result1label = 'rlabel',
result2label = 'rlabel',
result3label = 'rlabel',
projectowner = 'pjowner',
dbname = 'dbname',
dblogin = 'dblogin',
dbpw = 'dbpw',
role = 'role',
preference1 = 'pref1',
preference2 = 'pref2',
preference3 = 'pref3' )

        try:
            cursor.execute(sql_stmt)
            return 'SUCCESS'
        except MySQLdb.Error:
            sys.stdout.write("MySQLdb error...%s" % sys.exc_info()[0])
            return 'FAILURE'

On the Java client side, I am using the following code to send the POST request and data from the client.

public void DB_NewProjectREST(ProjectData proj, WPUser usr) {
        // public static String excutePost(String targetURL, String urlParameters)
        //URL url;
        HttpURLConnection connection = null;  

        ///First, all the GSON/JSon stuff up front
        Gson gson = new Gson();
        //convert java object to JSON format
        String json = gson.toJson(proj);
      //Then credentials and send string
        String send_string = usr.getUserEmail()+"+++++"+usr.getUserHash();

        try {
          //Create connection
          URL url = new URL("http://127.0.0.1:5000/update_project/"+send_string);
          String urlParameters = "fName=" + URLEncoder.encode(json, "UTF-8");

          connection = (HttpURLConnection)url.openConnection();
          connection.setRequestMethod("POST");
          connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

          connection.setRequestProperty("Content-Length", "" + Integer.toString(urlParameters.getBytes().length));
          connection.setRequestProperty("Content-Language", "en-US");  

          connection.setUseCaches(false);
          connection.setDoInput(true);
          connection.setDoOutput(true);

          //Send request
          DataOutputStream wr = new DataOutputStream (connection.getOutputStream ());
          wr.writeBytes (urlParameters);
          wr.flush ();
          wr.close ();

          //Get Response    
          InputStream is = connection.getInputStream();
          BufferedReader rd = new BufferedReader(new InputStreamReader(is));
          String line;
          StringBuffer response = new StringBuffer(); 
          while((line = rd.readLine()) != null) {
            response.append(line);
            response.append('\r');
          }
          rd.close();
        } catch (Exception e) {
            e.printStackTrace();
            //return null;
        }finally {
            if(connection != null) {
                connection.disconnect(); 
            }
        }
    }

It seems like I have to send some kind of response (for the input stream) back to the client and that is where my python code is abruptly returning.(?) The data is getting from the java client to the python/flask code, so is there any way of returning quick 'OK' and continue processing the db update. Or, is the cursor connection call in the python updateProject function interfering with the http connection somehow?

Any help appreciated.

1 Answer 1

2

Here is the code on the python server side that works, but not sure if it's the 'right' way to do it....

@app.route("/update_project/<project_data>", methods=['GET','POST'])
def updateWPProject(project_data):
    """project_data = user+++++pw+++++pj_jsondoc.
    This will update an existing project data or insert a non-existant project data item."""
    usrpw = project_data.split("+++++")
    dblogin = wplogin(usr=usrpw[0], pw=usrpw[1])
    if dblogin[0] == 'SUCCESS':
        db_name = dblogin[1][0].strip()
        db_user = dblogin[1][1].strip()
        db_pw = dblogin[1][2].strip()
        if flask.request.method == 'POST':
            fname = flask.request.form['fName']
            if fname:
                pj = Project()
                try:
                    pj = json.loads(fname)
                    try:
                        #threading.Thread(target=updateProject, args=(db_name,db_user,db_pw,pj)).start()
                        return Response(updateProject(db_name,db_user,db_pw,pj), direct_passthrough=True)

                    except Exception, errtxt:
                        sys.stdout.write(errtxt)
                    #threading.thread.start_new_thread(updateProject,(db_name,db_user,db_pw,pj))
                except TypeError:
                    sys.stdout.write("JSON conversion error...%s" % sys.exc_info()[0])
                except AttributeError:
                    sys.stdout.write("JSON conversion error...%s" % sys.exc_info()[0])
    else:
        return 'Login failure.'
    pass

Most notably, 'return Response(......' is what solved the challenge. I think.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.