Skip to content
This repository has been archived by the owner on Jun 20, 2023. It is now read-only.

Commit

Permalink
feat: adds superset docker services and open edx integrations
Browse files Browse the repository at this point in the history
* install custom requirements for mysql and OAuth2
* configure Superset to use the Open edX mysql service
* install custom oauth2 manager and course permissions plugin
* init OAuth2 application on LMS
  • Loading branch information
pomegranited committed Nov 30, 2022
1 parent e6d11af commit 99cddf7
Show file tree
Hide file tree
Showing 9 changed files with 670 additions and 7 deletions.
16 changes: 14 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,29 @@ Installation

::

pip install git+https://github.com/opencraft/tutor-contrib-superset
pip install git+https://github.com/open-craft/tutor-contrib-superset

Usage
-----

::

tutor plugins enable superset
tutor local start superset-launcher

# Initialize superset data
tutor local start superset-init

# Set up SSO
tutor dev init --limit superset_service


Connect to Superset's UI on the configured port (default is `:8088`):

http://local.overhang.io:8088


License
-------

This software is licensed under the terms of the AGPLv3.
This software is licensed under the terms of the AGPLv3.
134 changes: 129 additions & 5 deletions tutorsuperset/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@
# Each new setting is a pair: (setting_name, default_value).
# Prefix your setting names with 'SUPERSET_'.
("SUPERSET_VERSION", __version__),
("SUPERSET_TAG", "latest-dev"),
("SUPERSET_HOST", "{{ LMS_HOST }}"),
("SUPERSET_PORT", "8088"),
("SUPERSET_DB_DIALECT", "mysql"),
("SUPERSET_DB_HOST", "{{ MYSQL_HOST }}"),
("SUPERSET_DB_PORT", "{{ MYSQL_PORT }}"),
("SUPERSET_DB_NAME", "superset"),
("SUPERSET_DB_USERNAME", "superset"),
("SUPERSET_OAUTH2_BASE_URL", "{% if ENABLE_HTTPS %}https{% else %}http{% endif %}://{{ LMS_HOST }}"),
("SUPERSET_OAUTH2_ACCESS_TOKEN_URL", "{{ SUPERSET_OAUTH2_BASE_URL }}/oauth2/access_token/"),
("SUPERSET_OAUTH2_AUTHORIZE_URL", "{{ SUPERSET_OAUTH2_BASE_URL }}/oauth2/authorize/"),
("SUPERSET_OPENEDX_USERNAME_URL", "{{ SUPERSET_OAUTH2_BASE_URL }}/api/user/v1/me"),
("SUPERSET_OPENEDX_USER_PROFILE_URL", "{{ SUPERSET_OAUTH2_BASE_URL }}/api/user/v1/accounts/{username}"),
("SUPERSET_OPENEDX_COURSES_LIST_URL",
"{{ SUPERSET_OAUTH2_BASE_URL }}/api/courses/v1/courses/?permissions={permission}&username={username}"),
]
)

Expand All @@ -27,7 +42,10 @@
# Each new setting is a pair: (setting_name, unique_generated_value).
# Prefix your setting names with 'SUPERSET_'.
# For example:
# ("SUPERSET_SECRET_KEY", "{{ 24|random_string }}"),
("SUPERSET_SECRET_KEY", "{{ 24|random_string }}"),
("SUPERSET_DB_PASSWORD", "{{ 24|random_string }}"),
("SUPERSET_OAUTH2_CLIENT_ID", "{{ 16|random_string }}"),
("SUPERSET_OAUTH2_CLIENT_SECRET", "{{ 16|random_string }}"),
]
)

Expand All @@ -46,10 +64,10 @@
########################################

# To run the script from templates/superset/tasks/myservice/init, add:
# hooks.Filters.COMMANDS_INIT.add_item((
# "myservice",
# ("superset", "tasks", "myservice", "init"),
# ))
hooks.Filters.COMMANDS_INIT.add_item((
"superset_service",
("superset", "tasks", "init.sh"),
))


########################################
Expand Down Expand Up @@ -100,6 +118,112 @@
],
)

# docker-compose statements shared between the superset services
SUPERSET_DOCKER_COMPOSE_SHARED = """
image: apache/superset:{{ SUPERSET_TAG }}
environment:
DATABASE_DIALECT: {{ SUPERSET_DB_DIALECT }}
DATABASE_HOST: {{ SUPERSET_DB_HOST }}
DATABASE_PORT: {{ SUPERSET_DB_PORT }}
DATABASE_DB: {{ SUPERSET_DB_NAME }}
DATABASE_HOST: {{ SUPERSET_DB_HOST }}
DATABASE_PASSWORD: {{ SUPERSET_DB_PASSWORD }}
DATABASE_USER: {{ SUPERSET_DB_USERNAME }}
OPENEDX_MYSQL_HOST: {{ MYSQL_HOST }}
OPENEDX_MYSQL_PORT: {{ MYSQL_PORT }}
OPENEDX_MYSQL_DATABASE: {{ OPENEDX_MYSQL_DATABASE }}
OPENEDX_MYSQL_USERNAME: {{ OPENEDX_MYSQL_USERNAME }}
OPENEDX_MYSQL_PASSWORD: {{ OPENEDX_MYSQL_PASSWORD }}
OAUTH2_CLIENT_ID: {{ SUPERSET_OAUTH2_CLIENT_ID }}
OAUTH2_CLIENT_SECRET: {{ SUPERSET_OAUTH2_CLIENT_SECRET }}
OAUTH2_BASE_URL: {{ SUPERSET_OAUTH2_BASE_URL }}
OAUTH2_ACCESS_TOKEN_URL: {{ SUPERSET_OAUTH2_ACCESS_TOKEN_URL }}
OAUTH2_AUTHORIZE_URL: {{ SUPERSET_OAUTH2_AUTHORIZE_URL }}
OPENEDX_USERNAME_URL: {{ SUPERSET_OPENEDX_USERNAME_URL }}
OPENEDX_USER_PROFILE_URL: {{ SUPERSET_OPENEDX_USER_PROFILE_URL }}
OPENEDX_COURSES_LIST_URL: {{ SUPERSET_OPENEDX_COURSES_LIST_URL }}
SECRET_KEY: {{ SUPERSET_SECRET_KEY }}
PYTHONPATH: /app/pythonpath:/app/docker/pythonpath_dev
REDIS_HOST: superset_redis
REDIS_PORT: 6379
FLASK_ENV: production
SUPERSET_ENV: production
SUPERSET_LOAD_EXAMPLES: 0
CYPRESS_CONFIG: 0
SUPERSET_PORT: {{ SUPERSET_PORT }}
user: root
restart: unless-stopped
depends_on:
- mysql
- superset_redis
volumes:
- ../../env/plugins/superset/apps/docker:/app/docker
- ../../env/plugins/superset/apps/pythonpath:/app/pythonpath
- ../../env/plugins/superset/apps/superset_home:/app/superset_home
"""

hooks.Filters.ENV_PATCHES.add_item(
(
"local-docker-compose-services",
f"""
# Modified from https://github.com/apache/superset/blob/969c963/docker-compose-non-dev.yml
# FIXME -- should we use Open edX's redis service instead?
superset_redis:
image: redis:latest
restart: unless-stopped
volumes:
- ../../data/superset/redis:/data
superset_service:
{SUPERSET_DOCKER_COMPOSE_SHARED}
command: ["bash", "/app/docker/docker-bootstrap.sh", "app-gunicorn"]
ports:
- 8088:{{{{ SUPERSET_PORT }}}}
superset_worker:
{SUPERSET_DOCKER_COMPOSE_SHARED}
command: ["bash", "/app/docker/docker-bootstrap.sh", "worker"]
healthcheck:
test: ["CMD-SHELL", "celery inspect ping -A superset.tasks.celery_app:app -d celery@$$HOSTNAME"]
superset_worker-beat:
{SUPERSET_DOCKER_COMPOSE_SHARED}
command: ["bash", "/app/docker/docker-bootstrap.sh", "worker"]
healthcheck:
disable: true
# All the superset services we need to run together
superset-launcher:
image: apache/superset:{{{{ SUPERSET_TAG }}}}
command: ["bash"]
depends_on:
- superset_service
- superset_worker
- superset_worker-beat
# One-off data initialization
superset-init:
{SUPERSET_DOCKER_COMPOSE_SHARED}
command: ["bash", "/app/docker/docker-init.sh"]
healthcheck:
disable: true
"""
)
)

hooks.Filters.ENV_PATCHES.add_item(
(
"local-docker-compose-jobs-services",
"""
superset_service-jobs:
image: apache/superset:{{ SUPERSET_TAG }}
depends_on:
- superset-launcher
"""
)
)


########################################
# PATCH LOADING
Expand Down
54 changes: 54 additions & 0 deletions tutorsuperset/templates/superset/apps/docker/docker-bootstrap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# Copied from original:
#
# https://github.com/apache/superset/blob/969c963/docker/docker-bootstrap.sh

set -eo pipefail

REQUIREMENTS_LOCAL="/app/docker/requirements-local.txt"
# If Cypress run – overwrite the password for admin and export env variables
if [ "$CYPRESS_CONFIG" == "true" ]; then
export SUPERSET_CONFIG=tests.integration_tests.superset_test_config
export SUPERSET_TESTENV=true
export SUPERSET__SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://superset:superset@db:5432/superset
fi
#
# Make sure we have dev requirements installed
#
if [ -f "${REQUIREMENTS_LOCAL}" ]; then
echo "Installing local overrides at ${REQUIREMENTS_LOCAL}"
pip install -r "${REQUIREMENTS_LOCAL}"
else
echo "Skipping local overrides"
fi

if [[ "${1}" == "worker" ]]; then
echo "Starting Celery worker..."
celery --app=superset.tasks.celery_app:app worker -Ofair -l INFO
elif [[ "${1}" == "beat" ]]; then
echo "Starting Celery beat..."
celery --app=superset.tasks.celery_app:app beat --pidfile /tmp/celerybeat.pid -l INFO -s "${SUPERSET_HOME}"/celerybeat-schedule
elif [[ "${1}" == "app" ]]; then
echo "Starting web app..."
flask run -p 8088 --with-threads --reload --debugger --host=0.0.0.0
elif [[ "${1}" == "app-gunicorn" ]]; then
echo "Starting web app..."
/usr/bin/run-server.sh
fi
79 changes: 79 additions & 0 deletions tutorsuperset/templates/superset/apps/docker/docker-init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/usr/bin/env bash
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# Modified from original:
#
# https://github.com/apache/superset/blob/969c963/docker/docker-init.sh

set -e

STEP_CNT=4

echo_step() {
cat <<EOF
######################################################################
Init Step ${1}/${STEP_CNT} [${2}] -- ${3}
######################################################################
EOF
}
# Initialize the database
echo_step "1" "Starting" "Applying DB migrations"
superset db upgrade
echo_step "1" "Complete" "Applying DB migrations"

# If Cypress run – overwrite the password for admin and export env variables
if [ "$CYPRESS_CONFIG" == "true" ]; then
ADMIN_USERNAME="admin"
ADMIN_PASSWORD="general"
export SUPERSET_CONFIG=tests.integration_tests.superset_test_config
export SUPERSET_TESTENV=true
export SUPERSET__SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://superset:superset@db:5432/superset
# Create an admin user
echo_step "2" "Starting" "Setting up admin user ( $ADMIN_USERNAME / $ADMIN_PASSWORD )"
superset fab create-admin \
--username $ADMIN_USERNAME \
--firstname Superset \
--lastname Admin \
--email admin@superset.com \
--password $ADMIN_PASSWORD
echo_step "2" "Complete" "Setting up admin user"
fi

# Create default roles and permissions
echo_step "3" "Starting" "Setting up roles and perms"
superset init
echo_step "3" "Complete" "Setting up roles and perms"

if [ "$SUPERSET_LOAD_EXAMPLES" = "yes" ]; then
# Load some data to play with
echo_step "4" "Starting" "Loading examples"
# If Cypress run which consumes superset_test_config – load required data for tests
if [ "$CYPRESS_CONFIG" == "true" ]; then
superset load_test_users
superset load_examples --load-test-data
else
superset load_examples
fi
echo_step "4" "Complete" "Loading examples"
fi
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
authlib # OAuth2
mysqlclient
Loading

0 comments on commit 99cddf7

Please sign in to comment.