|
1 | 1 | #!/bin/bash |
| 2 | +# cspell:ignore esac |
2 | 3 | # Run a specific sample for Azure AI Content Understanding SDK |
3 | 4 | # Usage: ./run_sample.sh <sample_name> |
4 | 5 | # Example: ./run_sample.sh sample_analyze_url |
@@ -40,11 +41,33 @@ list_samples() { |
40 | 41 | echo "" |
41 | 42 | } |
42 | 43 |
|
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 |
48 | 71 |
|
49 | 72 | # Check if sample name is provided |
50 | 73 | if [ -z "$1" ]; then |
@@ -106,12 +129,80 @@ else |
106 | 129 | print_info "Using active virtual environment: $VIRTUAL_ENV" |
107 | 130 | fi |
108 | 131 |
|
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 |
111 | 181 | print_warning "⚠ No .env file found. Some samples may fail without environment variables." |
112 | 182 | echo " Run: cp env.sample .env && edit .env" |
113 | 183 | fi |
114 | 184 |
|
| 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 | + |
115 | 206 | # Run the sample |
116 | 207 | echo "" |
117 | 208 | print_info "=== Running: $SAMPLE_NAME ===" |
|
0 commit comments