def photo_upload(
        self,
        path: Path,
        caption: str,
        upload_id: str = "",
        usertags: List[Usertag] = [],
        location: Location = None,
        extra_data: Dict[str, str] = {},
    ) -> Media:
        """
        Upload photo and configure to feed

        Parameters
        ----------
        path: Path
            Path to the media
        caption: str
            Media caption
        upload_id: str, optional
            Unique upload_id (String). When None, then generate automatically. Example from video.video_configure
        usertags: List[Usertag], optional
            List of users to be tagged on this upload, default is empty list.
        location: Location, optional
            Location tag for this upload, default is None
        extra_data: Dict[str, str], optional
            Dict of extra data, if you need to add your params, like {"share_to_facebook": 1}.

        Returns
        -------
        Media
            An object of Media class
        """
        path = Path(path)
        valid_extensions = [".jpg", ".jpeg", ".png", ".webp"]
        if path.suffix.lower() not in valid_extensions:
            raise ValueError(
                "Invalid file format. Only JPG/JPEG/PNG/WEBP files are supported."
            )

        upload_id, width, height = self.photo_rupload(path, upload_id)
        for attempt in range(10):
            self.logger.debug(f"Attempt #{attempt} to configure Photo: {path}")
            time.sleep(3)
            if self.photo_configure(
                upload_id,
                width,
                height,
                caption,
                usertags,
                location,
                extra_data=extra_data,
            ):
                media = self.last_json.get("media")
                self.expose()
                return extract_media_v1(media)
        raise PhotoConfigureError(response=self.last_response, **self.last_json)

        Upload photo and configure to feed

        Parameters
        ----------
        path: Path
            Path to the media
        caption: str
            Media caption
        upload_id: str, optional
            Unique upload_id (String). When None, then generate automatically. Example from video.video_configure
        usertags: List[Usertag], optional
            List of users to be tagged on this upload, default is empty list.
        location: Location, optional
            Location tag for this upload, default is None
        extra_data: Dict[str, str], optional
            Dict of extra data, if you need to add your params, like {"share_to_facebook": 1}.

        Returns
        -------
        Media
            An object of Media class
        
instagrapi/mixins/photo.py