# Path: yams_api/plugins/dev/api_utils/http_methods.py
# def http_requests_get_to_dict(url, headers={}):
#     """Fetch content at a URL, returning a namedtuple of python-request module attributes
# 
#     :param url: url to scrape
#     :param headers: dict of headers to use for the request
#     :return: a namedtuple containing ('headers', 'text', 'status') for Pythonic scripting
#     """
# 
#     # Keep these outside of the try/except so we can potentially get metadata even on exceptions.
#     # Defines some placeholders to avoid a potential NameError
#     _headers = dict()
#     _status = 200
#     _status_major_code = 0
# 
#     try:
#         r = requests.get(url, headers=headers)
#         # r.content is a bytes obj and probably won't be json serializable.  could return a tuple
#         _status = r.status_code
#         _str_status = str(_status)
#         _status_major_code = int(_str_status[0]) # '200' -> '2' ->2
# 
#         rh = r.headers
#         rt = r.text
# 
#         # common headers
#         _headers["status_code"] = _status
#         _headers["etag"] = rh.get("etag", "")
#         _headers["date"] = rh.get("date", "")
#         _headers["last-modified"] = rh.get("last-modified", "")
#         _headers["content-type"] = rh.get("content-type", "")
#         _headers["raw_headers"] = dict(rh)
# 
#         _http_namedtuple = HTTPResponse(
#             _headers,
#             rt,
#             _status,
#             (_status_major_code == 2),
#             _status_major_code,
#             False
#         )
# 
#     except ConnectionError as e:
#         _headers["response"] = str(e)
# 
#         _http_namedtuple = HTTPResponse(
#             _headers,
#             str(e),
#             _status,
#             (_status_major_code == 2),
#             _status_major_code,
#             True)
# 
#     return _http_namedtuple


from lxml.html import fromstring as html_string
from yams_api.plugins.dev.api_utils.http_methods import http_requests_get_to_dict
        else:
            _resp["status"] = "nok"

        # sengrid does a .components-section .components-container, then N- .component-container (note singular)
        by_service_status_divs = _content_div.xpath("div[contains(@class, 'components-section')]/div[contains(@class, 'components-container')]/div[contains(@class, 'component-container')]")

        _serv_status = {}
        for _service in by_service_status_divs:


            # we have to look into child-components container that is at the same level, e.g.
            # <div class="component-container">
            #   <div class="component-inner-container">
            #   <div class="child-components-container"> -> div.component-inner-container -> [span.name, span.component-status]
            #
            # if not, it's simply:
            # <div class="component-container">
            #   <div class="component-inner-container"> -> [span.name, span.component-status]

            _child_components_container = _service.xpath("div[contains(@class, 'child-components-container')]")

            # if we have a child container, move our inspection to the scope of that div.  otherwise, leave
            # at the top level for depth searching
            if len(_child_components_container) > 0:

                # step back to iter point, get name of the service header and make it into a dict for subitem statuses
                _service_name = _service.xpath("div[contains(@class, 'component-inner-container')]/span[contains(@class, 'name')]/span")[1].text.strip()
                _resp["response"]["services"][_service_name] = dict()

                # move our "cursor" to the child components container for searching

# Path: yams_api/plugins/dev/api_utils/http_methods.py
# def http_requests_get_to_dict(url, headers={}):
#     """Fetch content at a URL, returning a namedtuple of python-request module attributes
# 
#     :param url: url to scrape
#     :param headers: dict of headers to use for the request
#     :return: a namedtuple containing ('headers', 'text', 'status') for Pythonic scripting
#     """
# 
#     # Keep these outside of the try/except so we can potentially get metadata even on exceptions.
#     # Defines some placeholders to avoid a potential NameError
#     _headers = dict()
#     _status = 200
#     _status_major_code = 0
# 
#     try:
#         r = requests.get(url, headers=headers)
#         # r.content is a bytes obj and probably won't be json serializable.  could return a tuple
#         _status = r.status_code
#         _str_status = str(_status)
#         _status_major_code = int(_str_status[0]) # '200' -> '2' ->2
# 
#         rh = r.headers
#         rt = r.text
# 
#         # common headers
#         _headers["status_code"] = _status
#         _headers["etag"] = rh.get("etag", "")
#         _headers["date"] = rh.get("date", "")
#         _headers["last-modified"] = rh.get("last-modified", "")
#         _headers["content-type"] = rh.get("content-type", "")
#         _headers["raw_headers"] = dict(rh)
# 
#         _http_namedtuple = HTTPResponse(
#             _headers,
#             rt,
#             _status,
#             (_status_major_code == 2),
#             _status_major_code,
#             False
#         )
# 
#     except ConnectionError as e:
#         _headers["response"] = str(e)
# 
#         _http_namedtuple = HTTPResponse(
#             _headers,
#             str(e),
#             _status,
#             (_status_major_code == 2),
#             _status_major_code,
#             True)
# 
#     return _http_namedtuple


# Path: yams_api/plugins/dev/sendgrid/methods.py
from lxml.html import fromstring as html_string
from yams_api.plugins.dev.api_utils.http_methods import http_requests_get_to_dict

        else:
            _resp["status"] = "nok"

        # sengrid does a .components-section .components-container, then N- .component-container (note singular)
        by_service_status_divs = _content_div.xpath("div[contains(@class, 'components-section')]/div[contains(@class, 'components-container')]/div[contains(@class, 'component-container')]")

        _serv_status = {}
        for _service in by_service_status_divs:


            # we have to look into child-components container that is at the same level, e.g.
            # <div class="component-container">
            #   <div class="component-inner-container">
            #   <div class="child-components-container"> -> div.component-inner-container -> [span.name, span.component-status]
            #
            # if not, it's simply:
            # <div class="component-container">
            #   <div class="component-inner-container"> -> [span.name, span.component-status]

            _child_components_container = _service.xpath("div[contains(@class, 'child-components-container')]")

            # if we have a child container, move our inspection to the scope of that div.  otherwise, leave
            # at the top level for depth searching
            if len(_child_components_container) > 0:

                # step back to iter point, get name of the service header and make it into a dict for subitem statuses
                _service_name = _service.xpath("div[contains(@class, 'component-inner-container')]/span[contains(@class, 'name')]/span")[1].text.strip()
                _resp["response"]["services"][_service_name] = dict()

                # move our "cursor" to the child components container for searching

                _cursor = _child_components_container