Skip to content
Snippets Groups Projects

Ugliest shit you ever saw: get grafana dashboard as a screenshot.

The snippet can be accessed without any authentication.
Authored by Jan Harasym
Edited
grafana.py 4.44 KiB
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Don't ask
"""
import logging
import requests
from selenium import webdriver
from PIL import Image  # Pillow
from io import BytesIO
from os import getenv
from pprint import pprint
from time import sleep
if __name__ == '__main__':
    import sys
    import datetime

"""
curl -H "Authorization: Bearer <token>" http://msr-tctd-pgrafana01/api/dashboards/home
"""

_token = f"Bearer {getenv('HUNTER_GRAFANA_BEARER_TOKEN', '')}"
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.DEBUG)
grafana_host = getenv("HUNTER_GRAFANA_HOST", "https://grafana.prod.tctd2.ubisoft.com")


def deprecated_big_screen_dash_test(_from=1513604050864, _to=1513690450864):
    _tz = "CEST"
    LOGGER.debug(f"Range set from {_from} to {_to}")
    _url = (
        f"{grafana_host}/render/dashboard-solo/db/big-screen-dash-2?orgId=1&panelId=1" +
        f"&from={_from}&to={_to}&width=1000&height=800&tz={_tz}&kiosk=1&theme=light"
    )
    headers = {"Authorization": _token}
    _resp = requests.get(_url, headers=headers, stream=True)
    if _resp.ok:
        return _resp.raw
    else:
        raise Exception


def deprecated_solo_get(_from=0, _to=0, dashboardname="big-screen-dash-2", panelid=1):
    _tz = "CEST"
    LOGGER.debug(f"Range set from {_from} to {_to}")
    _url = (
        f"{grafana_host}/render/dashboard-solo/db/{dashboardname}?orgId=1&" +
        f"panelId={panelid}&from={_from}&to={_to}&width=1000&height=800&tz={_tz}&kiosk=1&theme=light"
    )
    headers = {"Authorization": _token}
    _resp = requests.get(_url, headers=headers, stream=True)
    if _resp.ok:
        return _resp.raw
    else:
        raise Exception


def deprecated_dashboard_get(_from=0, _to=0, dashboardname="big-screen-dash-2"):
    _tz = "CEST"
    LOGGER.debug(f"Range set from {_from} to {_to}")
    _url = (
        f"{grafana_host}/d/rLB28Gaik/concurrency-overview?refresh=5s&panelId=3&fullscreen&orgId=1"
        #f"{grafana_host}/render/dashboard/db/{dashboardname}?orgId=1&" +
        #f"from={_from}&to={_to}&width=1400&height=800&tz={_tz}&kiosk=1&theme=light"
    )
    headers = {"Authorization": _token}
    _resp = requests.get(_url, headers=headers, stream=True)
    #print(_resp.text)
    if _resp.ok:
        return _resp.raw
    else:
        raise Exception(_resp.text)


def dashboard_get(_from: int=0, _to: int=0):
    driver = webdriver.Chrome()

    #driver.get(f"{grafana_host}/login")
    driver.get(f"{grafana_host}/d/rLB28Gaik/concurrency-overview?refresh=5s&panelId=3&fullscreen&orgId=1&theme=light")
    driver.implicitly_wait(1)
    driver.find_element_by_id("login-view")
    driver.find_element_by_name("username").send_keys("[REDACTED]")
    driver.find_element_by_name("password").send_keys(r"[REDACTED]")
    driver.find_element_by_xpath(".//button[contains(text(), 'Log In')]").click()

    #driver.get(f"{grafana_host}/d/rLB28Gaik/concurrency-overview?refresh=300s&orgId=1&theme=light")
    LOGGER.info(pprint(driver.get_cookies()))
    driver.implicitly_wait(10)
    driver.stop_client()
    driver.fullscreen_window()  # otherwise we will get weird sizes
    sleep(2)  # we hope that it renders in 1s
    element = driver.find_element_by_class_name('dashboard-container')
    location = element.location
    size = element.size
    png = driver.get_screenshot_as_png()  # saves screenshot of entire page
    driver.quit()

    im = Image.open(BytesIO(png))  # uses PIL library to open image in memory

    left = location['x']
    top = location['y']
    right = location['x'] + size['width']
    bottom = location['y'] + size['height']
    im = im.crop((left, top, right, bottom))  # Crop the in-memory file to the size of the element. I don't know how big this is.
    return BytesIO(im._repr_png_())

if __name__ == "__console__" or __name__ == "__main__":
    ch = logging.StreamHandler(sys.stdout)
    ch.setLevel(logging.DEBUG)
    formatter = logging.Formatter(
        "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    )
    ch.setFormatter(formatter)
    LOGGER.addHandler(ch)
    _from = (
            datetime.datetime.now(datetime.timezone.utc)
            - datetime.timedelta(minutes=20)
    ).timestamp() * 1e3
    _to = datetime.datetime.now(datetime.timezone.utc).timestamp() * 1e3
    shit = dashboard_get(int(_from), int(_to)),
    with open('/tmp/grafana-test.png', 'wb') as f:
        f.write(shit[0])
        f.flush()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment