Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f1c6c07
Initial check-in
simonkurtz-MSFT Jun 2, 2026
6b24037
Improved APIM policies, testing, and reporting
simonkurtz-MSFT Jun 2, 2026
e0cdc5b
Merge branch 'main' into feature/add-inference-sample
simonkurtz-MSFT Jun 9, 2026
caea849
Intermittent checkin
simonkurtz-MSFT Jun 9, 2026
9815ba8
Update meta information
simonkurtz-MSFT Jun 9, 2026
66c36ee
Merge branch 'main' into feature/add-inference-sample
simonkurtz-MSFT Jun 9, 2026
023e97b
Clean up and test coverage increase
simonkurtz-MSFT Jun 9, 2026
a5f33fc
Fix mocks
simonkurtz-MSFT Jun 9, 2026
951c5bf
Merge branch 'main' into feature/add-inference-sample
simonkurtz-MSFT Jun 10, 2026
45dfb16
Merge branch 'main' into feature/add-inference-sample
simonkurtz-MSFT Jun 11, 2026
8cafa3d
Refactor inference-failover sample, add HTTP matrix
simonkurtz-MSFT Jun 11, 2026
26c70c0
Fix Markdown
simonkurtz-MSFT Jun 11, 2026
c519b0e
Refactor Markdown
simonkurtz-MSFT Jun 11, 2026
101ce55
Fix assertion
simonkurtz-MSFT Jun 11, 2026
9613384
Refine AI backend instructions
simonkurtz-MSFT Jun 11, 2026
e255515
Hone the circuit breaker setup
simonkurtz-MSFT Jun 11, 2026
cadb4a4
Fix tests
simonkurtz-MSFT Jun 11, 2026
d2e5fed
Format
simonkurtz-MSFT Jun 11, 2026
62948ee
Refine test output
simonkurtz-MSFT Jun 11, 2026
0b56218
Further refinement of APIM policy and reporting
simonkurtz-MSFT Jun 11, 2026
c4bba1b
Tweaking the sample
simonkurtz-MSFT Jun 12, 2026
4d50855
Fix padding
simonkurtz-MSFT Jun 12, 2026
e0d468f
Fix tests
simonkurtz-MSFT Jun 12, 2026
feb85ab
Fix error
simonkurtz-MSFT Jun 12, 2026
3034ae8
Merge branch 'main' into feature/add-inference-sample
simonkurtz-MSFT Jun 12, 2026
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
6 changes: 4 additions & 2 deletions .devcontainer/CODESPACES-QUICKSTART.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## ✅ What's ready for you

Your Codespace has automatically set up:

- Python virtual environment (`.venv`)
- Azure CLI
- All project dependencies
Expand Down Expand Up @@ -31,13 +32,15 @@ az login --tenant <your-tenant-id>
## 🚀 Ready to go?

### Start with a sample

1. Open any notebook in `infrastructure/` or `samples/`
2. If prompted, select the **Python (.venv)** kernel
3. Run the cells

Each folder has a `README.md` with full deployment steps.

### Use the Developer CLI

```bash
bash start.sh
```
Expand All @@ -47,13 +50,12 @@ bash start.sh
## 📋 If something isn't working

| Issue | Solution |
|-------|----------|
| --- | --- |
| Virtual environment not active | New terminals auto-activate. If you see no `(.venv)` prefix, run: `source .venv/bin/activate` |
| Extensions not ready | Wait for VS Code status bar to stop spinning (~1 minute) |
| Need to verify setup | Run: `python setup/verify_local_setup.py` |
| Something else | Check `.devcontainer/post-start-setup.sh` for startup commands |

---


Ready? Start with the README in the root folder for the big picture!
49 changes: 43 additions & 6 deletions .devcontainer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This directory contains the optimized dev container configuration for the Azure

## 📋 Table of Contents

<!-- markdownlint-disable MD051 -->
- [Overview](#overview)
- [Files in this Directory](#files-in-this-directory)
- [Setup Stages](#setup-stages)
Expand All @@ -12,6 +13,7 @@ This directory contains the optimized dev container configuration for the Azure
- [Jupyter Kernel Configuration](#jupyter-kernel-configuration)
- [Troubleshooting](#troubleshooting)
- [Performance Notes](#performance-notes)
<!-- markdownlint-enable MD051 -->

## 🎯 Overview

Expand All @@ -30,7 +32,7 @@ This approach ensures that time-consuming operations happen during container pre
### Core Configuration Files

| File | Purpose | Stage |
|------|---------|-------|
| --- | --- | --- |
| `python312/devcontainer.json` | Dev container configuration (Python 3.12) | All |
| `python312/Dockerfile` | Container image definition (Python 3.12) | Build |
| `python313/devcontainer.json` | Dev container configuration (Python 3.13) | All |
Expand All @@ -43,18 +45,21 @@ This approach ensures that time-consuming operations happen during container pre
### Configuration Details

#### `devcontainer.json` (per Python version folder)

- **Features**: Azure CLI, common utilities, Git, Docker-in-Docker
- **Extensions**: Python, Jupyter, Bicep, GitHub Copilot, and more
- **Lifecycle Commands**: Optimized three-stage setup
- **Port Forwarding**: Common development ports (3000, 5000, 8000, 8080)

#### `Dockerfile` (per Python version folder)

- **Base Image**: Microsoft's Python 3.12/3.13/3.14 dev container (depending on folder)
- **System Dependencies**: Essential packages and tools
- **Azure CLI Setup**: Extensions and configuration for Codespaces
- **Virtual Environment**: Auto-activation configuration

#### `post-start-setup.sh` (shared behavior)

- **Location**: `.devcontainer/post-start-setup.sh` is invoked by each Python variant's `post-start-setup.sh` wrapper
- **Environment Verification**: Quick checks and status reporting
- **Fallback Installation**: Safety net for missing components
Expand All @@ -73,6 +78,7 @@ All three are supported and prebuilt; choose the Python runtime that best matche
### ⚠️ About the "Default" Option

GitHub Codespaces will also display a generic **"Default"** dev container option. **Do not use this option** — it will result in:

- Significantly slower startup times (5-10 minutes vs. ~30 seconds)
- Missing tools, extensions, and optimizations
- Suboptimal development experience
Expand All @@ -82,25 +88,31 @@ GitHub Codespaces will also display a generic **"Default"** dev container option
## 🚀 Setup Stages

### Stage 1: Container Build (Dockerfile)

**When it runs**: During initial container build
**What it does**:

- Installs the selected Python version (3.12, 3.13, or 3.14) and system dependencies
- Configures Azure CLI for Codespaces (device code authentication)
- Installs Azure CLI extensions (`containerapp`, `front-door`)
- Sets up shell auto-activation for virtual environment

### Stage 2: Content Update (devcontainer.json)

**When it runs**: During prebuild when content changes
**What it does**:

- Creates Python virtual environment with uv
- Installs all Python packages via `uv sync` (pyproject.toml)
- Generates environment configuration (`.env` file)
- Registers Jupyter kernel
- Configures Azure CLI settings

### Stage 3: Runtime Verification (post-start-setup.sh)

**When it runs**: Every time the container starts
**What it does**:

- Verifies environment setup (< 10 seconds)
- Provides status reporting and user guidance
- Performs fallback installation if needed
Expand All @@ -109,6 +121,7 @@ GitHub Codespaces will also display a generic **"Default"** dev container option
## ⚡ Optimization Strategy

### What Moved to Prebuild

- ✅ Python package installation
- ✅ Virtual environment creation
- ✅ Azure CLI extension installation
Expand All @@ -117,12 +130,14 @@ GitHub Codespaces will also display a generic **"Default"** dev container option
- ✅ VS Code extension installation

### What Stays in Runtime

- ✅ Environment verification
- ✅ Status reporting and user guidance
- ✅ Fallback installation (safety net)
- ✅ Performance timing and completion messages

### Performance Benefits

- **Faster Startup**: Most heavy operations happen during prebuild
- **Better UX**: Users see verification instead of installation progress
- **Reliability**: Fallback mechanisms ensure robustness
Expand All @@ -133,7 +148,7 @@ GitHub Codespaces will also display a generic **"Default"** dev container option
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 |
Expand Down Expand Up @@ -172,7 +187,7 @@ This pre-installation happens in the Dockerfile and significantly reduces contai
### Prebuild Benefits

| Aspect | Without Prebuild | With Prebuild |
|--------|------------------|---------------|
| --- | --- | --- |
| **Startup Time** | 5-10 minutes | 10-30 seconds |
| **User Experience** | Watch installation progress | See verification only |
| **Resource Usage** | Build every time | Build once, use many times |
Expand All @@ -184,6 +199,7 @@ This pre-installation happens in the Dockerfile and significantly reduces contai
Our devcontainer uses two key lifecycle commands optimized for prebuild:

#### `onCreateCommand` (Container Creation)

```bash
# Creates Python virtual environment with uv and registers Jupyter kernel
# Note: The Python path varies by selected variant (3.12/3.13/3.14)
Expand All @@ -194,6 +210,7 @@ python -m ipykernel install --user --name=python-venv --display-name='Python (.v
```

#### `updateContentCommand` (Content Updates)

```bash
# Installs Python packages via uv and configures environment
source /workspaces/Apim-Samples/.venv/bin/activate &&
Expand All @@ -207,6 +224,7 @@ az extension add --name front-door --only-show-errors
### When Prebuild is Triggered

Prebuild automatically occurs when you push changes to:

- `.devcontainer/devcontainer.json`
- `.devcontainer/Dockerfile`
- `pyproject.toml` (when referenced in `updateContentCommand`)
Expand Down Expand Up @@ -246,16 +264,19 @@ You can monitor prebuild status in several ways:
To refresh the prebuilt container (recommended periodically):

#### Method 1: Trigger via Configuration Change

1. Make a small change to `.devcontainer/devcontainer.json` (e.g., add a comment)
2. Commit and push the change
3. GitHub will automatically trigger a new prebuild

#### Method 2: Manual Trigger (if available)

1. Go to your repository's Codespaces settings
2. Find the prebuild configuration
3. Click "Trigger prebuild" if the option is available

#### Method 3: Update Dependencies

1. Update `pyproject.toml` with newer package versions or add new dependencies
2. Commit and push the changes
3. Prebuild will automatically run with updated dependencies
Expand All @@ -272,7 +293,7 @@ To refresh the prebuilt container (recommended periodically):
### Prebuild vs Runtime Separation

| Operation | Prebuild Stage | Runtime Stage |
|-----------|----------------|---------------|
| --- | --- | --- |
| Python packages | ✅ Install all | ❌ Verify only |
| Virtual environment | ✅ Create and configure | ❌ Activate only |
| Azure CLI extensions | ✅ Install | ❌ Verify only |
Expand All @@ -289,12 +310,15 @@ The dev container is configured with a standardized Jupyter kernel for optimal P
- **Python Path**: `/workspaces/Apim-Samples/.venv/bin/python`

### Kernel Registration Details

The kernel is automatically registered during the prebuild stage using:

```bash
python -m ipykernel install --user --name=python-venv --display-name="Python (.venv)"
```

### VS Code Kernel Configuration

The `devcontainer.json` includes specific Jupyter settings to ensure proper kernel selection:

```jsonc
Expand All @@ -313,37 +337,46 @@ For more details on kernel configuration in VS Code, see: [VS Code Issue #130946
### Common Issues and Solutions

#### Virtual Environment Not Found

**Symptom**: Error about missing virtual environment
**Solution**: The virtual environment should be created during prebuild. If missing:

```bash
python3.12 -m venv /workspaces/Apim-Samples/.venv
source /workspaces/Apim-Samples/.venv/bin/activate
uv sync
```

#### Azure CLI Extensions Missing

**Symptom**: Commands fail with extension not found
**Solution**: Extensions should install during prebuild. If missing:

```bash
az extension add --name containerapp
az extension add --name front-door
```

#### Jupyter Kernel Not Available

**Symptom**: Kernel not visible in VS Code
**Solution**: Re-register the kernel:

```bash
python -m ipykernel install --user --name=python-venv --display-name="Python (.venv)"
```

#### Environment Variables Not Set

**Symptom**: Import errors or path issues
**Solution**: Regenerate the `.env` file:

```bash
python setup/local_setup.py --generate-env
```

### Debug Commands

Useful commands for troubleshooting:

```bash
Expand All @@ -370,17 +403,21 @@ cat .env
## 📊 Performance Notes

### Typical Timing

- **First Build**: ~5-10 minutes (includes all prebuild operations)
- **Subsequent Startups**: ~10-30 seconds (verification only)
- **Content Updates**: ~2-5 minutes (package updates during prebuild)

### Monitoring Setup Progress

The post-start script provides real-time feedback:

- **Terminal Output**: Keep the initial terminal open to see progress
- **Status Messages**: Clear indicators for each verification step
- **Error Handling**: Detailed messages for any issues encountered

### Best Practices

1. **Keep Initial Terminal Open**: Shows verification progress and status
2. **Wait for Completion**: Let the verification finish before starting work
3. **Check Status Messages**: Review any warnings or errors reported
Expand All @@ -390,13 +427,15 @@ The post-start script provides real-time feedback:
### Prebuild Refresh Recommendations

**When to refresh prebuilds**:

- Monthly maintenance (keep dependencies current)
- After major Python package updates
- When Azure CLI or extensions have significant updates
- If startup performance degrades over time
- Before important development cycles or team onboarding

**Quick refresh method**:

```bash
# Add a comment to trigger prebuild
# Edit .devcontainer/devcontainer.json and add/update a comment, then:
Expand All @@ -420,7 +459,5 @@ When modifying the dev container setup:

*This dev container configuration is optimized for Azure API Management samples development with fast startup times and comprehensive tooling support.*



[github-codespaces]: https://github.com/codespaces
[vscode-issue-130946]: https://github.com/microsoft/vscode/issues/130946#issuecomment-1899389049
2 changes: 2 additions & 0 deletions .github/agents/apim-sample-creator.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ argument-hint: "Describe the sample to add, including its sample name, display n
user-invocable: true
---

# APIM Sample Creator

You are the specialist for adding new samples to the APIM Samples repository.

## Required Inputs
Expand Down
19 changes: 11 additions & 8 deletions .github/agents/apim-sample-publisher.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ argument-hint: "Describe the sample to publish, including its folder name and wh
user-invocable: true
---

# APIM Sample Publisher

You are the specialist for publishing an APIM sample after its implementation is ready for a final quality pass. Your job is to leave the repository buttoned up for review or release: documentation is synchronized, public surfaces and search metadata agree, source artifacts are validated, and any remaining manual checks are explicit.

## Scope
Expand Down Expand Up @@ -61,9 +63,10 @@ Treat search visibility as a publication criterion, not as optional polish. Revi
- Remote, session, sleep, clock, or command boundaries are injectable where deterministic tests require them.
- Actively edited sample-local modules use module-qualified imports and selective autoreload, not broad autoreload.
6. Confirm every sample-local helper has focused tests under `tests/python/test_<sample>_helpers.py` covering meaningful success, failure, malformed-input, and cleanup paths without live Azure access. Target at least 95% coverage for changed helper modules.
7. Validate sample-owned structured files. Parse JSON and notebooks, check XML well-formedness, review APIM policy expressions against the allowed policy-expression surface, and compile or lint Bicep when the toolchain is available.
8. Confirm sample-owned APIM policy XML is under `apim-policies/` and KQL is under `queries/`. For migrations, verify every notebook, helper, Bicep, test, script, and documentation reference, including canonical-directory lookup, temporary root-level policy fallback, explicit paths, auto-detection, and missing-file behavior.
9. Run the combined Python quality checks from the repository root:
7. For multi-model inference samples, confirm that every model uses model-specific APIM backends as well as a model-specific backend pool. APIM tracks circuit-breaker state at the backend resource, so sharing a backend across models can allow a `429` or another configured failure from one model to suppress traffic to an otherwise healthy model.
8. Validate sample-owned structured files. Parse JSON and notebooks, check XML well-formedness, review APIM policy expressions against the allowed policy-expression surface, and compile or lint Bicep when the toolchain is available.
9. Confirm sample-owned APIM policy XML is under `apim-policies/` and KQL is under `queries/`. For migrations, verify every notebook, helper, Bicep, test, script, and documentation reference, including canonical-directory lookup, temporary root-level policy fallback, explicit paths, auto-detection, and missing-file behavior.
10. Run the combined Python quality checks from the repository root:

```powershell
.\tests\python\check_python.ps1
Expand All @@ -73,16 +76,16 @@ Treat search visibility as a publication criterion, not as optional polish. Revi
./tests/python/check_python.sh
```

10. Run markdownlint on all changed Markdown files and require zero violations. Fix violations instead of disabling rules unless a narrowly scoped suppression is necessary and documented.
11. Export the self-contained presentation and treat warnings about missing images as failures to investigate:
11. Run markdownlint on all changed Markdown files and require zero violations. Fix violations instead of disabling rules unless a narrowly scoped suppression is necessary and documented.
12. Export the self-contained presentation and treat warnings about missing images as failures to investigate:

```bash
uv run python setup/export_presentation.py
```

12. Run the SEO pass when public website content changed. Parse the inline JSON-LD block and `docs/sitemap.xml`, then verify that structured-data entries and visible cards stay synchronized.
13. Preview the staged website when website or deck content changed. Use `uv run python setup/serve_website.py` and review both the landing page and `/slide-deck.html`. Check desktop and narrow layouts when visual changes are material.
14. Inspect the final diff after validation. Do not include generated artifacts such as `build/`, `_site/`, coverage files, or lint reports unless the repository intentionally tracks them.
1. Run the SEO pass when public website content changed. Parse the inline JSON-LD block and `docs/sitemap.xml`, then verify that structured-data entries and visible cards stay synchronized.
2. Preview the staged website when website or deck content changed. Use `uv run python setup/serve_website.py` and review both the landing page and `/slide-deck.html`. Check desktop and narrow layouts when visual changes are material.
3. Inspect the final diff after validation. Do not include generated artifacts such as `build/`, `_site/`, coverage files, or lint reports unless the repository intentionally tracks them.

When live Azure validation is relevant but not requested or not available, report the exact notebook scenario and supported infrastructure combinations that remain to be exercised. Do not substitute unit tests for live scenario evidence.

Expand Down
Loading