diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 51dd5a9cb..ff34b830b 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -28,7 +28,7 @@ jobs: - name: Install aspects run: pip install -e . - name: Tutor config save - run: tutor config save + run: tutor config save --set ASPECTS_XAPI_SOURCE=ralph - name: Setup Docker Buildx uses: docker/setup-buildx-action@v4 - name: Free Disk Space (Ubuntu) @@ -101,7 +101,7 @@ jobs: - name: Install aspects run: pip install -e . - name: Tutor config save - run: tutor config save + run: tutor config save --set ASPECTS_XAPI_SOURCE=ralph - name: Setup Docker Buildx uses: docker/setup-buildx-action@v4 - name: Free Disk Space (Ubuntu) @@ -185,7 +185,7 @@ jobs: run: | pip install -r requirements/dev.txt pip install -e . - tutor config save + tutor config save --set ASPECTS_XAPI_SOURCE=ralph - name: Run Kubernetes tools uses: stefanprodan/kube-tools@v1 with: @@ -588,6 +588,298 @@ jobs: echo "------------------------" } + # Loop through each job-related pod and print logs + for job_name in "${job_list[@]}"; do + # Get the pods related to the current job + job_pod_list=($(kubectl get pods | grep -E "${job_name}-.*" | awk '{print $1}')) + + for pod_name in "${job_pod_list[@]}"; do + print_pod_logs "$pod_name" + done + done + local-vector: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v5 + - name: setup python + uses: actions/setup-python@v6 + with: + python-version: 3.12 + - name: Install python reqs + run: pip install -r requirements/dev.txt + - name: Install aspects + run: pip install -e . + - name: Tutor config save + run: tutor config save --set ASPECTS_XAPI_SOURCE=vector + - name: Confirm DB + # This should be "openedx" + run: tutor config printvalue ASPECTS_XAPI_DATABASE + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be + with: + # this might remove tools that are actually needed, + # if set to "true" but frees about 6 GB + tool-cache: false + + # all of these default to true, but feel free to set to + # "false" if necessary for your workflow + android: true + dotnet: true + haskell: true + large-packages: false + swap-storage: true + - name: Tutor build openedx + run: tutor images build openedx aspects aspects-superset + - name: Tutor start + run: tutor local start -d + - name: Tutor init + run: tutor local do init + - name: Test alembic + run: | + tutor local do alembic -c "downgrade base" + tutor local do alembic -c "upgrade head" + - name: Init clickhouse + run: tutor local do init-clickhouse + # This should: + # 1. Run all models, since alembic test removed our state + # 2. Find no models on the first run, state should now be up to date now + # 3. Force run all models + # 4. Successfully run tests + - name: Test dbt + run: | + tutor local do dbt -c "run" + tutor local do dbt -c "run" + tutor local do dbt --only_changed False -c "run" + tutor local do dbt --only_changed False -c "test" + - name: Load test + run: tutor local do load-xapi-test-data + - name: Import demo course + run: tutor local do importdemocourse + - name: Test commands + run: | + tutor local do dump-data-to-clickhouse --options "--object course_overviews --force" + make extract_translations + tutor local do import-assets + tutor local do collect-dbt-lineage + tutor local run lms python manage.py lms transform_tracking_logs --source_provider LOCAL --source_config '{"key": "/openedx/data/", "prefix": "tracking.log", "container": "logs"}' --destination_provider LRS --transformer_type xapi + - name: Performance metrics + run: tutor local do performance-metrics --fail_on_error + - name: Tutor stop + run: tutor local stop + + dev-vector: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v5 + - name: setup python + uses: actions/setup-python@v6 + with: + python-version: 3.12 + - name: Install python reqs + run: pip install -r requirements/dev.txt + - name: Install aspects + run: pip install -e . + - name: Tutor config save + run: tutor config save --set ASPECTS_XAPI_SOURCE=vector + - name: Confirm DB + # This should be "openedx" + run: tutor config printvalue ASPECTS_XAPI_DATABASE + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be + with: + # this might remove tools that are actually needed, + # if set to "true" but frees about 6 GB + tool-cache: false + + # all of these default to true, but feel free to set to + # "false" if necessary for your workflow + android: true + dotnet: true + haskell: true + large-packages: false + swap-storage: true + - name: Tutor build openedx + run: tutor images build openedx-dev aspects aspects-superset + - name: Tutor start + run: tutor dev start -d + - name: Tutor init + run: tutor dev do init + - name: Test alembic + run: | + tutor dev do alembic -c "downgrade base" + tutor dev do alembic -c "upgrade head" + - name: Init clickhouse + run: tutor dev do init-clickhouse + # This should: + # 1. Run all models, since alembic test removed our state + # 2. Find no models on the first run, state should now be up to date now + # 3. Force run all models + # 4. Successfully run tests + - name: Test dbt + run: | + tutor dev do dbt -c "run" + tutor dev do dbt -c "run" + tutor dev do dbt --only_changed False -c "run" + tutor dev do dbt --only_changed False -c "test" + - name: Load test + run: tutor dev do load-xapi-test-data + - name: Import demo course + run: tutor dev do importdemocourse + - name: Test commands + run: | + tutor dev do dump-data-to-clickhouse --options "--object course_overviews --force" + make extract_translations + tutor dev do import-assets + - name: Performance metrics + run: tutor dev do performance-metrics --fail_on_error + - name: Tutor stop + run: tutor dev stop + + k8s-vector: + runs-on: ubuntu-latest + steps: + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be + with: + # this might remove tools that are actually needed, + # if set to "true" but frees about 6 GB + tool-cache: true + + # all of these default to true, but feel free to set to + # "false" if necessary for your workflow + android: true + dotnet: true + haskell: true + large-packages: false + swap-storage: true + - name: Checkout + uses: actions/checkout@v5 + - name: setup python + uses: actions/setup-python@v6 + with: + python-version: 3.12 + - name: Generate env + run: | + pip install -r requirements/dev.txt + pip install -e . + tutor config save --set ASPECTS_XAPI_SOURCE=vector + tutor config printvalue ASPECTS_XAPI_DATABASE | grep openedx + - name: Run Kubernetes tools + uses: stefanprodan/kube-tools@v1 + with: + kubectl: 1.23.0 + kustomize: 4.4.1 + helmv3: 3.7.2 + kubeconform: 0.4.13 + command: | + kustomize build $TUTOR_ROOT/env | kubeconform -strict -ignore-missing-schemas -kubernetes-version 1.22.0 + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Tutor build openedx + run: tutor images build openedx aspects aspects-superset + - name: Create k8s Kind Cluster + uses: helm/kind-action@v1.12.0 + - name: Mount docker image + run: | + kind get clusters + kind load docker-image $(tutor images printtag openedx) --name chart-testing + kind load docker-image $(tutor images printtag aspects) --name chart-testing + kind load docker-image $(tutor images printtag aspects-superset) --name chart-testing + - name: Setup namespace + run: | + kubectl config set-context --current --namespace=openedx + kubectl get pods + - name: Init k8s environment + run: | + tutor k8s start + tutor k8s do init + - name: Test alembic + run: | + tutor k8s do alembic -c "downgrade base" + tutor k8s do alembic -c "upgrade head" + - name: Init clickhouse + run: tutor k8s do init-clickhouse + # This should: + # 1. Run all models, since alembic test removed our state + # 2. Find no models on the first run, state should now be up to date now + # 3. Force run all models + # 4. Successfully run tests + - name: Test dbt + run: | + tutor k8s do dbt -c "run" + tutor k8s do dbt -c "run" + tutor k8s do dbt --only_changed False -c "run" + tutor k8s do dbt --only_changed False -c "test" + - name: Load test + run: tutor k8s do load-xapi-test-data + - name: Import demo course + run: tutor k8s do importdemocourse + - name: Test commands + run: | + tutor k8s do dump-data-to-clickhouse --options "--object course_overviews --force" + make extract_translations + tutor k8s do import-assets + - name: Performance metrics + run: tutor k8s do performance-metrics --fail_on_error + - name: Check failure logs + if: failure() + run: | + # Use an array to store pod names + pod_list=($(kubectl get pods -o jsonpath='{.items[*].metadata.name}')) + + failed_jobs="" + + # Loop through each pod and check for failure + for pod_name in "${pod_list[@]}"; do + # Get the pod phase/status + pod_phase=$(kubectl get pod "$pod_name" -o jsonpath='{.status.phase}') + + if [[ "$pod_phase" != "Running" && "$pod_phase" != "Succeeded" ]]; then + # Job is not in Running or Succeeded state, consider it as failed + failed_jobs="$failed_jobs $pod_name" + # Print the logs for the failing pod + echo "Failure logs for pod: $pod_name" + kubectl logs "$pod_name" + fi + done + + # Check if any jobs failed + if [ -n "$failed_jobs" ]; then + echo "The following jobs failed: $failed_jobs" + else + echo "All jobs succeeded." + fi + - name: Check service logs + if: failure() + run: | + # Use an array to store service names + service_list=($(kubectl get services -o jsonpath='{.items[*].metadata.name}')) + + # Loop through each service and print logs + for service_name in "${service_list[@]}"; do + echo "Logs for service: $service_name" + kubectl logs "svc/$service_name" + echo "------------------------" + done + - name: Check jobs logs + if: "!cancelled()" + run: | + job_list=($(kubectl get jobs | grep job | awk '{print $1}')) + + # Function to print logs for a pod + print_pod_logs() { + local pod_name="$1" + echo "Logs for pod: $pod_name" + kubectl logs "$pod_name" + echo "------------------------" + } + # Loop through each job-related pod and print logs for job_name in "${job_list[@]}"; do # Get the pods related to the current job diff --git a/tutoraspects/commands_v1.py b/tutoraspects/commands_v1.py index 9eefcc907..6973e9f58 100644 --- a/tutoraspects/commands_v1.py +++ b/tutoraspects/commands_v1.py @@ -74,7 +74,6 @@ def dbt(only_changed: bool, command: string) -> list[tuple[str, str]]: return [ ( "aspects", - "echo 'Making dbt script executable...' && " f"echo 'Running dbt, only_changed: {only_changed} command: {command}' && " f"bash /app/aspects/scripts/dbt.sh {only_changed} {command} && " "echo 'Done!';", @@ -108,9 +107,7 @@ def alembic(command: string) -> list[tuple[str, str]]: return [ ( "aspects", - "echo 'Making dbt script executable...' && " - f"bash /app/aspects/scripts/alembic.sh {command} && " - "echo 'Done!';", + f"bash /app/aspects/scripts/alembic.sh {command} && " "echo 'Done!';", ), ] diff --git a/tutoraspects/patches/local-docker-compose-jobs-services b/tutoraspects/patches/local-docker-compose-jobs-services index e2d24601d..faac08606 100644 --- a/tutoraspects/patches/local-docker-compose-jobs-services +++ b/tutoraspects/patches/local-docker-compose-jobs-services @@ -16,6 +16,9 @@ aspects-job: volumes: - ../../env/plugins/aspects/apps/aspects:/app/aspects - ../../env/plugins/aspects/apps/aspects/scripts/:/app/aspects/scripts:ro + {%- for mount in iter_mounts(MOUNTS, "aspects-job") %} + - {{ mount }} + {%- endfor %} {% if RUN_CLICKHOUSE %} depends_on: - clickhouse diff --git a/tutoraspects/patches/xapi-db-load-config-yaml b/tutoraspects/patches/xapi-db-load-config-yaml index 7c347801d..fb1b5ab8f 100644 --- a/tutoraspects/patches/xapi-db-load-config-yaml +++ b/tutoraspects/patches/xapi-db-load-config-yaml @@ -1,6 +1,6 @@ # Ralph / ClickHouse backend configuration # ######################################## -backend: ralph_clickhouse +backend: vector db_host: {{ CLICKHOUSE_HOST }} db_port: {{ CLICKHOUSE_INTERNAL_HTTP_PORT }} db_name: {{ ASPECTS_XAPI_DATABASE }} @@ -11,9 +11,10 @@ lrs_username: "{{RALPH_LMS_USERNAME}}" lrs_password: "{{RALPH_LMS_PASSWORD}}" # Run options -log_dir: -num_batches: 3 +log_dir: logs +num_xapi_batches: 3 batch_size: 100 +num_workers: 4 # Overall start and end date for the entire run start_date: 2014-01-01 diff --git a/tutoraspects/plugin.py b/tutoraspects/plugin.py index efe09979e..448356817 100644 --- a/tutoraspects/plugin.py +++ b/tutoraspects/plugin.py @@ -33,9 +33,9 @@ ("ASPECTS_VERSION", __version__), # For our default deployment we currently use Celery -> Ralph for transport, # so Vector is off by default. - ("RUN_VECTOR", False), + ("RUN_VECTOR", True), ("RUN_CLICKHOUSE", True), - ("RUN_RALPH", True), + ("RUN_RALPH", False), ("RUN_SUPERSET", True), ("DOCKER_IMAGE_ASPECTS", "edunext/aspects:{{ ASPECTS_VERSION }}"), ("DOCKER_IMAGE_CLICKHOUSE", "clickhouse/clickhouse-server:25.8"), @@ -61,7 +61,7 @@ # reasons. # Turn on event batching by default, performance is severely impacted by # turning this off. - ("EVENT_ROUTING_BACKEND_BATCHING_ENABLED", True), + ("EVENT_ROUTING_BACKEND_BATCHING_ENABLED", False), # Events are sent when they hit either the batch size or the batch interval # time limit (defaults here are 100 events or 5 seconds). # https://event-routing-backends.readthedocs.io/en/latest/getting_started.html#batching-configuration @@ -160,7 +160,7 @@ }, ), # ClickHouse xAPI settings - ("ASPECTS_XAPI_SOURCE", "ralph"), + ("ASPECTS_XAPI_SOURCE", "vector"), ( "ASPECTS_XAPI_DATABASE", """ @@ -181,7 +181,6 @@ ("ASPECTS_VECTOR_STORE_XAPI", True), ("ASPECTS_VECTOR_DATABASE", "openedx"), ("ASPECTS_VECTOR_RAW_TRACKING_LOGS_TABLE", "_tracking"), - ("ASPECTS_VECTOR_RAW_XAPI_TABLE", "xapi_events_all"), ("ASPECTS_DATA_TTL_EXPRESSION", "toDateTime(emission_time) + INTERVAL 1 YEAR"), ("ASPECTS_ALEMBIC_MIGRATIONS_DATABASE", "{{RALPH_DATABASE}}"), # Make sure LMS / CMS have event-routing-backends installed @@ -519,6 +518,11 @@ def _mount_superset_compose( """ if name == "superset": volumes += [("superset", "/app")] + elif name == "aspects-dbt": + volumes += [ + ("aspects-job", "/app/aspects-dbt"), + ("aspects-docs", "/app/aspects-dbt"), + ] return volumes diff --git a/tutoraspects/templates/aspects/apps/aspects/migrations/alembic/versions/0008_vector.py b/tutoraspects/templates/aspects/apps/aspects/migrations/alembic/versions/0008_vector.py index 0cf0cedce..cd8b9d65f 100644 --- a/tutoraspects/templates/aspects/apps/aspects/migrations/alembic/versions/0008_vector.py +++ b/tutoraspects/templates/aspects/apps/aspects/migrations/alembic/versions/0008_vector.py @@ -24,7 +24,7 @@ def upgrade(): ) op.execute( f""" - CREATE TABLE IF NOT EXISTS {{ ASPECTS_VECTOR_DATABASE }}.{{ ASPECTS_VECTOR_RAW_XAPI_TABLE }} + CREATE TABLE IF NOT EXISTS {{ ASPECTS_VECTOR_DATABASE }}.{{ ASPECTS_RAW_XAPI_TABLE }} {on_cluster} ( event_id UUID, @@ -40,7 +40,7 @@ def upgrade(): def downgrade(): op.execute( - "DROP TABLE IF EXISTS {{ ASPECTS_VECTOR_DATABASE }}.{{ ASPECTS_VECTOR_RAW_XAPI_TABLE }}" + "DROP TABLE IF EXISTS {{ ASPECTS_VECTOR_DATABASE }}.{{ ASPECTS_RAW_XAPI_TABLE }}" f"{on_cluster}" ) op.execute( diff --git a/tutoraspects/templates/aspects/apps/aspects/migrations/alembic/versions/0011_vector_replacingmergetree_xapi_raw.py b/tutoraspects/templates/aspects/apps/aspects/migrations/alembic/versions/0011_vector_replacingmergetree_xapi_raw.py index d78d71a85..8ef68ddd9 100644 --- a/tutoraspects/templates/aspects/apps/aspects/migrations/alembic/versions/0011_vector_replacingmergetree_xapi_raw.py +++ b/tutoraspects/templates/aspects/apps/aspects/migrations/alembic/versions/0011_vector_replacingmergetree_xapi_raw.py @@ -5,7 +5,7 @@ branch_labels = None depends_on = None -DESTINATION_TABLE = "{{ ASPECTS_VECTOR_DATABASE }}.{{ ASPECTS_VECTOR_RAW_XAPI_TABLE }}" +DESTINATION_TABLE = "{{ ASPECTS_VECTOR_DATABASE }}.{{ ASPECTS_RAW_XAPI_TABLE }}" TMP_TABLE_NEW = f"{DESTINATION_TABLE}_tmp_{revision}" TMP_TABLE_ORIG = f"{DESTINATION_TABLE}_tmp_mergetree_{revision}" on_cluster = ( diff --git a/tutoraspects/templates/aspects/apps/aspects/scripts/bootstrap.sh b/tutoraspects/templates/aspects/apps/aspects/scripts/bootstrap.sh index 34d38a1cc..783e4ea8c 100644 --- a/tutoraspects/templates/aspects/apps/aspects/scripts/bootstrap.sh +++ b/tutoraspects/templates/aspects/apps/aspects/scripts/bootstrap.sh @@ -1,6 +1,5 @@ #!/usr/bin/env bash - set -eo pipefail if [ -z "${DBT_SSH_KEY+x}" ] @@ -14,29 +13,45 @@ then ssh-add /root/.ssh/id_rsa fi -export branch=$(git -C aspects-dbt/ branch --show-current) -export repo=$(git -C aspects-dbt/ config --get remote.origin.url) -if [ "$DBT_BRANCH" != "$branch" ] || [ "$DBT_REPOSITORY" != "$repo" ]; -then - rm -rf aspects-dbt +git config --global --add safe.directory '*' - echo "Installing aspects-dbt" - echo "git clone -b ${DBT_BRANCH} ${DBT_REPOSITORY}" - git clone -b ${DBT_BRANCH} ${DBT_REPOSITORY} aspects-dbt +MOUNTED=false +if [ -d "aspects-dbt/.git" ]; then + current_branch=$(git -C aspects-dbt/ branch --show-current) + current_repo=$(git -C aspects-dbt/ config --get remote.origin.url) + if [ ! -f "aspects-dbt/.git/shallow" ]; then + MOUNTED=true + fi +fi - cd aspects-dbt +if [ "$MOUNTED" = true ]; then + echo "Using mounted repo (branch: ${current_branch})" +else + # Only re-clone if branch/repo differ or directory is missing + if [ ! -d "aspects-dbt/.git" ] \ + || [ "${DBT_BRANCH}" != "${current_branch}" ] \ + || [ "${DBT_REPOSITORY}" != "${current_repo}" ]; then - if [ -e "./requirements.txt" ] - then - echo "Installing dbt python requirements" - pip install -r ./requirements.txt + rm -rf aspects-dbt + + echo "Installing aspects-dbt" + echo "git clone -b ${DBT_BRANCH} ${DBT_REPOSITORY}" + git clone -b "${DBT_BRANCH}" "${DBT_REPOSITORY}" aspects-dbt else - echo "No requirements.txt file found; skipping" + echo "Using existing cloned repo (branch: ${current_branch})" fi +fi - echo "Installing dbt dependencies" - dbt deps +cd aspects-dbt +if [ -e "./requirements.txt" ]; then + echo "Installing dbt python requirements" + uv pip install -r ./requirements.txt --system +else + echo "No requirements.txt file found; skipping" fi -mkdir -p $DBT_STATE +echo "Installing dbt dependencies" +dbt deps + +mkdir -p "${DBT_STATE}" \ No newline at end of file diff --git a/tutoraspects/templates/aspects/apps/vector/k8s.toml b/tutoraspects/templates/aspects/apps/vector/k8s.toml index 025aa357a..8af523232 100644 --- a/tutoraspects/templates/aspects/apps/vector/k8s.toml +++ b/tutoraspects/templates/aspects/apps/vector/k8s.toml @@ -8,6 +8,6 @@ extra_namespace_label_selector = "kubernetes.io/metadata.name={{ K8S_NAMESPACE } [transforms.openedx_containers] type = "filter" inputs = ["kubernetes_logs"] -condition = '.kubernetes.pod_namespace == "{{ K8S_NAMESPACE }}" && includes(["lms", "cms", "lms-job", "cms-job", "lms-worker", "cms-worker"], .kubernetes.container_name)' +condition = '.kubernetes.pod_namespace == "{{ K8S_NAMESPACE }}" && includes(["lms", "cms", "lms-worker", "cms-worker", "lms-job", "cms-job", "aspects-job", "aspects-consumer"], .kubernetes.container_name)' {% include "aspects/apps/vector/partials/common-post.toml" %} diff --git a/tutoraspects/templates/aspects/apps/vector/local.toml b/tutoraspects/templates/aspects/apps/vector/local.toml index b0131b1f3..ccbbdc816 100644 --- a/tutoraspects/templates/aspects/apps/vector/local.toml +++ b/tutoraspects/templates/aspects/apps/vector/local.toml @@ -8,6 +8,6 @@ type = "docker_logs" [transforms.openedx_containers] type = "filter" inputs = ["docker_logs"] -condition = 'includes(["lms", "cms", "lms-worker", "cms-worker", "lms-job", "cms-job"], .label."com.docker.compose.service")' +condition = 'includes(["lms", "cms", "lms-worker", "cms-worker", "lms-job", "cms-job", "aspects-job", "aspects-consumer"], .label."com.docker.compose.service")' {% include "aspects/apps/vector/partials/common-post.toml" %} diff --git a/tutoraspects/templates/aspects/apps/vector/partials/common-post.toml b/tutoraspects/templates/aspects/apps/vector/partials/common-post.toml index 6bce1cb0b..dc2d91216 100644 --- a/tutoraspects/templates/aspects/apps/vector/partials/common-post.toml +++ b/tutoraspects/templates/aspects/apps/vector/partials/common-post.toml @@ -125,7 +125,7 @@ date_time_best_effort = true inputs = ["xapi"] endpoint = "{% if CLICKHOUSE_SECURE_CONNECTION %}https{% else %}http{% endif %}://{{ CLICKHOUSE_HOST }}:{{ CLICKHOUSE_INTERNAL_HTTP_PORT }}" database = "{{ ASPECTS_VECTOR_DATABASE }}" -table = "{{ ASPECTS_VECTOR_RAW_XAPI_TABLE }}" +table = "{{ ASPECTS_RAW_XAPI_TABLE }}" healthcheck = false {% endif %} diff --git a/tutoraspects/templates/aspects/build/aspects/Dockerfile b/tutoraspects/templates/aspects/build/aspects/Dockerfile index eb8885f30..ccfe6b24b 100644 --- a/tutoraspects/templates/aspects/build/aspects/Dockerfile +++ b/tutoraspects/templates/aspects/build/aspects/Dockerfile @@ -2,16 +2,15 @@ FROM python:3.12 WORKDIR /app +COPY --from=ghcr.io/astral-sh/uv:0.10.8 /uv /uvx /bin/ +ENV PATH="/root/.local/bin/:$PATH" COPY ./requirements.txt /app/requirements.txt -RUN pip install -r /app/requirements.txt - -RUN git clone -b {{ DBT_BRANCH }} {{ DBT_REPOSITORY }} aspects-dbt +RUN uv pip install -r /app/requirements.txt --system +RUN git clone --depth 1 -b {{ DBT_BRANCH }} {{ DBT_REPOSITORY }} aspects-dbt WORKDIR /app/aspects-dbt - -RUN pip install -r requirements.txt - +RUN uv pip install -r requirements.txt --system RUN dbt deps WORKDIR /app diff --git a/tutoraspects/templates/aspects/build/aspects/requirements.txt b/tutoraspects/templates/aspects/build/aspects/requirements.txt index bbbf5e7c1..9d2e003ac 100644 --- a/tutoraspects/templates/aspects/build/aspects/requirements.txt +++ b/tutoraspects/templates/aspects/build/aspects/requirements.txt @@ -1,5 +1,5 @@ # alembic packages alembic==1.14.1 clickhouse-sqlalchemy==0.3.2 -git+https://github.com/openedx/xapi-db-load@1.5.0 +git+https://github.com/Ian2012/xapi-db-load@tmp-v2 pyyaml