diff --git a/.dockerignore b/.dockerignore
index 578118db7ef9ca6e700ae597b7fc3f32feaa535b..df212018a2cd5cd64aad1db7e7bb731c0f86604a 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -6,6 +6,7 @@
 .gitlab-ci.yml
 Dockerfile
 README.md
+client
 
 # temp files
 *.pyc
diff --git a/.gitignore b/.gitignore
index 5fbfdaba942fdd62cb5b4d2ba3184202ba38c096..84c287f467d5cae7704246a8adda7bda35b9426d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,8 @@
 *.pyc
 *~
 \#*\#
+
+# client temp files
+client/images/*.*
+client/error.log
+client/debug.log
diff --git a/client/.gitkeep b/client/.gitkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/client/haarcascade/.gitkeep b/client/haarcascade/.gitkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/contrib/src/web/emotion_gender_processor.py b/contrib/src/web/emotion_gender_processor.py
index 6b81edd04130aa62c69f54cf3097009041255449..eb960be2fbf0c6d995046c7b641a1ad4d03b62a0 100644
--- a/contrib/src/web/emotion_gender_processor.py
+++ b/contrib/src/web/emotion_gender_processor.py
@@ -1,4 +1,4 @@
-# this is a slightly modified version of the src/web/emotion_gender_processor.py to provide control over paths
+# this is a slightly modified version of the src/web/emotion_gender_processor.py to provide control over paths and other changes (see README.md)
 
 import os, logging, json
 
diff --git a/contrib/src/web/faces.py b/contrib/src/web/faces.py
index bacf31cf2cc8b97f49a914b75010b40eada7244c..7416d1b705199b180f1958ffef71eb5177c1c350 100644
--- a/contrib/src/web/faces.py
+++ b/contrib/src/web/faces.py
@@ -1,4 +1,4 @@
-# this is a slightly modified version of the src/web/faces.py to account for uwsgi import requirements
+# this is a slightly modified version of the src/web/faces.py to account for uwsgi import requirements and other changes (see README.md)
 
 import logging, requests, os, weakref
 
@@ -17,16 +17,15 @@ if not os.path.exists(dirname):
 logging.basicConfig(filename = os.path.join(dirname, 'debug.log'), level = logging.DEBUG)
 
 # PostgreSQL table classes:
-database = PostgresqlDatabase('stop', user='stop', password='PT52lRecp4NBKQrZT9',
-                           host='database')
+database = PostgresqlDatabase('stop', user='stop', password='PT52lRecp4NBKQrZT9', host='database')
 
 # NOTE: most docker images run in UTC by default
 def getCurrentTime(format = None):
-	ts = datetime.now(tzlocal())
-	if not format:
-		return ts
+    ts = datetime.now(tzlocal())
+    if not format:
+        return ts
 
-	return ts.strftime(format)
+    return ts.strftime(format)
 
 class UnknownField(object):
     def __init__(self, *_, **__): pass
@@ -58,8 +57,9 @@ class FileCleaner(object):
 
     def _deleteTask(self, wref):
         filepath = self.weak_references[wref]
-        logging.debug('Deleting request result: {0}'.format(filepath))
-        os.remove(filepath)
+        if filepath:
+            logging.debug('Deleting request result: {0}'.format(filepath))
+            os.remove(filepath)
 
 def initFlask():
     app = Flask(__name__)
@@ -97,8 +97,13 @@ def upload(version, type = 'mem'):
         if not processor.isValid():
             abort(503)
 
-        stopCode = request.args.get('stop_code', default = '', type = str)
-        detectEmotion = request.args.get('detect_emotion', default = 0, type = int)
+        stopCode = request.args.get('stop_code', default = None, type = str)
+        if stopCode == None:
+            stopCode = request.form.get('stop_code', default = 'unknown', type = str)
+        detectEmotion = request.args.get('detect_emotion', default = None, type = int)
+        if detectEmotion == None:
+            detectEmotion = request.form.get('detect_emotion', default = 0, type = int)
+
         result = processor.processImage(request.files['image'].read(), result_fname = getRequestID(request), type = type, detect_emotion = detectEmotion != 0)
 
         # VH Insert result into database
@@ -106,7 +111,7 @@ def upload(version, type = 'mem'):
             i = 0
             ts = getCurrentTime() # only one value for current time per request
             for face in result:
-                Gender_Stats.create(t = stopCode if stopCode else "unknown", t_ts = ts, rowid = i, gender_text = face["gender"])
+                Gender_Stats.create(t = stopCode, t_ts = ts, rowid = i, gender_text = face["gender"])
                 i += 1
 
         # by default avoid all disk I/O by using the result held in memory, explicit type argument will still roundtrip to disk
@@ -137,6 +142,9 @@ def upload(version, type = 'mem'):
         return response
     except Exception as err:
         logging.error('An error has occurred whilst processing the file: "{0}", from: {1}'.format(err, stopCode))
+        if resultFile:
+            os.remove(resultFile)
+
         abort(400)
 
 @app.route('/api/v<int:version>/classifyImage/', methods=['GET'])
@@ -153,7 +161,7 @@ def dowload(version, type = 'mem'):
         if not processor.isValid():
             abort(503)
 
-        stopCode = request.args.get('stop_code', default = '', type = str)
+        stopCode = request.args.get('stop_code', default = 'unknown', type = str)
         detectEmotion = request.args.get('detect_emotion', default = 0, type = int)
         result = processor.processImage(requests.get(uri).content, result_fname = getRequestID(request), type = type, detect_emotion = detectEmotion != 0)
 
@@ -162,7 +170,7 @@ def dowload(version, type = 'mem'):
             i = 0
             ts = getCurrentTime() # only one value for current time per request
             for face in result:
-                Gender_Stats.create(t = stopCode if stopCode else "unknown", t_ts = ts, rowid = i, gender_text = face["gender"])
+                Gender_Stats.create(t = stopCode, t_ts = ts, rowid = i, gender_text = face["gender"])
                 i += 1
 
         # by default avoid all disk I/O by using the result held in memory, explicit type argument will still roundtrip to disk
@@ -186,17 +194,16 @@ def dowload(version, type = 'mem'):
         if response == None:
             raise Exception('Unsupported type requested.')
 
-        
         cleaner.cleanup(response, resultFile)
         # require clients to explicitly handle caching results, HTTP caches are unpredictable
         response.headers.extend({'Cache-Control': 'no-cache', 'Expires': '0'})
-        
-        
-        return response
 
-        
+        return response
     except Exception as err:
         logging.error('An error has occurred whilst processing the file: "{0}", from: {1}'.format(err, stopCode))
+        if resultFile:
+            os.remove(resultFile)
+
         abort(400)
 
 @app.errorhandler(400)