예제 #1
0
파일: user.py 프로젝트: adw0rd/instagrapi
    def user_followers_gql_chunk(
            self,
            user_id: str,
            max_amount: int = 0,
            end_cursor: str = None) -> Tuple[List[UserShort], str]:
        """
        Get user's followers information by Public Graphql API and end_cursor

        Parameters
        ----------
        user_id: str
            User id of an instagram account
        max_amount: int, optional
            Maximum number of media to return, default is 0 - Inf
        end_cursor: str, optional
            The cursor from which it is worth continuing to receive the list of followers

        Returns
        -------
        Tuple[List[UserShort], str]
            List of objects of User type with cursor
        """
        user_id = str(user_id)
        users = []
        variables = {
            "id": user_id,
            "include_reel": True,
            "fetch_mutual": False,
            "first": 12
        }
        self.inject_sessionid_to_public()
        while True:
            if end_cursor:
                variables["after"] = end_cursor
            data = self.public_graphql_request(
                variables, query_hash="5aefa9893005572d237da5068082d8d5")
            if not data["user"] and not users:
                raise UserNotFound(user_id=user_id, **data)
            page_info = json_value(data,
                                   "user",
                                   "edge_followed_by",
                                   "page_info",
                                   default={})
            edges = json_value(data,
                               "user",
                               "edge_followed_by",
                               "edges",
                               default=[])
            for edge in edges:
                users.append(extract_user_short(edge["node"]))
            end_cursor = page_info.get("end_cursor")
            if not page_info.get("has_next_page") or not end_cursor:
                break
            if max_amount and len(users) >= max_amount:
                break
        return users, end_cursor
예제 #2
0
파일: user.py 프로젝트: adw0rd/instagrapi
    def user_following_gql(self,
                           user_id: str,
                           amount: int = 0) -> List[UserShort]:
        """
        Get user's following information by Public Graphql API

        Parameters
        ----------
        user_id: str
            User id of an instagram account
        amount: int, optional
            Maximum number of media to return, default is 0

        Returns
        -------
        List[UserShort]
            List of objects of User type
        """
        user_id = str(user_id)
        end_cursor = None
        users = []
        variables = {
            "id": user_id,
            "include_reel": True,
            "fetch_mutual": False,
            "first": 24,
        }
        self.inject_sessionid_to_public()
        while True:
            if end_cursor:
                variables["after"] = end_cursor
            data = self.public_graphql_request(
                variables, query_hash="e7e2f4da4b02303f74f0841279e52d76")
            if not data["user"] and not users:
                raise UserNotFound(user_id=user_id, **data)
            page_info = json_value(data,
                                   "user",
                                   "edge_follow",
                                   "page_info",
                                   default={})
            edges = json_value(data,
                               "user",
                               "edge_follow",
                               "edges",
                               default=[])
            for edge in edges:
                users.append(extract_user_short(edge["node"]))
            end_cursor = page_info.get("end_cursor")
            if not page_info.get("has_next_page") or not end_cursor:
                break
            if amount and len(users) >= amount:
                break
            # time.sleep(sleep)
        if amount:
            users = users[:amount]
        return users
예제 #3
0
파일: media.py 프로젝트: adw0rd/instagrapi
    def usertag_medias_gql(self,
                           user_id: int,
                           amount: int = 0,
                           sleep: int = 2) -> List[Media]:
        """
        Get medias where a user is tagged (by Public GraphQL API)

        Parameters
        ----------
        user_id: int
        amount: int, optional
            Maximum number of media to return, default is 0 (all medias)
        sleep: int, optional
            Timeout between pages iterations, default is 2

        Returns
        -------
        List[Media]
            A list of objects of Media
        """
        amount = int(amount)
        user_id = int(user_id)
        medias = []
        end_cursor = None
        variables = {
            "id": user_id,
            "first": 50 if not amount or amount > 50 else amount,
            # These are Instagram restrictions, you can only specify <= 50
        }
        while True:
            if end_cursor:
                variables["after"] = end_cursor
            data = self.public_graphql_request(
                variables, query_hash="be13233562af2d229b008d2976b998b5")
            page_info = json_value(data,
                                   "user",
                                   "edge_user_to_photos_of_you",
                                   "page_info",
                                   default={})
            edges = json_value(data,
                               "user",
                               "edge_user_to_photos_of_you",
                               "edges",
                               default=[])
            for edge in edges:
                medias.append(edge["node"])
            end_cursor = page_info.get("end_cursor")
            if not page_info.get("has_next_page") or not end_cursor:
                break
            if amount and len(medias) >= amount:
                break
            time.sleep(sleep)
        if amount:
            medias = medias[:amount]
        return [extract_media_gql(media) for media in medias]
예제 #4
0
    def user_medias_gql(self,
                        user_id: int,
                        amount: int = 50,
                        sleep: int = 2) -> List[Media]:
        """
        Get a user's media by Public Graphql API

        Parameters
        ----------
        user_id: int
        amount: int, optional
            Maximum number of media to return, default is 50
        sleep: int, optional
            Timeout between pages iterations, default is 2

        Returns
        -------
        List[Media]
            A list of objects of Media
        """
        amount = int(amount)
        user_id = int(user_id)
        medias = []
        end_cursor = None
        variables = {
            "id": user_id,
            "first": 50 if amount > 50 else
            amount,  # These are Instagram restrictions, you can only specify <= 50
        }
        while True:
            if end_cursor:
                variables["after"] = end_cursor
            data = self.public_graphql_request(
                variables, query_hash="e7e2f4da4b02303f74f0841279e52d76")
            page_info = json_value(data,
                                   "user",
                                   "edge_owner_to_timeline_media",
                                   "page_info",
                                   default={})
            edges = json_value(data,
                               "user",
                               "edge_owner_to_timeline_media",
                               "edges",
                               default=[])
            for edge in edges:
                medias.append(edge["node"])
            end_cursor = page_info.get("end_cursor")
            if not page_info.get("has_next_page") or not end_cursor:
                break
            if len(medias) >= amount:
                break
            time.sleep(sleep)
        return [extract_media_gql(media) for media in medias[:amount]]
예제 #5
0
파일: media.py 프로젝트: adw0rd/instagrapi
    def user_medias_paginated_gql(self,
                                  user_id: int,
                                  amount: int = 0,
                                  sleep: int = 2,
                                  end_cursor=None) -> Tuple[List[Media], str]:
        """
        Get a page of a user's media by Public Graphql API

        Parameters
        ----------
        user_id: int
        amount: int, optional
            Maximum number of media to return, default is 0 (all medias)
        sleep: int, optional
            Timeout between pages iterations, default is 2
        end_cursor: str, optional
            Cursor value to start at, obtained from previous call to this method
        Returns
        -------
        Tuple[List[Media], str]
            A tuple containing a list of medias and the next end_cursor value
        """
        amount = int(amount)
        user_id = int(user_id)
        medias = []
        variables = {
            "id": user_id,
            "first": 50 if not amount or amount > 50 else amount,
            # These are Instagram restrictions, you can only specify <= 50
        }
        variables["after"] = end_cursor
        data = self.public_graphql_request(
            variables, query_hash="e7e2f4da4b02303f74f0841279e52d76")
        page_info = json_value(data,
                               "user",
                               "edge_owner_to_timeline_media",
                               "page_info",
                               default={})
        edges = json_value(data,
                           "user",
                           "edge_owner_to_timeline_media",
                           "edges",
                           default=[])
        for edge in edges:
            medias.append(edge["node"])
        end_cursor = page_info.get("end_cursor")
        if amount:
            medias = medias[:amount]
        return ([extract_media_gql(media) for media in medias], end_cursor)
예제 #6
0
    def insights_account(self) -> Dict:
        """
        Get insights for account

        Returns
        -------
        Dict
            A dictionary of response from the call
        """
        assert self.user_id, "Login required"
        data = {
            "surface": "account",
            "doc_id": 2449243051851783,
            "locale": "en_US",
            "vc_policy": "insights_policy",
            "strip_nulls": False,
            "strip_defaults": False,
        }
        query_params = {
            "IgInsightsGridMediaImage_SIZE": 360,
            "activityTab": True,
            "audienceTab": True,
            "contentTab": True,
            "query_params": {"access_token": "", "id": self.user_id},
        }

        result = self.private_request(
            "ads/graphql/",
            self.with_query_params(data, query_params),
        )
        res = json_value(result, "data", "shadow_instagram_user", "business_manager")
        if not res:
            raise UserError("Account is not business account", **self.last_json)
        return res
예제 #7
0
파일: user.py 프로젝트: adw0rd/instagrapi
    def close_friend_remove(self, user_id: str):
        """
        Remove from Close Friends List

        Parameters
        ----------
        user_id: str
            Unique identifier of a User
        Returns
        -------
        bool
            A boolean value
        """
        assert self.user_id, "Login required"
        user_id = str(user_id)
        data = {
            "block_on_empty_thread_creation": "false",
            "module": "CLOSE_FRIENDS_V2_SEARCH",
            "source": "audience_manager",
            "_uid": self.user_id,
            "_uuid": self.uuid,
            "remove": [user_id],
            "add": []
        }
        result = self.private_request("friendships/set_besties/", data)
        return json_value(result, "friendship_statuses", user_id,
                          "is_bestie") == False
예제 #8
0
파일: public.py 프로젝트: adw0rd/instagrapi
    def public_a1_request(self,
                          endpoint,
                          data=None,
                          params=None,
                          headers=None):
        url = self.PUBLIC_API_URL + endpoint.lstrip("/")
        params = params or {}
        params.update({"__a": 1, '__d': 'dis'})

        response = self.public_request(url,
                                       data=data,
                                       params=params,
                                       headers=headers,
                                       return_json=True)
        try:
            return response["graphql"]
        except KeyError as e:
            error_type = response.get("error_type")
            if error_type == "generic_request_error":
                raise GenericRequestError(
                    json_value(response,
                               "errors",
                               "error",
                               0,
                               default=error_type), **response)
            raise e
예제 #9
0
파일: track.py 프로젝트: adw0rd/instagrapi
    def track_info_by_canonical_id(self, music_canonical_id: str) -> Track:
        """
        Get Track by music_canonical_id

        Parameters
        ----------
        music_canonical_id: str
            Unique identifier of the track

        Returns
        -------
        Track
            An object of Track type
        """
        data = {
            "tab_type": "clips",
            "referrer_media_id": "",
            "_uuid": self.uuid,
            "music_canonical_id": str(music_canonical_id),
        }
        result = self.private_request("clips/music/", data)
        track = json_value(result, "metadata", "music_info",
                           "music_asset_info")
        return extract_track(track)
예제 #10
0
    def insights_media_feed_all(
        self,
        post_type: str = "ALL",
        time_frame: str = "TWO_YEARS",
        data_ordering: str = "REACH_COUNT",
        count: int = 0,
        sleep: int = 2,
    ) -> List[Dict]:
        """
        Get insights for all medias from feed with page iteration with cursor and sleep timeout

        Parameters
        ----------
        post_type: str, optional
            Types of posts, default is "ALL"
            Options: ("ALL", "CAROUSEL_V2", "IMAGE", "SHOPPING", "VIDEO")
        time_frame: str, optional
            Time frame to pull media insights, default is "TWO_YEARS"
            Options: ("ONE_WEEK", "ONE_MONTH", "THREE_MONTHS", "SIX_MONTHS", "ONE_YEAR", "TWO_YEARS")
        data_ordering: str, optional
            Ordering strategy for the data, default is "REACH_COUNT"
            Options: ("REACH_COUNT", "LIKE_COUNT", "FOLLOW", "SHARE_COUNT", "BIO_LINK_CLICK", "COMMENT_COUNT", "IMPRESSION_COUNT", "PROFILE_VIEW", "VIDEO_VIEW_COUNT", "SAVE_COUNT"...)
        count: int, optional
            Max media count for retrieving, default is 0
        sleep: int, optional
            Timeout between pages iterations, default is 2

        Returns
        -------
        List[Dict]
            List of dictionaries of response from the call
        """
        assert self.user_id, "Login required"
        supported_post_types = ("ALL", "CAROUSEL_V2", "IMAGE", "SHOPPING", "VIDEO")
        supported_time_frames = (
            "ONE_WEEK",
            "ONE_MONTH",
            "THREE_MONTHS",
            "SIX_MONTHS",
            "ONE_YEAR",
            "TWO_YEARS",
        )
        assert post_type in supported_post_types, "Unsupported post type"
        assert time_frame in supported_time_frames, "Unsupported time frame"

        medias = []
        cursor = None
        data = {
            "surface": "post_grid",
            "doc_id": 2345520318892697,
            "locale": "en_US",
            "vc_policy": "insights_policy",
            "strip_nulls": False,
            "strip_defaults": False,
        }
        query_params = {
            "IgInsightsGridMediaImage_SIZE": 480,
            "count": 200,  # TODO Try to detect max allowed value
            # "cursor": "0",
            "dataOrdering": data_ordering,
            "postType": post_type,
            "timeframe": time_frame,
            "search_base": "USER",
            "is_user": "******",
            "queryParams": {"access_token": "", "id": self.user_id},
        }
        while True:
            if cursor:
                query_params["cursor"] = cursor

            result = self.private_request(
                "ads/graphql/",
                self.with_query_params(data, query_params),
            )
            if not json_value(
                result,
                "data",
                "shadow_instagram_user",
                "business_manager",
                default=None,
            ):
                raise UserError("Account is not business account", **self.last_json)

            stats = result["data"]["shadow_instagram_user"]["business_manager"][
                "top_posts_unit"
            ]["top_posts"]
            cursor = stats["page_info"]["end_cursor"]
            medias.extend(stats["edges"])
            if not stats["page_info"]["has_next_page"]:
                break
            if count and len(medias) >= count:
                break
            time.sleep(sleep)
        if count:
            medias = medias[:count]
        return medias
예제 #11
0
    def insights_media_feed_all(
        self,
        post_type: POST_TYPE = "ALL",
        time_frame: TIME_FRAME = "TWO_YEARS",
        data_ordering: DATA_ORDERING = "REACH_COUNT",
        count: int = 0,
        sleep: int = 2,
    ) -> List[Dict]:
        """
        Get insights for all medias from feed with page iteration with cursor and sleep timeout

        Parameters
        ----------
        post_type: str, optional
            Types of posts, default is "ALL"
        time_frame: str, optional
            Time frame to pull media insights, default is "TWO_YEARS"
        data_ordering: str, optional
            Ordering strategy for the data, default is "REACH_COUNT"
        count: int, optional
            Max media count for retrieving, default is 0
        sleep: int, optional
            Timeout between pages iterations, default is 2

        Returns
        -------
        List[Dict]
            List of dictionaries of response from the call
        """
        assert post_type in POST_TYPES, \
            f'Unsupported post_type="{post_type}" {POST_TYPES}'
        assert time_frame in TIME_FRAMES, \
            f'Unsupported time_frame="{time_frame}" {TIME_FRAMES}'
        assert data_ordering in DATA_ORDERS, \
            f'Unsupported data_ordering="{data_ordering}" {DATA_ORDERS}'
        assert self.user_id, "Login required"
        medias = []
        cursor = None
        data = {
            "surface": "post_grid",
            "doc_id": 2345520318892697,
            "locale": "en_US",
            "vc_policy": "insights_policy",
            "strip_nulls": False,
            "strip_defaults": False,
        }
        query_params = {
            "IgInsightsGridMediaImage_SIZE": 480,
            "count": 200,  # TODO Try to detect max allowed value
            # "cursor": "0",
            "dataOrdering": data_ordering,
            "postType": post_type,
            "timeframe": time_frame,
            "search_base": "USER",
            "is_user": "******",
            "queryParams": {"access_token": "", "id": self.user_id},
        }
        while True:
            if cursor:
                query_params["cursor"] = cursor
            result = self.private_request(
                "ads/graphql/",
                self.with_query_params(data, query_params),
            )
            if not json_value(
                result,
                "data",
                "shadow_instagram_user",
                "business_manager",
                default=None,
            ):
                raise UserError("Account is not business account", **self.last_json)
            stats = json_value(
                result, "data", "shadow_instagram_user",
                "business_manager", "top_posts_unit", "top_posts"
            )
            cursor = stats["page_info"]["end_cursor"]
            medias.extend(stats["edges"])
            if not stats["page_info"]["has_next_page"]:
                break
            if count and len(medias) >= count:
                break
            time.sleep(sleep)
        if count:
            medias = medias[:count]
        return medias