diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index a15810bd5c..641c278909 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -18,9 +18,3 @@ updates:
interval: "daily"
ignore:
- dependency-name: "*"
- - package-ecosystem: pip
- directory: /openfl-tutorials/interactive_api
- schedule:
- interval: "daily"
- ignore:
- - dependency-name: "*"
diff --git a/.github/workflows/docker-bench-security.yml b/.github/workflows/docker-bench-security.yml
index 3b5211f668..588c454187 100644
--- a/.github/workflows/docker-bench-security.yml
+++ b/.github/workflows/docker-bench-security.yml
@@ -3,12 +3,14 @@ name: Docker Bench for Security
on:
pull_request:
branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
jobs:
build:
+ if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
timeout-minutes: 10
diff --git a/.github/workflows/double_ws_export.yml b/.github/workflows/double_ws_export.yml
index 5f614cb720..bf9fe50965 100644
--- a/.github/workflows/double_ws_export.yml
+++ b/.github/workflows/double_ws_export.yml
@@ -6,6 +6,7 @@ name: Double workspace export
on:
pull_request:
branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
@@ -16,6 +17,7 @@ env:
jobs:
build:
+ if: github.event.pull_request.draft == false
runs-on: 'ubuntu-latest'
steps:
diff --git a/.github/workflows/experimental_workflow_tests.yml b/.github/workflows/experimental_workflow_tests.yml
index ab217cc6a5..ab039e5e52 100644
--- a/.github/workflows/experimental_workflow_tests.yml
+++ b/.github/workflows/experimental_workflow_tests.yml
@@ -5,13 +5,14 @@ on:
branches: [ develop ]
pull_request:
branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
jobs:
build:
- if: contains(github.event.pull_request.labels.*.name, 'workflow_interface')
+ if: (github.event.pull_request.draft == false && contains(github.event.pull_request.labels.*.name, 'workflow_interface'))
runs-on: ubuntu-latest
steps:
diff --git a/.github/workflows/gandlf.yml b/.github/workflows/gandlf.yml
index ff90a39c63..8a63492aa9 100644
--- a/.github/workflows/gandlf.yml
+++ b/.github/workflows/gandlf.yml
@@ -6,6 +6,7 @@ name: GaNDLF TaskRunner
on:
pull_request:
branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
@@ -16,7 +17,7 @@ env:
jobs:
build:
-
+ if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
diff --git a/.github/workflows/hadolint.yml b/.github/workflows/hadolint.yml
index aebc58fcca..265c457c43 100644
--- a/.github/workflows/hadolint.yml
+++ b/.github/workflows/hadolint.yml
@@ -6,13 +6,14 @@ name: Hadolint Security Scan
on:
pull_request:
branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
jobs:
build:
-
+ if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
diff --git a/.github/workflows/interactive-kvasir.yml b/.github/workflows/interactive-kvasir.yml
index 830da7abc5..93ff09126c 100644
--- a/.github/workflows/interactive-kvasir.yml
+++ b/.github/workflows/interactive-kvasir.yml
@@ -6,13 +6,14 @@ name: Interactive API - Pytorch Kvasir UNet
on:
pull_request:
branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
jobs:
build:
-
+ if: github.event.pull_request.draft == false
strategy:
matrix:
os: ['ubuntu-latest', 'windows-latest']
diff --git a/.github/workflows/interactive-tensorflow.yml b/.github/workflows/interactive-tensorflow.yml
index 4958ca139b..110ee1b175 100644
--- a/.github/workflows/interactive-tensorflow.yml
+++ b/.github/workflows/interactive-tensorflow.yml
@@ -6,12 +6,14 @@ name: Interactive API - Tensorflow MNIST
on:
pull_request:
branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
jobs:
build:
+ if: github.event.pull_request.draft == false
runs-on: ubuntu-latest # Add Windows support after https://github.com/keras-team/keras/issues/16308 is merged
steps:
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 1c7f9fe4aa..78b7278a4c 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -6,12 +6,14 @@ name: Check code format
on:
pull_request:
branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
jobs:
build:
+ if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
@@ -25,5 +27,5 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install -r linters-requirements.txt
- - name: Lint using built-in script
- run: bash shell/lint.sh
\ No newline at end of file
+ - name: Lint with OpenFL-specific rules
+ run: bash shell/lint.sh
diff --git a/.github/workflows/pki.yml b/.github/workflows/pki.yml
index 20471ef650..7d4f90df5c 100644
--- a/.github/workflows/pki.yml
+++ b/.github/workflows/pki.yml
@@ -6,6 +6,7 @@ name: Private Key Infrastructure
on:
pull_request:
branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
@@ -16,7 +17,7 @@ env:
jobs:
test_insecure_client:
-
+ if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
diff --git a/.github/workflows/pytest_coverage.yml b/.github/workflows/pytest_coverage.yml
index 6d50288ca8..f0543b62d1 100644
--- a/.github/workflows/pytest_coverage.yml
+++ b/.github/workflows/pytest_coverage.yml
@@ -6,6 +6,7 @@ name: Pytest and code coverage
on:
pull_request:
branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
workflow_dispatch:
permissions:
@@ -17,7 +18,7 @@ env:
jobs:
build:
-
+ if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
diff --git a/.github/workflows/straggler-handling.yml b/.github/workflows/straggler-handling.yml
index 9eead301db..dfb463104e 100644
--- a/.github/workflows/straggler-handling.yml
+++ b/.github/workflows/straggler-handling.yml
@@ -6,6 +6,7 @@ name: Straggler Handling Test
on:
pull_request:
branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
@@ -16,6 +17,7 @@ env:
jobs:
build:
+ if: github.event.pull_request.draft == false
strategy:
matrix:
os: ['ubuntu-latest', 'windows-latest']
diff --git a/.github/workflows/task_runner_e2e.yml b/.github/workflows/task_runner_e2e.yml
new file mode 100644
index 0000000000..9603db81cf
--- /dev/null
+++ b/.github/workflows/task_runner_e2e.yml
@@ -0,0 +1,161 @@
+---
+#---------------------------------------------------------------------------
+# Workflow to run Task Runner end to end tests
+# Authors - Noopur, Payal Chaurasiya
+#---------------------------------------------------------------------------
+name: Task Runner E2E
+
+on:
+ schedule:
+ - cron: "0 0 * * *" # Run every day at midnight
+ workflow_dispatch:
+ inputs:
+ num_rounds:
+ description: "Number of rounds to train"
+ required: false
+ default: "5"
+ type: string
+ num_collaborators:
+ description: "Number of collaborators"
+ required: false
+ default: "2"
+ type: string
+
+permissions:
+ contents: read
+
+# Environment variables common for all the jobs
+env:
+ NUM_ROUNDS: ${{ inputs.num_rounds || '5' }}
+ NUM_COLLABORATORS: ${{ inputs.num_collaborators || '2' }}
+
+jobs:
+ test:
+ name: tr_tls
+ runs-on: ubuntu-22.04
+ timeout-minutes: 120 # 2 hours
+ strategy:
+ matrix:
+ # There are open issues for some of the models, so excluding them for now:
+ # model_name: [ "torch_cnn_mnist", "keras_cnn_mnist", "torch_cnn_histology" ]
+ model_name: ["torch_cnn_mnist", "keras_cnn_mnist"]
+ python_version: ["3.8", "3.9", "3.10"]
+ fail-fast: false # do not immediately fail if one of the combinations fail
+
+ env:
+ MODEL_NAME: ${{ matrix.model_name }}
+ PYTHON_VERSION: ${{ matrix.python_version }}
+
+ steps:
+ - name: Checkout OpenFL repository
+ id: checkout_openfl
+ uses: actions/checkout@v4.1.1
+ with:
+ fetch-depth: 2 # needed for detecting changes
+ submodules: "true"
+ token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Set up Python
+ id: setup_python
+ uses: actions/setup-python@v3
+ with:
+ python-version: ${{ env.PYTHON_VERSION }}
+
+ - name: Install dependencies
+ id: install_dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install .
+ pip install -r test-requirements.txt
+
+ - name: Run Task Runner E2E tests with TLS
+ id: run_tests
+ run: |
+ python -m pytest -s tests/end_to_end/test_suites/task_runner_tests.py -m ${{ env.MODEL_NAME }} --num_rounds $NUM_ROUNDS --num_collaborators $NUM_COLLABORATORS --model_name ${{ env.MODEL_NAME }}
+ echo "Task runner end to end test run completed"
+
+ - name: Print test summary # Print the test summary only if the tests were run
+ id: print_test_summary
+ if: steps.run_tests.outcome == 'success' || steps.run_tests.outcome == 'failure'
+ run: |
+ export PYTHONPATH="$PYTHONPATH:."
+ python tests/end_to_end/utils/summary_helper.py
+ echo "Test summary printed"
+
+ - name: Tar files # Tar the test results only if the tests were run
+ id: tar_files
+ if: steps.run_tests.outcome == 'success' || steps.run_tests.outcome == 'failure'
+ run: tar -cvf result.tar results
+
+ - name: Upload Artifacts # Upload the test results only if the tar was created
+ id: upload_artifacts
+ uses: actions/upload-artifact@v4
+ if: steps.tar_files.outcome == 'success'
+ with:
+ name: task_runner_tls_${{ env.MODEL_NAME }}_python${{ env.PYTHON_VERSION }}_${{ github.run_id }}
+ path: result.tar
+
+ test_with_non_tls:
+ name: tr_non_tls
+ runs-on: ubuntu-22.04
+ timeout-minutes: 120 # 2 hours
+ strategy:
+ matrix:
+ # Testing non TLS scenario only for torch_cnn_mnist model and python 3.10
+ # If required, this can be extended to other models and python versions
+ model_name: ["torch_cnn_mnist"]
+ python_version: ["3.10"]
+ fail-fast: false # do not immediately fail if one of the combinations fail
+
+ env:
+ MODEL_NAME: ${{ matrix.model_name }}
+ PYTHON_VERSION: ${{ matrix.python_version }}
+
+ steps:
+ - name: Checkout OpenFL repository
+ id: checkout_openfl
+ uses: actions/checkout@v4.1.1
+ with:
+ fetch-depth: 2 # needed for detecting changes
+ submodules: "true"
+ token: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Set up Python
+ id: setup_python
+ uses: actions/setup-python@v3
+ with:
+ python-version: ${{ env.PYTHON_VERSION }}
+
+ - name: Install dependencies
+ id: install_dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install .
+ pip install -r test-requirements.txt
+
+ - name: Run Task Runner E2E tests without TLS
+ id: run_tests
+ run: |
+ python -m pytest -s tests/end_to_end/test_suites/task_runner_tests.py -m ${{ env.MODEL_NAME }} --num_rounds $NUM_ROUNDS --num_collaborators $NUM_COLLABORATORS --disable_tls
+ echo "Task runner end to end test run completed"
+
+ - name: Print test summary # Print the test summary only if the tests were run
+ id: print_test_summary
+ if: steps.run_tests.outcome == 'success' || steps.run_tests.outcome == 'failure'
+ run: |
+ export PYTHONPATH="$PYTHONPATH:."
+ python tests/end_to_end/utils/summary_helper.py
+ echo "Test summary printed"
+
+ - name: Tar files # Tar the test results only if the tests were run
+ id: tar_files
+ if: steps.run_tests.outcome == 'success' || steps.run_tests.outcome == 'failure'
+ run: tar -cvf result.tar results
+
+ - name: Upload Artifacts # Upload the test results only if the tar was created
+ id: upload_artifacts
+ uses: actions/upload-artifact@v4
+ if: steps.tar_files.outcome == 'success'
+ with:
+ name: task_runner_non_tls_${{ env.MODEL_NAME }}_python${{ env.PYTHON_VERSION }}_${{ github.run_id }}
+ path: result.tar
diff --git a/.github/workflows/taskrunner.yml b/.github/workflows/taskrunner.yml
index ea172e0732..1ae8a5af8b 100644
--- a/.github/workflows/taskrunner.yml
+++ b/.github/workflows/taskrunner.yml
@@ -6,6 +6,7 @@ name: TaskRunner
on:
pull_request:
branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
@@ -16,6 +17,7 @@ env:
jobs:
build:
+ if: github.event.pull_request.draft == false
strategy:
matrix:
os: ['ubuntu-latest', 'windows-latest']
diff --git a/.github/workflows/taskrunner_eden_pipeline.yml b/.github/workflows/taskrunner_eden_pipeline.yml
index cc35747ca5..e103fcf2aa 100644
--- a/.github/workflows/taskrunner_eden_pipeline.yml
+++ b/.github/workflows/taskrunner_eden_pipeline.yml
@@ -5,14 +5,15 @@ name: TaskRunner (Eden Compression)
on:
pull_request:
- branches: [ develop ]
+ branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
jobs:
build:
- if: contains(github.event.pull_request.labels.*.name, 'eden_compression')
+ if: (github.event.pull_request.draft == false && contains(github.event.pull_request.labels.*.name, 'eden_compression'))
strategy:
matrix:
os: ['ubuntu-latest', 'windows-latest']
diff --git a/.github/workflows/tr_docker_gramine_direct.yml b/.github/workflows/tr_docker_gramine_direct.yml
new file mode 100644
index 0000000000..d8f7480ea1
--- /dev/null
+++ b/.github/workflows/tr_docker_gramine_direct.yml
@@ -0,0 +1,97 @@
+# Tests an FL experiment in a Dockerized environment.
+name: TaskRunner (docker/gramine-direct)
+
+on:
+ pull_request:
+ branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ if: github.event.pull_request.draft == false
+ runs-on: ubuntu-latest
+ timeout-minutes: 10
+
+ steps:
+ - uses: actions/checkout@v3
+ - name: Set up Python 3.8
+ uses: actions/setup-python@v3
+ with:
+ python-version: "3.8"
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install .
+
+ - name: Create workspace image
+ run: |
+ fx workspace create --prefix example_workspace --template keras_cnn_mnist
+ cd example_workspace
+ fx plan initialize -a localhost
+ fx workspace dockerize --save --revision https://github.com/${GITHUB_REPOSITORY}.git@${{ github.event.pull_request.head.sha }}
+
+ - name: Create certificate authority for workspace
+ run: |
+ cd example_workspace
+ fx workspace certify
+
+ - name: Create signed cert for collaborator
+ run: |
+ cd example_workspace
+ fx collaborator create -d 1 -n charlie --silent
+ fx collaborator generate-cert-request -n charlie --silent
+ fx collaborator certify --request-pkg col_charlie_to_agg_cert_request.zip --silent
+
+ # Pack the collaborator's private key, signed cert, and data.yaml into a tarball
+ tarfiles="plan/data.yaml agg_to_col_charlie_signed_cert.zip"
+ for entry in cert/client/*; do
+ if [[ "$entry" == *.key ]]; then
+ tarfiles="$tarfiles $entry"
+ fi
+ done
+
+ tar -cf cert_col_charlie.tar $tarfiles
+
+ # Clean up
+ rm -f $tarfiles
+ rm -f col_charlie_to_agg_cert_request.zip
+
+ - name: Create signed cert for aggregator
+ run: |
+ cd example_workspace
+ fx aggregator generate-cert-request --fqdn localhost
+ fx aggregator certify --fqdn localhost --silent
+
+ # Pack all files that aggregator needs to start training
+ tar -cf cert_agg.tar plan cert save
+
+ # Remove the directories after archiving
+ rm -rf plan cert save
+
+ - name: Load workspace image
+ run: |
+ cd example_workspace
+ docker load -i example_workspace.tar
+
+ - name: Run aggregator and collaborator
+ run: |
+ cd example_workspace
+
+ set -x
+ docker run --rm \
+ --network host \
+ --security-opt seccomp=unconfined \
+ --mount type=bind,source=./cert_agg.tar,target=/certs.tar \
+ --env KERAS_HOME=/tmp \
+ example_workspace bash -c "tar -xf /certs.tar && gramine-direct fx aggregator start" &
+
+ # TODO: Run with two collaborators instead.
+ docker run --rm \
+ --network host \
+ --security-opt seccomp=unconfined \
+ --mount type=bind,source=./cert_col_charlie.tar,target=/certs.tar \
+ --env KERAS_HOME=/tmp \
+ example_workspace bash -c "tar -xf /certs.tar && fx collaborator certify --import agg_to_col_charlie_signed_cert.zip && gramine-direct fx collaborator start -n charlie"
\ No newline at end of file
diff --git a/.github/workflows/dockerization.yml b/.github/workflows/tr_docker_native.yml
similarity index 95%
rename from .github/workflows/dockerization.yml
rename to .github/workflows/tr_docker_native.yml
index 07e41c95b7..899fcd8296 100644
--- a/.github/workflows/dockerization.yml
+++ b/.github/workflows/tr_docker_native.yml
@@ -1,15 +1,17 @@
# Tests an FL experiment in a Dockerized environment.
-name: Dockerization
+name: TaskRunner (docker/native)
on:
pull_request:
branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
jobs:
build:
+ if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
timeout-minutes: 10
diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml
index 40e3cafbfd..8a303bd765 100644
--- a/.github/workflows/trivy.yml
+++ b/.github/workflows/trivy.yml
@@ -3,12 +3,15 @@ on:
push:
branches: [ develop ]
pull_request:
+ branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
jobs:
build:
+ if: github.event.pull_request.draft == false
permissions:
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
- actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
+ actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
name: Build
runs-on: ubuntu-22.04
steps:
@@ -20,11 +23,13 @@ jobs:
docker build --pull -t docker.io/securefederatedai/openfl:${{ github.sha }} -f openfl-docker/Dockerfile.base .
- name: Run Trivy vulnerability scanner
- uses: aquasecurity/trivy-action@0.24.0
+ uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: 'docker.io/securefederatedai/openfl:${{ github.sha }}'
format: 'sarif'
output: 'trivy-results.sarif'
+ env:
+ TRIVY_DB_REPOSITORY: 'ghcr.io/aquasecurity/trivy-db,public.ecr.aws/aquasecurity/trivy-db'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
@@ -53,7 +58,7 @@ jobs:
path: trivy-code-results.json
- name: Run Trivy vulnerability scanner for Docker image (JSON Output)
- uses: aquasecurity/trivy-action@0.24.0
+ uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: 'docker.io/securefederatedai/openfl:${{ github.sha }}'
format: 'json'
@@ -62,6 +67,8 @@ jobs:
ignore-unfixed: true
vuln-type: 'os,library'
severity: 'CRITICAL,HIGH,MEDIUM,LOW'
+ env:
+ TRIVY_DB_REPOSITORY: 'ghcr.io/aquasecurity/trivy-db,public.ecr.aws/aquasecurity/trivy-db'
- name: Upload Docker Vulnerability Scan
uses: actions/upload-artifact@v3
@@ -87,7 +94,7 @@ jobs:
path: trivy-code-spdx-results.json
- name: Run Trivy vulnerability scanner for Docker image (SPDX-JSON Output)
- uses: aquasecurity/trivy-action@0.24.0
+ uses: aquasecurity/trivy-action@0.28.0
with:
image-ref: 'docker.io/securefederatedai/openfl:${{ github.sha }}'
format: 'spdx-json'
@@ -96,6 +103,8 @@ jobs:
ignore-unfixed: true
vuln-type: 'os,library'
severity: 'CRITICAL,HIGH,MEDIUM,LOW'
+ env:
+ TRIVY_DB_REPOSITORY: 'ghcr.io/aquasecurity/trivy-db,public.ecr.aws/aquasecurity/trivy-db'
- name: Upload Docker Vulnerability Scan
uses: actions/upload-artifact@v3
diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml
index 1c1dfe49c7..175e71b862 100644
--- a/.github/workflows/ubuntu.yml
+++ b/.github/workflows/ubuntu.yml
@@ -7,6 +7,10 @@ on:
permissions:
contents: read
+env:
+ # A workaround for long FQDN names provided by GitHub actions.
+ FQDN: "localhost"
+
jobs:
lint: # from lint.yml
runs-on: ubuntu-latest
@@ -16,14 +20,12 @@ jobs:
uses: actions/setup-python@v3
with:
python-version: "3.8"
- - name: Install dependencies
+ - name: Install linters
run: |
python -m pip install --upgrade pip
pip install -r linters-requirements.txt
- pip install .
- - name: Lint with flake8
- run: |
- flake8 --show-source
+ - name: Lint with OpenFL-specific rules
+ run: bash shell/lint.sh
pytest-coverage: # from pytest_coverage.yml
needs: lint
@@ -45,28 +47,8 @@ jobs:
coverage run -m pytest -rA
coverage report
- interactive-kvasir: # from interactive-kvasir.yml
- needs: [lint, pytest-coverage]
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - name: Set up Python 3.8
- uses: actions/setup-python@v3
- with:
- python-version: "3.8"
- - name: Install dependencies
- run: |
- python -m pip install --upgrade pip
- pip install .
- - name: Interactive API - pytorch_kvasir_unet
- run: |
- python setup.py build_grpc
- pip install torch==1.13.1
- pip install torchvision==0.14.1
- python -m tests.github.interactive_api_director.experiments.pytorch_kvasir_unet.run
-
cli:
- needs: [lint, pytest-coverage, interactive-kvasir]
+ needs: [lint, pytest-coverage]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index f7d9ca30b9..bd751fc10c 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -7,6 +7,10 @@ on:
permissions:
contents: read
+env:
+ # A workaround for long FQDN names provided by GitHub actions.
+ FQDN: "localhost"
+
jobs:
pytest-coverage: # from pytest_coverage.yml
runs-on: windows-latest
@@ -27,28 +31,8 @@ jobs:
coverage run -m pytest -rA
coverage report
- interactive-kvasir: # from interactive-kvasir.yml
- needs: [pytest-coverage]
- runs-on: windows-latest
- steps:
- - uses: actions/checkout@v3
- - name: Set up Python 3.8
- uses: actions/setup-python@v3
- with:
- python-version: "3.8"
- - name: Install dependencies
- run: |
- python -m pip install --upgrade pip
- pip install .
- - name: Interactive API - pytorch_kvasir_unet
- run: |
- python setup.py build_grpc
- pip install torch==1.13.1
- pip install torchvision==0.14.1
- python -m tests.github.interactive_api_director.experiments.pytorch_kvasir_unet.run
-
cli: # from taskrunner.yml
- needs: [pytest-coverage, interactive-kvasir]
+ needs: [pytest-coverage]
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
diff --git a/.github/workflows/workflow_interface_101_mnist.yml b/.github/workflows/workflow_interface_101_mnist.yml
index 1f2c75c95a..a980d1088d 100644
--- a/.github/workflows/workflow_interface_101_mnist.yml
+++ b/.github/workflows/workflow_interface_101_mnist.yml
@@ -7,6 +7,7 @@ name: Workflow Interface 101 MNIST Notebook
on:
pull_request:
branches: [ develop ]
+ types: [opened, synchronize, reopened, ready_for_review]
workflow_dispatch:
@@ -15,6 +16,7 @@ permissions:
jobs:
run_notebook:
+ if: github.event.pull_request.draft == false
runs-on: ubuntu-22.04
steps:
- name: Checkout OpenFL repository
diff --git a/.gitignore b/.gitignore
index 578b6ed112..8a106933ef 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,4 @@ venv/*
.eggs
eggs/*
*.pyi
+results/*
\ No newline at end of file
diff --git a/README.md b/README.md
index 50ef28ba66..aba069a867 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@
-[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/intel/openfl/blob/develop/openfl-tutorials/interactive_api/numpy_linear_regression/workspace/SingleNotebook.ipynb)
+[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/intel/openfl/blob/develop/openfl-tutorials/Federated_Pytorch_MNIST_Tutorial.ipynb)
Open Federated Learning (OpenFL) is a Python 3 framework for Federated Learning. OpenFL is designed to be a _flexible_, _extensible_ and _easily learnable_ tool for data scientists. OpenFL is hosted by The Linux Foundation, aims to be community-driven, and welcomes contributions back to the project.
@@ -37,9 +37,6 @@ For more installation options check out the [online documentation](https://openf
OpenFL enables data scientists to set up a federated learning experiment following one of the workflows:
-- [Director-based Workflow](https://openfl.readthedocs.io/en/latest/about/features_index/interactive.html):
-Setup long-lived components to run many experiments in series. Recommended for FL research when many changes to model, dataloader, or hyperparameters are expected
-
- [Aggregator-based Workflow](https://openfl.readthedocs.io/en/latest/about/features_index/taskrunner.html):
Define an experiment and distribute it manually. All participants can verify model code and [FL plan](https://openfl.readthedocs.io/en/latest/about/features_index/taskrunner.html#federated-learning-plan-fl-plan-settings) prior to execution. The federation is terminated when the experiment is finished
diff --git a/docs/about/features.rst b/docs/about/features.rst
index 4bb5b5f9d3..d57569484f 100644
--- a/docs/about/features.rst
+++ b/docs/about/features.rst
@@ -23,7 +23,7 @@ Task Runner
features_index/taskrunner
-Interactive
+Interactive (Deprecated)
Setup long-lived components to run many experiments in series. Recommended for FL research when many changes to model, dataloader, or hyperparameters are expected.
Formerly known as the director-based workflow.
For more info see :doc:`features_index/interactive`
@@ -83,7 +83,6 @@ FedCurv
Use :py:class:`openfl.utilities.fedcurv.torch.FedCurv` to override train function using :code:`.get_penalty()`, :code:`.on_train_begin()`, and :code:`.on_train_end()` methods.
In addition, you should override default :code:`AggregationFunction` of the train task with :class:`openfl.interface.aggregation_functions.FedCurvWeightedAverage`.
- See :code:`PyTorch_Histology_FedCurv` tutorial in :code:`../openfl-tutorials/interactive_api` directory for more details.
.. _federated_evaluation:
@@ -110,4 +109,4 @@ Quantitatively audit data privacy in statistical and machine learning algorithms
:hidden:
features_index/privacy_meter
-
\ No newline at end of file
+
diff --git a/docs/about/features_index/interactive.rst b/docs/about/features_index/interactive.rst
index 3a37e2992c..ea7654443c 100644
--- a/docs/about/features_index/interactive.rst
+++ b/docs/about/features_index/interactive.rst
@@ -3,9 +3,9 @@
.. _running_interactive:
-================
-Interactive API
-================
+============================
+Interactive API (Deprecated)
+============================
A director-based workflow uses long-lived components in a federation. These components continue to be available to distribute more experiments in the federation.
@@ -670,4 +670,4 @@ Assigner with additional validation round:
.. toctree
.. overview.how_can_intel_protect_federated_learning
-.. overview.what_is_intel_federated_learning
\ No newline at end of file
+.. overview.what_is_intel_federated_learning
diff --git a/docs/about/features_index/taskrunner.rst b/docs/about/features_index/taskrunner.rst
index 4e67622088..f4e3cc0730 100644
--- a/docs/about/features_index/taskrunner.rst
+++ b/docs/about/features_index/taskrunner.rst
@@ -112,7 +112,7 @@ Each task subsection contains the following:
.. _running_the_federation_manual:
-.. _interactive_api:
+.. _interactive_api (Deprecated):
diff --git a/docs/about/releases.md b/docs/about/releases.md
index b1aa526bcc..22ffc7443b 100644
--- a/docs/about/releases.md
+++ b/docs/about/releases.md
@@ -11,7 +11,7 @@
- **Workflow API enhancements**: Introducing an experimental [Workspace Export](https://github.com/securefederatedai/openfl/blob/develop/openfl-tutorials/experimental/1001_Workspace_Creation_from_JupyterNotebook.ipynb) feature that can be used to transform a Workflow API-based FL experiment into the TaskRunner API format for running in a distributed deployment. There is also groundwork laid for a future FederatedRuntime implementation for Workflow API, in addition to the currently supported LocalRuntime.
- **Federated Evaluation**: Federated evaluation allows for the assessment of ML models in a federated learning system by validating the model's performance locally on decentralized collaborator nodes, and then aggregating these metrics to gauge overall effectiveness, without compromising data privacy and security. FE is now officially supported by OpenFL, including [example tutorials](https://openfl.readthedocs.io/en/latest/about/features_index/fed_eval.html) on how to use this new feature (via TaskRunner API).
-- **Expanded AI Accelerator Support**: Intel® Data Center GPU Max Series support via the Intel® Extension for PyTorch, including examples for training on datasets such as [MNIST](https://github.com/securefederatedai/openfl/blob/develop/openfl-tutorials/experimental/104_MNIST_XPU.ipynb) (via Workflow API) and [TinyImageNet](https://github.com/securefederatedai/openfl/tree/develop/openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU) (via Interactive API)
+- **Expanded AI Accelerator Support**: Intel® Data Center GPU Max Series support via the Intel® Extension for PyTorch, including examples for training on datasets such as [MNIST](https://github.com/securefederatedai/openfl/blob/develop/openfl-tutorials/experimental/104_MNIST_XPU.ipynb) (via Workflow API) and [TinyImageNet](https://github.com/securefederatedai/openfl/tree/main/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU) (via Interactive API)
- **Improved straggler collaborator handling**: Improvements and bug fixes to aggregator’s fault-tolerance when collaborators stop responding or drop out of a federation. Introducing a cut-off timer-based policy and enabling other policies to be plugged-in. This capability is particularly relevant for large or geo-distributed federations.
@@ -35,9 +35,9 @@ We are excited to announce the release of OpenFL 1.5.1 - our first since moving
- **Documentation accessibility improvements**: As part of our [Global Accessibility Awareness Day](https://www.intel.com/content/www/us/en/developer/articles/community/open-fl-project-improve-accessibility-for-devs.html) (GAAD) Pledge, the OpenFL project is making strides towards more accessible documentation. This release includes the integration of [Intel® One Mono](https://www.intel.com/content/www/us/en/company-overview/one-monospace-font.html) font, contrast color improvements, formatting improvements, and [new accessibility focused issues](https://github.com/securefederatedai/openfl/issues?q=is%3Aissue+is%3Aopen+accessibility) to take up in the future.
- **[Documentation to federate a Generally Nuanced Deep Learning Framework (GaNDLF) model with OpenFL](https://openfl.readthedocs.io/en/latest/running_the_federation_with_gandlf.html)**
- **New OpenFL Interactive API Tutorials**:
- - [Linear regression with SciKit-Learn](https://github.com/securefederatedai/openfl/tree/develop/openfl-tutorials/interactive_api/scikit_learn_linear_regression)
- - [MedMNIST 2D Classification Using FedProx Optimizer](https://github.com/securefederatedai/openfl/blob/develop/openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/README.md?plain=1)
- - [PyTorch Linear Regression Example](https://github.com/securefederatedai/openfl/tree/develop/openfl-tutorials/interactive_api/PyTorch_LinearRegression)
+ - [Linear regression with SciKit-Learn](https://github.com/securefederatedai/openfl/tree/main/openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression)
+ - [MedMNIST 2D Classification Using FedProx Optimizer](https://github.com/securefederatedai/openfl/tree/main/openfl-tutorials/deprecaed/interactive_api/PyTorch_FedProx_MNIST/README.md?plain=1)
+ - [PyTorch Linear Regression Example](https://github.com/securefederatedai/openfl/tree/main/openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression)
- **Improvements to workspace export and import**
- **Many documentation improvements and updates**
- **Bug fixes**
@@ -54,10 +54,10 @@ We are excited to announce the release of OpenFL 1.5.1 - our first since moving
* **[Vertical Federated Learning Examples](https://github.com/intel/openfl/tree/develop/openfl-tutorials/experimental/Vertical_FL)**
* **[Federated Model Watermarking](https://github.com/intel/openfl/blob/develop/openfl-tutorials/experimental/301_MNIST_Watermarking.ipynb)** using the [WAFFLE](https://arxiv.org/pdf/2008.07298.pdf) method
* **[Differential Privacy](https://github.com/intel/openfl/tree/develop/openfl-tutorials/experimental/Global_DP)** – Global differentially private federated learning using Opacus library to achieve a differentially private result w.r.t the inclusion or exclusion of any collaborator in the training process. At each round, a subset of collaborators are selected using a Poisson distribution over all collaborators, the selected collaborators perform local training with periodic clipping of their model delta (with respect to the current global model) to bound their contribution to the average of local model updates. Gaussian noise is then added to the average of these local models at the aggregator. This example is implemented in two different but statistically equivalent ways – the lower level API utilizes RDPAccountant and DPDataloader Opacus objects to perform privacy accounting and collaborator selection respectively, whereas the higher level API uses PrivacyEngine Opacus object for collaborator selection and internally utilizes RDPAccountant for privacy accounting.
-* **[Habana Accelerator Support](https://github.com/intel/openfl/tree/develop/openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet)**
+* **[Habana Accelerator Support](https://github.com/securefederatedai/openfl/tree/main/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet)**
* **Official support for Python 3.9 and 3.10**
* **[EDEN Compression Pipeline](https://github.com/intel/openfl/blob/develop/openfl/pipelines/eden_pipeline.py)**: Communication-Efficient and Robust Distributed Mean Estimation for Federated Learning ([paper link](https://proceedings.mlr.press/v162/vargaftik22a.html))
-* **[FLAX Framework Support](https://github.com/intel/openfl/tree/develop/openfl-tutorials/interactive_api/Flax_CNN_CIFAR)**
+* **[FLAX Framework Support](https://github.com/securefederatedai/openfl/tree/main/openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR)**
* **Improvements to the resiliency and security of the director / envoy infrastructure**:
* Optional notification to plan participants to agree to experiment sent to their infrastructure
* Improved resistance to loss of network connectivity and failure at various stages of execution
@@ -109,7 +109,7 @@ The OpenFL v1.2 release contains the following updates:
The OpenFL v1.1 release contains the following updates:
-- New [Interactive Python API](https://github.com/intel/openfl/blob/develop/openfl-tutorials/interactive_api_tutorials_(experimental)/Pytorch_Kvasir_UNET_workspace/new_python_api_UNET.ipynb) (experimental)
+- New [Interactive Python API](https://github.com/securefederatedai/openfl/tree/main/openfl-tutorials/deprecated/interactive_api) (experimental)
- Example FedProx algorithm implementation for PyTorch and Tensorflow
- `AggregationFunctionInterface` for custom aggregation functions
- Adds a [Keras-based NLP Example](https://github.com/intel/openfl/tree/develop/openfl-workspace/keras_nlp)
diff --git a/docs/developer_guide/advanced_topics/overriding_agg_fn.rst b/docs/developer_guide/advanced_topics/overriding_agg_fn.rst
index 141b7d1282..ba393f86ca 100644
--- a/docs/developer_guide/advanced_topics/overriding_agg_fn.rst
+++ b/docs/developer_guide/advanced_topics/overriding_agg_fn.rst
@@ -194,8 +194,8 @@ The following is an example of a **plan.yaml** with a modified aggregation funct
- loss
-Interactive API
-================
+Interactive API (Deprecated)
+============================
You can override aggregation function that will be used for the task this function corresponds to.
In order to do this, call the ``set_aggregation_function`` decorator method of ``TaskInterface`` and pass ``AggregationFunction`` subclass instance as a parameter.
For example, you can try:
diff --git a/docs/developer_guide/advanced_topics/overriding_plan_settings.rst b/docs/developer_guide/advanced_topics/overriding_plan_settings.rst
index 25c3b59384..629e8a017a 100644
--- a/docs/developer_guide/advanced_topics/overriding_plan_settings.rst
+++ b/docs/developer_guide/advanced_topics/overriding_plan_settings.rst
@@ -8,7 +8,7 @@ Updating plan settings
***********************
With the director-based workflow, you can use custom plan settings before starting the experiment. Changing plan settings in command line interface is straightforward by modifying plan.yaml.
-When using Python API or Director Envoy based interactive API, **override_config** can be used to update plan settings.
+When using Python API or Director Envoy based interactive API (Deprecated), **override_config** can be used to update plan settings.
Python API
@@ -24,8 +24,8 @@ Modify the plan settings:
})
-Director Envoy Based Interactive API Interface
-==============================================
+Director Envoy Based Interactive API Interface (Deprecated)
+===========================================================
Once you create an FL_experiment object, a basic federated learning plan with default settings is created. To check the default plan settings, print the plan as shown below:
.. code-block:: python
@@ -96,4 +96,4 @@ Since 'aggregator.settings.db_store_rounds' and 'compression_pipeline.template'
INFO Did not find compression_pipeline.settings.n_clusters in config. Make sure it should exist. Creating... native.py:105
-A full implementation can be found at `Federated_Pytorch_MNIST_Tutorial.ipynb `_ and at `Tensorflow_MNIST.ipynb `_.
\ No newline at end of file
+A full implementation can be found at `Federated_Pytorch_MNIST_Tutorial.ipynb `_ and at `Tensorflow_MNIST.ipynb `_.
diff --git a/docs/developer_guide/structure/components.rst b/docs/developer_guide/structure/components.rst
index 160c0bb84c..ad2cc140dd 100644
--- a/docs/developer_guide/structure/components.rst
+++ b/docs/developer_guide/structure/components.rst
@@ -49,7 +49,7 @@ The Collaborator is a short-lived entity that manages training the model on loca
- exchanging model parameters with the Aggregator.
The Collaborator is created by the :ref:`Envoy ` when a new experiment is submitted
-in the :ref:`Director-based workflow `. The Collaborator should be started from CLI if a user follows the
+in the :ref:`Director-based workflow ` (Deprecated). The Collaborator should be started from CLI if a user follows the
:ref:`Aggregator-based workflow `
Every Collaborator is a unique service. The data loader is loaded with a local *shard descriptor* to perform tasks
@@ -67,7 +67,7 @@ they would like see supported in |productName|.
Long-Lived Components
======================
-These components were introduced to support the :ref:`Director-based workflow `.
+These components were introduced to support the :ref:`Director-based workflow ` (Deprecated).
- The *Director* is the central node of the federation. This component starts an *Aggregator* for each experiment, broadcasts experiment archive to connected collaborator nodes, and provides updates on the status.
- The *Envoy* runs on collaborator nodes and is always connected to the *Director*. When the *Director* starts an experiment, the *Envoy* starts the *Collaborator* to train the global model.
@@ -81,7 +81,7 @@ Director
The Director is a long-lived entity and is the central node of the federation. It accepts connections from:
- - Frontend clients (data scientists using :ref:`interactive_python_api`)
+ - Frontend clients (data scientists using :ref:`interactive_python_api`) (Deprecated)
- Envoys, if their Shard Descriptors are complient to the same data interface
The Director supports concurrent frontend connections.
@@ -101,7 +101,7 @@ The Envoy is a long-lived entity that runs on collaborator nodes connected to th
Every Envoy is matched to one `shard descriptor `_
in order to run. When the Director starts an experiment, the Envoy accepts the experiment workspace,
-prepares the environment, and starts a Collaborator.
+prepares the environment, and starts a Collaborator. (Note this approach is deprecated)
The envoy is also responsible for sending heartbeat messages to the Director. These messages may also include information
regarding collaborator machine resource utilization. Refer to :ref:`device monitor plugin ` for details.
diff --git a/docs/get_started/examples.rst b/docs/get_started/examples.rst
index 4b9ad39f66..f358090e06 100644
--- a/docs/get_started/examples.rst
+++ b/docs/get_started/examples.rst
@@ -8,9 +8,9 @@ Examples for Running a Federation
=================================
|productName| currently offers four ways to set up and run experiments with a federation:
-the Task Runner API, Python Native API, the Interactive API, and the Workflow API.
+the Task Runner API, Python Native API, the Interactive API (Deprecated), and the Workflow API.
the Task Runner API is advised for production scenarios where the workload needs to be verified prior to execution, whereas the python native API provides a clean python interface on top of it intended for simulation purposes.
-The Interactive API introduces a convenient way to set up a federation and brings “long-lived” components in a federation (“Director” and “Envoy”),
+The Interactive API (Deprecated) introduces a convenient way to set up a federation and brings “long-lived” components in a federation (“Director” and “Envoy”),
while the Task Runner API workflow is advised for scenarios where the workload needs to be verified prior to execution. In contrast, the currently experimental Workflow API
is introduced to provide significant flexility to researchers and developers in the construction of federated learning experiments.
@@ -43,9 +43,9 @@ See :ref:`python_native_pytorch_mnist`
examples/python_native_pytorch_mnist
--------------------------
-Interactive API
--------------------------
+----------------------------
+Interactive API (Deprecated)
+----------------------------
Setup long-lived components to run many experiments
See :ref:`interactive_tensorflow_mnist`
diff --git a/docs/get_started/examples/interactive_tensorflow_mnist.rst b/docs/get_started/examples/interactive_tensorflow_mnist.rst
index 906a396148..0cecfc6b35 100644
--- a/docs/get_started/examples/interactive_tensorflow_mnist.rst
+++ b/docs/get_started/examples/interactive_tensorflow_mnist.rst
@@ -3,8 +3,8 @@
.. _interactive_tensorflow_mnist:
-Interactive API: MNIST Classification Tutorial
-===================================================
+Interactive API (Deprecated): MNIST Classification Tutorial
+===========================================================
In this tutorial, we will set up a federation and train a basic TensoFlow model on the MNIST dataset using the interactive API.
See `full tutorial `_.
@@ -371,4 +371,4 @@ Time to start a federated learning experiment
.. code-block:: python
- fl_experiment.stream_metrics()
\ No newline at end of file
+ fl_experiment.stream_metrics()
diff --git a/openfl-docker/Dockerfile.base b/openfl-docker/Dockerfile.base
index 0b5d746aca..f58d83747f 100644
--- a/openfl-docker/Dockerfile.base
+++ b/openfl-docker/Dockerfile.base
@@ -1,7 +1,7 @@
# Copyright (C) 2024 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
# ------------------------------------
-# OpenFL Base Image
+# OpenFL Base Image w/ Gramine support
# $> docker build . -t openfl -f Dockerfile.base [--build-arg OPENFL_REVISION=GIT_URL@COMMIT_ID]
# ------------------------------------
FROM ubuntu:22.04 AS base
@@ -15,25 +15,41 @@ RUN --mount=type=cache,id=apt-dev,target=/var/cache/apt \
apt-get update && \
apt-get install -y \
git \
+ curl \
python3-pip \
python3.10-dev \
+ python3.10-venv \
ca-certificates \
build-essential \
--no-install-recommends && \
apt-get purge -y linux-libc-dev && \
rm -rf /var/lib/apt/lists/*
+# Create a python virtual environment.
+RUN python3.10 -m venv /opt/venv && \
+ /opt/venv/bin/pip install --no-cache-dir --upgrade pip setuptools wheel
+ENV PATH=/opt/venv/bin:$PATH
+
+# Install Gramine
+RUN --mount=type=cache,id=apt-dev,target=/var/cache/apt \
+ curl -fsSLo /usr/share/keyrings/gramine-keyring.gpg https://packages.gramineproject.io/gramine-keyring.gpg && \
+ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/gramine-keyring.gpg] https://packages.gramineproject.io/ jammy main" \
+ | tee /etc/apt/sources.list.d/gramine.list && \
+ curl -fsSLo /usr/share/keyrings/intel-sgx-deb.asc https://download.01.org/intel-sgx/sgx_repo/ubuntu/intel-sgx-deb.key && \
+ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/intel-sgx-deb.asc] https://download.01.org/intel-sgx/sgx_repo/ubuntu jammy main" \
+ | tee /etc/apt/sources.list.d/intel-sgx.list && \
+ apt-get update && \
+ apt-get install -y gramine --no-install-recommends && \
+ rm -rf /var/lib/apt/lists/*
+
+# Install OpenFL.
+ARG OPENFL_REVISION=https://github.com/securefederatedai/openfl.git@v1.6
+RUN pip install --no-cache-dir git+${OPENFL_REVISION} && \
+ INSTALL_SOURCES=yes /opt/venv/lib/python3.10/site-packages/openfl-docker/licenses.sh
+
# Create an unprivileged user.
RUN groupadd -g 1001 default && \
useradd -m -u 1001 -g default user
USER user
-WORKDIR /home/user
-ENV PATH=/home/user/.local/bin:$PATH
-
-# Install OpenFL.
-ARG OPENFL_REVISION=https://github.com/securefederatedai/openfl.git@v1.6
-RUN pip install --no-cache-dir -U pip setuptools wheel && \
- pip install --no-cache-dir git+${OPENFL_REVISION} && \
- INSTALL_SOURCES=yes /home/user/.local/lib/python3.10/site-packages/openfl-docker/licenses.sh
CMD ["/bin/bash"]
diff --git a/openfl-docker/Dockerfile.workspace b/openfl-docker/Dockerfile.workspace
index 08446663c6..0165f557c1 100644
--- a/openfl-docker/Dockerfile.workspace
+++ b/openfl-docker/Dockerfile.workspace
@@ -1,18 +1,33 @@
# Copyright (C) 2024 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
# ------------------------------------
-# Workspace Image
+# Gramine-ready Workspace Image
+# Usage:
+# $> docker build . -t openfl-workspace -f Dockerfile.workspace \
+# [--build-arg BASE_IMAGE=openfl:latest] \
+# [--build-arg WORKSPACE_NAME=WORKSPACE_NAME] \
+# [--secret id=signer-key,src=signer-key.pem]
# ------------------------------------
ARG BASE_IMAGE=openfl:latest
FROM ${BASE_IMAGE}
+USER root
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
-USER user
+# Import workspace
+WORKDIR /
ARG WORKSPACE_NAME
-COPY ${WORKSPACE_NAME}.zip .
-RUN fx workspace import --archive ${WORKSPACE_NAME}.zip && \
- pip install --no-cache-dir -r ${WORKSPACE_NAME}/requirements.txt
+COPY ${WORKSPACE_NAME}.zip /workspace.zip
+RUN fx workspace import --archive /workspace.zip && \
+ pip install --no-cache-dir -r /workspace/requirements.txt
+
+# Build enclaves
+WORKDIR /workspace
+RUN --mount=type=secret,id=signer-key,dst=/key.pem \
+ cp -r /opt/venv/lib/python3.10/site-packages/openfl-docker/gramine_app/* /workspace/ && \
+ make SGX=1 SGX_SIGNER_KEY=/key.pem >> fx.mr_enclave && \
+ echo "$(cat fx.mr_enclave)" && \
+ chown -R user /workspace
-WORKDIR /home/user/${WORKSPACE_NAME}
+USER user
CMD ["/bin/bash"]
\ No newline at end of file
diff --git a/openfl-docker/README.md b/openfl-docker/README.md
new file mode 100644
index 0000000000..da8540770d
--- /dev/null
+++ b/openfl-docker/README.md
@@ -0,0 +1,89 @@
+# Using OpenFL within a Container
+
+OpenFL can be used within a container for simulating Federated Learning experiments, or to deploy real-world experiments within Trusted Execution Environments (TEEs).
+
+## Base Image
+
+To develop or simulate experiments within a container, build the base image (or pull one from docker hub).
+
+```shell
+# Pull latest stable base image
+$> docker pull intel/openfl
+
+# Or, build a base image from the latest source code
+$> docker build . -t openfl -f Dockerfile.base \
+ --build-arg OPENFL_REVISION=https://github.com/securefederatedai/openfl.git@develop
+```
+
+Run the container:
+```shell
+user@vm:~/openfl$ docker run -it --rm openfl:latest bash
+user@7b40624c207a:/$ fx
+OpenFL - Open Federated Learning
+
+BASH COMPLETE ACTIVATION
+
+Run in terminal:
+ _FX_COMPLETE=bash_source fx > ~/.fx-autocomplete.sh
+ source ~/.fx-autocomplete.sh
+If ~/.fx-autocomplete.sh has already exist:
+ source ~/.fx-autocomplete.sh
+
+CORRECT USAGE
+
+fx [options] [command] [subcommand] [args]
+```
+
+## Deployment
+This section assumes familiarity with the [TaskRunner API](https://openfl.readthedocs.io/en/latest/about/features_index/taskrunner.html#running-the-task-runner).
+
+### Building a workspace image
+OpenFL supports [Gramine-based](https://gramine.readthedocs.io/en/stable/) TEEs that run within SGX.
+
+To build a TEE-ready workspace image, run the following command from an existing workspace directory. Ensure PKI setup and plan confirmations are done before this step.
+
+```shell
+# Optional, generate an enclave signing key (auto-generated otherwise)
+user@vm:~/example_workspace$ openssl genrsa -out key.pem -3 3072
+user@vm:~/example_workspace$ fx workspace dockerize --enclave-key ./key.pem --save
+```
+This command builds the base image and a TEE-ready workspace image. Refer to `fx workspace dockerize --help` for more details.
+
+A signed docker image named `example_workspace.tar` will be saved in the workspace. This image (along with respective PKI certificates) can be shared across participating entities.
+
+### Running without a TEE
+Using native `fx` command within the image will run the experiment without TEEs.
+
+```shell
+# Aggregator
+docker run --rm \
+ --network host \
+ --mount type=bind,source=./certs.tar,target=/certs.tar \
+ example_workspace bash -c "fx aggregator start ..."
+
+# Collaborator(s)
+docker run --rm \
+ --network host \
+ --mount type=bind,source=./certs.tar,target=/certs.tar \
+ example_workspace bash -c "fx collaborator start ..."
+```
+
+### Running within a TEE
+To run `fx` within a TEE, mount SGX device and AESMD volumes. In addition, prefix the `fx` command with `gramine-sgx` directive.
+```shell
+# Aggregator
+docker run --rm \
+ --network host \
+ --device=/dev/sgx_enclave \
+ -v /var/run/aesmd/aesm.socket:/var/run/aesmd/aesm.socket \
+ --mount type=bind,source=./certs.tar,target=/certs.tar \
+ example_workspace bash -c "gramine-sgx fx aggregator start ..."
+
+# Collaborator(s)
+docker run --rm \
+ --network host \
+ --device=/dev/sgx_enclave \
+ -v /var/run/aesmd/aesm.socket:/var/run/aesmd/aesm.socket \
+ --mount type=bind,source=./certs.tar,target=/certs.tar \
+ example_workspace bash -c "gramine-sgx fx collaborator start ..."
+```
\ No newline at end of file
diff --git a/openfl-docker/gramine_app/Makefile b/openfl-docker/gramine_app/Makefile
new file mode 100644
index 0000000000..4dbc8ef142
--- /dev/null
+++ b/openfl-docker/gramine_app/Makefile
@@ -0,0 +1,54 @@
+# Copyright (C) 2024 Intel Corporation
+# SPDX-License-Identifier: Apache-2.0
+# ------------------------------------
+# Makefile for Gramine application within a container
+# Usage:
+# 1. Activate the python venv.
+# 2. Provide paths VENV_ROOT and WORKSPACE_ROOT.
+# 3. make SGX=0/1 [SGX_SIGNER_KEY=]
+# ------------------------------------
+VENV_ROOT ?= $(shell dirname $(shell dirname $(shell which python)))
+WORKSPACE_ROOT ?= $(shell pwd)
+ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine)
+SGX_SIGNER_KEY ?= /key.pem
+
+ifeq ($(DEBUG),1)
+GRAMINE_LOG_LEVEL = debug
+else
+GRAMINE_LOG_LEVEL = error
+endif
+
+.PHONY: all
+all: fx.manifest
+ifeq ($(SGX),1)
+all: fx.manifest.sgx fx.sig
+endif
+
+fx.manifest: fx.manifest.template
+ @echo "Making fx.manifest file"
+ gramine-manifest \
+ -Dlog_level=$(GRAMINE_LOG_LEVEL) \
+ -Darch_libdir=$(ARCH_LIBDIR) \
+ -Dvenv_root=$(VENV_ROOT) \
+ -Dentrypoint=$(VENV_ROOT)/bin/fx \
+ -Dworkspace_root=$(WORKSPACE_ROOT) \
+ $< >$@
+
+fx.manifest.sgx: fx.manifest
+ @echo "Making fx.manifest.sgx file"
+ @test -s $(SGX_SIGNER_KEY) || \
+ { echo "SGX signer private key was not found, please specify SGX_SIGNER_KEY!"; exit 1; }
+ @gramine-sgx-sign \
+ --key $(SGX_SIGNER_KEY) \
+ --manifest $< \
+ --output $@ | tail -n 1 | tr -d ' ' | xargs -I {} echo "fx.mr_enclave={}"
+
+fx.sig: fx.manifest.sgx
+
+.PHONY: clean
+clean:
+ $(RM) *.manifest *.manifest.sgx *.token *.sig OUTPUT* *.PID TEST_STDOUT TEST_STDERR
+ $(RM) -r scripts/__pycache__
+
+.PHONY: distclean
+distclean: clean
diff --git a/openfl-docker/gramine_app/fx.manifest.template b/openfl-docker/gramine_app/fx.manifest.template
new file mode 100755
index 0000000000..928dff0f56
--- /dev/null
+++ b/openfl-docker/gramine_app/fx.manifest.template
@@ -0,0 +1,73 @@
+# Copyright (C) 2024 Intel Corporation
+# SPDX-License-Identifier: Apache-2.0
+# -------------------------------------
+# Enclave Manifest for OpenFL TaskRunner API.
+# This defines the configuration for the Gramine loader to run a Python application.
+# -------------------------------------
+
+libos.entrypoint = "{{ entrypoint }}"
+loader.entrypoint.uri = "file:{{ gramine.libos }}"
+loader.log_level = "{{ log_level }}"
+
+loader.insecure__use_cmdline_argv = true
+loader.insecure__use_host_env = true
+
+loader.env.LD_LIBRARY_PATH = "{{ venv_root }}:{{ arch_libdir }}:/usr/{{ arch_libdir }}:/lib:/usr/lib"
+loader.env.SSL_CERT_DIR = "/etc/ssl/certs"
+
+# Filesystem configuration within Gramine LibOS
+fs.start_dir = "{{ workspace_root }}"
+fs.mounts = [
+ # System mounts (URI: path on host, PATH: pointer inside gramine)
+ { uri = "file:{{ gramine.runtimedir() }}", path = "/lib" },
+ { uri = "file:{{ arch_libdir }}", path = "{{ arch_libdir }}" },
+ { uri = "file:/etc/ssl/certs", path = "/etc/ssl/certs" },
+ { uri = "file:/usr", path = "/usr" },
+ { type = "tmpfs", path = "/tmp" },
+ # User-defined mounts specific to the application.
+ { uri = "file:{{ workspace_root }}", path = "{{ workspace_root }}" },
+ { uri = "file:{{ venv_root }}", path = "{{ venv_root }}" },
+]
+
+# System configuration
+sys.stack.size = "4M"
+sys.brk.max_size = "1M"
+sys.enable_sigterm_injection = true
+sys.enable_extra_runtime_domain_names_conf = true
+
+# SGX configuration
+sgx.debug = false
+sgx.enclave_size = "16G"
+sgx.preheat_enclave = false
+sgx.remote_attestation = "dcap"
+sgx.max_threads = 512
+
+# List of trusted files, that are hashed and signed by the enclave.
+# If these files change after signing of an enclave, application cannot run.
+sgx.trusted_files = [
+ "file:{{ gramine.libos }}",
+ "file:{{ entrypoint }}",
+ "file:{{ gramine.runtimedir() }}/",
+ "file:{{ arch_libdir }}/",
+ "file:/usr/{{ arch_libdir }}/",
+ "file:/etc/ssl/certs/",
+ "file:{{ python.stdlib }}/",
+ "file:{{ python.distlib }}/",
+{% for path in python.get_sys_path('python') %}
+ "file:{{ path }}{{ '/' if path.is_dir() else '' }}",
+{% endfor %}
+ "file:{{ venv_root }}/",
+ "file:{{ workspace_root }}/src/",
+]
+
+# List of allowed files that SGX enclave does NOT verify with signatures.
+# One should be conservative as to which files are allowed, these can be modified by enclave.
+sgx.allowed_files = [
+ "file:{{ workspace_root }}/save",
+ "file:{{ workspace_root }}/logs",
+ "file:{{ workspace_root }}/cert",
+ "file:{{ workspace_root }}/data",
+ "file:{{ workspace_root }}/plan/cols.yaml",
+ "file:{{ workspace_root }}/plan/data.yaml",
+ "file:{{ workspace_root }}/plan/plan.yaml",
+]
diff --git a/openfl-docker/licenses.sh b/openfl-docker/licenses.sh
index 005a8bccfa..4eba1e8c97 100755
--- a/openfl-docker/licenses.sh
+++ b/openfl-docker/licenses.sh
@@ -45,6 +45,6 @@ if [ "$INSTALL_SOURCES" = "yes" ]; then
# Append dependency list to all_dependencies.txt
pip-licenses | awk '{for(i=1;i<=NF;i++) if(i!=2) printf $i" "; print ""}' | tee -a all_dependencies.txt
- # Download source packages for Python packages with specific licenses
- pip-licenses | grep -E 'GPL|MPL|EPL' | awk '{OFS="=="} {print $1,$2}' | xargs pip download --no-binary :all:
+ # Download source packages for Python packages (if exists) with specific licenses
+ pip-licenses | grep -E 'GPL|MPL|EPL' | awk '{OFS="=="} {print $1,$2}' | xargs -I {} sh -c 'pip download --no-binary :all: {} || true'
fi
diff --git a/openfl-tutorials/interactive_api/Flax_CNN_CIFAR/README.md b/openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/Flax_CNN_CIFAR/README.md
rename to openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR/README.md
diff --git a/openfl-tutorials/interactive_api/Flax_CNN_CIFAR/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/Flax_CNN_CIFAR/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/Flax_CNN_CIFAR/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/Flax_CNN_CIFAR/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/Flax_CNN_CIFAR/envoy/cifar10_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR/envoy/cifar10_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/Flax_CNN_CIFAR/envoy/cifar10_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR/envoy/cifar10_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/Flax_CNN_CIFAR/envoy/envoy_config_1.yaml b/openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR/envoy/envoy_config_1.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/Flax_CNN_CIFAR/envoy/envoy_config_1.yaml
rename to openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR/envoy/envoy_config_1.yaml
diff --git a/openfl-tutorials/interactive_api/Flax_CNN_CIFAR/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/Flax_CNN_CIFAR/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/Flax_CNN_CIFAR/requirements.txt b/openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/Flax_CNN_CIFAR/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR/requirements.txt
diff --git a/openfl-tutorials/interactive_api/Flax_CNN_CIFAR/workspace/FLAX_CIFAR10_CNN.ipynb b/openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR/workspace/FLAX_CIFAR10_CNN.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/Flax_CNN_CIFAR/workspace/FLAX_CIFAR10_CNN.ipynb
rename to openfl-tutorials/deprecated/interactive_api/Flax_CNN_CIFAR/workspace/FLAX_CIFAR10_CNN.ipynb
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/README.md b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/README.md
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/README.md
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/director/start_director_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/director/start_director_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/director/start_director_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/director/start_director_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/envoy_config_no_gpu.yaml b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/envoy_config_no_gpu.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/envoy_config_no_gpu.yaml
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/envoy_config_no_gpu.yaml
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/kvasir_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/kvasir_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/kvasir_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/kvasir_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/kvasir_shard_descriptor_with_data_splitter.py b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/kvasir_shard_descriptor_with_data_splitter.py
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/kvasir_shard_descriptor_with_data_splitter.py
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/kvasir_shard_descriptor_with_data_splitter.py
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/sd_requirements.txt b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/sd_requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/sd_requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/sd_requirements.txt
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/start_envoy_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/start_envoy_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/start_envoy_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/envoy/start_envoy_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/workspace/PyTorch_Kvasir_UNet.ipynb b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/workspace/PyTorch_Kvasir_UNet.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/workspace/PyTorch_Kvasir_UNet.ipynb
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/workspace/PyTorch_Kvasir_UNet.ipynb
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/workspace/layers.py b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/workspace/layers.py
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_Kvasir_UNet/workspace/layers.py
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_Kvasir_UNet/workspace/layers.py
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_MedMNIST_2D/README.md b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_MedMNIST_2D/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_MedMNIST_2D/README.md
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_MedMNIST_2D/README.md
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_MedMNIST_2D/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_MedMNIST_2D/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_MedMNIST_2D/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_MedMNIST_2D/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_MedMNIST_2D/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_MedMNIST_2D/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_MedMNIST_2D/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_MedMNIST_2D/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_MedMNIST_2D/envoy/envoy_config.yaml b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_MedMNIST_2D/envoy/envoy_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_MedMNIST_2D/envoy/envoy_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_MedMNIST_2D/envoy/envoy_config.yaml
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_MedMNIST_2D/envoy/medmnist_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_MedMNIST_2D/envoy/medmnist_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_MedMNIST_2D/envoy/medmnist_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_MedMNIST_2D/envoy/medmnist_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_MedMNIST_2D/envoy/requirements.txt b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_MedMNIST_2D/envoy/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_MedMNIST_2D/envoy/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_MedMNIST_2D/envoy/requirements.txt
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_MedMNIST_2D/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_MedMNIST_2D/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_MedMNIST_2D/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_MedMNIST_2D/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_MedMNIST_2D/workspace/HPU_Pytorch_MedMNIST_2D.ipynb b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_MedMNIST_2D/workspace/HPU_Pytorch_MedMNIST_2D.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_MedMNIST_2D/workspace/HPU_Pytorch_MedMNIST_2D.ipynb
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_MedMNIST_2D/workspace/HPU_Pytorch_MedMNIST_2D.ipynb
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet/README.md b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet/README.md
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet/README.md
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet/envoy/envoy_config_1.yaml b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet/envoy/envoy_config_1.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet/envoy/envoy_config_1.yaml
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet/envoy/envoy_config_1.yaml
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet/envoy/requirements.txt b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet/envoy/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet/envoy/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet/envoy/requirements.txt
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet/envoy/tinyimagenet_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet/envoy/tinyimagenet_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet/envoy/tinyimagenet_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet/envoy/tinyimagenet_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet/workspace/hpu_pytorch_tinyimagenet.ipynb b/openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet/workspace/hpu_pytorch_tinyimagenet.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/HPU/PyTorch_TinyImageNet/workspace/hpu_pytorch_tinyimagenet.ipynb
rename to openfl-tutorials/deprecated/interactive_api/HPU/PyTorch_TinyImageNet/workspace/hpu_pytorch_tinyimagenet.ipynb
diff --git a/openfl-tutorials/interactive_api/MXNet_landmarks/README.md b/openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/MXNet_landmarks/README.md
rename to openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/README.md
diff --git a/openfl-tutorials/interactive_api/MXNet_landmarks/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/MXNet_landmarks/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/MXNet_landmarks/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/MXNet_landmarks/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/MXNet_landmarks/envoy/envoy_config_one.yaml b/openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/envoy/envoy_config_one.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/MXNet_landmarks/envoy/envoy_config_one.yaml
rename to openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/envoy/envoy_config_one.yaml
diff --git a/openfl-tutorials/interactive_api/MXNet_landmarks/envoy/envoy_config_two.yaml b/openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/envoy/envoy_config_two.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/MXNet_landmarks/envoy/envoy_config_two.yaml
rename to openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/envoy/envoy_config_two.yaml
diff --git a/openfl-tutorials/interactive_api/MXNet_landmarks/envoy/landmark_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/envoy/landmark_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/MXNet_landmarks/envoy/landmark_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/envoy/landmark_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/MXNet_landmarks/envoy/sd_requirements.txt b/openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/envoy/sd_requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/MXNet_landmarks/envoy/sd_requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/envoy/sd_requirements.txt
diff --git a/openfl-tutorials/interactive_api/MXNet_landmarks/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/MXNet_landmarks/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/MXNet_landmarks/workspace/MXNet_landmarks.ipynb b/openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/workspace/MXNet_landmarks.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/MXNet_landmarks/workspace/MXNet_landmarks.ipynb
rename to openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/workspace/MXNet_landmarks.ipynb
diff --git a/openfl-tutorials/interactive_api/MXNet_landmarks/workspace/mxnet_adapter.py b/openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/workspace/mxnet_adapter.py
similarity index 100%
rename from openfl-tutorials/interactive_api/MXNet_landmarks/workspace/mxnet_adapter.py
rename to openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/workspace/mxnet_adapter.py
diff --git a/openfl-tutorials/interactive_api/MXNet_landmarks/workspace/requirements.txt b/openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/workspace/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/MXNet_landmarks/workspace/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/MXNet_landmarks/workspace/requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/README.md b/openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/README.md
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/README.md
diff --git a/openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/envoy/dogs_cats_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/envoy/dogs_cats_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/envoy/dogs_cats_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/envoy/dogs_cats_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/envoy/envoy_config_one.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/envoy/envoy_config_one.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/envoy/envoy_config_one.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/envoy/envoy_config_one.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/envoy/envoy_config_two.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/envoy/envoy_config_two.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/envoy/envoy_config_two.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/envoy/envoy_config_two.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/envoy/sd_requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/envoy/sd_requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/envoy/sd_requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/envoy/sd_requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/workspace/PyTorch_DogsCats_ViT.ipynb b/openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/workspace/PyTorch_DogsCats_ViT.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/workspace/PyTorch_DogsCats_ViT.ipynb
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/workspace/PyTorch_DogsCats_ViT.ipynb
diff --git a/openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/workspace/requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/workspace/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_DogsCats_ViT/workspace/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_DogsCats_ViT/workspace/requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/README.md b/openfl-tutorials/deprecated/interactive_api/PyTorch_FedProx_MNIST/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/README.md
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_FedProx_MNIST/README.md
diff --git a/openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_FedProx_MNIST/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_FedProx_MNIST/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_FedProx_MNIST/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_FedProx_MNIST/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/envoy/envoy_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_FedProx_MNIST/envoy/envoy_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/envoy/envoy_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_FedProx_MNIST/envoy/envoy_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/envoy/medmnist_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_FedProx_MNIST/envoy/medmnist_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/envoy/medmnist_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_FedProx_MNIST/envoy/medmnist_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/envoy/requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_FedProx_MNIST/envoy/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/envoy/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_FedProx_MNIST/envoy/requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_FedProx_MNIST/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_FedProx_MNIST/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/workspace/Pytorch_FedProx_MedMNIST_2D.ipynb b/openfl-tutorials/deprecated/interactive_api/PyTorch_FedProx_MNIST/workspace/Pytorch_FedProx_MedMNIST_2D.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_FedProx_MNIST/workspace/Pytorch_FedProx_MedMNIST_2D.ipynb
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_FedProx_MNIST/workspace/Pytorch_FedProx_MedMNIST_2D.ipynb
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology/README.md b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology/README.md
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/README.md
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology/director/director_config_review_exp.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/director/director_config_review_exp.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology/director/director_config_review_exp.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/director/director_config_review_exp.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology/director/start_director_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/director/start_director_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology/director/start_director_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/director/start_director_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology/envoy/.gitignore b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/envoy/.gitignore
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology/envoy/.gitignore
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/envoy/.gitignore
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology/envoy/envoy_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/envoy/envoy_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology/envoy/envoy_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/envoy/envoy_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology/envoy/envoy_config_review_exp.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/envoy/envoy_config_review_exp.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology/envoy/envoy_config_review_exp.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/envoy/envoy_config_review_exp.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology/envoy/histology_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/envoy/histology_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology/envoy/histology_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/envoy/histology_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology/envoy/requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/envoy/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology/envoy/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/envoy/requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology/envoy/start_envoy_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/envoy/start_envoy_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology/envoy/start_envoy_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/envoy/start_envoy_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology/workspace/pytorch_histology.ipynb b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/workspace/pytorch_histology.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology/workspace/pytorch_histology.ipynb
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology/workspace/pytorch_histology.ipynb
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/README.md b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/README.md
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/README.md
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/director/start_director_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/director/start_director_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/director/start_director_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/director/start_director_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/envoy/.gitignore b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/envoy/.gitignore
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/envoy/.gitignore
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/envoy/.gitignore
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/envoy/envoy_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/envoy/envoy_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/envoy/envoy_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/envoy/envoy_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/envoy/histology_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/envoy/histology_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/envoy/histology_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/envoy/histology_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/envoy/populate_envoys.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/envoy/populate_envoys.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/envoy/populate_envoys.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/envoy/populate_envoys.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/envoy/requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/envoy/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/envoy/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/envoy/requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/envoy/start_envoy_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/envoy/start_envoy_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/envoy/start_envoy_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/envoy/start_envoy_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/envoy/start_envoys.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/envoy/start_envoys.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/envoy/start_envoys.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/envoy/start_envoys.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/workspace/.gitignore b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/workspace/.gitignore
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/workspace/.gitignore
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/workspace/.gitignore
diff --git a/openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/workspace/pytorch_histology.ipynb b/openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/workspace/pytorch_histology.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Histology_FedCurv/workspace/pytorch_histology.ipynb
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Histology_FedCurv/workspace/pytorch_histology.ipynb
diff --git a/openfl-tutorials/interactive_api/PyTorch_Huggingface_transformers_SUPERB/README.md b/openfl-tutorials/deprecated/interactive_api/PyTorch_Huggingface_transformers_SUPERB/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Huggingface_transformers_SUPERB/README.md
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Huggingface_transformers_SUPERB/README.md
diff --git a/openfl-tutorials/interactive_api/PyTorch_Huggingface_transformers_SUPERB/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Huggingface_transformers_SUPERB/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Huggingface_transformers_SUPERB/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Huggingface_transformers_SUPERB/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Huggingface_transformers_SUPERB/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Huggingface_transformers_SUPERB/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Huggingface_transformers_SUPERB/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Huggingface_transformers_SUPERB/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Huggingface_transformers_SUPERB/envoy/envoy_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Huggingface_transformers_SUPERB/envoy/envoy_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Huggingface_transformers_SUPERB/envoy/envoy_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Huggingface_transformers_SUPERB/envoy/envoy_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Huggingface_transformers_SUPERB/envoy/sd_requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_Huggingface_transformers_SUPERB/envoy/sd_requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Huggingface_transformers_SUPERB/envoy/sd_requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Huggingface_transformers_SUPERB/envoy/sd_requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_Huggingface_transformers_SUPERB/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Huggingface_transformers_SUPERB/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Huggingface_transformers_SUPERB/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Huggingface_transformers_SUPERB/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Huggingface_transformers_SUPERB/envoy/superb_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_Huggingface_transformers_SUPERB/envoy/superb_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Huggingface_transformers_SUPERB/envoy/superb_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Huggingface_transformers_SUPERB/envoy/superb_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_Huggingface_transformers_SUPERB/workspace/PyTorch_Huggingface_transformers_SUPERB.ipynb b/openfl-tutorials/deprecated/interactive_api/PyTorch_Huggingface_transformers_SUPERB/workspace/PyTorch_Huggingface_transformers_SUPERB.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Huggingface_transformers_SUPERB/workspace/PyTorch_Huggingface_transformers_SUPERB.ipynb
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Huggingface_transformers_SUPERB/workspace/PyTorch_Huggingface_transformers_SUPERB.ipynb
diff --git a/openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/README.md b/openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/README.md
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/README.md
diff --git a/openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/director/start_director_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/director/start_director_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/director/start_director_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/director/start_director_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/envoy/envoy_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/envoy/envoy_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/envoy/envoy_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/envoy/envoy_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/envoy/envoy_config_no_gpu.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/envoy/envoy_config_no_gpu.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/envoy/envoy_config_no_gpu.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/envoy/envoy_config_no_gpu.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/envoy/kvasir_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/envoy/kvasir_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/envoy/kvasir_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/envoy/kvasir_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/envoy/kvasir_shard_descriptor_with_data_splitter.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/envoy/kvasir_shard_descriptor_with_data_splitter.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/envoy/kvasir_shard_descriptor_with_data_splitter.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/envoy/kvasir_shard_descriptor_with_data_splitter.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/envoy/sd_requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/envoy/sd_requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/envoy/sd_requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/envoy/sd_requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/envoy/start_envoy_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/envoy/start_envoy_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/envoy/start_envoy_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/envoy/start_envoy_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/workspace/PyTorch_Kvasir_UNet.ipynb b/openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/workspace/PyTorch_Kvasir_UNet.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/workspace/PyTorch_Kvasir_UNet.ipynb
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/workspace/PyTorch_Kvasir_UNet.ipynb
diff --git a/openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/workspace/layers.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/workspace/layers.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Kvasir_UNet/workspace/layers.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Kvasir_UNet/workspace/layers.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/README.md b/openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/README.md
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/README.md
diff --git a/openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/envoy_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/envoy_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/envoy_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/envoy_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/envoy_config_no_gpu.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/envoy_config_no_gpu.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/envoy_config_no_gpu.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/envoy_config_no_gpu.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/mnist_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/mnist_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/mnist_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/mnist_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/sd_requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/sd_requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/sd_requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/sd_requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/workspace/PyTorch_Lightning_GAN.ipynb b/openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/workspace/PyTorch_Lightning_GAN.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/workspace/PyTorch_Lightning_GAN.ipynb
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/workspace/PyTorch_Lightning_GAN.ipynb
diff --git a/openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/workspace/plugin_for_multiple_optimizers.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/workspace/plugin_for_multiple_optimizers.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Lightning_MNIST_GAN/workspace/plugin_for_multiple_optimizers.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Lightning_MNIST_GAN/workspace/plugin_for_multiple_optimizers.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_LinearRegression/README.md b/openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_LinearRegression/README.md
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/README.md
diff --git a/openfl-tutorials/interactive_api/PyTorch_LinearRegression/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_LinearRegression/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_LinearRegression/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_LinearRegression/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_LinearRegression/envoy/envoy_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/envoy/envoy_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_LinearRegression/envoy/envoy_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/envoy/envoy_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_LinearRegression/envoy/regression_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/envoy/regression_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_LinearRegression/envoy/regression_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/envoy/regression_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_LinearRegression/envoy/requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/envoy/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_LinearRegression/envoy/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/envoy/requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_LinearRegression/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_LinearRegression/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_LinearRegression/workspace/requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/workspace/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_LinearRegression/workspace/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/workspace/requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_LinearRegression/workspace/torch_linear_regression.ipynb b/openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/workspace/torch_linear_regression.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_LinearRegression/workspace/torch_linear_regression.ipynb
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_LinearRegression/workspace/torch_linear_regression.ipynb
diff --git a/openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/README.md b/openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/README.md
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/README.md
diff --git a/openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/director/start_director_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/director/start_director_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/director/start_director_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/director/start_director_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/envoy_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/envoy_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/envoy_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/envoy_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/mvtec_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/mvtec_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/mvtec_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/mvtec_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/sd_requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/sd_requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/sd_requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/sd_requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/start_envoy_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/start_envoy_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/start_envoy_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/envoy/start_envoy_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/workspace/PatchSVDD_with_Director.ipynb b/openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/workspace/PatchSVDD_with_Director.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/workspace/PatchSVDD_with_Director.ipynb
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/workspace/PatchSVDD_with_Director.ipynb
diff --git a/openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/workspace/data_transf.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/workspace/data_transf.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/workspace/data_transf.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/workspace/data_transf.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/workspace/inspection.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/workspace/inspection.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/workspace/inspection.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/workspace/inspection.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/workspace/utils.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/workspace/utils.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MVTec_PatchSVDD/workspace/utils.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MVTec_PatchSVDD/workspace/utils.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/README.md b/openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/README.md
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/README.md
diff --git a/openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/director/start_director_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/director/start_director_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/director/start_director_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/director/start_director_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/envoy/envoy_config_one.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/envoy/envoy_config_one.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/envoy/envoy_config_one.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/envoy/envoy_config_one.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/envoy/envoy_config_two.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/envoy/envoy_config_two.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/envoy/envoy_config_two.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/envoy/envoy_config_two.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/envoy/market_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/envoy/market_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/envoy/market_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/envoy/market_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/envoy/requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/envoy/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/envoy/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/envoy/requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/envoy/start_envoy_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/envoy/start_envoy_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/envoy/start_envoy_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/envoy/start_envoy_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/workspace/PyTorch_Market_Re-ID.ipynb b/openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/workspace/PyTorch_Market_Re-ID.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/workspace/PyTorch_Market_Re-ID.ipynb
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/workspace/PyTorch_Market_Re-ID.ipynb
diff --git a/openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/workspace/losses.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/workspace/losses.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/workspace/losses.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/workspace/losses.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/workspace/requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/workspace/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/workspace/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/workspace/requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/workspace/tools.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/workspace/tools.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/workspace/tools.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/workspace/tools.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/workspace/transforms.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/workspace/transforms.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_Market_Re-ID/workspace/transforms.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_Market_Re-ID/workspace/transforms.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_2D/README.md b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_2D/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_2D/README.md
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_2D/README.md
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_2D/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_2D/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_2D/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_2D/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_2D/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_2D/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_2D/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_2D/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_2D/envoy/envoy_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_2D/envoy/envoy_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_2D/envoy/envoy_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_2D/envoy/envoy_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_2D/envoy/medmnist_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_2D/envoy/medmnist_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_2D/envoy/medmnist_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_2D/envoy/medmnist_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_2D/envoy/requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_2D/envoy/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_2D/envoy/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_2D/envoy/requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_2D/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_2D/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_2D/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_2D/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_2D/workspace/Pytorch_MedMNIST_2D.ipynb b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_2D/workspace/Pytorch_MedMNIST_2D.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_2D/workspace/Pytorch_MedMNIST_2D.ipynb
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_2D/workspace/Pytorch_MedMNIST_2D.ipynb
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/README.md b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/README.md
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/README.md
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/envoy/envoy_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/envoy/envoy_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/envoy/envoy_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/envoy/envoy_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/envoy/medmnist_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/envoy/medmnist_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/envoy/medmnist_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/envoy/medmnist_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/envoy/requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/envoy/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/envoy/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/envoy/requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/workspace/Pytorch_MedMNIST_3D.ipynb b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/workspace/Pytorch_MedMNIST_3D.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/workspace/Pytorch_MedMNIST_3D.ipynb
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/workspace/Pytorch_MedMNIST_3D.ipynb
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/__init__.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/__init__.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/__init__.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/__init__.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/batchnorm.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/batchnorm.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/batchnorm.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/batchnorm.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/comm.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/comm.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/comm.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/comm.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/replicate.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/replicate.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/replicate.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/replicate.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/utils.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/utils.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/utils.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_MedMNIST_3D/workspace/wspace_utils/utils.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet/README.md b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet/README.md
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/README.md
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet/director/start_director_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/director/start_director_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet/director/start_director_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/director/start_director_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet/envoy/envoy_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/envoy/envoy_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet/envoy/envoy_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/envoy/envoy_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet/envoy/requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/envoy/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet/envoy/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/envoy/requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet/envoy/start_envoy_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/envoy/start_envoy_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet/envoy/start_envoy_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/envoy/start_envoy_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet/envoy/tinyimagenet_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/envoy/tinyimagenet_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet/envoy/tinyimagenet_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/envoy/tinyimagenet_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet/workspace/non-federated_case.ipynb b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/workspace/non-federated_case.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet/workspace/non-federated_case.ipynb
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/workspace/non-federated_case.ipynb
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet/workspace/pytorch_tinyimagenet.ipynb b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/workspace/pytorch_tinyimagenet.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet/workspace/pytorch_tinyimagenet.ipynb
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/workspace/pytorch_tinyimagenet.ipynb
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet/workspace/requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/workspace/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet/workspace/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet/workspace/requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/README.md b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/README.md
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/README.md
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/director/start_director_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/director/start_director_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/director/start_director_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/director/start_director_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/envoy/envoy_config.yaml b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/envoy/envoy_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/envoy/envoy_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/envoy/envoy_config.yaml
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/envoy/requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/envoy/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/envoy/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/envoy/requirements.txt
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/envoy/start_envoy_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/envoy/start_envoy_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/envoy/start_envoy_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/envoy/start_envoy_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/envoy/tinyimagenet_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/envoy/tinyimagenet_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/envoy/tinyimagenet_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/envoy/tinyimagenet_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/workspace/pytorch_tinyimagenet_XPU.ipynb b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/workspace/pytorch_tinyimagenet_XPU.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/workspace/pytorch_tinyimagenet_XPU.ipynb
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/workspace/pytorch_tinyimagenet_XPU.ipynb
diff --git a/openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/workspace/requirements.txt b/openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/workspace/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/PyTorch_TinyImageNet_XPU/workspace/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/PyTorch_TinyImageNet_XPU/workspace/requirements.txt
diff --git a/openfl-tutorials/interactive_api/README.md b/openfl-tutorials/deprecated/interactive_api/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/README.md
rename to openfl-tutorials/deprecated/interactive_api/README.md
diff --git a/openfl-tutorials/interactive_api/Tensorflow_CIFAR_tfdata/README.md b/openfl-tutorials/deprecated/interactive_api/Tensorflow_CIFAR_tfdata/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_CIFAR_tfdata/README.md
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_CIFAR_tfdata/README.md
diff --git a/openfl-tutorials/interactive_api/Tensorflow_CIFAR_tfdata/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/Tensorflow_CIFAR_tfdata/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_CIFAR_tfdata/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_CIFAR_tfdata/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/Tensorflow_CIFAR_tfdata/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/Tensorflow_CIFAR_tfdata/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_CIFAR_tfdata/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_CIFAR_tfdata/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/Tensorflow_CIFAR_tfdata/envoy/cifar10_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/Tensorflow_CIFAR_tfdata/envoy/cifar10_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_CIFAR_tfdata/envoy/cifar10_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_CIFAR_tfdata/envoy/cifar10_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/Tensorflow_CIFAR_tfdata/envoy/envoy_config_one.yaml b/openfl-tutorials/deprecated/interactive_api/Tensorflow_CIFAR_tfdata/envoy/envoy_config_one.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_CIFAR_tfdata/envoy/envoy_config_one.yaml
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_CIFAR_tfdata/envoy/envoy_config_one.yaml
diff --git a/openfl-tutorials/interactive_api/Tensorflow_CIFAR_tfdata/envoy/envoy_config_two.yaml b/openfl-tutorials/deprecated/interactive_api/Tensorflow_CIFAR_tfdata/envoy/envoy_config_two.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_CIFAR_tfdata/envoy/envoy_config_two.yaml
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_CIFAR_tfdata/envoy/envoy_config_two.yaml
diff --git a/openfl-tutorials/interactive_api/Tensorflow_CIFAR_tfdata/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/Tensorflow_CIFAR_tfdata/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_CIFAR_tfdata/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_CIFAR_tfdata/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/Tensorflow_CIFAR_tfdata/workspace/Tensorflow_CIFAR.ipynb b/openfl-tutorials/deprecated/interactive_api/Tensorflow_CIFAR_tfdata/workspace/Tensorflow_CIFAR.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_CIFAR_tfdata/workspace/Tensorflow_CIFAR.ipynb
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_CIFAR_tfdata/workspace/Tensorflow_CIFAR.ipynb
diff --git a/openfl-tutorials/interactive_api/Tensorflow_MNIST/README.md b/openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_MNIST/README.md
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/README.md
diff --git a/openfl-tutorials/interactive_api/Tensorflow_MNIST/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_MNIST/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/Tensorflow_MNIST/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_MNIST/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/Tensorflow_MNIST/director/start_director_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/director/start_director_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_MNIST/director/start_director_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/director/start_director_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/Tensorflow_MNIST/envoy/envoy_config_one.yaml b/openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/envoy/envoy_config_one.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_MNIST/envoy/envoy_config_one.yaml
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/envoy/envoy_config_one.yaml
diff --git a/openfl-tutorials/interactive_api/Tensorflow_MNIST/envoy/envoy_config_two.yaml b/openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/envoy/envoy_config_two.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_MNIST/envoy/envoy_config_two.yaml
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/envoy/envoy_config_two.yaml
diff --git a/openfl-tutorials/interactive_api/Tensorflow_MNIST/envoy/mnist_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/envoy/mnist_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_MNIST/envoy/mnist_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/envoy/mnist_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/Tensorflow_MNIST/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_MNIST/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/Tensorflow_MNIST/envoy/start_envoy_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/envoy/start_envoy_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_MNIST/envoy/start_envoy_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/envoy/start_envoy_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/Tensorflow_MNIST/workspace/Tensorflow_MNIST.ipynb b/openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/workspace/Tensorflow_MNIST.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_MNIST/workspace/Tensorflow_MNIST.ipynb
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_MNIST/workspace/Tensorflow_MNIST.ipynb
diff --git a/openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/README.md b/openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/README.md
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/README.md
diff --git a/openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/director/start_director_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/director/start_director_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/director/start_director_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/director/start_director_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/envoy/envoy_config_one.yaml b/openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/envoy/envoy_config_one.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/envoy/envoy_config_one.yaml
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/envoy/envoy_config_one.yaml
diff --git a/openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/envoy/envoy_config_three.yaml b/openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/envoy/envoy_config_three.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/envoy/envoy_config_three.yaml
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/envoy/envoy_config_three.yaml
diff --git a/openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/envoy/envoy_config_two.yaml b/openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/envoy/envoy_config_two.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/envoy/envoy_config_two.yaml
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/envoy/envoy_config_two.yaml
diff --git a/openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/envoy/sd_requirements.txt b/openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/envoy/sd_requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/envoy/sd_requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/envoy/sd_requirements.txt
diff --git a/openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/envoy/shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/envoy/shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/envoy/shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/envoy/shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/envoy/start_envoy_with_tls.sh b/openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/envoy/start_envoy_with_tls.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/envoy/start_envoy_with_tls.sh
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/envoy/start_envoy_with_tls.sh
diff --git a/openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/workspace/Tensorflow_Word_Prediction.ipynb b/openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/workspace/Tensorflow_Word_Prediction.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/workspace/Tensorflow_Word_Prediction.ipynb
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/workspace/Tensorflow_Word_Prediction.ipynb
diff --git a/openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/workspace/requirements.txt b/openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/workspace/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/Tensorflow_Word_Prediction/workspace/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/Tensorflow_Word_Prediction/workspace/requirements.txt
diff --git a/openfl-tutorials/interactive_api/jax_linear_regression/README.md b/openfl-tutorials/deprecated/interactive_api/jax_linear_regression/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/jax_linear_regression/README.md
rename to openfl-tutorials/deprecated/interactive_api/jax_linear_regression/README.md
diff --git a/openfl-tutorials/interactive_api/jax_linear_regression/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/jax_linear_regression/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/jax_linear_regression/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/jax_linear_regression/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/jax_linear_regression/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/jax_linear_regression/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/jax_linear_regression/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/jax_linear_regression/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/jax_linear_regression/envoy/envoy_config_1.yaml b/openfl-tutorials/deprecated/interactive_api/jax_linear_regression/envoy/envoy_config_1.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/jax_linear_regression/envoy/envoy_config_1.yaml
rename to openfl-tutorials/deprecated/interactive_api/jax_linear_regression/envoy/envoy_config_1.yaml
diff --git a/openfl-tutorials/interactive_api/jax_linear_regression/envoy/regression_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/jax_linear_regression/envoy/regression_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/jax_linear_regression/envoy/regression_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/jax_linear_regression/envoy/regression_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/jax_linear_regression/envoy/requirements.txt b/openfl-tutorials/deprecated/interactive_api/jax_linear_regression/envoy/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/jax_linear_regression/envoy/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/jax_linear_regression/envoy/requirements.txt
diff --git a/openfl-tutorials/interactive_api/jax_linear_regression/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/jax_linear_regression/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/jax_linear_regression/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/jax_linear_regression/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/jax_linear_regression/workspace/JAX_linear_regression.ipynb b/openfl-tutorials/deprecated/interactive_api/jax_linear_regression/workspace/JAX_linear_regression.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/jax_linear_regression/workspace/JAX_linear_regression.ipynb
rename to openfl-tutorials/deprecated/interactive_api/jax_linear_regression/workspace/JAX_linear_regression.ipynb
diff --git a/openfl-tutorials/interactive_api/jax_linear_regression/workspace/custom_adapter.py b/openfl-tutorials/deprecated/interactive_api/jax_linear_regression/workspace/custom_adapter.py
similarity index 100%
rename from openfl-tutorials/interactive_api/jax_linear_regression/workspace/custom_adapter.py
rename to openfl-tutorials/deprecated/interactive_api/jax_linear_regression/workspace/custom_adapter.py
diff --git a/openfl-tutorials/interactive_api/numpy_linear_regression/README.md b/openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/numpy_linear_regression/README.md
rename to openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/README.md
diff --git a/openfl-tutorials/interactive_api/numpy_linear_regression/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/numpy_linear_regression/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/numpy_linear_regression/envoy/envoy_config.yaml b/openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/envoy/envoy_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/numpy_linear_regression/envoy/envoy_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/envoy/envoy_config.yaml
diff --git a/openfl-tutorials/interactive_api/numpy_linear_regression/envoy/linreg_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/envoy/linreg_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/numpy_linear_regression/envoy/linreg_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/envoy/linreg_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/numpy_linear_regression/envoy/requirements.txt b/openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/envoy/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/numpy_linear_regression/envoy/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/envoy/requirements.txt
diff --git a/openfl-tutorials/interactive_api/numpy_linear_regression/workspace/LinReg.ipynb b/openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/workspace/LinReg.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/numpy_linear_regression/workspace/LinReg.ipynb
rename to openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/workspace/LinReg.ipynb
diff --git a/openfl-tutorials/interactive_api/numpy_linear_regression/workspace/SingleNotebook.ipynb b/openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/workspace/SingleNotebook.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/numpy_linear_regression/workspace/SingleNotebook.ipynb
rename to openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/workspace/SingleNotebook.ipynb
diff --git a/openfl-tutorials/interactive_api/numpy_linear_regression/workspace/custom_adapter.py b/openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/workspace/custom_adapter.py
similarity index 100%
rename from openfl-tutorials/interactive_api/numpy_linear_regression/workspace/custom_adapter.py
rename to openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/workspace/custom_adapter.py
diff --git a/openfl-tutorials/interactive_api/numpy_linear_regression/workspace/requirements.txt b/openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/workspace/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/numpy_linear_regression/workspace/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/workspace/requirements.txt
diff --git a/openfl-tutorials/interactive_api/numpy_linear_regression/workspace/start_federation.ipynb b/openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/workspace/start_federation.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/numpy_linear_regression/workspace/start_federation.ipynb
rename to openfl-tutorials/deprecated/interactive_api/numpy_linear_regression/workspace/start_federation.ipynb
diff --git a/openfl-tutorials/interactive_api/scikit_learn_linear_regression/README.md b/openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/README.md
similarity index 100%
rename from openfl-tutorials/interactive_api/scikit_learn_linear_regression/README.md
rename to openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/README.md
diff --git a/openfl-tutorials/interactive_api/scikit_learn_linear_regression/director/director_config.yaml b/openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/director/director_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/scikit_learn_linear_regression/director/director_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/director/director_config.yaml
diff --git a/openfl-tutorials/interactive_api/scikit_learn_linear_regression/director/start_director.sh b/openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/director/start_director.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/scikit_learn_linear_regression/director/start_director.sh
rename to openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/director/start_director.sh
diff --git a/openfl-tutorials/interactive_api/scikit_learn_linear_regression/envoy/envoy_config.yaml b/openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/envoy/envoy_config.yaml
similarity index 100%
rename from openfl-tutorials/interactive_api/scikit_learn_linear_regression/envoy/envoy_config.yaml
rename to openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/envoy/envoy_config.yaml
diff --git a/openfl-tutorials/interactive_api/scikit_learn_linear_regression/envoy/linreg_shard_descriptor.py b/openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/envoy/linreg_shard_descriptor.py
similarity index 100%
rename from openfl-tutorials/interactive_api/scikit_learn_linear_regression/envoy/linreg_shard_descriptor.py
rename to openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/envoy/linreg_shard_descriptor.py
diff --git a/openfl-tutorials/interactive_api/scikit_learn_linear_regression/envoy/requirements.txt b/openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/envoy/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/scikit_learn_linear_regression/envoy/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/envoy/requirements.txt
diff --git a/openfl-tutorials/interactive_api/scikit_learn_linear_regression/envoy/start_envoy.sh b/openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/envoy/start_envoy.sh
similarity index 100%
rename from openfl-tutorials/interactive_api/scikit_learn_linear_regression/envoy/start_envoy.sh
rename to openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/envoy/start_envoy.sh
diff --git a/openfl-tutorials/interactive_api/scikit_learn_linear_regression/workspace/custom_adapter.py b/openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/workspace/custom_adapter.py
similarity index 100%
rename from openfl-tutorials/interactive_api/scikit_learn_linear_regression/workspace/custom_adapter.py
rename to openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/workspace/custom_adapter.py
diff --git a/openfl-tutorials/interactive_api/scikit_learn_linear_regression/workspace/requirements.txt b/openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/workspace/requirements.txt
similarity index 100%
rename from openfl-tutorials/interactive_api/scikit_learn_linear_regression/workspace/requirements.txt
rename to openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/workspace/requirements.txt
diff --git a/openfl-tutorials/interactive_api/scikit_learn_linear_regression/workspace/scikit_learn_linear_regression.ipynb b/openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/workspace/scikit_learn_linear_regression.ipynb
similarity index 100%
rename from openfl-tutorials/interactive_api/scikit_learn_linear_regression/workspace/scikit_learn_linear_regression.ipynb
rename to openfl-tutorials/deprecated/interactive_api/scikit_learn_linear_regression/workspace/scikit_learn_linear_regression.ipynb
diff --git a/openfl/federated/data/loader_gandlf.py b/openfl/federated/data/loader_gandlf.py
index 6e1a04342a..648ebe2930 100644
--- a/openfl/federated/data/loader_gandlf.py
+++ b/openfl/federated/data/loader_gandlf.py
@@ -25,7 +25,10 @@ def __init__(self, data_path, feature_shape):
data_path (str): The path to the directory containing the data.
feature_shape (tuple): The shape of an example feature array.
"""
- self.train_csv = data_path + "/train.csv"
+ if "inference" in data_path:
+ self.train_csv = None
+ else:
+ self.train_csv = data_path + "/train.csv"
self.val_csv = data_path + "/valid.csv"
self.train_dataloader = None
self.val_dataloader = None
diff --git a/openfl/interface/workspace.py b/openfl/interface/workspace.py
index 260c71eed1..b138ad67db 100644
--- a/openfl/interface/workspace.py
+++ b/openfl/interface/workspace.py
@@ -389,6 +389,17 @@ def export_() -> str:
default=False,
help="If set, rebuilds docker images with `--no-cache` option.",
)
+@option(
+ "--enclave-key",
+ "enclave_key",
+ type=str,
+ required=False,
+ help=(
+ "Path to an enclave signing key. If not provided, a key will be auto-generated in the workspace. "
+ "Note that this command builds a TEE-ready image, key is NOT packaged along with the image. "
+ "You have the flexibility to not run inside a TEE later."
+ ),
+)
@option(
"--revision",
required=False,
@@ -401,8 +412,8 @@ def export_() -> str:
),
)
@pass_context
-def dockerize_(context, save, rebuild, revision):
- """Package current workspace as a Docker image."""
+def dockerize_(context, save: bool, rebuild: bool, enclave_key: str, revision: str):
+ """Package current workspace as a TEE-ready Docker image."""
# Docker build options
options = []
@@ -430,10 +441,24 @@ def dockerize_(context, save, rebuild, revision):
_execute(base_image_build_cmd)
# Build workspace image.
+ options = []
+ options.append("--no-cache" if rebuild else "")
+ options = " ".join(options)
+ if enclave_key is None:
+ _execute("openssl genrsa -out key.pem -3 3072")
+ enclave_key = os.path.abspath("key.pem")
+ logging.info(f"Generated new enclave key: {enclave_key}")
+ else:
+ enclave_key = os.path.abspath(enclave_key)
+ if not os.path.exists(enclave_key):
+ raise FileNotFoundError(f"Enclave key `{enclave_key}` does not exist")
+ logging.info(f"Using enclave key: {enclave_key}")
+
logging.info("Building workspace image")
ws_image_build_cmd = (
"DOCKER_BUILDKIT=1 docker build {options} "
"--build-arg WORKSPACE_NAME={workspace_name} "
+ "--secret id=signer-key,src={enclave_key} "
"-t {image_name} "
"-f {dockerfile} "
"{build_context}"
@@ -441,6 +466,7 @@ def dockerize_(context, save, rebuild, revision):
options=options,
image_name=workspace_name,
workspace_name=workspace_name,
+ enclave_key=enclave_key,
dockerfile=os.path.join(SITEPACKS, "openfl-docker", "Dockerfile.workspace"),
build_context=".",
)
diff --git a/test-requirements.txt b/test-requirements.txt
index 80ed75cde5..19bf081db1 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,3 +1,4 @@
+lxml==5.3.0
pytest==8.3.3
pytest-asyncio==0.24.0
pytest-mock==3.14.0
diff --git a/tests/end_to_end/README.md b/tests/end_to_end/README.md
new file mode 100644
index 0000000000..ae725a170f
--- /dev/null
+++ b/tests/end_to_end/README.md
@@ -0,0 +1,69 @@
+# End-to-end Pytest Framework
+
+This project aims at integration testing of ```openfl-workspace``` using pytest framework.
+
+## Test Structure
+
+```
+tests/end_to_end
+├── models # Central location for all model-related code for testing purpose
+├── test_suites # Folder containing test files
+├── utils # Folder containing helper files
+├── conftest.py # Pytest framework configuration file
+├── pytest.ini # Pytest initialisation file
+└── README.md # Readme file
+```
+
+** File `sample_tests.py` provided under `test_suites` acts as a reference on how to add a new test case.
+
+## Pre-requisites
+
+1. Setup virtual environment and install OpenFL using [online documentation](https://openfl.readthedocs.io/en/latest/get_started/installation.html).
+2. Ensure that the OpenFL workspace (inside openfl-workspace) is present for the model being tested. If not, create it first.
+
+## Installation
+
+To install the required dependencies on above virtual environment, run:
+
+```sh
+pip install -r test-requirements.txt
+```
+
+## Usage
+
+### Running Tests
+
+To run a specific test case, use below command:
+
+```sh
+python -m pytest -s tests/end_to_end/test_suites/ -k
+```
+
+** -s will ensure all the logs are printed on screen. Ignore, if not required.
+
+Below parameters are available for modification:
+
+1. --num_collaborators - to modify the number of collaborators
+2. --num_rounds - to modify the number of rounds to train
+3. --model_name - to use a specific model
+4. --disable_tls - to disable TLS communication (by default it is enabled)
+5. --disable_client_auth - to disable the client authentication (by default it is enabled)
+
+For example, to run Task runner with - torch_cnn_mnist model, 3 collaborators, 5 rounds and non-TLS scenario:
+
+```sh
+python -m pytest -s tests/end_to_end/test_suites/task_runner_tests.py --num_rounds 5 --num_collaborators 3 --model_name torch_cnn_mnist --disable_tls
+```
+
+### Output Structure
+
+```
+results
+ ├── # Based on the workspace name provided during test run.
+ ├── results.xml # Output file in JUNIT.
+ └── deployment.log # Log file containing step by step test progress.
+```
+
+## Contribution
+
+https://github.com/securefederatedai/openfl/blob/develop/CONTRIBUTING.md
diff --git a/tests/end_to_end/conftest.py b/tests/end_to_end/conftest.py
new file mode 100644
index 0000000000..d2c9c20f89
--- /dev/null
+++ b/tests/end_to_end/conftest.py
@@ -0,0 +1,321 @@
+# Copyright 2020-2023 Intel Corporation
+# SPDX-License-Identifier: Apache-2.0
+
+import pytest
+import collections
+import os
+import shutil
+import xml.etree.ElementTree as ET
+import logging
+
+from tests.end_to_end.utils.logger import configure_logging
+from tests.end_to_end.utils.logger import logger as log
+from tests.end_to_end.utils.conftest_helper import parse_arguments
+import tests.end_to_end.utils.constants as constants
+import tests.end_to_end.models.participants as participants
+
+# Define a named tuple to store the objects for model owner, aggregator, and collaborators
+federation_fixture = collections.namedtuple(
+ "federation_fixture",
+ "model_owner, aggregator, collaborators, model_name, disable_client_auth, disable_tls, workspace_path, results_dir",
+)
+
+
+def pytest_addoption(parser):
+ """
+ Add custom command line options to the pytest parser.
+ Args:
+ parser: pytest parser object
+ """
+ parser.addini("results_dir", "Directory to store test results", default="results")
+ parser.addini("log_level", "Logging level", default="DEBUG")
+ parser.addoption(
+ "--results_dir", action="store", type=str, default="results", help="Results directory"
+ )
+ parser.addoption(
+ "--num_collaborators",
+ action="store",
+ type=int,
+ default=constants.NUM_COLLABORATORS,
+ help="Number of collaborators",
+ )
+ parser.addoption(
+ "--num_rounds",
+ action="store",
+ type=int,
+ default=constants.NUM_ROUNDS,
+ help="Number of rounds to train",
+ )
+ parser.addoption(
+ "--model_name",
+ action="store",
+ type=str,
+ help="Model name",
+ )
+ parser.addoption(
+ "--disable_client_auth",
+ action="store_true",
+ help="Disable client authentication",
+ )
+ parser.addoption(
+ "--disable_tls",
+ action="store_true",
+ help="Disable TLS for communication",
+ )
+
+
+@pytest.fixture(scope="session", autouse=True)
+def setup_logging(pytestconfig):
+ """
+ Setup logging for the test session.
+ Args:
+ pytestconfig: pytest config object
+ Returns:
+ logger: logger object
+ """
+ results_dir = pytestconfig.getini("results_dir")
+ log_level = pytestconfig.getini("log_level")
+
+ if not os.path.exists(results_dir):
+ os.makedirs(results_dir)
+
+ # Setup a global logger to ensure logging works before any test-specific logs are set
+ configure_logging(os.path.join(results_dir, "deployment.log"), log_level)
+ return logging.getLogger()
+
+
+@pytest.hookimpl(tryfirst=True, hookwrapper=True)
+def pytest_runtest_makereport(item, call):
+ """
+ Hook to capture the result of setup, call, and teardown phases.
+ This avoids duplicate entries for Pass/Fail in the XML report.
+ """
+ outcome = yield
+ report = outcome.get_result()
+
+ # Retrieve the custom test_id marker if it exists
+ test_id_marker = item.get_closest_marker("test_id")
+ outcome_mapping = {"passed": "Pass", "failed": "Fail"}
+ report_when_mapping = {"setup": "Setup", "call": "Test", "teardown": "Teardown"}
+ final_outcome = outcome_mapping.get(report.outcome, report.outcome)
+ report_phase = report_when_mapping.get(report.when, report.when)
+
+ # Modify nodeid if test_id is provided and append outcome and phase
+ if test_id_marker:
+ test_id = test_id_marker.args[0]
+ report.nodeid = (
+ f"{report.nodeid} [{test_id}] [outcome: {final_outcome}] [phase: {report_phase}]"
+ )
+
+ # Initialize XML structure if not already initialized
+ if not hasattr(item.config, "_xml_report"):
+ item.config._xml_report = ET.Element(
+ "testsuite",
+ {
+ "name": "pytest",
+ "errors": "0",
+ "failures": "0",
+ "skipped": "0",
+ "tests": "0",
+ "time": "0",
+ "timestamp": "",
+ "hostname": "",
+ },
+ )
+
+ # Store the result of each phase (setup/call/teardown)
+ if not hasattr(item, "_results"):
+ item._results = {}
+
+ # Save the outcome and other details per phase
+ item._results[report.when] = {
+ "outcome": final_outcome,
+ "longrepr": report.longrepr,
+ "duration": report.duration,
+ }
+ # Log failures
+ if report.when == "call" and report.failed:
+ logger = logging.getLogger()
+ logger.error(f"Test {report.nodeid} failed: {call.excinfo.value}")
+
+ # Only create the XML element after the teardown phase
+ if report.when == "teardown" and not hasattr(item, "_xml_created"):
+ item._xml_created = True # Ensure XML creation happens only once
+
+ # Determine final outcome based on the worst phase result
+ if "call" in item._results:
+ final_outcome = item._results["call"]["outcome"]
+ elif "setup" in item._results:
+ final_outcome = item._results["setup"]["outcome"]
+ else:
+ final_outcome = "skipped"
+
+ # Create the XML element
+ testcase = ET.SubElement(
+ item.config._xml_report,
+ "testcase",
+ {
+ "classname": item.module.__name__,
+ "name": item.name,
+ "time": str(sum(result["duration"] for result in item._results.values())),
+ },
+ )
+
+ # Add or tags based on the final outcome
+ if final_outcome == "Fail":
+ failure_message = item._results.get("call", {}).get(
+ "longrepr", item._results.get("setup", {}).get("longrepr", "Unknown Error")
+ )
+ failure = ET.SubElement(
+ testcase,
+ "error",
+ {
+ "message": str(failure_message),
+ },
+ )
+ failure.text = str(failure_message)
+ elif final_outcome == "skipped":
+ skipped_message = item._results.get("setup", {}).get("longrepr", "Skipped")
+ skipped = ET.SubElement(
+ testcase,
+ "skipped",
+ {
+ "message": str(skipped_message),
+ },
+ )
+ skipped.text = str(skipped_message)
+
+ # Update the testsuite summary statistics
+ tests = int(item.config._xml_report.attrib["tests"]) + 1
+ item.config._xml_report.attrib["tests"] = str(tests)
+ if final_outcome == "Fail":
+ failures = int(item.config._xml_report.attrib["failures"]) + 1
+ item.config._xml_report.attrib["failures"] = str(failures)
+ elif final_outcome == "skipped":
+ skipped = int(item.config._xml_report.attrib["skipped"]) + 1
+ item.config._xml_report.attrib["skipped"] = str(skipped)
+
+
+def pytest_sessionfinish(session, exitstatus):
+ """
+ Operations to be performed after the test session is finished.
+ More functionalities to be added in this function in future.
+ """
+ cache_dir = os.path.join(session.config.rootdir, ".pytest_cache")
+ log.debug(f"\nClearing .pytest_cache directory at {cache_dir}")
+ if os.path.exists(cache_dir):
+ shutil.rmtree(cache_dir, ignore_errors=False)
+ log.debug(f"Cleared .pytest_cache directory at {cache_dir}")
+
+
+@pytest.fixture(scope="function")
+def fx_federation(request, pytestconfig):
+ """
+ Fixture for federation. This fixture is used to create the model owner, aggregator, and collaborators.
+ It also creates workspace.
+ Assumption: OpenFL workspace is present for the model being tested.
+ Args:
+ request: pytest request object. Model name is passed as a parameter to the fixture from test cases.
+ pytestconfig: pytest config object
+ Returns:
+ federation_fixture: Named tuple containing the objects for model owner, aggregator, and collaborators
+
+ Note: As this is a function level fixture, thus no import is required at test level.
+ """
+ collaborators = []
+ agg_domain_name = "localhost"
+
+ # Parse the command line arguments
+ args = parse_arguments()
+ # Use the model name from the test case name if not provided as a command line argument
+ model_name = args.model_name if args.model_name else request.node.name.split("test_")[1]
+ results_dir = args.results_dir or pytestconfig.getini("results_dir")
+ num_collaborators = args.num_collaborators
+ num_rounds = args.num_rounds
+ disable_client_auth = args.disable_client_auth
+ disable_tls = args.disable_tls
+
+ log.info(
+ f"Running federation setup using Task Runner API on single machine with below configurations:\n"
+ f"\tNumber of collaborators: {num_collaborators}\n"
+ f"\tNumber of rounds: {num_rounds}\n"
+ f"\tModel name: {model_name}\n"
+ f"\tClient authentication: {not disable_client_auth}\n"
+ f"\tTLS: {not disable_tls}"
+ )
+
+ # Validate the model name and create the workspace name
+ if not model_name.upper() in constants.ModelName._member_names_:
+ raise ValueError(f"Invalid model name: {model_name}")
+
+ workspace_name = f"workspace_{model_name}"
+
+ # Create model owner object and the workspace for the model
+ model_owner = participants.ModelOwner(workspace_name, model_name)
+ try:
+ workspace_path = model_owner.create_workspace(results_dir=results_dir)
+ except Exception as e:
+ log.error(f"Failed to create the workspace: {e}")
+ raise e
+
+ # Modify the plan
+ try:
+ model_owner.modify_plan(
+ new_rounds=num_rounds,
+ num_collaborators=num_collaborators,
+ disable_client_auth=disable_client_auth,
+ disable_tls=disable_tls,
+ )
+ except Exception as e:
+ log.error(f"Failed to modify the plan: {e}")
+ raise e
+
+ # For TLS enabled (default) scenario: when the workspace is certified, the collaborators are registered as well
+ # For TLS disabled scenario: collaborators need to be registered explicitly
+ if args.disable_tls:
+ log.info("Disabling TLS for communication")
+ try:
+ model_owner.register_collaborators(num_collaborators)
+ except Exception as e:
+ log.error(f"Failed to register the collaborators: {e}")
+ raise e
+ else:
+ log.info("Enabling TLS for communication")
+ try:
+ model_owner.certify_workspace()
+ except Exception as e:
+ log.error(f"Failed to certify the workspace: {e}")
+ raise e
+
+ # Initialize the plan
+ try:
+ model_owner.initialize_plan(agg_domain_name=agg_domain_name)
+ except Exception as e:
+ log.error(f"Failed to initialize the plan: {e}")
+ raise e
+
+ # Create the objects for aggregator and collaborators
+ aggregator = participants.Aggregator(
+ agg_domain_name=agg_domain_name, workspace_path=workspace_path
+ )
+
+ for i in range(num_collaborators):
+ collaborator = participants.Collaborator(
+ collaborator_name=f"collaborator{i+1}",
+ data_directory_path=i + 1,
+ workspace_path=workspace_path,
+ )
+ collaborator.create_collaborator()
+ collaborators.append(collaborator)
+
+ # Return the federation fixture
+ return federation_fixture(
+ model_owner=model_owner,
+ aggregator=aggregator,
+ collaborators=collaborators,
+ model_name=model_name,
+ disable_client_auth=disable_client_auth,
+ disable_tls=disable_tls,
+ workspace_path=workspace_path,
+ results_dir=results_dir,
+ )
diff --git a/tests/end_to_end/models/participants.py b/tests/end_to_end/models/participants.py
new file mode 100644
index 0000000000..5bde7f39ec
--- /dev/null
+++ b/tests/end_to_end/models/participants.py
@@ -0,0 +1,466 @@
+# Copyright 2020-2023 Intel Corporation
+# SPDX-License-Identifier: Apache-2.0
+
+import os
+import yaml
+import logging
+
+import tests.end_to_end.utils.constants as constants
+import tests.end_to_end.utils.subprocess_helper as sh
+
+log = logging.getLogger(__name__)
+
+
+# Define the ModelOwner class
+class ModelOwner:
+ """
+ ModelOwner class to handle the model related operations.
+ Note: Aggregator can also act as a model owner.
+ This includes (non-exhaustive list):
+ 1. Creating the workspace - to create a workspace using given workspace and model names.
+ 2. Modifying based on input params provided and initializing the plan.
+ 3. Certifying the workspace and setting up the PKI.
+ 4. Importing and exporting the workspace etc.
+ """
+
+ def __init__(self, workspace_name, model_name):
+ """
+ Initialize the ModelOwner class
+ Args:
+ workspace_name (str): Workspace name
+ model_name (str): Model name
+ """
+ self.workspace_name = workspace_name
+ self.model_name = model_name
+ self.aggregator = None
+ self.collaborators = []
+ self.workspace_path = None
+ self.plan_path = None
+ self.num_collaborators = constants.NUM_COLLABORATORS
+ self.rounds_to_train = constants.NUM_ROUNDS
+
+ def create_workspace(self, results_dir=None):
+ """
+ Create the workspace for the model
+ Args:
+ results_dir (str): Results directory path
+ Returns:
+ str: Path to the workspace
+ """
+ try:
+ results_dir = results_dir if results_dir else os.getcwd()
+ return_code, _, error = sh.run_command(
+ f"fx workspace create --prefix {self.workspace_name} --template {self.model_name}",
+ work_dir=results_dir,
+ )
+ if return_code != 0:
+ log.error(f"Failed to create the workspace: {error}")
+ raise Exception(f"Failed to create the workspace: {error}")
+
+ log.info(f"Created the workspace {self.workspace_name} for the {self.model_name} model")
+ self.workspace_path = os.path.join(results_dir, self.workspace_name)
+ log.info(f"Workspace path: {self.workspace_path}")
+ except Exception as e:
+ log.error(f"Failed to create the workspace: {e}")
+ raise e
+ return self.workspace_path
+
+ def get_workspace_path(self, results_dir, workspace_name):
+ """
+ Get the workspace path
+ Args:
+ results_dir (str): Results directory path
+ workspace_name (str): Workspace name
+ Returns:
+ str: Path to the workspace
+ """
+ workspace_path = os.path.join(results_dir, workspace_name)
+ log.info(f"Workspace path: {workspace_path}")
+ if os.path.exists(workspace_path):
+ self.workspace_path = workspace_path
+ log.info(f"Workspace path: {self.workspace_path}")
+ else:
+ log.error(f"Workspace {workspace_name} does not exist in {results_dir}")
+ raise FileNotFoundError(f"Workspace {workspace_name} does not exist in {results_dir}")
+ return self.workspace_path
+
+ def certify_collaborator(self, collaborator_name):
+ """
+ Sign the CSR for the collaborator
+ Args:
+ collaborator_name (str): Name of the collaborator
+ Returns:
+ bool: True if successful, else False
+ """
+ try:
+ zip_name = f"col_{collaborator_name}_to_agg_cert_request.zip"
+ col_zip = os.path.join(os.getcwd(), self.workspace_path, zip_name)
+ return_code, output, error = sh.run_command(
+ f"fx collaborator certify --request-pkg {col_zip} -s", work_dir=self.workspace_path
+ )
+ msg_received = [line for line in output if constants.SUCCESS_MARKER in line]
+ log.info(f"Message received: {msg_received}")
+ if return_code == 0 and len(msg_received):
+ log.info(
+ f"Successfully signed the CSR for the collaborator {collaborator_name} with zip path {col_zip}"
+ )
+ else:
+ log.error(f"Failed to sign the CSR for collaborator {collaborator_name}: {error}")
+
+ except Exception as e:
+ log.error(f"Failed to sign the CSR: {e}")
+ raise e
+ return True
+
+ def modify_plan(self, new_rounds=None, num_collaborators=None, disable_client_auth=False, disable_tls=False):
+ """
+ Modify the plan to train the model
+ Args:
+ new_rounds (int): Number of rounds to train
+ num_collaborators (int): Number of collaborators
+ disable_client_auth (bool): Disable client authentication
+ disable_tls (bool): Disable TLS communication
+ Returns:
+ bool: True if successful, else False
+ """
+ self.plan_path = os.path.join(self.workspace_path, "plan", "plan.yaml")
+ # Open the file and modify the entries
+ self.rounds_to_train = new_rounds if new_rounds else self.rounds_to_train
+ self.num_collaborators = num_collaborators if num_collaborators else self.num_collaborators
+
+ with open(self.plan_path) as fp:
+ data = yaml.load(fp, Loader=yaml.FullLoader)
+
+ data["aggregator"]["settings"]["rounds_to_train"] = int(self.rounds_to_train)
+ data["data_loader"]["settings"]["collaborator_count"] = int(self.num_collaborators)
+ data["network"]["settings"]["disable_client_auth"] = disable_client_auth
+ data["network"]["settings"]["tls"] = not disable_tls
+
+ with open(self.plan_path, "w+") as write_file:
+ yaml.dump(data, write_file)
+
+ log.info(f"Modified the plan at {self.plan_path} with provided parameters.")
+ return True
+
+ def initialize_plan(self, agg_domain_name):
+ """
+ Initialize the plan
+ Args:
+ agg_domain_name (str): Aggregator domain name
+ Returns:
+ bool: True if successful, else False
+ """
+ try:
+ log.info("Initializing the plan. It will take some time to complete..")
+ return_code, _, error = sh.run_command(f"fx plan initialize -a {agg_domain_name}", work_dir=self.workspace_path)
+ if return_code != 0:
+ log.error(f"Failed to initialize the plan: {error}")
+ raise Exception(f"Failed to initialize the plan: {error}")
+
+ log.info(f"Initialized the plan for the workspace {self.workspace_name}")
+ except Exception as e:
+ log.error(f"Failed to initialize the plan: {e}")
+ raise e
+ return True
+
+ def certify_workspace(self):
+ """
+ Certify the workspace
+ Returns:
+ bool: True if successful, else False
+ """
+ try:
+ return_code, _, error = sh.run_command("fx workspace certify", work_dir=self.workspace_path)
+ if return_code != 0:
+ log.error(f"Failed to certify the workspace: {error}")
+ raise Exception(f"Failed to certify the workspace: {error}")
+
+ log.info(f"Certified the workspace {self.workspace_name}")
+ except Exception as e:
+ log.error(f"Failed to certify the workspace: {e}")
+ raise e
+ return True
+
+ def register_collaborators(self, num_collaborators=None):
+ """
+ Register the collaborators
+ Args:
+ num_collaborators (int, Optional): Number of collaborators
+ Returns:
+ bool: True if successful, else False
+ """
+ self.cols_path = os.path.join(self.workspace_path, "plan", "cols.yaml")
+ log.info(f"Registering the collaborators..")
+ self.num_collaborators = num_collaborators if num_collaborators else self.num_collaborators
+
+ try:
+ # Straightforward writing to the yaml file is not recommended here
+ # As the file might contain spaces and tabs which can cause issues
+ with open(self.cols_path, "r", encoding="utf-8") as f:
+ doc = yaml.load(f, Loader=yaml.FullLoader)
+
+ if "collaborators" not in doc.keys() or not doc["collaborators"]:
+ doc["collaborators"] = [] # Create empty list
+
+ for i in range(num_collaborators):
+ col_name = "collaborator" + str(i+1)
+ doc["collaborators"].append(col_name)
+ with open(self.cols_path, "w", encoding="utf-8") as f:
+ yaml.dump(doc, f)
+
+ log.info(
+ f"Successfully registered collaborators in {self.cols_path}"
+ )
+ except Exception as e:
+ log.error(f"Failed to register the collaborators: {e}")
+ raise e
+ return True
+
+ def certify_aggregator(self, agg_domain_name):
+ """
+ Certify the aggregator request
+ Args:
+ agg_domain_name (str): Aggregator domain name
+ Returns:
+ bool: True if successful, else False
+ """
+ log.info(f"CA should sign the aggregator request")
+ try:
+ return_code, _, error = sh.run_command(
+ f"fx aggregator certify --silent --fqdn {agg_domain_name}",
+ work_dir=self.workspace_path,
+ )
+ if return_code != 0:
+ log.error(f"Failed to certify the aggregator request: {error}")
+ raise Exception(f"Failed to certify the aggregator request: {error}")
+
+ log.info(f"CA signed the request from aggregator")
+ except Exception as e:
+ log.error(f"Failed to certify the aggregator request : {e}")
+ raise e
+ return True
+
+ def export_workspace(self):
+ """
+ Export the workspace
+ Returns:
+ bool: True if successful, else False
+ """
+ try:
+ return_code, _, error = sh.run_command("fx workspace export", work_dir=self.workspace_path)
+ if return_code != 0:
+ log.error(f"Failed to export the workspace: {error}")
+ raise Exception(f"Failed to export the workspace: {error}")
+
+ log.info(f"Exported the workspace")
+ except Exception as e:
+ log.error(f"Failed to export the workspace: {e}")
+ raise e
+ return True
+
+ def import_workspace(self, workspace_zip):
+ """
+ Import the workspace
+ Args:
+ workspace_zip (str): Path to the workspace zip file
+ Returns:
+ bool: True if successful, else False
+ """
+ try:
+ return_code, _, error = sh.run_command(
+ f"fx workspace import --archive {workspace_zip}", work_dir=self.workspace_path
+ )
+ if return_code != 0:
+ log.error(f"Failed to import the workspace: {error}")
+ raise Exception(f"Failed to import the workspace: {error}")
+
+ log.info(f"Imported the workspace")
+ except Exception as e:
+ log.error(f"Failed to import the workspace: {e}")
+ raise e
+ return True
+
+
+# Define the Aggregator class
+class Aggregator:
+ """
+ Aggregator class to handle the aggregator operations.
+ This includes (non-exhaustive list):
+ 1. Generating the sign request
+ 2. Starting the aggregator
+ """
+
+ def __init__(self, agg_domain_name=None, workspace_path=None):
+ """
+ Initialize the Aggregator class
+ """
+ self.name = "aggregator"
+ self.agg_domain_name = agg_domain_name
+ self.workspace_path = workspace_path
+
+ def generate_sign_request(self):
+ """
+ Generate a sign request for the aggregator
+ Returns:
+ bool: True if successful, else False
+ """
+ try:
+ return_code, _, error = sh.run_command(
+ f"fx aggregator generate-cert-request --fqdn {self.agg_domain_name}",
+ work_dir=self.workspace_path,
+ )
+ if return_code != 0:
+ log.error(f"Failed to generate the sign request: {error}")
+ raise Exception(f"Failed to generate the sign request: {error}")
+
+ log.info(f"Generated a sign request for {self.name}")
+ except Exception as e:
+ log.error(f"Failed to generate the sign request: {e}")
+ raise e
+ return True
+
+ def start(self):
+ """
+ Start the aggregator
+ Returns:
+ str: Path to the log file
+ """
+ try:
+ log.info(f"Starting {self.name}")
+ filename = f"{self.name}.log"
+ res_file = os.path.join(os.getcwd(), self.workspace_path, filename)
+ bg_file = open(res_file, "w", buffering=1)
+
+ sh.run_command_background(
+ "fx aggregator start",
+ work_dir=self.workspace_path,
+ redirect_to_file=bg_file,
+ check_sleep=60,
+ )
+ log.info(
+ f"Started {self.name} and tracking the logs at {os.path.join(self.workspace_path, filename)}"
+ )
+ except Exception as e:
+ log.error(f"Failed to start the aggregator: {e}")
+ res_file.close()
+ raise e
+ return res_file
+
+
+# Define the Collaborator class
+class Collaborator:
+ """
+ Collaborator class to handle the collaborator operations.
+ This includes (non-exhaustive list):
+ 1. Generating the sign request
+ 2. Creating the collaborator
+ 3. Importing and certifying the CSR
+ 4. Starting the collaborator
+ """
+
+ def __init__(self, collaborator_name=None, data_directory_path=None, workspace_path=None):
+ """
+ Initialize the Collaborator class
+ """
+ self.name = collaborator_name
+ self.collaborator_name = collaborator_name
+ self.data_directory_path = data_directory_path
+ self.workspace_path = workspace_path
+
+ def generate_sign_request(self):
+ """
+ Generate a sign request for the collaborator
+ Returns:
+ bool: True if successful, else False
+ """
+ try:
+ return_code, _, error = sh.run_command(
+ f"fx collaborator generate-cert-request -n {self.collaborator_name}",
+ work_dir=self.workspace_path,
+ )
+ if return_code != 0:
+ log.error(f"Failed to generate the sign request: {error}")
+ raise Exception(f"Failed to generate the sign request: {error}")
+
+ log.info(f"Generated a sign request for {self.collaborator_name}")
+ except Exception as e:
+ log.error(f"Failed to generate the sign request: {e}")
+ raise e
+ return True
+
+ def create_collaborator(self):
+ """
+ Create the collaborator
+ Returns:
+ bool: True if successful, else False
+ """
+ try:
+ return_code, _, error = sh.run_command(
+ f"fx collaborator create -n {self.collaborator_name} -d {self.data_directory_path}",
+ work_dir=self.workspace_path,
+ )
+ if return_code != 0:
+ log.error(f"Failed to create the collaborator: {error}")
+ raise Exception(f"Failed to create the collaborator: {error}")
+ log.info(
+ f"Created {self.collaborator_name} with the data directory {self.data_directory_path}"
+ )
+ except Exception as e:
+ log.error(f"Failed to create the collaborator: {e}")
+ raise e
+ return True
+
+ def import_pki(self):
+ """
+ Import and certify the CSR for the collaborator
+ Returns:
+ bool: True if successful, else False
+ """
+ try:
+ zip_name = f"agg_to_col_{self.collaborator_name}_signed_cert.zip"
+ col_zip = os.path.join(os.getcwd(), self.workspace_path, zip_name)
+ return_code, output, error = sh.run_command(
+ f"fx collaborator certify --import {col_zip}", work_dir=self.workspace_path
+ )
+ msg_received = [line for line in output if constants.SUCCESS_MARKER in line]
+ log.info(f"Message received: {msg_received}")
+ if return_code == 0 and len(msg_received):
+ log.info(
+ f"Successfully imported and certified the CSR for {self.collaborator_name} with zip path {col_zip}"
+ )
+ else:
+ log.error(
+ f"Failed to import and certify the CSR for {self.collaborator_name}: {error}"
+ )
+
+ except Exception as e:
+ log.error(f"Failed to import and certify the CSR: {e}")
+ raise e
+ return True
+
+ def start(self):
+ """
+ Start the collaborator
+ Returns:
+ str: Path to the log file
+ """
+ try:
+ log.info(f"Starting {self.collaborator_name}")
+ filename = f"{self.collaborator_name}.log"
+ res_file = os.path.join(os.getcwd(), self.workspace_path, filename)
+ bg_file = open(res_file, "w", buffering=1)
+
+ sh.run_command_background(
+ f"fx collaborator start -n {self.collaborator_name}",
+ work_dir=self.workspace_path,
+ redirect_to_file=bg_file,
+ check_sleep=60,
+ )
+ log.info(
+ f"Started {self.collaborator_name} and tracking the logs at {os.path.join(self.workspace_path, filename)}"
+ )
+ except Exception as e:
+ log.error(f"Failed to start the collaborator: {e}")
+ res_file.close()
+ raise e
+ return res_file
diff --git a/tests/end_to_end/pytest.ini b/tests/end_to_end/pytest.ini
new file mode 100644
index 0000000000..8d18441dd6
--- /dev/null
+++ b/tests/end_to_end/pytest.ini
@@ -0,0 +1,12 @@
+[pytest]
+addopts = -ra -q -s --junitxml=results/results.xml
+testpaths = test_suites
+junit_family = xunit2
+results_dir = results
+log_level = INFO
+markers =
+ torch_cnn_mnist: mark a test as a torch CNN MNIST test.
+ keras_cnn_mnist: mark a test as a Keras CNN MNIST test.
+ torch_cnn_histology: mark a test as a torch CNN histology test.
+asyncio_mode=auto
+asyncio_default_fixture_loop_scope="function"
diff --git a/tests/end_to_end/test_suites/sample_tests.py b/tests/end_to_end/test_suites/sample_tests.py
new file mode 100644
index 0000000000..a27bf76cbf
--- /dev/null
+++ b/tests/end_to_end/test_suites/sample_tests.py
@@ -0,0 +1,35 @@
+# Copyright 2020-2023 Intel Corporation
+# SPDX-License-Identifier: Apache-2.0
+
+import pytest
+import logging
+
+from tests.end_to_end.utils import federation_helper as fed_helper
+
+log = logging.getLogger(__name__)
+
+# ** IMPORTANT **: This is just an example on how to add a test with below pre-requisites.
+# Task Runner API Test function for federation run using sample_model
+# 1. Create OpenFL workspace, if not present for the model and add relevant dataset and its path in plan/data.yaml
+# 2. Append the model name to ModelName enum in tests/end_to_end/utils/constants.py
+# 3. Add the model name to tests/end_to_end/pytest.ini marker, if not present
+# 4. Use fx_federation fixture in the test function - it will provide the federation object.
+# 5. Fixture will contain - model_owner, aggregator, collaborators, model_name, workspace_path, results_dir
+# 6. Setup PKI for trusted communication within the federation
+# 7. Start the federation using aggregator and given no of collaborators.
+# 8. Verify the completion of the federation run.
+
+@pytest.mark.sample_model_name
+def test_sample_model_name(fx_federation):
+ """
+ Add a proper docstring here.
+ """
+ log.info(f"Running sample model test {fx_federation.model_name}")
+ # Setup PKI for trusted communication within the federation
+ assert fed_helper.setup_pki(fx_federation), "Failed to setup PKI"
+
+ # Start the federation
+ results = fed_helper.run_federation(fx_federation)
+
+ # Verify the completion of the federation run
+ assert fed_helper.verify_federation_run_completion(fx_federation, results), "Federation completion failed"
diff --git a/tests/end_to_end/test_suites/task_runner_tests.py b/tests/end_to_end/test_suites/task_runner_tests.py
new file mode 100644
index 0000000000..371fee8f08
--- /dev/null
+++ b/tests/end_to_end/test_suites/task_runner_tests.py
@@ -0,0 +1,60 @@
+# Copyright 2020-2023 Intel Corporation
+# SPDX-License-Identifier: Apache-2.0
+
+import pytest
+import logging
+
+from tests.end_to_end.utils import federation_helper as fed_helper
+
+log = logging.getLogger(__name__)
+
+
+@pytest.mark.torch_cnn_mnist
+def test_torch_cnn_mnist(fx_federation):
+ """
+ Test for torch_cnn_mnist model.
+ """
+ log.info("Testing torch_cnn_mnist model")
+
+ # Setup PKI for trusted communication within the federation
+ if not fx_federation.disable_tls:
+ assert fed_helper.setup_pki(fx_federation), "Failed to setup PKI for trusted communication"
+
+ # Start the federation
+ results = fed_helper.run_federation(fx_federation)
+
+ # Verify the completion of the federation run
+ assert fed_helper.verify_federation_run_completion(fx_federation, results), "Federation completion failed"
+
+
+@pytest.mark.keras_cnn_mnist
+def test_keras_cnn_mnist(fx_federation):
+ log.info("Testing keras_cnn_mnist model")
+
+ # Setup PKI for trusted communication within the federation
+ if not fx_federation.disable_tls:
+ assert fed_helper.setup_pki(fx_federation), "Failed to setup PKI for trusted communication"
+
+ # Start the federation
+ results = fed_helper.run_federation(fx_federation)
+
+ # Verify the completion of the federation run
+ assert fed_helper.verify_federation_run_completion(fx_federation, results), "Federation completion failed"
+
+
+@pytest.mark.torch_cnn_histology
+def test_torch_cnn_histology(fx_federation):
+ """
+ Test for torch_cnn_histology model
+ """
+ log.info("Testing torch_cnn_histology model")
+
+ # Setup PKI for trusted communication within the federation
+ if not fx_federation.disable_tls:
+ assert fed_helper.setup_pki(fx_federation), "Failed to setup PKI for trusted communication"
+
+ # Start the federation
+ results = fed_helper.run_federation(fx_federation)
+
+ # Verify the completion of the federation run
+ assert fed_helper.verify_federation_run_completion(fx_federation, results), "Federation completion failed"
diff --git a/tests/end_to_end/utils/conftest_helper.py b/tests/end_to_end/utils/conftest_helper.py
new file mode 100644
index 0000000000..b8d70fa7ba
--- /dev/null
+++ b/tests/end_to_end/utils/conftest_helper.py
@@ -0,0 +1,40 @@
+# Copyright 2020-2023 Intel Corporation
+# SPDX-License-Identifier: Apache-2.0
+
+import argparse
+import sys
+import logging
+
+log = logging.getLogger(__name__)
+
+
+def parse_arguments():
+ """
+ Parse command line arguments to provide the required parameters for running the tests.
+
+ Returns:
+ argparse.Namespace: Parsed command line arguments with the following attributes:
+ - results_dir (str, optional): Directory to store the results
+ - num_collaborators (int, default=2): Number of collaborators
+ - num_rounds (int, default=5): Number of rounds to train
+ - model_name (str, default="torch_cnn_mnist"): Model name
+ - disable_client_auth (bool): Disable client authentication
+ - disable_tls (bool): Disable TLS for communication
+
+ Raises:
+ SystemExit: If the required arguments are not provided or if any argument parsing error occurs.
+ """
+ try:
+ parser = argparse.ArgumentParser(description="Provide the required arguments to run the tests")
+ parser.add_argument("--results_dir", type=str, required=False, default="results", help="Directory to store the results")
+ parser.add_argument("--num_collaborators", type=int, default=2, help="Number of collaborators")
+ parser.add_argument("--num_rounds", type=int, default=5, help="Number of rounds to train")
+ parser.add_argument("--model_name", type=str, help="Model name")
+ parser.add_argument("--disable_client_auth", action="store_true", help="Disable client authentication")
+ parser.add_argument("--disable_tls", action="store_true", help="Disable TLS for communication")
+ args = parser.parse_known_args()[0]
+ return args
+
+ except Exception as e:
+ log.error(f"Failed to parse arguments: {e}")
+ sys.exit(1)
diff --git a/tests/end_to_end/utils/constants.py b/tests/end_to_end/utils/constants.py
new file mode 100644
index 0000000000..0b724c7ced
--- /dev/null
+++ b/tests/end_to_end/utils/constants.py
@@ -0,0 +1,21 @@
+# Copyright 2020-2023 Intel Corporation
+# SPDX-License-Identifier: Apache-2.0
+
+from enum import Enum
+
+# Define the model names. This is a non exhaustive list of models that can be used in the tests
+class ModelName(Enum):
+ """
+ Enum class to define the model names.
+ """
+ # IMP - The model name must be same (and in uppercase) as the model value.
+ # This is used to identify the model in the tests.
+ TORCH_CNN_MNIST = "torch_cnn_mnist"
+ KERAS_CNN_MNIST = "keras_cnn_mnist"
+ TORCH_CNN_HISTOLOGY = "torch_cnn_histology"
+
+NUM_COLLABORATORS = 2
+NUM_ROUNDS = 5
+WORKSPACE_NAME = "my_federation"
+DEFAULT_MODEL_NAME = "torch_cnn_mnist"
+SUCCESS_MARKER = "✔️ OK"
diff --git a/tests/end_to_end/utils/federation_helper.py b/tests/end_to_end/utils/federation_helper.py
new file mode 100644
index 0000000000..1da1c68012
--- /dev/null
+++ b/tests/end_to_end/utils/federation_helper.py
@@ -0,0 +1,134 @@
+# Copyright 2020-2023 Intel Corporation
+# SPDX-License-Identifier: Apache-2.0
+
+import time
+import concurrent.futures
+import logging
+
+from tests.end_to_end.utils.constants import SUCCESS_MARKER
+
+log = logging.getLogger(__name__)
+
+
+def setup_pki(fed_obj):
+ """
+ Setup PKI for trusted communication within the federation
+
+ Args:
+ fed_obj (object): Federation fixture object
+ Returns:
+ bool: True if successful, else False
+ """
+ success = False
+ # Aggregator and model owner operations
+ try:
+ log.info(f"Performing operations for {fed_obj.aggregator.name}")
+ fed_obj.aggregator.generate_sign_request()
+ fed_obj.model_owner.certify_aggregator(fed_obj.aggregator.agg_domain_name)
+ except Exception as e:
+ log.error(f"Failed to perform aggregator operations: {e}")
+ raise e
+
+ # Collaborator and model owner operations
+ for collaborator in fed_obj.collaborators:
+ try:
+ log.info(f"Performing operations for {collaborator.collaborator_name}")
+ collaborator.generate_sign_request()
+ # Below step will add collaborator entries in cols.yaml file.
+ fed_obj.model_owner.certify_collaborator(collaborator.collaborator_name)
+ collaborator.import_pki()
+ except Exception as e:
+ log.error(f"Failed to perform collaborator operations: {e}")
+ raise e
+ success = True
+
+ log.info("CSR operations completed successfully for all participants")
+ return success
+
+
+def run_federation(fed_obj):
+ """
+ Start the federation
+ Args:
+ fed_obj (object): Federation fixture object
+ Returns:
+ list: List of response files for all the participants
+ """
+ executor = concurrent.futures.ThreadPoolExecutor()
+ # As the collaborators will wait for aggregator to start, we need to start them in parallel.
+ futures = [
+ executor.submit(
+ participant.start
+ )
+ for participant in fed_obj.collaborators + [fed_obj.aggregator]
+ ]
+
+ # Result will contain response files for all the participants.
+ results = [f.result() for f in futures]
+ return results
+
+
+def verify_federation_run_completion(fed_obj, results):
+ """
+ Verify the completion of the process for all the participants
+ Args:
+ fed_obj (object): Federation fixture object
+ results (list): List of results
+ Returns:
+ list: List of response (True or False) for all the participants
+ """
+ log.info("Verifying the completion of the process for all the participants")
+ # Start the collaborators and aggregator
+ executor = concurrent.futures.ThreadPoolExecutor()
+ # As the collaborators will wait for aggregator to start, we need to start them in parallel.
+ futures = [
+ executor.submit(
+ _verify_completion_for_participant,
+ participant,
+ results[i]
+ )
+ for i, participant in enumerate(fed_obj.collaborators + [fed_obj.aggregator])
+ ]
+
+ # Result will contain a list of boolean values for all the participants.
+ # True - successful completion, False - failed/incomplete
+ results = [f.result() for f in futures]
+ log.info(f"Results: {results}")
+
+ # If any of the participant failed, return False, else return True
+ return all(results)
+
+
+def _verify_completion_for_participant(participant, result_file):
+ """
+ Verify the completion of the process for the participant
+ Args:
+ participant (object): Participant object
+ result_file (str): Result file
+ Returns:
+ bool: True if successful, else False
+ """
+ # Wait for the successful output message to appear in the log till timeout
+ timeout = 900 # in seconds
+ log.info(f"Printing the last line of the log file for {participant.name} to track the progress")
+ with open(result_file, 'r') as file:
+ content = file.read()
+ start_time = time.time()
+ while (
+ SUCCESS_MARKER not in content and time.time() - start_time < timeout
+ ):
+ with open(result_file, 'r') as file:
+ content = file.read()
+ # Print last 2 lines of the log file on screen to track the progress
+ log.info(f"{participant.name}: {content.splitlines()[-1:]}")
+ if SUCCESS_MARKER in content:
+ break
+ log.info(f"Process is yet to complete for {participant.name}")
+ time.sleep(45)
+
+ if SUCCESS_MARKER not in content:
+ log.error(f"Process failed/is incomplete for {participant.name} after timeout of {timeout} seconds")
+ return False
+ else:
+ log.info(f"Process completed for {participant.name} in {time.time() - start_time} seconds")
+ return True
diff --git a/tests/end_to_end/utils/logger.py b/tests/end_to_end/utils/logger.py
new file mode 100644
index 0000000000..b3e9d95311
--- /dev/null
+++ b/tests/end_to_end/utils/logger.py
@@ -0,0 +1,38 @@
+# Copyright 2020-2023 Intel Corporation
+# SPDX-License-Identifier: Apache-2.0
+
+import logging
+
+# Get the logger instance configured in conftest.py
+logger = logging.getLogger()
+
+
+def configure_logging(log_file, log_level):
+ """
+ Configures logging for the application.
+
+ This function sets up logging to a specified file and the console with the given log level.
+ It formats the log messages to include the timestamp, logger name, log level, filename,
+ function name, and the actual log message.
+
+ Args:
+ log_file (str): Path to the log file.
+ log_level (int): Logging level (e.g., logging.DEBUG, logging.INFO).
+
+ Raises:
+ OSError: If there is an issue with creating the log file handler.
+ """
+ formatter = logging.Formatter(
+ "\n%(asctime)s - %(levelname)s: [%(filename)s - %(funcName)s]: %(message)s", datefmt="%Y-%m-%d %H:%M:%S"
+ )
+ handler = logging.FileHandler(log_file)
+ handler.setFormatter(formatter)
+ handler.setLevel(log_level)
+
+ console_handler = logging.StreamHandler()
+ console_handler.setFormatter(formatter)
+ console_handler.setLevel(log_level)
+ logger = logging.getLogger()
+ logger.setLevel(log_level)
+ logger.addHandler(handler)
+ logger.addHandler(console_handler)
diff --git a/tests/end_to_end/utils/subprocess_helper.py b/tests/end_to_end/utils/subprocess_helper.py
new file mode 100644
index 0000000000..ec09412762
--- /dev/null
+++ b/tests/end_to_end/utils/subprocess_helper.py
@@ -0,0 +1,127 @@
+# Copyright 2020-2023 Intel Corporation
+# SPDX-License-Identifier: Apache-2.0
+
+import subprocess
+import time
+import traceback
+import logging
+
+log = logging.getLogger(__name__)
+
+
+def run_command_background(
+ cmd, return_error=False, print_stdout=False, work_dir=None, redirect_to_file=None, check_sleep=1
+):
+ """Execute a command and let it run in background.
+
+ Args:
+ cmd (Union[str, list]): Command to execute.
+ Can be a shell type string or a list of command and args.
+ e.g. ['ps', '-ef'], ['/bin/bash/', script.sh], './script.sh'
+ return_error: Whether to return error message. This has no effect.
+ print_stdout: If True and the process completes immediately, print the stdout.
+ This is obsolete. Will always print debug output and errors.
+ Output will be truncated to 10 lines.
+ work_dir: Directory from which to run the command. Current directory if None.
+ redirect_to_file: The file descriptor to which the STDERR and STDOUT will be written.
+ check_sleep: Time in seconds to sleep before polling to make sure
+ the background process is still running.
+
+ Returns:
+ Popen object of the subprocess. None, if the command completed immediately.
+ """
+ if isinstance(cmd, list):
+ shell = False
+ else:
+ shell = True
+
+ if redirect_to_file:
+ output_redirect = redirect_to_file
+ error_redirect = subprocess.STDOUT
+ else:
+ output_redirect = subprocess.PIPE
+ error_redirect = subprocess.PIPE
+ process = subprocess.Popen(
+ cmd, stdout=output_redirect, stderr=error_redirect, shell=shell, text=True, cwd=work_dir
+ )
+ time.sleep(check_sleep)
+ return_code = process.poll()
+ if return_code is None:
+ return process
+ elif return_code != 0:
+ if redirect_to_file:
+ log.info(
+ "The background process has been writing STDERR and STDOUT to a file passed in as 'redirect_to_file' arg"
+ )
+ else:
+ error = process.stderr.read().rstrip("\n")
+ log.warning(f"Error is: {error}")
+ log.error(f"Error Traceback: {traceback.print_exc()}")
+ raise subprocess.CalledProcessError(returncode=return_code, cmd=cmd)
+ else:
+ log.warning("Process for Command completed instantly.")
+ if redirect_to_file:
+ log.info(
+ "The background process has been writing STDERR and STDOUT to a file passed in as 'redirect_to_file' arg"
+ )
+ else:
+ output = process.stdout.read().rstrip("\n").split("\n")
+ if print_stdout and output is not None:
+ log.info(f"Command to run - {cmd} output - {output}")
+ return None
+
+
+def run_command(
+ cmd, return_error=True, print_stdout=False, work_dir=None, timeout=None, check=True
+):
+ """
+ Execute the command using subprocess and log the output to logger.
+
+ Args:
+ cmd (str or list): The command to run.
+ return_error (bool): Whether to return errors or raise them.
+ print_stdout (bool): Whether to print the standard output.
+ work_dir (str): The working directory for the command.
+ timeout (int): The timeout in seconds for the command to complete.
+ check (bool): Whether to check for errors after command execution.
+
+ Returns:
+ tuple: (return_code, output, error)
+ """
+ if isinstance(cmd, list):
+ shell = False
+ else:
+ shell = True
+
+ try:
+ result = subprocess.run(
+ cmd, capture_output=True, shell=shell, text=True, cwd=work_dir, check=check, timeout=timeout
+ )
+ except subprocess.CalledProcessError as e:
+ log.error(f"Command '{cmd}' failed with return code {e.returncode}")
+ log.error(f"Error output: {e.stderr}")
+ if not return_error:
+ raise
+ return e.returncode, [], [e.stderr]
+ except Exception as e:
+ log.error(f"Failed to execute command '{cmd}': {str(e)}")
+ log.error(f"Error Traceback: {traceback.format_exc()}")
+ if not return_error:
+ raise
+ return -1, [], [str(e)]
+
+ output = result.stdout.splitlines()
+ error = result.stderr.splitlines()
+
+ if result.returncode == 0:
+ log.info(f"Successfully ran command: {cmd}")
+ if print_stdout:
+ log.info(f"Command output: {result.stdout}")
+ else:
+ log.error(f"Subprocess command '{cmd}' returned non-zero return_code [{result.returncode}]:")
+ log.error(f"stderr: {result.stderr}")
+ log.error(f"stdout: {result.stdout}")
+ if not return_error:
+ raise subprocess.CalledProcessError(returncode=result.returncode, cmd=cmd, stderr=result.stderr)
+
+ return result.returncode, output, error
diff --git a/tests/end_to_end/utils/summary_helper.py b/tests/end_to_end/utils/summary_helper.py
new file mode 100644
index 0000000000..e82ecfe2c2
--- /dev/null
+++ b/tests/end_to_end/utils/summary_helper.py
@@ -0,0 +1,124 @@
+# Copyright 2020-2023 Intel Corporation
+# SPDX-License-Identifier: Apache-2.0
+
+import xml.etree.ElementTree as ET
+from lxml import etree
+import os
+
+# Initialize the XML parser
+parser = etree.XMLParser(recover=True, encoding='utf-8')
+tree = ET.parse("results/results.xml", parser=parser)
+
+# Get the root element
+testsuites = tree.getroot()
+
+
+def get_aggregated_accuracy(agg_log_file):
+ """
+ Get the aggregated accuracy from aggregator logs
+ Args:
+ agg_log_file: the aggregator log file
+ Returns:
+ agg_accuracy: the aggregated accuracy
+ """
+ if not os.path.exists(agg_log_file):
+ print(f"Aggregator log file {agg_log_file} not found. Cannot get aggregated accuracy")
+ return "Not Found"
+
+ # Example line(s) containing spaces and special characters:
+ """
+ METRIC {'metric_origin': 'aggregator', 'task_name': 'aggregated_model_validation', 'metric_name': 'accuracy', 'metric_value': aggregator.py:933
+ 0.15911591053009033, 'round': 0}
+ """
+ try:
+ with open(agg_log_file, 'r') as f:
+ for line in f:
+ if "metric_origin" in line and "aggregator" in line and "aggregated_model_validation" in line:
+ line = line.split("aggregator.py:")[0].strip()
+ # If the line does not contain closing bracket "}", then concatenate the next line
+ reqd_line = line if "}" in line else line + next(f).strip()
+ agg_accuracy = eval(reqd_line.split("METRIC")[1].strip('"'))["metric_value"]
+ return agg_accuracy
+
+ except Exception as e:
+ # Do not fail the test if the accuracy cannot be fetched
+ print(f"Error while reading aggregator log file: {e}")
+ return "Not Found"
+
+
+def get_test_status(result):
+ """
+ Get the test status/verdict
+ Args
+ result: the result object to check`
+ Returns
+ status of the test status
+ """
+ status = "FAILED"
+ if "failure" in result.tag or "error" in result.tag:
+ # If the result has a tag "failure", set status as "FAIL"
+ status = "FAILED"
+ elif "skipped" in result.tag:
+ # If the result has a tag "skipped", set status as "SKIPPED"
+ status = "SKIPPED"
+ else:
+ status = "PASSED"
+ return status
+
+
+def get_testcase_result():
+ """
+ Get the test case results from the XML file
+ """
+ database_list = []
+ status = None
+ # Iterate over each testsuite in testsuites
+ for testsuite in testsuites:
+ # Populate testcase details in a dictionary
+ for testcase in testsuite:
+ database_dict = {}
+ if testcase.attrib.get("name"):
+ database_dict["name"] = testcase.attrib.get("name")
+ database_dict["time"] = testcase.attrib.get("time")
+
+ # Successful test won't have any result/subtag
+ if len(testcase) == 0:
+ database_dict["result"] = "PASSED"
+
+ # Iterate over each result in testsuite
+ for result in testcase:
+ status = get_test_status(result)
+ database_dict["result"] = status
+
+ # Append the dictionary to database_list
+ database_list.append(database_dict)
+ status = None
+
+ return database_list
+
+
+if __name__ == "__main__":
+ """
+ Main function to get the test case results and aggregator logs
+ And write the results to GitHub step summary
+ """
+ result = get_testcase_result()
+
+ num_cols = os.getenv("NUM_COLLABORATORS")
+ num_rounds = os.getenv("NUM_ROUNDS")
+ model_name = os.getenv("MODEL_NAME")
+
+ if not model_name:
+ print("MODEL_NAME is not set, cannot find out aggregator logs")
+ else:
+ workspace_name = "workspace_" + model_name
+ agg_log_file = os.path.join("results", workspace_name, "aggregator.log")
+ agg_accuracy = get_aggregated_accuracy(agg_log_file)
+
+ # Write the results to GitHub step summary
+ with open(os.getenv('GITHUB_STEP_SUMMARY'), 'a') as fh:
+ # DO NOT change the print statements
+ print("| Name | Time (in seconds) | Result | Collaborators | Rounds to train | Score (if applicable) |", file=fh)
+ print("| ------------- | ------------- | ------------- | ------------- | ------------- | ------------- |", file=fh)
+ for item in result:
+ print(f"| {item['name']} | {item['time']} | {item['result']} | {num_cols} | {num_rounds} | {agg_accuracy} |", file=fh)