francesco
francesco

Reputation: 57

Does apache or flask need special setting for a web application which use pickle?

In Visual Studio i have realized a web api in python with flask which uses pickle to load an SVM, the overall system has been then deployed on apache. My problem is that when i try the system debugging from visual studio everything works fine, but when i load it on the apache server the page just load wihtout giving either results or errors.
The code of the web application is reported below:

import PythonApplication2 as ml
import requests
import json
from flask_cors import CORS, cross_origin
from flask import Flask, jsonify, request, render_template
import pickle as pk

MLwebapp = Flask(__name__)

left_model=pk.load(open('C:\\myapp\\app\\left_classifier.pickle','rb'))
right_model=pk.load(open('C:\\myapp\\app\\right_classifier.pickle','rb'))

wsgi_app = MLwebapp.wsgi_app
# Make the WSGI interface available at the top level so wfastcgi can get it.


@MLwebapp.route('/')
def start():
    return render_template('WebPage1.html')

@MLwebapp.route('/test')
def hello():
    number='203'
    list_left=[]
    list_right=[]
    for i in range(0,19):
        data=requests.get('url here'+number+str(i))
        json_data=json.loads(data.json())
        number=json.loads(json_data['Dati'])
        left_temp=[x[1] for x in number]
        right_temp=[z[2] for z in number]
        list_left.append(left_temp)
        list_right.append(right_temp)
    patient_vector_right,patient_vector_left=ml.funzionetotale(list_left,list_right)
    patient_vector_left=patient_vector_left.reshape(1, -1)
    patient_vector_right=patient_vector_right.reshape(1, -1)
    prediction=ml.machine_learning(patient_vector_left,patient_vector_right,left_model,right_model)
    risultato="Risultato: " + prediction
    return jsonify(risultato)

if __name__ == '__main__':
    import os
    HOST = os.environ.get('SERVER_HOST', 'localhost')
    try:
        PORT = int(os.environ.get('SERVER_PORT', '8080'))
    except ValueError:
        PORT = 8080
    MLwebapp.run(HOST, PORT)

The template WebPage1.html is very simple with just a button for testing the system:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Ciao</title>
</head>
<body>
    <h1>Test button2</h1>
    <form method="get" action="/test">
        <input type="submit" value="Press for test"/>
    </form>
</body>
</html>

Regarding settings for apache and WSGI:
In httpd.conf:

added  
LoadFile "c:/program files (x86)/microsoft visual studio/shared/python36_64/python36.dll"
LoadModule wsgi_module "c:/myapp/flask/lib/site-packages/mod_wsgi/server/mod_wsgi.cp36-win_amd64.pyd"
WSGIPythonHome "c:/myapp/flask"  
Removed the # from LoadModule cgi_module modules/mod_cgi.so  
added  
Listen 8080
Removed the # from conf/extra/httpd-vhosts.conf

In httpd-vhosts.conf:

added  
<VirtualHost *:8080>
        ServerAdmin localhost
        ServerName  localhost:8080
        WSGIScriptAlias / "C:/myapp/app/web.wsgi"
        DocumentRoot "C:/myapp/app"
        <Directory "C:/myapp/app">
                Require all granted
        </Directory>
        ErrorLog "C:/myapp/app/logs/error.log"
        CustomLog "C:/myapp/app/logs/access.log" common
</VirtualHost>

Created web.wsgi file in the app root with:

import sys

sys.path.insert(0, 'C:/myapp/app')

from app import MLwebapp as application

With some tests i've understand that the problem lies in the relation between wsgi and pickle, but i couldn't find a guide or post which could help me resolve my problem.

Upvotes: 0

Views: 181

Answers (1)

Dave W. Smith
Dave W. Smith

Reputation: 24966

One way forward is to rule out pickle being an issue. An easy way to do that is to catch any exception that occurs when trying to load the pickle, and pass those along to your starting template. Something like

try:
    left_model=pk.load(open('C:\\myapp\\app\\left_classifier.pickle','rb'))
    left_model_ex = None
except Exception as ex:
    left_model = None
    left_model_ex = repr(ex)

(and the same for right_model)

pass left_model_ex into the template, which do something like

{% if left_model_ex %}<div>{{ left_model_ex }}</div>{% endif %}

where it'll be visible.

Upvotes: 1

Related Questions