Cannot Deploy Fastai Model in Webapp (Google Cloud Platform) - NotImplementedError: cannot instantiate 'WindowsPath' on your system

So I’ve been trying to implement a fastai model into a Flask model on Google Cloud Platform, but I keep having issues with my exported model since I built my model on Windows. Note that I’ve tried to use the work around that exists for converting between PosixPaths and WindowsPaths (assuming I understand this correctly), but it does not seem to work when I deploy to GCP.

Edit: I have attempted to recreate the entire model on a Google Colab notebook assuming that my operating system was the issue, but I receive the exact same error even after doing this and replacing the model.pkl file. Does fastai not deal very well with os or something?

app.py:

import imghdr
import os
from fastai.vision.all import *
import sys
from flask import Flask, render_template, request, redirect, url_for, abort, \
    send_from_directory
from werkzeug.utils import secure_filename
import pathlib

app = Flask(__name__, static_url_path='', 
            static_folder='./static',
            template_folder='./templates')
app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024
app.config['UPLOAD_EXTENSIONS'] = ['.jpg', '.png', '.gif','.jpeg']
app.config['UPLOAD_PATH'] = '/tmp'

temp = pathlib.PosixPath
pathlib.PosixPath = pathlib.WindowsPath

try:
  import googleclouddebugger
  googleclouddebugger.enable(
    breakpoint_enable_canary=True
  )
except ImportError:
  pass

def validate_image(stream):
    header = stream.read(512)  # 512 bytes should be enough for a header check
    stream.seek(0)  # reset stream pointer
    format = imghdr.what(None, header)
    if not format:
        return None
    return '.' + (format if format != 'jpeg' else 'jpg')

def deleteImages():
    for f in os.listdir(app.config['UPLOAD_PATH']):
        file_ext = os.path.splitext(f)[1:]
        if file_ext in app.config['UPLOAD_EXTENSIONS']:
            os.remove(os.path.join(app.config['UPLOAD_PATH'], f))

def predict(img_path):
    temp = pathlib.WindowsPath
    pathlib.WindowsPath = pathlib.PosixPath
    
    learn = load_learner('./static/model1.pkl')
    
    pathlib.WindowsPath = temp
    pred_classes, pred_idx, probs = learn.predict(img_path)
    return pred_classes, pred_idx, probs

@app.route('/')
def index():
    if os.listdir(app.config['UPLOAD_PATH']):
        deleteImages()
    files = os.listdir(app.config['UPLOAD_PATH'])
    return render_template('index.html', files=files)

@app.route('/', methods=['POST'])
def upload_files():
    if os.listdir(app.config['UPLOAD_PATH']):
        deleteImages()
    uploaded_file = request.files['file']
    filename = secure_filename(uploaded_file.filename)
    if filename != '':
        file_ext = os.path.splitext(filename)[1]
        if file_ext not in app.config['UPLOAD_EXTENSIONS'] or \
                file_ext != validate_image(uploaded_file.stream):
            abort(400)
        img_path = os.path.join(app.config['UPLOAD_PATH'], filename)
        uploaded_file.save(os.path.join(app.config['UPLOAD_PATH'], filename))
        pred_classes, pred_idx, probs = predict(img_path)
        pred_classes = ', '.join([x.capitalize() for x in pred_classes])
        probs = ', '.join([str(round(x, 4)) for x in probs[pred_idx].tolist()])
        files = os.listdir(app.config['UPLOAD_PATH'])
    return render_template('index.html', files=files, pred_class=pred_classes,
        outputs=str(probs))

@app.route('/uploads/<filename>')
def upload(filename):
    return send_from_directory(app.config['UPLOAD_PATH'], filename)

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

This is the error log I get from GCP:

Traceback (most recent call last):
  File "/env/lib/python3.6/site-packages/flask/app.py", line 2073, in wsgi_app
    response = self.full_dispatch_request()
  File "/env/lib/python3.6/site-packages/flask/app.py", line 1518, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/env/lib/python3.6/site-packages/flask/app.py", line 1516, in full_dispatch_request
    rv = self.dispatch_request()
  File "/env/lib/python3.6/site-packages/flask/app.py", line 1502, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/home/vmagent/app/app.py", line 61, in upload_files
    pred_classes, pred_idx, probs = predict(img_path)
  File "/home/vmagent/app/app.py", line 37, in predict
    learn = load_learner('./static/model1.pkl')
  File "/env/lib/python3.6/site-packages/fastai/learner.py", line 384, in load_learner
    res = torch.load(fname, map_location='cpu' if cpu else None, pickle_module=pickle_module)
  File "/env/lib/python3.6/site-packages/torch/serialization.py", line 594, in load
    return _load(opened_zipfile, map_location, pickle_module, **pickle_load_args)
  File "/env/lib/python3.6/site-packages/torch/serialization.py", line 853, in _load
    result = unpickler.load()
  File "/opt/python3.6/lib/python3.6/pathlib.py", line 1004, in __new__
    % (cls.__name__,))
NotImplementedError: cannot instantiate 'WindowsPath' on your system
1 Like

Hi Sarah
Does this help (cannot instantiate 'WindowsPath' on your system · Issue #1482 · fastai/fastai · GitHub).
Regards Conwyn

1 Like

Add this line of code to the start of your app.py

import pathlib
plt = platform.system()
if plt == 'Linux': pathlib.WindowsPath = pathlib.PosixPath
1 Like