def login(self):
        resp = self.send_request(
            'si/fetch_headers/?challenge_type=signup&guid=' +
            utils.generate_uuid(), None)
        if resp.status_code != 200:
            return False

        data = {
            'phone_id': self.phone_id,
            '_csrftoken': resp.cookies['csrftoken'],
            'username': self.username,
            'guid': self.uuid,
            'device_id': self.device_id,
            'password': self.password,
            'login_attempt_count': '0'
        }

        resp = self.send_request('accounts/login/',
                                 self.generate_signature(json.dumps(data)))
        if resp.status_code != 200:
            return False

        resp_json = utils.resp_to_json(resp)
        self.logged_in_user = resp_json["logged_in_user"]
        self.username_id = self.logged_in_user["pk"]
        self.rank_token = "%s_%s" % (self.username_id, self.uuid)
        self.token = resp.cookies["csrftoken"]
        return True
    def media_likers(self, media_id):
        uri = 'media/{}/likers/?'.format(media_id)
        resp = self.send_request(uri)
        if resp.status_code != 200:
            return False

        resp_json = utils.resp_to_json(resp)
        return resp_json
    def direct_thread(self, thread, next_page=''):
        uri = 'direct_v2/threads/{}/'.format(thread)
        if next_page:
            uri += '?cursor=' + next_page

        resp = self.send_request(uri)
        if resp.status_code != 200:
            return False

        resp_json = utils.resp_to_json(resp)
        return resp_json
    def direct_list(self, next_page=''):
        uri = 'direct_v2/inbox/'
        if next_page:
            uri += '?cursor=' + next_page

        resp = self.send_request(uri)
        if resp.status_code != 200:
            return False

        resp_json = utils.resp_to_json(resp)
        return resp_json
    def followings(self, username_id, max_id=''):
        uri = 'friendships/{}/following/?ig_sig_key_version={}&rank_token={}'.format(
            username_id, self.SIG_KEY_VERSION, self.rank_token)
        if max_id:
            uri += '&max_id=' + max_id
        resp = self.send_request(uri)
        if resp.status_code != 200:
            return False

        resp_json = utils.resp_to_json(resp)
        return resp_json
    def delete_direct_message(self, thread_id, item_id):
        data = {
            "_uuid": self.uuid,
            "_csrftoken": self.token,
        }
        resp = self.send_request('direct_v2/threads/{}/items/{}/delete/'.format(thread_id, item_id),
                                 self.generate_signature(json.dumps(data)))
        if resp.status_code != 200:
            return False

        resp_json = utils.resp_to_json(resp)
        return resp_json
    def user_feed(self, username_id, max_id='', min_timestamp=None):
        uri = 'feed/user/{}/?rank_token={}&ranked_content=true'.format(
            username_id, self.rank_token)
        if max_id:
            uri += '&max_id=' + max_id
        if min_timestamp:
            uri += '&min_timestamp=' + min_timestamp

        resp = self.send_request(uri)
        if resp.status_code != 200:
            return False

        resp_json = utils.resp_to_json(resp)
        return resp_json