diff --git a/.gitignore b/.gitignore
index 55953a51369f24fd547985c0a7bfa45ab62e8a78..e4bf474de943329146db1eaadeb0b6c0613934bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,10 +2,13 @@
 *.pyc
 *.swp
 .DS_Store
+.vscode/
 
 # virtualenv files
 .Python
 /bin/
 /include/
 /lib/
-/lib64/
\ No newline at end of file
+/lib64/
+build/
+
diff --git a/spotseeker_restclient.egg-info/PKG-INFO b/spotseeker_restclient.egg-info/PKG-INFO
new file mode 100644
index 0000000000000000000000000000000000000000..fd99de6fcae7094220cdf5c265012ca6f44ee8be
--- /dev/null
+++ b/spotseeker_restclient.egg-info/PKG-INFO
@@ -0,0 +1,45 @@
+Metadata-Version: 1.0
+Name: spotseeker-restclient
+Version: 0.1
+Summary: A Django app for consuming the spotseeker REST API
+Home-page: UNKNOWN
+Author: UNKNOWN
+Author-email: UNKNOWN
+License: Apache License, Version 2.0
+Description: DoIT fork of [spotseeker_client](https://github.com/uw-it-aca/spotseeker_client)
+        by the University of Washington Information Technology's Academic Experience Design & Delivery group.
+        Major changes are from upstream project is this fork has been updated Python 3.x and Django 2.x.
+        
+        ### Requirement
+        * Python 3.6.x
+        * Django 2.x
+        
+        ### Development 
+        Install spotseeker_client as a Django module in [WiScout](https://git.doit.wisc.edu/andrew-summers/wiscout) Django app.
+        
+        * Clone WiScout to your machine.
+        
+        * Install spotseeker_server as an editable dependency.
+          
+        ```sh
+        # from wiscout
+        $ pipenv install -e /path/to/spotseeker_client
+        ```
+          
+        * Add spotseeker_client to `INSTALLED_APPS`
+          
+        ```py
+        # wiscout/settings.py
+        INSTALLED_APPS = [
+        ...
+        'spotseeker_restclient',
+        ....
+        ]
+        ```
+        
+        ### Run Unit Tests
+        ```py
+        # from wiscout 
+        $ python manage.py test spotseeker_restclient.test.spot
+        ```
+Platform: UNKNOWN
diff --git a/spotseeker_restclient.egg-info/SOURCES.txt b/spotseeker_restclient.egg-info/SOURCES.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c56e2f3d100b788224eed4f4eadd35e7a1e9cd8e
--- /dev/null
+++ b/spotseeker_restclient.egg-info/SOURCES.txt
@@ -0,0 +1,22 @@
+README.md
+setup.py
+/Users/apsummers/Developer/spotseeker_client/spotseeker_restclient.egg-info/PKG-INFO
+/Users/apsummers/Developer/spotseeker_client/spotseeker_restclient.egg-info/SOURCES.txt
+/Users/apsummers/Developer/spotseeker_client/spotseeker_restclient.egg-info/dependency_links.txt
+/Users/apsummers/Developer/spotseeker_client/spotseeker_restclient.egg-info/requires.txt
+/Users/apsummers/Developer/spotseeker_client/spotseeker_restclient.egg-info/top_level.txt
+spotseeker_restclient/__init__.py
+spotseeker_restclient/admin.py
+spotseeker_restclient/cache_implementation.py
+spotseeker_restclient/cache_manager.py
+spotseeker_restclient/dao.py
+spotseeker_restclient/exceptions.py
+spotseeker_restclient/mock_http.py
+spotseeker_restclient/spotseeker.py
+spotseeker_restclient/tests.py
+spotseeker_restclient/views.py
+spotseeker_restclient.egg-info/PKG-INFO
+spotseeker_restclient.egg-info/SOURCES.txt
+spotseeker_restclient.egg-info/dependency_links.txt
+spotseeker_restclient.egg-info/requires.txt
+spotseeker_restclient.egg-info/top_level.txt
\ No newline at end of file
diff --git a/spotseeker_restclient.egg-info/dependency_links.txt b/spotseeker_restclient.egg-info/dependency_links.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/spotseeker_restclient.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/spotseeker_restclient.egg-info/requires.txt b/spotseeker_restclient.egg-info/requires.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bdcaef7a8bb58bb9ac0ce760b1f54ab317931e43
--- /dev/null
+++ b/spotseeker_restclient.egg-info/requires.txt
@@ -0,0 +1,6 @@
+setuptools
+Django
+urllib3
+oauth2
+requests-oauthlib
+PermissionsLogging
diff --git a/spotseeker_restclient.egg-info/top_level.txt b/spotseeker_restclient.egg-info/top_level.txt
new file mode 100644
index 0000000000000000000000000000000000000000..db73674581fbe7ebd67fa025d3780e3c40bcf968
--- /dev/null
+++ b/spotseeker_restclient.egg-info/top_level.txt
@@ -0,0 +1 @@
+spotseeker_restclient
diff --git a/spotseeker_restclient/migrations/0001_initial.py b/spotseeker_restclient/migrations/0001_initial.py
new file mode 100644
index 0000000000000000000000000000000000000000..1a9521b734161434f765c3a22554397d9d6f1f23
--- /dev/null
+++ b/spotseeker_restclient/migrations/0001_initial.py
@@ -0,0 +1,136 @@
+# Generated by Django 2.1.3 on 2018-11-16 19:21
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='CacheEntry',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('service', models.CharField(db_index=True, max_length=50)),
+                ('url', models.CharField(db_index=True, max_length=255, unique=True)),
+                ('status', models.PositiveIntegerField()),
+                ('header_pickle', models.TextField()),
+                ('content', models.TextField()),
+            ],
+        ),
+        migrations.CreateModel(
+            name='ItemImage',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('image_id', models.IntegerField()),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('display_index', models.PositiveIntegerField(blank=True, null=True)),
+                ('width', models.IntegerField()),
+                ('height', models.IntegerField()),
+                ('content_type', models.CharField(max_length=40)),
+                ('creation_date', models.DateTimeField(auto_now_add=True)),
+                ('upload_user', models.CharField(max_length=40)),
+                ('upload_application', models.CharField(max_length=100)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='Spot',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('spot_id', models.IntegerField()),
+                ('name', models.CharField(blank=True, max_length=100)),
+                ('uri', models.CharField(max_length=255)),
+                ('thumbnail_root', models.CharField(max_length=255)),
+                ('latitude', models.DecimalField(decimal_places=8, max_digits=11, null=True)),
+                ('longitude', models.DecimalField(decimal_places=8, max_digits=11, null=True)),
+                ('height_from_sea_level', models.DecimalField(blank=True, decimal_places=8, max_digits=11, null=True)),
+                ('building_name', models.CharField(blank=True, max_length=100)),
+                ('floor', models.CharField(blank=True, max_length=50)),
+                ('room_number', models.CharField(blank=True, max_length=25)),
+                ('building_description', models.CharField(blank=True, max_length=100)),
+                ('capacity', models.IntegerField(blank=True, null=True)),
+                ('display_access_restrictions', models.CharField(blank=True, max_length=200)),
+                ('organization', models.CharField(blank=True, max_length=50)),
+                ('manager', models.CharField(blank=True, max_length=50)),
+                ('etag', models.CharField(max_length=40)),
+                ('last_modified', models.DateTimeField()),
+                ('external_id', models.CharField(blank=True, default=None, max_length=100, null=True, unique=True)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='SpotAvailableHours',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('day', models.CharField(max_length=9)),
+                ('start_time', models.TimeField()),
+                ('end_time', models.TimeField()),
+            ],
+        ),
+        migrations.CreateModel(
+            name='SpotExtendedInfo',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('key', models.CharField(max_length=50)),
+                ('value', models.CharField(max_length=255)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='SpotImage',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('image_id', models.IntegerField()),
+                ('url', models.CharField(max_length=255)),
+                ('description', models.CharField(blank=True, max_length=200)),
+                ('display_index', models.PositiveIntegerField(blank=True, null=True)),
+                ('content_type', models.CharField(max_length=40)),
+                ('width', models.IntegerField()),
+                ('height', models.IntegerField()),
+                ('creation_date', models.DateTimeField()),
+                ('modification_date', models.DateTimeField()),
+                ('upload_user', models.CharField(max_length=40)),
+                ('upload_application', models.CharField(max_length=100)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='SpotItem',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('item_id', models.IntegerField()),
+                ('name', models.CharField(blank=True, max_length=100)),
+                ('category', models.CharField(max_length=255)),
+                ('subcategory', models.CharField(max_length=255)),
+            ],
+        ),
+        migrations.CreateModel(
+            name='SpotType',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.SlugField()),
+            ],
+        ),
+        migrations.CreateModel(
+            name='CacheEntryExpires',
+            fields=[
+                ('cacheentry_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='spotseeker_restclient.CacheEntry')),
+                ('time_expires', models.DateTimeField()),
+            ],
+            bases=('spotseeker_restclient.cacheentry',),
+        ),
+        migrations.CreateModel(
+            name='CacheEntryTimed',
+            fields=[
+                ('cacheentry_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='spotseeker_restclient.CacheEntry')),
+                ('time_saved', models.DateTimeField()),
+            ],
+            bases=('spotseeker_restclient.cacheentry',),
+        ),
+        migrations.AlterUniqueTogether(
+            name='cacheentry',
+            unique_together={('service', 'url')},
+        ),
+    ]
diff --git a/spotseeker_restclient/migrations/__init__.py b/spotseeker_restclient/migrations/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/spotseeker_restclient/spotseeker.py b/spotseeker_restclient/spotseeker.py
index 4dfc40cf9941d3a5f4909b036286264a3a43689d..26447d7e00e01f20b2521760078798dd0632ff02 100644
--- a/spotseeker_restclient/spotseeker.py
+++ b/spotseeker_restclient/spotseeker.py
@@ -1,4 +1,3 @@
-from io import StringIO
 from spotseeker_restclient.dao import SPOTSEEKER_DAO
 from spotseeker_restclient.exceptions import DataFailureException
 from spotseeker_restclient.models.spot import Spot, SpotAvailableHours, \
@@ -12,7 +11,6 @@ import urllib
 import requests
 from requests_oauthlib import OAuth1
 
-
 class Spotseeker(object):
 
     def post_image(self, spot_id, image):
@@ -28,7 +26,7 @@ class Spotseeker(object):
                 auth = OAuth1(settings.SPOTSEEKER_OAUTH_KEY,
                               settings.SPOTSEEKER_OAUTH_SECRET)
                 full_url = settings.SPOTSEEKER_HOST + "/" + url
-                files = {'image': ('image.jpg', StringIO.StringIO(image))}
+                files = {'image': ('image.jpg', image)}
 
                 # Using requests lib here as urllib does not have good support
                 # for multipart form uploads.
@@ -72,7 +70,7 @@ class Spotseeker(object):
                 auth = OAuth1(settings.SPOTSEEKER_OAUTH_KEY,
                               settings.SPOTSEEKER_OAUTH_SECRET)
                 full_url = settings.SPOTSEEKER_HOST + "/" + url
-                files = {'image': ('image.jpg', StringIO.StringIO(image))}
+                files = {'image': ('image.jpg', image)}
 
                 # Using requests lib here as urllib does not have good support
                 # for multipart form uploads.
diff --git a/spotseeker_restclient/tests.py b/spotseeker_restclient/tests.py
index aed2c7d71b737cff70eeee55c5831eb6e773c37d..16e10f55a08cc53ba2d26cd134387ccf015c8bda 100644
--- a/spotseeker_restclient/tests.py
+++ b/spotseeker_restclient/tests.py
@@ -1,3 +1 @@
-from django.utils import unittest
-
 from spotseeker_restclient.test.spot import SpotseekerTest