diff --git a/changelog.md b/changelog.md
index 9350dcf..1871743 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,6 +1,7 @@
 # Change Log
 
 ## Unreleased
+* Add: Support uploading `activity_file` object with type `bytes` (@gitexel, #308)
 
 ## v1.1.0
 
diff --git a/stravalib/client.py b/stravalib/client.py
index e2ac772..fa23a81 100644
--- a/stravalib/client.py
+++ b/stravalib/client.py
@@ -694,7 +694,7 @@ class Client(object):
         https://developers.strava.com/docs/reference/#api-Uploads-createUpload
 
         :param activity_file: The file object to upload or file contents.
-        :type activity_file: file or str
+        :type activity_file: TextIOWrapper, str or bytes
 
         :param data_type: File format for upload. Possible values: fit, fit.gz, tcx, tcx.gz, gpx, gpx.gz
         :type data_type: str
@@ -734,7 +734,7 @@ class Client(object):
         if not hasattr(activity_file, 'read'):
             if isinstance(activity_file, str):
                 activity_file = BytesIO(activity_file.encode('utf-8'))
-            elif isinstance(activity_file, str):
+            elif isinstance(activity_file, bytes):
                 activity_file = BytesIO(activity_file)
             else:
                 raise TypeError("Invalid type specified for activity_file: {0}".format(type(activity_file)))

diff --git a/stravalib/tests/integration/test_client.py b/stravalib/tests/integration/test_client.py
index 30d1812..10aa27d 100644
--- a/stravalib/tests/integration/test_client.py
+++ b/stravalib/tests/integration/test_client.py
@@ -83,6 +83,7 @@ def test_update_activity(
     (
         ('file', 'tcx', {}, {'data_type': 'tcx'}, None, None),
         ('str', 'tcx', {}, {'data_type': 'tcx'}, None, None),
+        ('bytes', 'tcx', {}, {'data_type': 'tcx'}, None, None),
         ('not_supported', 'tcx', {}, {}, None, TypeError),
         ('file', 'invalid', {}, {}, None, ValueError),
         ('file', 'tcx', {'name': 'name'}, {'data_type': 'tcx', 'name': 'name'}, None, None),
@@ -135,6 +136,8 @@ def test_upload_activity(
             _call_upload(f)
         elif activity_file_type == 'str':
             _call_upload(f.read())
+        elif activity_file_type == 'bytes':
+            _call_upload(f.read().encode('utf-8'))
         else:
             _call_upload({})
 
diff --git a/stravalib/tests/unit/test_client_utils.py b/stravalib/tests/unit/test_client_utils.py
index 88a8a8a..e3e6cd4 100644
--- a/stravalib/tests/unit/test_client_utils.py
+++ b/stravalib/tests/unit/test_client_utils.py
@@ -1,5 +1,8 @@
+import os
+from unittest import mock
+
 from stravalib.client import Client
-from stravalib.tests import TestBase
+from stravalib.tests import TestBase, RESOURCES_DIR
 import datetime
 import pytz
 from urllib import parse as urlparse
@@ -54,3 +57,32 @@ class ClientAuthorizationUrlTest(TestBase):
         self.assertEqual(self.get_url_param(url, "client_id"), "1")
         self.assertEqual(self.get_url_param(url, "redirect_uri"), "www.example.com")
         self.assertEqual(self.get_url_param(url, "approval_prompt"), "auto")
+
+
+class TestClientUploadActivity(TestBase):
+    client = Client()
+
+    def test_upload_activity_file_with_different_types(self):
+        """
+        Test uploading an activity with different activity_file object types.
+
+        """
+
+        with mock.patch("stravalib.protocol.ApiV3.post", return_value={}), open(
+            os.path.join(RESOURCES_DIR, "sample.tcx")
+        ) as fp:
+            # test activity_file with type TextIOWrapper
+            uploader = self.client.upload_activity(fp, data_type="tcx")
+            self.assertTrue(uploader.is_processing)
+
+            # test activity_file with type str
+            uploader = self.client.upload_activity(
+                fp.read(), data_type="tcx", activity_type="ride"
+            )
+            self.assertTrue(uploader.is_processing)
+
+            # test activity_file with type bytes
+            uploader = self.client.upload_activity(
+                fp.read().encode("utf-8"), data_type="tcx", activity_type="ride"
+            )
+            self.assertTrue(uploader.is_processing)

unable to upload_activity if its bytes type
When calling `client.upload_activity` and `activity_file` type is `bytes`, 
I get this error 
`Invalid type specified for activity_file: bytes`
stravalib/tests/integration/test_client.py::test_upload_activity[bytes-tcx-upload_kwargs2-expected_params2-None-None] stravalib/tests/unit/test_client_utils.py::TestClientUploadActivity::test_upload_activity_file_with_different_types
stravalib/tests/integration/test_client.py::test_get_athlete stravalib/tests/integration/test_client.py::test_get_activity[None-/activities/42?include_all_efforts=False] stravalib/tests/integration/test_client.py::test_get_activity[False-/activities/42?include_all_efforts=False] stravalib/tests/integration/test_client.py::test_get_activity[True-/activities/42?include_all_efforts=True] stravalib/tests/integration/test_client.py::test_update_activity[update_kwargs0-expected_params0-None-None] stravalib/tests/integration/test_client.py::test_update_activity[update_kwargs1-expected_params1-None-None] stravalib/tests/integration/test_client.py::test_update_activity[update_kwargs2-expected_params2-None-ValueError] stravalib/tests/integration/test_client.py::test_update_activity[update_kwargs3-expected_params3-None-None] stravalib/tests/integration/test_client.py::test_update_activity[update_kwargs4-expected_params4-None-None] stravalib/tests/integration/test_client.py::test_update_activity[update_kwargs5-expected_params5-None-None] stravalib/tests/integration/test_client.py::test_update_activity[update_kwargs6-expected_params6-DeprecationWarning-None] stravalib/tests/integration/test_client.py::test_update_activity[update_kwargs7-expected_params7-None-None] stravalib/tests/integration/test_client.py::test_update_activity[update_kwargs8-expected_params8-None-None] stravalib/tests/integration/test_client.py::test_update_activity[update_kwargs9-expected_params9-None-None] stravalib/tests/integration/test_client.py::test_update_activity[update_kwargs10-expected_params10-None-None] stravalib/tests/integration/test_client.py::test_update_activity[update_kwargs11-expected_params11-DeprecationWarning-None] stravalib/tests/integration/test_client.py::test_update_activity[update_kwargs12-expected_params12-None-None] stravalib/tests/integration/test_client.py::test_upload_activity[file-tcx-upload_kwargs0-expected_params0-None-None] stravalib/tests/integration/test_client.py::test_upload_activity[str-tcx-upload_kwargs1-expected_params1-None-None] stravalib/tests/integration/test_client.py::test_upload_activity[not_supported-tcx-upload_kwargs3-expected_params3-None-TypeError] stravalib/tests/integration/test_client.py::test_upload_activity[file-invalid-upload_kwargs4-expected_params4-None-ValueError] stravalib/tests/integration/test_client.py::test_upload_activity[file-tcx-upload_kwargs5-expected_params5-None-None] stravalib/tests/integration/test_client.py::test_upload_activity[file-tcx-upload_kwargs6-expected_params6-None-None] stravalib/tests/integration/test_client.py::test_upload_activity[file-tcx-upload_kwargs7-expected_params7-FutureWarning-None] stravalib/tests/integration/test_client.py::test_upload_activity[file-tcx-upload_kwargs8-expected_params8-FutureWarning-None] stravalib/tests/integration/test_client.py::test_upload_activity[file-tcx-upload_kwargs9-None-None-ValueError] stravalib/tests/integration/test_client.py::test_upload_activity[file-tcx-upload_kwargs10-expected_params10-DeprecationWarning-None] stravalib/tests/integration/test_client.py::test_upload_activity[file-tcx-upload_kwargs11-expected_params11-None-None] stravalib/tests/integration/test_client.py::test_upload_activity[file-tcx-upload_kwargs12-expected_params12-None-None] stravalib/tests/integration/test_client.py::test_upload_activity[file-tcx-upload_kwargs13-expected_params13-None-None] stravalib/tests/integration/test_client.py::test_update_athlete[update_kwargs0-expected_params0-None-None] stravalib/tests/integration/test_client.py::test_update_athlete[update_kwargs1-expected_params1-DeprecationWarning-None] stravalib/tests/integration/test_client.py::test_update_athlete[update_kwargs2-expected_params2-DeprecationWarning-None] stravalib/tests/integration/test_client.py::test_update_athlete[update_kwargs3-expected_params3-DeprecationWarning-None] stravalib/tests/integration/test_client.py::test_update_athlete[update_kwargs4-expected_params4-DeprecationWarning-None] stravalib/tests/integration/test_client.py::test_update_athlete[update_kwargs5-expected_params5-None-ValueError] stravalib/tests/integration/test_client.py::test_update_athlete[update_kwargs6-expected_params6-None-None] stravalib/tests/integration/test_client.py::test_update_athlete[update_kwargs7-expected_params7-None-None] stravalib/tests/integration/test_client.py::test_update_athlete[update_kwargs8-expected_params8-None-None] stravalib/tests/integration/test_client.py::test_create_activity[extra_create_kwargs0-extra_expected_params0-None] stravalib/tests/integration/test_client.py::test_create_activity[extra_create_kwargs1-extra_expected_params1-None] stravalib/tests/integration/test_client.py::test_create_activity[extra_create_kwargs2-extra_expected_params2-None] stravalib/tests/integration/test_client.py::test_create_activity[extra_create_kwargs3-extra_expected_params3-ValueError] stravalib/tests/integration/test_client.py::test_create_activity[extra_create_kwargs4-extra_expected_params4-None] stravalib/tests/integration/test_client.py::test_create_activity[extra_create_kwargs5-extra_expected_params5-None] stravalib/tests/integration/test_client.py::test_create_activity[extra_create_kwargs6-extra_expected_params6-None] stravalib/tests/integration/test_client.py::test_create_activity[extra_create_kwargs7-extra_expected_params7-None] stravalib/tests/integration/test_client.py::test_create_activity[extra_create_kwargs8-extra_expected_params8-None] stravalib/tests/integration/test_client.py::test_activity_uploader stravalib/tests/integration/test_client.py::test_get_route stravalib/tests/integration/test_client.py::test_get_starred_segments[None-0-0] stravalib/tests/integration/test_client.py::test_get_starred_segments[None-10-10] stravalib/tests/integration/test_client.py::test_get_starred_segments[10-10-10] stravalib/tests/integration/test_client.py::test_get_starred_segments[10-20-10] stravalib/tests/integration/test_client.py::test_get_starred_segments[10-1-1] stravalib/tests/integration/test_client.py::test_get_starred_segments[10-0-0] stravalib/tests/integration/test_client.py::test_get_activities[None-10-10] stravalib/tests/integration/test_client.py::test_get_activities[None-0-0] stravalib/tests/integration/test_client.py::test_get_activities[10-10-10] stravalib/tests/integration/test_client.py::test_get_activities[10-20-10] stravalib/tests/integration/test_client.py::test_get_activities[10-1-1] stravalib/tests/integration/test_client.py::test_get_activities[10-0-0] stravalib/tests/integration/test_client.py::test_get_activities_paged stravalib/tests/unit/test_client_utils.py::ClientUtilsTest::test_utc_datetime_to_epoch_utc_datetime_given_correct_epoch_returned stravalib/tests/unit/test_client_utils.py::ClientAuthorizationUrlTest::test_correct_scope stravalib/tests/unit/test_client_utils.py::ClientAuthorizationUrlTest::test_incorrect_approval_prompt_raises stravalib/tests/unit/test_client_utils.py::ClientAuthorizationUrlTest::test_incorrect_scope_raises stravalib/tests/unit/test_client_utils.py::ClientAuthorizationUrlTest::test_params stravalib/tests/unit/test_client_utils.py::ClientAuthorizationUrlTest::test_scope_may_be_list stravalib/tests/unit/test_client_utils.py::ClientAuthorizationUrlTest::test_state_param