Repository: keras-team/autokeras

Issue:
PermissionError: [Errno 13] Permission denied: '/tmp/autokeras/searcher'
I've encountered with this error
File "/home/me/venv/lib64/python3.6/site-packages/autokeras/classifier.py", line 258, in save_searcher
    pickle.dump(searcher, open(os.path.join(self.path, 'searcher'), 'wb'))
PermissionError: [Errno 13] Permission denied: '/tmp/autokeras/searcher'

I'm running this on linux server on virtual environment. Could you please give me the suggestion?


Discussion:
A hint, just specifies a new approachable path when creating the classifier is ok. You can check it by referring docstring by help() method.
Auto Keras may figure out a better default path.
It would be better if it is OS aware.

Resolving patch:
diff --git a/autokeras/constant.py b/autokeras/constant.py
--- a/autokeras/constant.py
+++ b/autokeras/constant.py
@@ -1,6 +1,4 @@
 class Constant:
-    DEFAULT_SAVE_PATH = '/tmp/autokeras/'
-
     # Data
 
     VALIDATION_SET_SIZE = 0.08333
diff --git a/autokeras/image_classifier.py b/autokeras/image_classifier.py
--- a/autokeras/image_classifier.py
+++ b/autokeras/image_classifier.py
@@ -1,24 +1,22 @@
+import csv
 import os
 import pickle
-import csv
 import time
 from functools import reduce
 
-import torch
-
-import scipy.ndimage as ndimage
-
 import numpy as np
+import scipy.ndimage as ndimage
+import torch
 from sklearn.metrics import accuracy_score
 from sklearn.model_selection import train_test_split
 from torch.utils.data import DataLoader
 
+from autokeras.classifier import Classifier
 from autokeras.constant import Constant
 from autokeras.metric import Accuracy
 from autokeras.preprocessor import OneHotEncoder, DataTransformer
 from autokeras.search import BayesianSearcher, train
-from autokeras.utils import ensure_dir, has_file, pickle_from_file, pickle_to_file
-from autokeras.classifier import Classifier
+from autokeras.utils import ensure_dir, has_file, pickle_from_file, pickle_to_file, temp_folder_generator
 
 
 def _validate(x_train, y_train):
@@ -126,7 +124,7 @@ class ImageClassifier(Classifier):
         augment: A boolean value indicating whether the data needs augmentation.
     """
 
-    def __init__(self, verbose=False, path=Constant.DEFAULT_SAVE_PATH, resume=False, searcher_args=None, augment=None):
+    def __init__(self, verbose=False, path=None, resume=False, searcher_args=None, augment=None):
         """Initialize the instance.
 
         The classifier will be loaded from the files in 'path' if parameter 'resume' is True.
@@ -144,6 +142,9 @@ def __init__(self, verbose=False, path=Constant.DEFAULT_SAVE_PATH, resume=False,
         if searcher_args is None:
             searcher_args = {}
 
+        if path is None:
+            path = temp_folder_generator()
+
         if augment is None:
             augment = Constant.DATA_AUGMENTATION
 
diff --git a/autokeras/utils.py b/autokeras/utils.py
--- a/autokeras/utils.py
+++ b/autokeras/utils.py
@@ -1,11 +1,11 @@
 import os
-import sys
 import pickle
-import numpy as np
+import sys
+import tempfile
 from copy import deepcopy
 
+import numpy as np
 import torch
-
 from torch.utils.data import DataLoader
 
 from autokeras.constant import Constant
@@ -192,3 +192,11 @@ def pickle_from_file(path):
 
 def pickle_to_file(obj, path):
     pickle.dump(obj, open(path, 'wb'))
+
+
+def temp_folder_generator():
+    sys_temp = tempfile.gettempdir()
+    path = os.path.join(sys_temp, 'autokeras')
+    if not os.path.exists(path):
+        os.makedirs(path)
+    return path


Test patch:
diff --git a/tests/test_image_classifier.py b/tests/test_image_classifier.py
--- a/tests/test_image_classifier.py
+++ b/tests/test_image_classifier.py
@@ -4,7 +4,6 @@
 import pytest
 
 from autokeras.image_classifier import *
-from autokeras.constant import Constant
 from tests.common import clean_dir, MockProcess
 
 
@@ -148,3 +147,9 @@ def test_fit_csv_file(_, _1):
     assert len(clf.load_searcher().history) == 1
     assert len(results) == 5
     clean_dir(os.path.join(path, "temp"))
+
+
+@patch('autokeras.image_classifier.temp_folder_generator', return_value='dummy_path/')
+def test_init_image_classifier_with_none_path(_):
+    clf = ImageClassifier()
+    assert clf.path == 'dummy_path/'
diff --git a/tests/test_utils.py b/tests/test_utils.py
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -1,7 +1,8 @@
+from unittest.mock import patch
+
 from autokeras.generator import DefaultClassifierGenerator
 from autokeras.metric import Accuracy
-from autokeras.utils import *
-
+from autokeras.utils import ModelTrainer, temp_folder_generator
 from tests.common import get_processed_data
 
 
@@ -9,3 +10,9 @@ def test_model_trainer():
     model = DefaultClassifierGenerator(3, (28, 28, 3)).generate().produce_model()
     train_data, test_data = get_processed_data()
     ModelTrainer(model, train_data, test_data, Accuracy, False).train_model(max_iter_num=3)
+
+
+@patch('tempfile.gettempdir', return_value="dummy_path/")
+def test_temp_folder_generator(_):
+    path = temp_folder_generator()
+    assert path == "dummy_path/autokeras"