apache / superset

Apache Superset is a Data Visualization and Data Exploration Platform
https://superset.apache.org/
Apache License 2.0
61.8k stars 13.53k forks source link

Cannot create screenshot using chart REST API #17725

Closed Palamariuk closed 2 years ago

Palamariuk commented 2 years ago

I'm using dockerized Superset and trying to create a chart screenshot using /chart/{id}/screenshot/{digest} endpoint (with authentication and caching chart before that) but every time I receive {"message": "Not found"}.

My superset-config.py:

import logging
import os
from datetime import timedelta
from typing import Optional

from cachelib.file import FileSystemCache
from celery.schedules import crontab
from superset.typing import CacheConfig

logger = logging.getLogger()

def get_env_variable(var_name: str, default: Optional[str] = None) -> str:
    """Get the environment variable or raise exception."""
    try:
        return os.environ[var_name]
    except KeyError:
        if default is not None:
            return default
        else:
            error_msg = "The environment variable {} was missing, abort...".format(
                var_name
            )
            raise EnvironmentError(error_msg)

DATABASE_DIALECT = get_env_variable("DATABASE_DIALECT")
DATABASE_USER = get_env_variable("DATABASE_USER")
DATABASE_PASSWORD = get_env_variable("DATABASE_PASSWORD")
DATABASE_HOST = get_env_variable("DATABASE_HOST")
DATABASE_PORT = get_env_variable("DATABASE_PORT")
DATABASE_DB = get_env_variable("DATABASE_DB")

# The SQLAlchemy connection string.
SQLALCHEMY_DATABASE_URI = "%s://%s:%s@%s:%s/%s" % (
    DATABASE_DIALECT,
    DATABASE_USER,
    DATABASE_PASSWORD,
    DATABASE_HOST,
    DATABASE_PORT,
    DATABASE_DB,
)

REDIS_HOST = get_env_variable("REDIS_HOST")
REDIS_PORT = get_env_variable("REDIS_PORT")
REDIS_CELERY_DB = get_env_variable("REDIS_CELERY_DB", "0")
REDIS_RESULTS_DB = get_env_variable("REDIS_RESULTS_DB", "1")

BASE_CACHE_DIR = "/app/superset_home/sqllab"
CACHE_THRESHOLD = 1000
CACHE_DEFAULT_TIMEOUT = 100

FEATURE_FLAGS = {"ALERT_REPORTS": True, "THUMBNAILS": True, "THUMBNAILS_SQLA_LISTENERS": True}

CACHE_CONFIG: CacheConfig = {
    'CACHE_TYPE': 'redis',
    'CACHE_DEFAULT_TIMEOUT': 24*60*60, # 1 day
    'CACHE_KEY_PREFIX': 'superset_',
    'CACHE_REDIS_URL': 'redis://localhost:6379/3'
}
DATA_CACHE_CONFIG: CacheConfig = {
    'CACHE_TYPE': 'redis',
    'CACHE_DEFAULT_TIMEOUT': 24*60*60, # 1 day
    'CACHE_KEY_PREFIX': 'data_',
    'CACHE_REDIS_URL': 'redis://localhost:6379/3'
}
THUMBNAIL_SELENIUM_USER = "admin"
THUMBNAIL_CACHE_CONFIG: CacheConfig = {
    'CACHE_TYPE': 'redis',
    'CACHE_DEFAULT_TIMEOUT': 24*60*60,
    'CACHE_KEY_PREFIX': 'thumbnail_',
    'CACHE_NO_NULL_WARNING': True,
    'CACHE_REDIS_URL': 'redis://localhost:6379/3'
}

RESULTS_BACKEND = FileSystemCache(
    cache_dir=os.path.join(BASE_CACHE_DIR, 'results/'),
    threshold=CACHE_THRESHOLD,
    default_timeout=CACHE_DEFAULT_TIMEOUT
)

SCREENSHOT_LOCATE_WAIT = 100
SCREENSHOT_LOAD_WAIT = 600

class CeleryConfig(object):
    BROKER_URL = f"redis://{REDIS_HOST}:{REDIS_PORT}/{REDIS_CELERY_DB}"
    CELERY_IMPORTS = ("superset.sql_lab", "superset.tasks", 'superset.tasks.thumbnails')
    CELERY_RESULT_BACKEND = f"redis://{REDIS_HOST}:{REDIS_PORT}/{REDIS_RESULTS_DB}"
    CELERYD_LOG_LEVEL = "DEBUG"
    CELERYD_PREFETCH_MULTIPLIER = 10
    CELERY_ACKS_LATE = True
    CELERY_ANNOTATIONS = {
        'sql_lab.get_sql_results': {
            'rate_limit': '100/s',
        },
        'email_reports.send': {
            'rate_limit': '1/s',
            'time_limit': 600,
            'soft_time_limit': 600,
            'ignore_result': True,
        },
    }
    CELERYBEAT_SCHEDULE = {
        'reports.scheduler': {
            'task': 'reports.scheduler',
            'schedule': crontab(minute='*', hour='*'),
        },
        'reports.prune_log': {
            'task': 'reports.prune_log',
            'schedule': crontab(minute=0, hour=0),
        },
        'cache-warmup-hourly': {
            'task': 'cache-warmup',
            'schedule': crontab(minute='*/30', hour='*'),
            'kwargs': {
                'strategy_name': 'top_n_dashboards',
                'top_n': 10,
                'since': '7 days ago',
            },
       },
    }

CELERY_CONFIG = CeleryConfig

ALERT_REPORTS_NOTIFICATION_DRY_RUN = True

WEBDRIVER_TYPE = "firefox"
WEBDRIVER_BASEURL = "http://127.0.0.1:8088"  
WEBDRIVER_BASEURL_USER_FRIENDLY = WEBDRIVER_BASEURL

SQLLAB_CTAS_NO_LIMIT = True

try:
    import superset_config_docker
    from superset_config_docker import *  # noqa

    logger.info(
        f"Loaded your Docker configuration at " f"[{superset_config_docker.__file__}]"
    )
except ImportError:
    logger.info("Using default Docker config...")

Error in worker:

Failed at generating thumbnail Message: Reached error page: about:neterror?e=connectionFailure&u=http%3A//localhost%3A8088/superset/slice/292/%3Fstandalone%3Dtrue%26standalone%3D3&c=UTF-8&d=Firefox%20can%E2%80%99t%20establish%20a%20connection%20to%20the%20server%20at%20localhost%3A8088.
Traceback (most recent call last):
  File "/app/superset/utils/screenshots.py", line 152, in compute_and_cache
    payload = self.get_screenshot(user=user, window_size=window_size)
  File "/app/superset/utils/screenshots.py", line 74, in get_screenshot
    self.screenshot = driver.get_screenshot(self.url, self.element, user)
  File "/app/superset/utils/webdriver.py", line 117, in get_screenshot
    driver.get(url)
  File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 333, in get
    self.execute(Command.GET, {'url': url})
  File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: Reached error page: about:neterror?e=connectionFailure&u=http%3A//localhost%3A8088/superset/slice/292/%3Fstandalone%3Dtrue%26standalone%3D3&c=UTF-8&d=Firefox%20can%E2%80%99t%20establish%20a%20connection%20to%20the%20server%20at%20localhost%3A8088.

Thank you in advance!

betodealmeida commented 2 years ago

Can you try changing the URL?

WEBDRIVER_BASEURL = "http://host.docker.internal:8088/"
Palamariuk commented 2 years ago

Thank you very much, @betodealmeida! Everything works. Yes, the main problem was changing localhost to internal docker host (both superset and redis in my case)

mennymendoza commented 2 years ago

@Palamariuk Would you mind specifying what URL constants you changed? I'm having the same issue. Or @betodealmeida ?