def post_photo(self, photo_data, size, caption='', upload_id=None, to_reel=False, **kwargs):
        """
        Upload a photo.

        [CAUTION] FLAKY, IG is very finicky about sizes, etc, needs testing.

        :param photo_data: byte string of the image
        :param size: tuple of (width, height)
        :param caption:
        :param upload_id:
        :param to_reel: a Story photo
        :param kwargs:
            - **location**: a dict of venue/location information, from :meth:`location_search`
              or :meth:`location_fb_search`
            - **disable_comments**: bool to disable comments
        :return:
        """
        warnings.warn('This endpoint has not been fully tested.', UserWarning)

        # if upload_id is provided, it's a thumbnail for a vid upload
        for_video = True if upload_id else False

        if not for_video:
            if not to_reel and not self.compatible_aspect_ratio(size):
                raise ValueError('Incompatible aspect ratio.')
            if to_reel and not self.reel_compatible_aspect_ratio(size):
                raise ValueError('Incompatible reel aspect ratio.')
            if not 320 <= size[0] <= 1080:
                # range from https://help.instagram.com/1631821640426723
                raise ValueError('Invalid image width.')

        location = kwargs.pop('location', None)
        if location:
            self._validate_location(location)
        disable_comments = True if kwargs.pop('disable_comments', False) else False

        is_sidecar = kwargs.pop('is_sidecar', False)
        if not upload_id:
            upload_id = str(int(time.time() * 1000))

        endpoint = 'upload/photo/'
        fields = [
            ('upload_id', upload_id),
            ('_uuid', self.uuid),
            ('_csrftoken', self.csrftoken),
            ('image_compression', '{"lib_name":"jt","lib_version":"1.3.0","quality":"87"}')
        ]
        if is_sidecar:
            fields.append(('is_sidecar', '1'))
            if for_video:
                fields.append(('media_type', MediaTypes.VIDEO))

        files = [
            ('photo', 'pending_media_{0!s}{1!s}'.format(str(int(time.time() * 1000)), '.jpg'),
             'application/octet-stream', photo_data)
        ]

        content_type, body = MultipartFormDataEncoder().encode(fields, files)
        headers = self.default_headers
        headers['Content-Type'] = content_type
        headers['Content-Length'] = len(body)

        endpoint_url = '{0}{1}'.format(self.api_url.format(version='v1'), endpoint)
        req = compat_urllib_request.Request(endpoint_url, body, headers=headers)
        try:
            self.logger.debug('POST {0!s}'.format(endpoint_url))
            response = self.opener.open(req, timeout=self.timeout)
        except compat_urllib_error.HTTPError as e:
            error_response = self._read_response(e)
            self.logger.debug('RESPONSE: {0:d} {1!s}'.format(e.code, error_response))
            ErrorHandler.process(e, error_response)
        except (SSLError, timeout, SocketError,
                compat_urllib_error.URLError,   # URLError is base of HTTPError
                compat_http_client.HTTPException) as connection_error:
            raise ClientConnectionError('{} {}'.format(
                connection_error.__class__.__name__, str(connection_error)))

        post_response = self._read_response(response)
        self.logger.debug('RESPONSE: {0:d} {1!s}'.format(response.code, post_response))
        json_response = json.loads(post_response)

        if for_video and is_sidecar:
            return json_response

        upload_id = json_response['upload_id']

        # # NOTES: Logging traffic doesn't seem to indicate any additional "configure" after upload
        # # BUT not doing a "configure" causes a video post to fail with a
        # # "Other media configure error: b'yEmZkUpAj4'" error
        # if for_video:
        #     logger.debug('Skip photo configure.')
        #     return json_response
        if to_reel:
            return self.configure_to_reel(upload_id, size)
        else:
            return self.configure(upload_id, size, caption=caption, location=location,
                                  disable_comments=disable_comments, is_sidecar=is_sidecar)

        Upload a photo.

        [CAUTION] FLAKY, IG is very finicky about sizes, etc, needs testing.

        :param photo_data: byte string of the image
        :param size: tuple of (width, height)
        :param caption:
        :param upload_id:
        :param to_reel: a Story photo
        :param kwargs:
            - **location**: a dict of venue/location information, from :meth:`location_search`
              or :meth:`location_fb_search`
            - **disable_comments**: bool to disable comments
        :return:
        
instagram_private_api/endpoints/upload.py