Skip to content

Commit 383d90f

Browse files
committed
Merge branch 'actionlint' of https://github.com/mikeharder/azure-sdk-for-python into actionlint
2 parents a3c9e92 + 40eeed2 commit 383d90f

13 files changed

Lines changed: 693 additions & 86 deletions

File tree

.github/workflows/actionlint.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ on:
55
branches:
66
- main
77
paths:
8-
- .github/workflows/**
8+
- .github/**
99
pull_request:
1010
paths:
11-
- .github/workflows/**
11+
- .github/**
1212
workflow_dispatch:
1313

1414
permissions:

sdk/contentunderstanding/azure-ai-contentunderstanding/.github/skills/cu-sdk-common-knowledge/SKILL.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Always read the relevant page (via `fetch_webpage`) before answering if the refe
3030
| **Service limits** | https://learn.microsoft.com/azure/ai-services/content-understanding/service-limits |
3131
| **Region & language support** | https://learn.microsoft.com/azure/ai-services/content-understanding/language-region-support |
3232
| **Prebuilt analyzers** | https://learn.microsoft.com/azure/ai-services/content-understanding/concepts/prebuilt-analyzers |
33-
| **Create custom analyzer** | https://learn.microsoft.com/azure/ai-services/content-understanding/tutorial/create-custom-analyzer?tabs=portal%2Cdocument&pivots=programming-language-rest |
33+
| **Create custom analyzer** | https://learn.microsoft.com/azure/ai-services/content-understanding/tutorial/create-custom-analyzer?tabs=portal%2Cdocument&pivots=programming-language-python |
3434
| **Document markdown** | https://learn.microsoft.com/azure/ai-services/content-understanding/document/markdown |
3535
| **Document elements** | https://learn.microsoft.com/azure/ai-services/content-understanding/document/elements |
3636
| **Video overview** | https://learn.microsoft.com/azure/ai-services/content-understanding/video/overview |
@@ -41,6 +41,14 @@ Always read the relevant page (via `fetch_webpage`) before answering if the refe
4141

4242
> **Search tip:** If the above pages don't cover the user's question, search the doc tree at `https://learn.microsoft.com/azure/ai-services/content-understanding/`.
4343
44+
### Python SDK Resources
45+
46+
| Resource | Link |
47+
|----------|------|
48+
| **Python package on PyPI** | https://pypi.org/project/azure-ai-contentunderstanding/ |
49+
| **Python SDK README** | https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/contentunderstanding/azure-ai-contentunderstanding/README.md |
50+
| **Python SDK Samples** | https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/contentunderstanding/azure-ai-contentunderstanding/samples |
51+
4452
## Related Skills
4553

4654
- `cu-sdk-setup` — Set up Python environment and run samples

sdk/contentunderstanding/azure-ai-contentunderstanding/.github/skills/cu-sdk-sample-run/SKILL.md

Lines changed: 229 additions & 17 deletions
Large diffs are not rendered by default.

sdk/contentunderstanding/azure-ai-contentunderstanding/.github/skills/cu-sdk-sample-run/scripts/run_sample.sh

Lines changed: 98 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/bin/bash
2+
# cspell:ignore esac
23
# Run a specific sample for Azure AI Content Understanding SDK
34
# Usage: ./run_sample.sh <sample_name>
45
# Example: ./run_sample.sh sample_analyze_url
@@ -40,11 +41,33 @@ list_samples() {
4041
echo ""
4142
}
4243

43-
# Check for --list flag
44-
if [ "$1" == "--list" ] || [ "$1" == "-l" ]; then
45-
list_samples
46-
exit 0
47-
fi
44+
show_help() {
45+
cat <<EOF
46+
Usage: $(basename "$0") <sample_name> [options]
47+
48+
Run a Python SDK sample for Azure AI Content Understanding.
49+
50+
Arguments:
51+
<sample_name> Sample name (e.g. sample_analyze_url), with or without .py
52+
extension. Append "_async" to run the async variant.
53+
54+
Options:
55+
--list, -l List all available samples and exit.
56+
--help, -h Show this help message.
57+
58+
Examples:
59+
$(basename "$0") sample_analyze_url
60+
$(basename "$0") sample_analyze_invoice.py
61+
$(basename "$0") sample_analyze_url_async
62+
$(basename "$0") --list
63+
EOF
64+
}
65+
66+
# Check for --help / --list flags
67+
case "$1" in
68+
--help|-h) show_help; exit 0 ;;
69+
--list|-l) list_samples; exit 0 ;;
70+
esac
4871

4972
# Check if sample name is provided
5073
if [ -z "$1" ]; then
@@ -106,12 +129,80 @@ else
106129
print_info "Using active virtual environment: $VIRTUAL_ENV"
107130
fi
108131

109-
# Check for .env file
110-
if [ ! -f ".env" ] && [ ! -f "$RUN_DIR/.env" ]; then
132+
# Load environment variables from a .env file (safe parser).
133+
# Only accepts `[export ]NAME=VALUE` lines where NAME is a valid shell
134+
# identifier; strips a single matching pair of surrounding double or single
135+
# quotes from the value. Lines that don't match are skipped silently. We avoid
136+
# `eval`/`source` so a malicious or malformed .env file cannot execute
137+
# arbitrary shell code in this script's process.
138+
load_env_file() {
139+
local env_file="$1"
140+
[ -f "$env_file" ] || return 0
141+
while IFS= read -r line || [ -n "$line" ]; do
142+
# Strip leading whitespace and skip empties / comments
143+
line="${line#"${line%%[![:space:]]*}"}"
144+
[ -z "$line" ] && continue
145+
case "$line" in \#*) continue ;; esac
146+
# Optional leading `export `
147+
case "$line" in export\ *) line="${line#export }" ;; esac
148+
# Must contain `=` and start with a valid identifier
149+
case "$line" in
150+
[a-zA-Z_]*=*) ;;
151+
*) continue ;;
152+
esac
153+
local name="${line%%=*}"
154+
local value="${line#*=}"
155+
# Validate identifier (letters, digits, underscore only)
156+
case "$name" in *[!a-zA-Z0-9_]*) continue ;; esac
157+
# Strip a matching pair of surrounding quotes
158+
if [[ "$value" == \"*\" ]]; then
159+
value="${value%\"}"
160+
value="${value#\"}"
161+
elif [[ "$value" == \'*\' ]]; then
162+
value="${value%\'}"
163+
value="${value#\'}"
164+
fi
165+
export "$name=$value"
166+
done < "$env_file"
167+
}
168+
169+
# Check for .env file and load it so later checks (e.g. DEMO MODE) and the
170+
# sample subprocess both see the configured variables.
171+
ENV_FILE=""
172+
if [ -f ".env" ]; then
173+
ENV_FILE=".env"
174+
elif [ -f "$RUN_DIR/.env" ]; then
175+
ENV_FILE="$RUN_DIR/.env"
176+
fi
177+
if [ -n "$ENV_FILE" ]; then
178+
print_info "Loading environment from $ENV_FILE"
179+
load_env_file "$ENV_FILE"
180+
else
111181
print_warning "⚠ No .env file found. Some samples may fail without environment variables."
112182
echo " Run: cp env.sample .env && edit .env"
113183
fi
114184

185+
# sample_create_analyzer_with_labels demo-mode banner: warn if the user is about
186+
# to run the labeled-data sample without configuring either Option A (SAS URL)
187+
# or Option B (storage account + container) — the sample will still run but skip
188+
# the labeled-data code path AND the analyze-test step.
189+
if [[ "$SAMPLE_NAME" == sample_create_analyzer_with_labels* ]]; then
190+
if [[ -z "${CONTENTUNDERSTANDING_TRAINING_DATA_SAS_URL:-}" ]]; then
191+
if [[ -z "${CONTENTUNDERSTANDING_TRAINING_DATA_STORAGE_ACCOUNT:-}" \
192+
|| -z "${CONTENTUNDERSTANDING_TRAINING_DATA_CONTAINER:-}" ]]; then
193+
print_warning "⚠ DEMO MODE: no training data configured for $SAMPLE_NAME."
194+
echo " The analyzer will be created without labeled data ('Knowledge sources: 0')."
195+
echo " To exercise the labeled-data API path AND test the analyzer with a sample"
196+
echo " document, configure ONE of:"
197+
echo " Option A: CONTENTUNDERSTANDING_TRAINING_DATA_SAS_URL=<container SAS URL>"
198+
echo " Option B: CONTENTUNDERSTANDING_TRAINING_DATA_STORAGE_ACCOUNT=<account>"
199+
echo " CONTENTUNDERSTANDING_TRAINING_DATA_CONTAINER=<container>"
200+
echo " then re-run this script (it will reload .env automatically)."
201+
echo ""
202+
fi
203+
fi
204+
fi
205+
115206
# Run the sample
116207
echo ""
117208
print_info "=== Running: $SAMPLE_NAME ==="

sdk/contentunderstanding/azure-ai-contentunderstanding/.github/skills/cu-sdk-setup/scripts/setup_user_env.ps1

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,14 @@ function Set-EnvValue {
311311
$pattern = "(?m)^$([regex]::Escape($Key))=.*$"
312312
$replacement = "$Key=$Value"
313313
if ([regex]::IsMatch($content, $pattern)) {
314-
$content = [regex]::Replace($content, $pattern, $replacement)
314+
# Use a MatchEvaluator so $ and \ in user-supplied values (API keys,
315+
# endpoints) are written literally instead of being interpreted as
316+
# regex replacement metacharacters ($1, $&, $$, etc.).
317+
$content = [regex]::Replace(
318+
$content,
319+
$pattern,
320+
[System.Text.RegularExpressions.MatchEvaluator] { param($match) $replacement }
321+
)
315322
} else {
316323
if ($content -and -not $content.EndsWith("`n")) { $content += "`n" }
317324
$content += "$replacement`n"

sdk/contentunderstanding/azure-ai-contentunderstanding/.github/skills/cu-sdk-setup/scripts/setup_user_env.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ PY
371371

372372
# GPT_4_1_MINI_DEPLOYMENT
373373
if [ -z "$gpt41mini" ]; then
374-
read -r -p "Enter GPT_4_1_MINI_DEPLOYMENT (default: gpt-4.1-mini): " gpt41mini || gpt41mini="" gpt41mini
374+
read -r -p "Enter GPT_4_1_MINI_DEPLOYMENT (default: gpt-4.1-mini): " gpt41mini || gpt41mini=""
375375
gpt41mini="${gpt41mini:-gpt-4.1-mini}"
376376
else
377377
echo " ✓ Using detected GPT_4_1_MINI_DEPLOYMENT=$gpt41mini"

sdk/contentunderstanding/azure-ai-contentunderstanding/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
### Features Added
1414
- Added `to_llm_input` helper function that converts `AnalysisResult` objects into LLM-friendly text with YAML front matter and markdown content. Supports documents, audio/video, and classification hierarchies.
1515

16+
### Other Changes
17+
- Aligned `sample_create_analyzer_with_labels` (sync + async) with the .NET and Java equivalents: added an analyze step (calls `begin_analyze` on the newly created analyzer to extract `MerchantName` / `TotalPrice` from a sample invoice when training data is configured), a `DEMO MODE` banner when no training data is configured, a field-schema verification banner, and `try` / `finally` cleanup so the analyzer is deleted even if creation fails.
18+
1619
## 1.1.0 (2026-04-20)
1720

1821
### Features Added

sdk/contentunderstanding/azure-ai-contentunderstanding/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "python",
44
"TagPrefix": "python/contentunderstanding/azure-ai-contentunderstanding",
5-
"Tag": "python/contentunderstanding/azure-ai-contentunderstanding_3b4e92c5d3"
5+
"Tag": "python/contentunderstanding/azure-ai-contentunderstanding_afaf0a7032"
66
}

0 commit comments

Comments
 (0)