Skip to content
This repository was archived by the owner on Apr 16, 2023. It is now read-only.

Commit 191a6da

Browse files
author
Patrick Kuehn
committed
Add docstrings
- Add docstrings for new classes - Remove unused imports
1 parent fa5bd2b commit 191a6da

File tree

9 files changed

+200
-17
lines changed

9 files changed

+200
-17
lines changed

autofocus/predict/app/models/File.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,61 @@
22
from werkzeug import secure_filename
33
from ..app import app
44

5+
56
class File:
7+
"""
8+
Store a file and remove it upon destruction
9+
10+
Parameters:
11+
path: The path to the file
12+
name: Secured filename (Can be empty)
13+
"""
14+
615
def __init__(self, file=None):
16+
"""
17+
Constructor of File
18+
19+
Save the file on the server if a file is given.
20+
21+
Parameters:
22+
file: Uploaded file object from flask
23+
"""
724
if file:
825
self.setFromUploadedFile(file)
926

1027
def __del__(self):
28+
"""
29+
Destructor of File
30+
31+
Remove the file from the server.
32+
"""
1133
os.remove(self.path)
1234

1335
def setFromUploadedFile(self, file):
36+
"""
37+
Save file from uploaded file
38+
39+
Parameters:
40+
file: Uploaded file object from flask
41+
"""
1442
self.name = secure_filename(file.filename)
1543
self.path = os.path.join(app.config["UPLOAD_FOLDER"], self.name)
1644
file.save(self.path)
1745

1846
def setPath(self, path):
47+
"""
48+
Set the path to a saved file
49+
50+
Parameters:
51+
path: Path to the file
52+
"""
1953
self.path = path
2054

2155
def getPath(self):
56+
"""
57+
Return the saved path
58+
59+
Returns:
60+
string: Path to the file
61+
"""
2262
return self.path
Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,44 @@
1-
import time
21
from pathlib import Path
2+
33
from fastai.vision import load_learner, open_image
44

5-
from ..model import predict_single
65

76
MODEL_DIR = Path(__file__).resolve().parents[2] / "models"
87
MODEL_NAME = "multilabel_model_20190407.pkl"
98
model = load_learner(MODEL_DIR, MODEL_NAME)
109
CLASSES = model.data.classes
1110

11+
1212
class Predictor:
13+
"""
14+
Predicts probabilities with the model based on given files
15+
16+
Parameters:
17+
probabilities: Array of probabilities calculated in predict
18+
"""
19+
1320
def predict(self, file):
21+
"""
22+
Predict probabilities of single file
23+
24+
Parameters:
25+
file: File object of image file
26+
"""
1427
image = open_image(file.getPath())
1528
# Get the predictions (output of the softmax) for this image
1629
pred_classes, preds, probs = model.predict(image)
1730
self.probabilities = [prob.item() for prob in probs]
1831

1932
def predict_multiple(self, files):
33+
"""
34+
Predict probabilities of multiple files
35+
36+
Parameters:
37+
files: Dict with File objects of image file
38+
39+
Returns:
40+
dict: Dictionary of probabilities for each file in files
41+
"""
2042
predictions = {}
2143
for key in files:
2244
self.predict(files[key])
@@ -25,4 +47,10 @@ def predict_multiple(self, files):
2547

2648

2749
def getProbabilities(self):
50+
"""
51+
Return formated Probabilities
52+
53+
Returns:
54+
dict: A dictionary of classes to probabilities
55+
"""
2856
return dict(zip(CLASSES, self.probabilities))
Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,86 @@
1-
from zipfile import ZipFile
21
import os
3-
2+
from zipfile import ZipFile
43
from . import File
54
from ..requests import ALLOWED_IMAGE_FILES
65
from ..utils import allowed_file
76

7+
88
class ZipArchive:
9+
"""
10+
Archive of a zip file
11+
12+
This class is to store and access a zip file.
13+
14+
Parameters:
15+
file: The storage of the zip file (gets removed from the os upon destructor call)
16+
zip: Opened zip file
17+
"""
18+
919
def __init__(self, file):
20+
"""
21+
Constructor of ZipFile
22+
23+
Store the given file and open the zip file.
24+
25+
Parameters:
26+
file: Uploaded file from flask
27+
"""
1028
self.file = File.File(file)
1129
self.zip = ZipFile(self.file.getPath())
1230

1331
def listFiles(self):
32+
"""
33+
List all files in the zip
34+
35+
Returns:
36+
array: Array of filenames
37+
"""
1438
return [file.filename for file in self.zip.infolist()]
1539

1640
def listAllImages(self, extensions=ALLOWED_IMAGE_FILES):
41+
"""
42+
List all image files
43+
44+
Lists all image files within the zip archive based on the given extensions
45+
46+
Parameters:
47+
extensions: Array of allowed image extensions
48+
49+
Returns:
50+
array: Array of filenames matching the extension
51+
"""
1752
return [file for file in self.listFiles() if allowed_file(file, extensions)]
1853

1954
def hasImages(self, extensions=ALLOWED_IMAGE_FILES):
55+
"""
56+
Check for images in the zip file
57+
58+
Parameters:
59+
extensions: Array of allowed image extensions
60+
61+
Returns:
62+
boolean: True if zip has images
63+
"""
2064
return len(self.listAllImages(extensions)) > 0
2165

22-
def extractAll(self, path=None, members=None, pwd=None):
23-
self.zip.extractall(path, members, pwd)
66+
def extractAll(self, path=None, members=None):
67+
"""
68+
Extract all the given files
69+
70+
Extractes all the given files and stores them as File objects.
71+
Upon destruction of the array, files are getting removed from os.
72+
73+
Parameters:
74+
path: Path to store files
75+
members: Files to extract
76+
77+
Returns:
78+
array: Array of extracted File objects
79+
"""
80+
self.zip.extractall(path, members)
2481
extractedFiles = {}
2582
for member in members:
2683
file = File.File()
2784
file.setPath(os.path.join(path, member))
2885
extractedFiles[member] = file
29-
return extractedFiles
86+
return extractedFiles
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
from .File import File
2-
from .ZipArchive import ZipArchive
32
from .Predictor import Predictor
3+
from .ZipArchive import ZipArchive

autofocus/predict/app/requests/PredictRequestValidator.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
1-
from . import Validator, ALLOWED_IMAGE_FILES
1+
from . import ALLOWED_IMAGE_FILES, Validator
22
from ..utils import allowed_file
33

4+
45
class PredictRequestValidator(Validator):
6+
"""
7+
Validate request for endpoint predict
8+
"""
9+
510
def validate(self):
11+
"""
12+
Validate the given request
13+
14+
Check if the request has a file and the extension is an allowed image extension.
15+
16+
Returns:
17+
boolean: True if the request is valid
18+
"""
619
self.error = {}
720

821
file = self.request.files.get('file', None)

autofocus/predict/app/requests/PredictZipRequestValidator.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
1-
from . import Validator, ALLOWED_ZIP_FILES
1+
from . import ALLOWED_ZIP_FILES, Validator
22
from ..utils import allowed_file
33

4+
45
class PredictZipRequestValidator(Validator):
6+
"""
7+
Validate request for endpoint predict_zip
8+
"""
9+
510
def validate(self):
11+
"""
12+
Validate the given request
13+
14+
Check if the request has a file and the extension is ".zip".
15+
16+
Returns:
17+
boolean: True if the request is valid
18+
"""
619
self.error = {}
720

821
file = self.request.files.get('file', None)

autofocus/predict/app/requests/Validator.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,54 @@
11
from abc import ABC, abstractmethod
2-
from flask import jsonify, make_response, abort
2+
from flask import abort, jsonify, make_response
33
from flask_api import status
44

5+
56
class Validator(ABC):
7+
"""
8+
Validate given request
9+
10+
Validator validates a given request based upon the abstract method validate.
11+
12+
Parameters:
13+
request: Given request to validate
14+
error: Dict of errors
15+
"""
16+
617
def __init__(self, request):
18+
"""
19+
Constructor of Validator
20+
21+
Store the request and create an empty error Dict.
22+
23+
Parameters:
24+
request: Request to validate
25+
"""
726
self.request = request
827
self.error = {}
928

1029
@abstractmethod
1130
def validate(self):
31+
"""
32+
Validate the given request
33+
34+
Returns:
35+
boolean: True if request is valid
36+
"""
1237
pass
1338

1439
def getError(self):
40+
"""
41+
Return the error dictionary
42+
43+
Returns:
44+
dict: The errors found during validation
45+
"""
1546
return self.error
1647

1748
def abort(self):
49+
"""
50+
Abort with errors
51+
"""
1852
abort(make_response(
1953
jsonify(
2054
status=status.HTTP_400_BAD_REQUEST,
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
ALLOWED_IMAGE_FILES = set(["png", "jpg", "jpeg", "gif", "bmp"])
2-
ALLOWED_ZIP_FILES = {"zip"}
3-
4-
from .Validator import Validator
5-
61
from .PredictRequestValidator import PredictRequestValidator
2+
from .Validator import Validator
73
from .PredictZipRequestValidator import PredictZipRequestValidator
4+
5+
ALLOWED_IMAGE_FILES = set(["png", "jpg", "jpeg", "gif", "bmp"])
6+
ALLOWED_ZIP_FILES = {"zip"}

autofocus/predict/app/utils.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from pathlib import Path
2-
from zipfile import ZipFile
32

43

54
def allowed_file(filename, allowed_extensions):

0 commit comments

Comments
 (0)