def _query(self, method, path, data=None, page=False, retry=0):
        """
        Fetch an object from the Graph API and parse the output, returning a tuple where the first item
        is the object yielded by the Graph API and the second is the URL for the next page of results, or
        ``None`` if results have been exhausted.

        :param method: A string describing the HTTP method.
        :param path: A string describing the object in the Graph API.
        :param data: A dictionary of HTTP GET parameters (for GET requests) or POST data (for POST requests).
        :param page: A boolean describing whether to return an iterator that iterates over each page of results.
        :param retry: An integer describing how many times the request may be retried.
        """

        if(data):
            data = dict(
                (k.replace('_sqbro_', '['), v) for k, v in data.items())
            data = dict(
                (k.replace('_sqbrc_', ']'), v) for k, v in data.items())
            data = dict(
                (k.replace('__', ':'), v) for k, v in data.items())
        data = data or {}

        def load(method, url, data):
            for key in data:
                value = data[key]

                if isinstance(value, (list, dict, set)):
                    data[key] = json.dumps(value)

            try:
                if method in ['GET', 'DELETE']:
                    response = self.session.request(
                        method, url, params=data, allow_redirects=True,
                        verify=self.verify_ssl_certificate, timeout=self.timeout
                    )

                if method in ['POST', 'PUT']:
                    files = {}

                    for key in data:
                        if hasattr(data[key], 'read'):
                            files[key] = data[key]

                    for key in files:
                        data.pop(key)

                    response = self.session.request(
                        method, url, data=data, files=files,
                        verify=self.verify_ssl_certificate, timeout=self.timeout
                    )

                if 500 <= response.status_code < 600:
                    # Facebook 5XX errors usually come with helpful messages
                    # as a JSON object describing the problem with the request.
                    # If this is the case, an error will be raised and we just
                    # need to re-raise it. This is most likely to happen
                    # with the Ads API.
                    # This will raise an exception if a JSON-like error object
                    # comes in the response.
                    self._parse(response.content)
                    # If Facebook does not provide any JSON-formatted error
                    # but just a plain-text, useless error, we'll just inform
                    # about a Facebook Internal errror occurred.
                    raise FacebookError(
                        'Internal Facebook error occurred',
                        response.status_code
                    )

            except requests.RequestException as exception:
                raise HTTPError(exception)

            result = self._parse(response.content)

            try:
                next_url = result['paging']['next']
            except (__HOLE__, TypeError):
                next_url = None

            return result, next_url

        def paginate(method, url, data):
            while url:
                result, url = load(method, url, data)

                # Reset pagination parameters.
                for key in ['offset', 'until', 'since']:
                    if key in data:
                        del data[key]

                yield result

        # Convert option lists to comma-separated values.
        for key in data:
            if isinstance(data[key], (list, set, tuple)) and all([isinstance(item, six.string_types) for item in data[key]]):
                data[key] = ','.join(data[key])

        # Support absolute paths too
        if not path.startswith('/'):
            if six.PY2:
                path = '/' + six.text_type(path.decode('utf-8'))
            else:
                path = '/' + path

        url = self._get_url(path)

        if self.oauth_token:
            data['access_token'] = self.oauth_token

        if self.appsecret and self.oauth_token:
            data['appsecret_proof'] = self._generate_appsecret_proof()

        try:
            if page:
                return paginate(method, url, data)
            else:
                return load(method, url, data)[0]
        except FacepyError:
            if retry:
                return self._query(method, path, data, page, retry - 1)
            else:
                raise
dataset/ETHPy150Open jgorset/facepy/facepy/graph_api.py/GraphAPI._query