- name
- cu-sdk-setup
- description
- Guide SDK users through setting up their Python environment for Azure AI Content Understanding. Use this skill when users need help installing the SDK, configuring Azure resources, deploying required models, setting environment variables, or running samples.
# SDK User Environment Setup for Azure AI Content Understanding
Set up your Python environment to use the Azure AI Content Understanding SDK and run samples.
> **[COPILOT INTERACTION MODEL]:** This skill is designed to be interactive. At each step marked with **[ASK USER]**, pause execution and prompt the user for input or confirmation before proceeding. Do NOT silently skip these prompts. Use the `ask_questions` tool when available.
> **[COPILOT] Step numbering is stable contract.** Authoring skills
> ([`cu-sdk-author-analyzer`](../cu-sdk-author-analyzer/SKILL.md) and
> [`cu-sdk-author-analyzer-classify-route`](../cu-sdk-author-analyzer-classify-route/SKILL.md))
> route the user to specific steps here on probe failures — e.g. "endpoint
> `MISSING` → Step 4 (env vars)". When renumbering or restructuring this
> skill, update the routing tables in those skills (or keep step numbers
> stable).
## Prerequisites
Before starting, ensure you have:
- **Python 3.9 or later** installed
- An **Azure subscription** ([create one for free](https://azure.microsoft.com/free/))
- A **Microsoft Foundry resource** in a [supported region](https://learn.microsoft.com/azure/ai-services/content-understanding/language-region-support)
> **[COPILOT] Probe Python runtime first (before asking):**
> Do not take the user's word for it — run these checks, then report. This prevents silent failures later in `python -m venv`.
>
> ```bash
> # POSIX / WSL / macOS
> python3 --version 2>/dev/null || python --version 2>/dev/null
> python3 -m pip --version 2>/dev/null || python -m pip --version 2>/dev/null
> python3 -c "import venv" 2>/dev/null && echo "venv: ok" || echo "venv: MISSING"
> ```
>
> ```powershell
> # Windows PowerShell
> py -3 --version 2>$null; if ($LASTEXITCODE -ne 0) { python --version }
> py -3 -m pip --version 2>$null
> py -3 -c "import venv" 2>$null; if ($LASTEXITCODE -eq 0) { 'venv: ok' } else { 'venv: MISSING' }
> ```
>
> **Decision table:**
>
> | Finding | Action |
> |---|---|
> | `Python 3.9+` and `venv: ok` and `pip` present | ✓ Good to go. Proceed to Step 1. |
> | Python missing or `< 3.9` | Report the finding, then go to the **[ASK USER] Python install choice** block below. |
> | `venv: MISSING` (common on Debian/Ubuntu base images) | Report the finding, then go to the **[ASK USER] Python install choice** block below. |
> | Windows resolves to a `WindowsApps\python*.exe` stub | Report the finding, then go to the **[ASK USER] Python install choice** block below (auto-install cannot fix this — user must disable App Execution Aliases). |
>
> **[ASK USER] Python install choice (only when probe fails):**
> Ask the user: "Python is missing / too old / the `venv` module is unavailable. How would you like to proceed?"
> - **Option A: Install it for me** — Agent runs the platform-appropriate install command (see below), verifies, and continues. Requires elevated privileges on Linux (`sudo`). Not available for the Windows App Execution Alias case — that requires manual UI action.
> - **Option B: I'll install it myself** — Agent prints the install command for the user's platform and stops. User runs it, re-opens the terminal, and tells the agent to resume.
>
> **Default install commands (Option A):**
> - **macOS** → `brew install python@3.12` (requires Homebrew; if not installed, fall back to Option B)
> - **Debian / Ubuntu / WSL** → `sudo apt update && sudo apt install -y python3.12 python3.12-venv` (will prompt for sudo password)
> - **Debian / Ubuntu — `venv: MISSING` only** → `sudo apt install -y python3-venv` (matches the existing Python version)
> - **Windows** → `winget install Python.Python.3.12` (run in an elevated PowerShell if needed)
>
> **Before running Option A, confirm with the user one more time** by restating the exact command that will execute, then proceed. After install, re-run the probe to verify `Python 3.9+` and `venv: ok` before continuing.
>
> **Windows gotcha — App Execution Aliases:** Even after uninstalling the Store Python stub, the `python.exe` / `python3.exe` entries under `C:\Users\<you>\AppData\Local\Microsoft\WindowsApps\` may persist as **App Execution Aliases** and shadow a real install. If the probe still reports a stub after the user confirms they installed real Python:
> 1. Point them to **Settings → Apps → Advanced app settings → App execution aliases**, and toggle **off** `python.exe` and `python3.exe`.
> 2. As a fallback, suggest invoking Python via the `py` launcher (`py -3 -m venv .venv`) or the explicit install path (e.g. `%LOCALAPPDATA%\Programs\Python\Python312\python.exe`). The companion `setup_user_env.ps1` script already probes well-known install paths automatically.
>
> Report the detected version + venv status back to the user in one sentence before the `[ASK USER]` block below.
> **[ASK USER] Prerequisites Check:**
> After the probe above, confirm the remaining items:
> 1. "Do you already have a **Microsoft Foundry resource** set up in Azure?" — If no, jump to **Step 5** (Azure Resource Setup) first, then return here.
> 2. "Have you already deployed the required **AI models** (gpt-5.2, text-embedding-3-large) in Microsoft Foundry?" — If no, include Step 5.3 and Step 6 in the workflow.
## Package Directory
```
sdk/contentunderstanding/azure-ai-contentunderstanding
```
## Workflow
### Step 1: Navigate to Package Directory
```bash
cd sdk/contentunderstanding/azure-ai-contentunderstanding
```
### Step 2: Create and Activate Virtual Environment
> **[ASK USER] Platform:**
> Ask the user: "Which **platform** are you on?" with options:
> - Linux/macOS
> - Windows PowerShell
> - Windows Command Prompt
>
> Use their answer to show the correct activation command throughout the rest of the setup.
**Check and create virtual environment:**
```bash
if [ -d ".venv" ]; then
echo "Virtual environment already exists at .venv"
else
echo "Creating virtual environment..."
python -m venv .venv
echo "Virtual environment created at .venv"
fi
```
> **[COPILOT] Existing `.venv` behavior:**
> If `.venv` already exists, prefer reusing it. If the existing virtual environment was created with a different Python minor version than the interpreter selected in the prerequisite probe, or if the environment is incomplete/corrupted, recreate `.venv` before continuing. This avoids subtle failures when the machine later upgrades from one supported Python version to another (for example, 3.9 → 3.12).
**Activate virtual environment:**
| Platform | Command |
|----------|---------|
| Linux/macOS | `source .venv/bin/activate` |
| Windows PowerShell | `.venv\Scripts\Activate.ps1` |
| Windows Command Prompt | `.venv\Scripts\activate.bat` |
**Verify activation:**
```bash
which python # Linux/macOS
# where python # Windows
# Should show path inside .venv
```
> **[ASK USER] Confirm venv:**
> After running the activation command, ask: "Does `which python` (or `where python` on Windows) show a path inside `.venv`? Please confirm the virtual environment is active before we install dependencies."
> If the user reports an error, troubleshoot before continuing.
### Step 3: Install SDK and Dependencies
> **[ASK USER] Installation mode:**
> Ask the user: "How would you like to install the SDK?"
> - **Option A: PyPI install (recommended)** — Installs the latest published version from PyPI. Best for running samples and developing Content Understanding-based solutions using the SDK.
> - **Option B: Local editable install (for SDK contribution)** — Use this only when you are contributing to the Content Understanding SDK. Installs from local source code; changes are reflected immediately without reinstalling.
**Option A: PyPI install (recommended):**
```bash
pip install azure-ai-contentunderstanding
pip install -r dev_requirements.txt
```
**Option B: Local editable install (for Content Understanding SDK contribution):**
```bash
pip install -e .
pip install -r dev_requirements.txt
```
> **[COPILOT] Repeated-run behavior:**
> On repeated runs, if the required SDK/sample dependencies are already importable from the active virtual environment, the setup scripts may skip the `pip install` step instead of reinstalling everything. Only rerun the install commands when dependencies are missing or the virtual environment was recreated.
This also installs all dependencies needed to run samples:
- `aiohttp` - Required for async operations
- `python-dotenv` - For loading `.env` files
- `azure-identity` - For `DefaultAzureCredential` authentication
> **[ASK USER] Installation check:**
> After running the install commands, ask: "Did the installation complete without errors?" If the user reports errors (e.g., permission issues, missing Python headers), help troubleshoot before continuing.
### Step 4: Configure Environment Variables
#### 4.1 Copy env.sample to .env (with safety check)
**Important:** This step copies the template without overwriting any existing `.env` file.
```bash
if [ -f ".env" ]; then
echo "WARNING: .env file already exists - NOT overwriting"
echo "If you want to start fresh, manually delete .env first: rm .env"
else
cp env.sample .env
echo "Created .env from env.sample"
echo "Please edit .env and configure the required variables (see Step 4.2)"
fi
```
**For Windows PowerShell:**
```powershell
if (Test-Path ".env") {
Write-Host "WARNING: .env file already exists - NOT overwriting"
Write-Host "If you want to start fresh, manually delete .env first: Remove-Item .env"
} else {
Copy-Item env.sample .env
Write-Host "Created .env from env.sample"
Write-Host "Please edit .env and configure the required variables (see Step 4.2)"
}
```
> **[ASK USER] Existing .env:**
> If a `.env` file already exists, ask: "A `.env` file already exists. Would you like to **keep** the existing one, or **start fresh** by deleting it and copying from `env.sample`?"
#### 4.2 Configure Required Variables
> **[ASK USER] Authentication method:**
> Ask the user: "How would you like to **authenticate** with Azure?"
> - **Option A: API Key** — Configure `CONTENTUNDERSTANDING_KEY` locally without sharing it in chat.
> - **Option B: DefaultAzureCredential (recommended)** — Uses `az login` or managed identity. No API key needed.
>
> Based on their choice, guide accordingly below.
> **[ASK USER] Provide endpoint:**
> Ask the user: "Please provide your **Microsoft Foundry endpoint URL**."
> - It should look like: `https://<your-resource-name>.services.ai.azure.com/`
> - Validate: it should NOT include `api-version` or other query parameters.
> - If the user doesn't know where to find it: direct them to Azure Portal → Their Foundry resource → Keys and Endpoint.
> **[COPILOT] Configure API key locally (if Option A):**
> Never ask the user to paste, send, or otherwise expose an API key in chat or a tool argument.
> Prefer `DefaultAzureCredential`. If the user chooses key authentication, tell them to get the key
> from Azure Portal → Their Foundry resource → Keys and Endpoint → Key1 or Key2, then either:
> - edit `CONTENTUNDERSTANDING_KEY` in `.env` directly, or
> - run the setup helper themselves in an interactive terminal and enter the key at its hidden prompt.
>
> Ask only for confirmation that local configuration is complete. Do not read, print, summarize, or
> validate the secret value through the model.
>
> If the user chose DefaultAzureCredential, remind them: "Make sure you've run `az login` to authenticate."
Open `.env` in your editor and set the following **required** variables:
| Variable | Description | How to Get It |
|----------|-------------|---------------|
| `CONTENTUNDERSTANDING_ENDPOINT` | Your Microsoft Foundry endpoint URL | Azure Portal → Your Foundry resource → Keys and Endpoint |
| `CONTENTUNDERSTANDING_KEY` | API key (optional if using DefaultAzureCredential) | Azure Portal → Your Foundry resource → Keys and Endpoint → Key1 or Key2 |
**For running `sample_update_defaults.py` (one-time model configuration):**
> **[COPILOT] Probe existing model defaults on the Foundry resource:**
> Before asking the user for deployment names, probe what the resource already has configured. The venv is active and the SDK is installed, so call `get_defaults()` via a short inline Python snippet. Export `CONTENTUNDERSTANDING_ENDPOINT` first. For Option A, have the user configure `CONTENTUNDERSTANDING_KEY` locally as described above; never pass it in a command or tool argument. The snippet inherits it from the environment.
>
> ```bash
> python - <<'PY'
> import os, sys
> from azure.ai.contentunderstanding import ContentUnderstandingClient
> from azure.core.credentials import AzureKeyCredential
> from azure.identity import DefaultAzureCredential
> from azure.core.exceptions import HttpResponseError, ClientAuthenticationError
>
> ep = os.environ["CONTENTUNDERSTANDING_ENDPOINT"]
> key = os.environ.get("CONTENTUNDERSTANDING_KEY") or None
> cred = AzureKeyCredential(key) if key else DefaultAzureCredential()
> try:
> d = ContentUnderstandingClient(ep, cred).get_defaults().model_deployments or {}
> except ClientAuthenticationError:
> sys.exit(3)
> except HttpResponseError as e:
> sys.exit(3 if e.status_code in (401, 403) else 1)
> except Exception:
> sys.exit(1)
>
> keys = ["gpt-5.2", "text-embedding-3-large"]
> vals = [d.get(k, "") for k in keys]
> print(";".join(f"{k}={v}" for k, v in zip(keys, vals)))
> sys.exit(0 if all(vals) else (2 if not any(vals) else 10))
> PY
> ```
>
> Branch on the exit code:
>
> | Exit | Meaning | Action |
> |------|---------|--------|
> | `0` | **ALL_SET** — all 3 deployments already mapped on the resource | Show the detected values and ask *"Detected existing defaults: gpt-5.2=`<A>`, text-embedding-3-large=`<C>`. Use these? (Y/n)"*. On Y, prefill the 3 env vars and **skip Step 6** (defaults already configured). On n, fall through to the per-model prompts below. |
> | `10` | **PARTIAL** — some mapped, some missing | Prefill the ones that are set. For missing models, ask per-item with the default shown below. After Step 4 completes, run Step 6 to fill the gaps. |
> | `2` | **NONE** — resource has no defaults yet | Fall through to the per-model prompts below. Step 6 will configure them. |
> | `3` | **AUTH_ERROR** (401/403) | Print a one-line warning: *"Probe unavailable (auth failed). If you're using DefaultAzureCredential, run `az login` and ensure the Cognitive Services User role is assigned. Continuing with manual entry."* Fall through to per-model prompts. |
> | other | Unexpected error | Print *"Probe failed: `<error>`. Continuing with manual entry."* Fall through. |
>
> Only proceed to the per-model prompts below when the probe outcome requires it.
View on GitHub