Uploads video file to Twitter servers in chunks. The file will be available to be attached
        to a status for 60 minutes. To attach to a update, pass a list of returned media ids
        to the :meth:`update_status` method using the ``media_ids`` param.

        Upload happens in 3 stages:
        - INIT call with size of media to be uploaded(in bytes). If this is more than 15mb, twitter will return error.
        - APPEND calls each with media chunk. This returns a 204(No Content) if chunk is received.
        - FINALIZE call to complete media upload. This returns media_id to be used with status update.

        Twitter media upload api expects each chunk to be not more than 5mb. We are sending chunk of 1mb each.

        Docs:
        https://developer.twitter.com/en/docs/media/upload-media/uploading-media/chunked-media-upload

def upload_video(self, media, media_type, media_category=None, size=None, check_progress=False):
        """Uploads video file to Twitter servers in chunks. The file will be available to be attached
        to a status for 60 minutes. To attach to a update, pass a list of returned media ids
        to the :meth:`update_status` method using the ``media_ids`` param.

        Upload happens in 3 stages:
        - INIT call with size of media to be uploaded(in bytes). If this is more than 15mb, twitter will return error.
        - APPEND calls each with media chunk. This returns a 204(No Content) if chunk is received.
        - FINALIZE call to complete media upload. This returns media_id to be used with status update.

        Twitter media upload api expects each chunk to be not more than 5mb. We are sending chunk of 1mb each.

        Docs:
        https://developer.twitter.com/en/docs/media/upload-media/uploading-media/chunked-media-upload

        """
        upload_url = 'https://upload.twitter.com/1.1/media/upload.json'
        if not size:
            media.seek(0, os.SEEK_END)
            size = media.tell()
            media.seek(0)

        # Stage 1: INIT call
        params = {
            'command': 'INIT',
            'media_type': media_type,
            'total_bytes': size,
            'media_category': media_category
        }
        response_init = self.post(upload_url, params=params)
        media_id = response_init['media_id']

        # Stage 2: APPEND calls with 1mb chunks
        segment_index = 0
        while True:
            data = media.read(1*1024*1024)
            if not data:
                break
            media_chunk = BytesIO()
            media_chunk.write(data)
            media_chunk.seek(0)

            params = {
                'command': 'APPEND',
                'media_id': media_id,
                'segment_index': segment_index,
                'media': media_chunk,
            }
            self.post(upload_url, params=params)
            segment_index += 1

        # Stage 3: FINALIZE call to complete upload
        params = {
            'command': 'FINALIZE',
            'media_id': media_id
        }

        response = self.post(upload_url, params=params)

        # Only get the status if explicity asked to
        # Default to False
        if check_progress:

            # Stage 4: STATUS call if still processing
            params = {
                'command': 'STATUS',
                'media_id': media_id
            }

            # added code to handle if media_category is NOT set and check_progress=True
            # the API will return a NoneType object in this case
            try:
                processing_state = response.get('processing_info').get('state')
            except AttributeError:
                return response

            if processing_state:
                while (processing_state == 'pending' or processing_state == 'in_progress') :
                    # get the secs to wait
                    check_after_secs = response.get('processing_info').get('check_after_secs')

                    if check_after_secs:
                        sleep(check_after_secs)
                        response = self.get(upload_url, params=params)
                        # get new state after waiting
                        processing_state = response.get('processing_info').get('state')

        return response