def upload_activity(self, activity_file, data_type, name=None, description=None,
                        activity_type=None, private=None, external_id=None):
        """
        Uploads a GPS file (tcx, gpx) to create a new activity for current athlete.

        http://strava.github.io/api/v3/athlete/#get-details

        :param activity_file: The file object to upload or file contents.
        :type activity_file: file or str

        :param data_type: File format for upload. Possible values: fit, fit.gz, tcx, tcx.gz, gpx, gpx.gz
        :type data_type: str

        :param name: (optional) if not provided, will be populated using start date and location, if available
        :type name: str

        :param description: (optional) The description for the activity
        :type name: str

        :param activity_type: (optional) case-insensitive type of activity.
                              possible values: ride, run, swim, workout, hike, walk,
                              nordicski, alpineski, backcountryski, iceskate, inlineskate,
                              kitesurf, rollerski, windsurf, workout, snowboard, snowshoe
                              Type detected from file overrides, uses athlete's default type if not specified
        :type activity_type: str

        :param private: (optional) set to True to mark the resulting activity as private, 'view_private' permissions will be necessary to view the activity
        :type private: bool

        :param external_id: (optional) An arbitrary unique identifier may be specified which will be included in status responses.
        :type external_id: str
        """
        if not hasattr(activity_file, 'read'):
            if isinstance(activity_file, six.string_types):
                activity_file = BytesIO(activity_file.encode('utf-8'))
            elif isinstance(activity_file, str):
                activity_file = BytesIO(activity_file)
            else:
                raise TypeError("Invalid type specified for activity_file: {0}".format(type(activity_file)))

        valid_data_types = ('fit', 'fit.gz', 'tcx', 'tcx.gz', 'gpx', 'gpx.gz')
        if not data_type in valid_data_types:
            raise ValueError("Invalid data type {0}. Possible values {1!r}".format(data_type, valid_data_types))

        params = {'data_type': data_type}
        if name is not None:
            params['name'] = name
        if description is not None:
            params['description'] = description
        if activity_type is not None:
            if not activity_type.lower() in [t.lower() for t in model.Activity.TYPES]:
                raise ValueError("Invalid activity type: {0}.  Possible values: {1!r}".format(activity_type, model.Activity.TYPES))
            params['activity_type'] = activity_type
        if private is not None:
            params['private'] = int(private)
        if external_id is not None:
            params['external_id'] = external_id

        initial_response = self.protocol.post('/uploads',
                                              files={'file': activity_file},
                                              check_for_errors=False,
                                              **params)

        return ActivityUploader(self, response=initial_response)
Uploads a GPS file (tcx, gpx) to create a new activity for current athlete.

        http://strava.github.io/api/v3/athlete/#get-details

        :param activity_file: The file object to upload or file contents.
        :type activity_file: file or str

        :param data_type: File format for upload. Possible values: fit, fit.gz, tcx, tcx.gz, gpx, gpx.gz
        :type data_type: str

        :param name: (optional) if not provided, will be populated using start date and location, if available
        :type name: str

        :param description: (optional) The description for the activity
        :type name: str

        :param activity_type: (optional) case-insensitive type of activity.
                              possible values: ride, run, swim, workout, hike, walk,
                              nordicski, alpineski, backcountryski, iceskate, inlineskate,
                              kitesurf, rollerski, windsurf, workout, snowboard, snowshoe
                              Type detected from file overrides, uses athlete's default type if not specified
        :type activity_type: str

        :param private: (optional) set to True to mark the resulting activity as private, 'view_private' permissions will be necessary to view the activity
        :type private: bool

        :param external_id: (optional) An arbitrary unique identifier may be specified which will be included in status responses.
        :type external_id: str