Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
3b381ed
Clean up
simonkurtz-MSFT Jun 11, 2025
ebf692b
Simplify postStartCommand
simonkurtz-MSFT Jun 11, 2025
b77b9f5
fixes
simonkurtz-MSFT Jun 12, 2025
3282369
Fix kernel
simonkurtz-MSFT Jun 12, 2025
32c72be
Fixed JSON
simonkurtz-MSFT Jun 12, 2025
94a0672
Fix JSON, add schema
simonkurtz-MSFT Jun 12, 2025
80dfa55
big kernel changes
simonkurtz-MSFT Jun 12, 2025
07c10c7
More kernel changes
simonkurtz-MSFT Jun 12, 2025
ba2e051
Handle activation
simonkurtz-MSFT Jun 12, 2025
469a771
Remove shell activation from Dockerfile
simonkurtz-MSFT Jun 12, 2025
20576ff
Clean up
simonkurtz-MSFT Jun 12, 2025
47630ee
Add determine bicep directory internal function
simonkurtz-MSFT Jun 12, 2025
5c7db5e
Path fixes
simonkurtz-MSFT Jun 12, 2025
de8fb33
Minor copy changes
simonkurtz-MSFT Jun 12, 2025
d2097f4
Remove erronous apimSku passing
simonkurtz-MSFT Jun 12, 2025
0fc6f39
Add TROUBLESHOOTING.md
simonkurtz-MSFT Jun 12, 2025
096b039
Fix accidentally removed code
simonkurtz-MSFT Jun 12, 2025
68b9bc4
Rename afd-apim to afd-apim-pe due to pathing issues
simonkurtz-MSFT Jun 12, 2025
2f984e2
Align kernel name
simonkurtz-MSFT Jun 12, 2025
b8c76c0
Fixes and additional tests
simonkurtz-MSFT Jun 13, 2025
a336ea7
Fix utils tests
simonkurtz-MSFT Jun 13, 2025
95b258f
Set kernelspec
simonkurtz-MSFT Jun 13, 2025
496a706
Fix virtual environment command
simonkurtz-MSFT Jun 13, 2025
f965753
Format
simonkurtz-MSFT Jun 13, 2025
e2f9bfe
Add filter
simonkurtz-MSFT Jun 13, 2025
76d9a89
Revert breaking changes from #2f984e
simonkurtz-MSFT Jun 13, 2025
4ee6aa8
Preinstall VS Code extensions in container
simonkurtz-MSFT Jun 13, 2025
cb3120d
Revert the showTabs behavior once more.
simonkurtz-MSFT Jun 13, 2025
a9e4edf
Revert failing VS Code extension installation
simonkurtz-MSFT Jun 13, 2025
6999b07
Refine instructions
simonkurtz-MSFT Jun 13, 2025
f6bcceb
Add help to setup_python_path.py
simonkurtz-MSFT Jun 13, 2025
5804f57
Reset index
simonkurtz-MSFT Jun 13, 2025
4a8d1ce
Add new line at end of file
simonkurtz-MSFT Jun 13, 2025
684f57d
Add Test Matrix
simonkurtz-MSFT Jun 13, 2025
00bd851
Refine next steps
simonkurtz-MSFT Jun 13, 2025
e949e34
Reduce logging
simonkurtz-MSFT Jun 13, 2025
fe06286
Add infrastructure and better formatting
simonkurtz-MSFT Jun 13, 2025
d1b79b9
Matrix refinement
simonkurtz-MSFT Jun 13, 2025
f977ea6
Add Test-Matrix.html
simonkurtz-MSFT Jun 13, 2025
f3f3a44
Add new line at end of file
simonkurtz-MSFT Jun 13, 2025
e6e971a
Restructure Text Matrix
simonkurtz-MSFT Jun 13, 2025
54cf513
Fix typo
simonkurtz-MSFT Jun 13, 2025
7557194
Fix load balancing by moving charts to shared
simonkurtz-MSFT Jun 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,18 @@ RUN az config set core.login_experience_v2=off 2>/dev/null || true && \
az extension add --name containerapp --only-show-errors 2>/dev/null || true && \
az extension add --name front-door --only-show-errors 2>/dev/null || true

# Configure shell to auto-activate virtual environment
RUN echo "# Auto-activate APIM Samples virtual environment" >> ~/.bashrc && \
echo "if [ -f /workspaces/Apim-Samples/.venv/bin/activate ]; then" >> ~/.bashrc && \
echo " source /workspaces/Apim-Samples/.venv/bin/activate" >> ~/.bashrc && \
echo "fi" >> ~/.bashrc && \
echo "# Auto-activate APIM Samples virtual environment" >> ~/.zshrc && \
echo "if [ -f /workspaces/Apim-Samples/.venv/bin/activate ]; then" >> ~/.zshrc && \
echo " source /workspaces/Apim-Samples/.venv/bin/activate" >> ~/.zshrc && \
echo "fi" >> ~/.zshrc && \
# Add helpful aliases
# Configure shell aliases and helpful commands (venv handled by devcontainer)
RUN echo "# APIM Samples helpful aliases" >> ~/.bashrc && \
echo "alias ll='ls -alF'" >> ~/.bashrc && \
echo "alias la='ls -A'" >> ~/.bashrc && \
echo "alias l='ls -CF'" >> ~/.bashrc && \
echo "alias pytest-cov='python -m pytest --cov=. --cov-report=html'" >> ~/.bashrc
echo "alias pytest-cov='python -m pytest --cov=. --cov-report=html'" >> ~/.bashrc && \
echo "" >> ~/.zshrc && \
echo "# APIM Samples helpful aliases" >> ~/.zshrc && \
echo "alias ll='ls -alF'" >> ~/.zshrc && \
echo "alias la='ls -A'" >> ~/.zshrc && \
echo "alias l='ls -CF'" >> ~/.zshrc && \
echo "alias pytest-cov='python -m pytest --cov=. --cov-report=html'" >> ~/.zshrc

# Set final working directory
WORKDIR /workspaces/Apim-Samples
Expand Down
27 changes: 26 additions & 1 deletion .devcontainer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ This directory contains the optimized dev container configuration for the Azure

The dev container uses a **three-stage optimization approach** to minimize startup time:

1. **Build Stage** (Dockerfile): Base system setup and Azure CLI configuration
1. **Build Stage** (Dockerfile): Base system setup, Azure CLI configuration, and VS Code extension pre-installation
2. **Prebuild Stage** (devcontainer.json): Heavy installations and environment setup
3. **Runtime Stage** (post-start-setup.sh): Fast verification and user guidance

Expand Down Expand Up @@ -87,6 +87,7 @@ This approach ensures that time-consuming operations happen during container pre
- ✅ Azure CLI extension installation
- ✅ Jupyter kernel registration
- ✅ Environment file generation
- ✅ VS Code extension installation

### What Stays in Runtime
- ✅ Environment verification
Expand All @@ -100,6 +101,30 @@ This approach ensures that time-consuming operations happen during container pre
- **Reliability**: Fallback mechanisms ensure robustness
- **Transparency**: Clear status reporting throughout

## 🔌 Pre-installed VS Code Extensions

To further optimize the startup experience, several VS Code extensions are pre-installed in the container image rather than being installed at container startup:

| Extension ID | Description |
|-------------|-------------|
| ms-python.python | Python language support |
| ms-python.debugpy | Python debugging |
| ms-toolsai.jupyter | Jupyter notebook support |
| ms-toolsai.jupyter-keymap | Jupyter keyboard shortcuts |
| ms-toolsai.jupyter-renderers | Jupyter output renderers |
| ms-toolsai.vscode-jupyter-cell-tags | Jupyter cell tags |
| ms-toolsai.vscode-jupyter-slideshow | Jupyter slideshow |
| ms-azuretools.vscode-bicep | Bicep language support |
| ms-vscode.azurecli | Azure CLI support |
| ms-azure-devops.azure-pipelines | Azure Pipelines support |
| redhat.vscode-yaml | YAML language support |
| ms-vscode.vscode-json | JSON language support |
| donjayamanne.vscode-default-python-kernel | Default Python kernel |

A few extensions like GitHub Copilot and Copilot Chat are still installed at container startup because they require authentication or have licensing considerations.

This pre-installation happens in the Dockerfile and significantly reduces container startup time as VS Code doesn't need to download and install these extensions.

## 🔧 Jupyter Kernel Configuration

The dev container is configured with a custom Jupyter kernel for optimal Python development experience:
Expand Down
59 changes: 29 additions & 30 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.schema.json",
"name": "APIM Samples",
"build": {
"dockerfile": "Dockerfile",
Expand Down Expand Up @@ -67,28 +68,27 @@
"jupyter.interactiveWindow.textEditor.executeSelection": true,
"jupyter.notebookFileRoot": "${workspaceFolder}",
"jupyter.kernels.excludePythonEnvironments": [
"**/anaconda3/**",
"**/conda/**",
"**/miniconda3/**",
"**/python3.*",
"*/site-packages/*",
"/bin/python",
"/bin/python3",
"/opt/python/*/bin/python*",
"/usr/bin/python",
"/usr/bin/python3",
"/usr/local/bin/python",
"/usr/local/bin/python3",
"python",
"python3"
"**/anaconda3/**",
"**/conda/**",
"**/miniconda3/**",
"**/python3.*",
"*/site-packages/*",
"/bin/python",
"/bin/python3",
"/opt/python/*/bin/python*",
"/usr/bin/python",
"/usr/bin/python3",
"/usr/local/bin/python",
"/usr/local/bin/python3",
"python",
"python3"
],
"jupyter.kernels.trusted": [
"/workspaces/Apim-Samples/.venv/bin/python"
],
"files.associations": {
"*.bicep": "bicep"
},
// Auto-show terminal output during codespace startup
"terminal.integrated.showExitAlert": false,
"terminal.integrated.focusAfterRun": "terminal",
"terminal.integrated.defaultProfile.linux": "bash",
Expand All @@ -98,35 +98,34 @@
"workbench.startupEditor": "none",
"workbench.panel.defaultPanelHeight": 400,
"workbench.view.alwaysShowHeaderActions": true,
// Auto-open terminal panel on startup
"workbench.action.terminal.focus": true,
"workbench.action.togglePanel": true,
"terminal.integrated.defaultLocation": "view",
// Auto-allow clipboard operations in Codespaces
"security.workspace.trust.enabled": false,
"editor.experimental.pasteActions.enabled": true,
"workbench.editor.enablePreview": false
}
},
"containerEnv": {
"PATH": "/workspaces/Apim-Samples/.venv/bin:${PATH}",
"PYTHONPATH": "/workspaces/Apim-Samples/shared/python:/workspaces/Apim-Samples",
"VIRTUAL_ENV": "/workspaces/Apim-Samples/.venv"
}
},
"containerEnv": {
"PYTHONPATH": "/workspaces/Apim-Samples/shared/python:/workspaces/Apim-Samples"
},
// Container lifecycle commands for optimal Codespaces prebuild performance: https://containers.dev/implementors/features/#lifecycle-hooks
// 1. onCreateCommand: Runs only once during initial prebuild - creates venv
// 2. updateContentCommand: Runs during any prebuild when content changes - installs/updates packages
// 3. postStartCommand: Runs on every startup - verifies and configures
"onCreateCommand": [
"bash", "-c",
"echo '🚀 Creating Python virtual environment in workspace...' && /usr/local/bin/python3.12 -m venv /workspaces/Apim-Samples/.venv --copies && source /workspaces/Apim-Samples/.venv/bin/activate && pip install --upgrade pip setuptools wheel && echo '✅ Virtual environment created'"
"bash",
"-c",
"echo '🚀 Creating Python virtual environment in workspace...' && /usr/local/bin/python3.12 -m venv /workspaces/Apim-Samples/.venv --copies && source /workspaces/Apim-Samples/.venv/bin/activate && pip install --upgrade pip setuptools wheel ipykernel && echo '✅ Virtual environment created' && echo '🔧 Registering Jupyter kernel during prebuild...' && python -m ipykernel install --user --name=apim-samples --display-name='APIM Samples Python 3.12' && echo '🧹 Removing default python3 kernel...' && rm -rf /workspaces/Apim-Samples/.venv/share/jupyter/kernels/python3 2>/dev/null || true && echo '✅ Jupyter kernel registered in prebuild'"
],
"updateContentCommand": [
"bash", "-c",
"echo '📦 Installing/updating Python packages from requirements.txt...' && source /workspaces/Apim-Samples/.venv/bin/activate && pip install -r requirements.txt && pip install pytest pytest-cov coverage ipykernel && echo '✅ Python packages installed/updated' && python setup/setup_python_path.py --generate-env && echo '✅ Environment configuration updated' && echo '🔧 Registering Jupyter kernel...' && python -m ipykernel install --user --name=apim-samples --display-name='APIM Samples Python 3.12' && echo '✅ Jupyter kernel registered' && echo '⚙️ Configuring Azure CLI...' && az config set core.login_experience_v2=off 2>/dev/null || true && az extension add --name containerapp --only-show-errors 2>/dev/null || true && az extension add --name front-door --only-show-errors 2>/dev/null || true && echo '✅ Azure CLI configured for Codespaces'"
"bash",
"-c",
"echo '📦 Installing/updating Python packages from requirements.txt...' && source /workspaces/Apim-Samples/.venv/bin/activate && pip install -r requirements.txt && pip install pytest pytest-cov coverage && echo '✅ Python packages installed/updated' && python setup/setup_python_path.py --generate-env && echo '✅ Environment configuration updated' && echo '⚙️ Configuring Azure CLI...' && az config set core.login_experience_v2=off 2>/dev/null || true && az extension add --name containerapp --only-show-errors 2>/dev/null || true && az extension add --name front-door --only-show-errors 2>/dev/null || true && echo '✅ Azure CLI configured for Codespaces'"
],
"postStartCommand": [
"bash", "-c",
"echo '� APIM Samples Codespace Starting - Keep this terminal open to see progress!' && echo '============================================================' && bash .devcontainer/post-start-setup.sh && echo '============================================================' && echo '✅ Setup completed! This terminal will remain open for your reference.' && echo '💡 Tip: You can minimize this panel if needed, but the setup logs above show your environment status.' && sleep 2"
"bash",
"-c",
"echo 'APIM Samples Codespace Starting - Keep this terminal open to see progress!' && bash .devcontainer/post-start-setup.sh"
],
"forwardPorts": [
8000,
Expand Down
162 changes: 32 additions & 130 deletions .devcontainer/post-start-setup.sh
Original file line number Diff line number Diff line change
@@ -1,176 +1,78 @@
#!/bin/bash

# ------------------------------
# APIM SAMPLES POST-START VERIFICATION
# APIM SAMPLES INSTANT VERIFICATION
# ------------------------------

start=$(date +%s.%N)

# Make terminal output more prominent
clear
echo "============================================================================"
echo " 🚀 APIM SAMPLES CODESPACE VERIFICATION "
echo " 🚀 APIM SAMPLES - INSTANT VERIFICATION "
echo "============================================================================"
echo ""
echo "🔧 This terminal shows the Codespace verification progress."
echo "📋 Keep this panel open to monitor the environment status."
echo "⚡ All heavy setup was completed during prebuild - verifying environment..."
echo ""
echo -e "✅ Most setup completed during prebuild - verifying environment...\n"

# ------------------------------
# CONFIGURATION
# LIGHTNING FAST VERIFICATION
# ------------------------------

echo -e "1/5) Detecting & setting environment variables...\n"

WORKSPACE_ROOT="/workspaces/Apim-Samples"
VENV_PATH="$WORKSPACE_ROOT/.venv"
PYTHON_EXECUTABLE="$VENV_PATH/bin/python"

echo " Workspace : $WORKSPACE_ROOT"
echo " Virtual Environment : $VENV_PATH"
echo " Python Executable : $PYTHON_EXECUTABLE"

# Activate virtual environment to get the correct Python version
source "$VENV_PATH/bin/activate" 2>/dev/null || true
PYTHON_VERSION=$(python --version | grep "Python" | awk '{print $2}')
echo " Python Version : $PYTHON_VERSION"

# Extract Azure CLI version (suppress warnings and get just the version number)
AZ_CLI_VERSION=$(az --version 2>/dev/null | grep "azure-cli" | awk '{print $2}' | head -1)
echo " Azure CLI Version : $AZ_CLI_VERSION"

# ------------------------------
# ENVIRONMENT VERIFICATION
# ------------------------------

echo -e "\n2/5) Verifying virtual environment...\n"
echo -e "Environment Status:\n"

# Verify virtual environment exists
# Ultra-fast file system checks (no command execution)
if [ -d "$VENV_PATH" ]; then
echo " ✅ Virtual environment found at $VENV_PATH"
if [ -f "$PYTHON_EXECUTABLE" ]; then
echo " ✅ Python executable available"
# Activate and verify
source "$VENV_PATH/bin/activate"
echo " ✅ Python version : $PYTHON_VERSION"
# Commenting out the number of packages installed as this does take some time to run. When the setup was verified, a count of 125 packages was printed.
# echo " ✅ Packages installed: $(pip list | wc -l)"
else
echo " ❌ Python executable not found"
exit 1
fi
else
echo " ❌ Virtual environment not found at $VENV_PATH"
echo " 💡 Virtual environment should have been created during container setup"
exit 1
fi

# ------------------------------
# ENVIRONMENT FILE VERIFICATION
# ------------------------------

echo -e "\n3/5) Verifying .env file...\n"

cd "$WORKSPACE_ROOT"
if [ -f ".env" ]; then
echo " ✅ .env file exists"
echo " ✅ Virtual environment"
else
echo " ⚠️ .env file missing, regenerating..."
if [ -f "setup/setup_python_path.py" ]; then
python setup/setup_python_path.py --generate-env
echo " ✅ .env file regenerated"
else
echo " ⚠️ setup_python_path.py not found, creating basic .env"
cat > .env << EOF
# Auto-generated for APIM Samples dev container
PROJECT_ROOT=$WORKSPACE_ROOT
PYTHONPATH=$WORKSPACE_ROOT/shared/python:$WORKSPACE_ROOT
EOF
echo " ✅ Basic .env file created"
fi
echo " ❌ Virtual environment missing"
fi

# ------------------------------
# AZURE CLI VERIFICATION
# ------------------------------

echo -e "\n4/5) Verifying Azure CLI configuration...\n"

# Verify Azure CLI extensions are installed (they should be from prebuild)
echo " Checking Azure CLI extensions..."
if az extension list --query "[?name=='containerapp']" -o tsv | grep -q "containerapp"; then
echo " ✅ containerapp extension installed"
if [ -f "$WORKSPACE_ROOT/.env" ]; then
echo " ✅ Environment file"
else
echo " ⚠️ containerapp extension missing, installing..."
az extension add --name containerapp --only-show-errors 2>/dev/null || true
echo " ❌ Environment file missing"
fi

if az extension list --query "[?name=='front-door']" -o tsv | grep -q "front-door"; then
echo " ✅ front-door extension installed"
# Quick command availability checks (fast)
if command -v az >/dev/null 2>&1; then
echo " ✅ Azure CLI"
else
echo " ⚠️ front-door extension missing, installing..."
az extension add --name front-door --only-show-errors 2>/dev/null || true
echo " ❌ Azure CLI missing"
fi

# Verify Azure CLI configuration
echo " ✅ Azure CLI configured for device code authentication"

# ------------------------------
# FINAL VERIFICATION
# ------------------------------

echo -e "\n5/5) Environment Summary\n"
echo " Virtual Environment : $VIRTUAL_ENV"
echo " Python : $PYTHON_VERSION at $(which python)"
# Commenting out the number of packages installed as this does take some time to run. When the setup was verified, a count of 125 packages was printed.
# echo " Packages: $(pip list | wc -l) installed"
echo " .env File exists? : $([ -f .env ] && echo "✅" || echo "❌")"
echo " Azure CLI Version : $AZ_CLI_VERSION"

# Verify Jupyter kernel registration
echo " Jupyter Kernels : $(jupyter kernelspec list --json | python -c "import sys, json; data=json.load(sys.stdin); print(len(data['kernelspecs'])) if 'kernelspecs' in data else print('0')" 2>/dev/null || echo "unknown")"

if jupyter kernelspec list | grep -q "apim-samples" 2>/dev/null; then
echo " APIM Samples Kernel : ✅"
if command -v python >/dev/null 2>&1; then
echo " ✅ Python"
else
echo " APIM Samples Kernel : ⚠️ (missing, re-registering...)"
python -m ipykernel install --user --name=apim-samples --display-name="APIM Samples Python 3.12" 2>/dev/null && echo " ✅ Kernel registered successfully" || echo " ❌ Failed to register kernel"
echo " ❌ Python missing"
fi

# Test core imports
python -c "
try:
import requests, jwt, pandas, matplotlib, azure.identity
print(f' Core packages : ✅')
except ImportError as e:
print(f' Core packages : ❌')
print(f' {e}')
"

# Calculate total duration using Python
# Calculate total duration
end=$(date +%s.%N)
duration=$(python3 -c "print(f'{float('$end') - float('$start'):.2f}')")
duration=$(python3 -c "print(f'{float('$end') - float('$start'):.1f}')" 2>/dev/null || echo "0.1")

echo ""
echo "============================================================================"
echo " 🎉 VERIFICATION COMPLETED! "
echo " ⚡ INSTANT VERIFICATION COMPLETE! "
echo "============================================================================"
echo ""
printf "⏱️ Total verification time: %s seconds\n" "$duration"
echo "💡 Environment prebuild optimizations have significantly reduced startup time!"
echo ""
echo "🔍 This terminal shows your Codespace verification progress and logs."
echo "📋 You can minimize this panel or open a new terminal for your work."
printf "⏱️ Verification time: %s seconds\n" "$duration"
echo ""
echo "🚀 Your APIM Samples environment is ready to use!"
echo "🎉 Your APIM Samples environment is ready to use!"
echo -e "\n"
echo " Next Steps:"
echo ""
echo " 1. Open a new terminal and log in via the Azure CLI: az login"
echo ""
echo " NEXT STEPS:"
echo " -----------"
echo " 2. Wait until Codespace is fully started (it's fairly quick):"
echo " - Watch progress indicators in status bar"
echo " - Wait for all extensions to install"
echo " --> ✅ (.venv) prefix will appear when you open a new terminal"
echo ""
echo " 1. Log in via the Azure CLI: az login"
echo " 2. Start using the infrastructures and samples!"
echo " 3. Start using the infrastructures and samples!"
echo ""
echo "============================================================================"
echo -e "\n\n\n"
echo -e "\n\n"
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ labs-in-progress/
tests/python/htmlcov/

shared/bicep/modules/**/*.json
main.json
main.json

Test-Matrix.html
Loading
Loading