Arcade Adventure: Google Cloud ML APIs | GSP048

Solution for Arcade Adventure: Google Cloud ML APIs | GSP048. 1 lab: GSP048. Fast copy-paste commands for Google Cloud.

GSP048 — Speech to Text Transcription with the Speech-to-Text API

Estimated time: 15 minutes

# 🚀 Speech to Text Transcription with the Speech-to-Text API | GSP048 > ⚠️ **Disclaimer:** This is an independent, community-made walkthrough created for educational purposes, hands-on practice, and Google Cloud certification preparation. It helps learners explore speech recognition, API authentication, audio transcription, and multilingual processing using Google Cloud Speech-to-Text. Always attempt the lab yourself first and follow Google Cloud Skills Boost / Qwiklabs Terms of Service. This

clear
RESET=

\033[0m'; BOLD=

\033[1m'; CYAN=

\033[1;36m'; BLUE=

\033[1;34m'; GREEN=

\033[1;32m'; YELLOW=

\033[1;33m'; RED=

\033[1;31m'; MAGENTA=

\033[1;35m'; WHITE=

\033[1;37m'; ORANGE=

\033[38;5;208m'
set +H

echo "${CYAN}${BOLD}"
echo "   ____       _     _ _            __   ___             "
echo "  / __ \     | |   (_) |          / _| / _ \            "
echo " | |  | |_ __| |__  _| |_   ___  | |_ | | | |_ __  ___  "
echo " | |  | | '__| '_ \| | __| / _ \ |  _|| | | | '_ \/ __| "
echo " | |__| | |  | |_) | | |_ | (_) || |  | |_| | |_) \__ \ "
echo "  \____/|_|  |_.__/|_|\__| \___/ |_|   \___/| .__/|___/ "
echo "                                            | |         "
echo "                                            |_|         "
echo "${RESET}"

BAR=$(printf '═%.0s' {1..60})
echo "${MAGENTA}${BOLD}╔${BAR}╗${RESET}"
printf "${MAGENTA}${BOLD}║${RESET}${ORANGE}${BOLD} %-58s ${RESET}${MAGENTA}${BOLD}║${RESET}\n" "BROUGHT TO YOU BY ORBIT OF OPS"
printf "${MAGENTA}${BOLD}║${RESET}${GREEN}${BOLD} %-58s ${RESET}${MAGENTA}${BOLD}║${RESET}\n" "STAGE 1 OF 3 : CREATE THE API KEY (TASK 1)"
printf "${MAGENTA}${BOLD}║${RESET}${CYAN}${BOLD} %-58s ${RESET}${MAGENTA}${BOLD}║${RESET}\n" "GSP048 | Speech-to-Text API"
echo "${MAGENTA}${BOLD}╚${BAR}╝${RESET}"

o_step() { echo; echo "${CYAN}${BOLD}▶ $*${RESET}"; }
o_ok()   { echo "  ${GREEN}${BOLD}[ OK ]${RESET} ${GREEN}$*${RESET}"; }
o_info() { echo "  ${BLUE}${BOLD}[INFO]${RESET} ${WHITE}$*${RESET}"; }
o_warn() { echo "  ${YELLOW}${BOLD}[WARN]${RESET} ${YELLOW}$*${RESET}"; }
o_bad()  { ORBIT_FAILS=$((ORBIT_FAILS+1)); echo "  ${RED}${BOLD}[FAIL]${RESET} ${RED}$*${RESET}"; }
ORBIT_FAILS=0

orbit_key() {
  KEYNAME=$(gcloud services api-keys list --project=$PROJECT_ID --format=json 2>/dev/null | python3 -c 'import sys,json; d=json.load(sys.stdin); print(next((k["name"] for k in d if any(t.get("service")=="speech.googleapis.com" for t in k.get("restrictions",{}).get("apiTargets",[]))), ""))' 2>/dev/null)
  [ -n "$KEYNAME" ]
}

orbit_stage1() {
  PROJECT_ID=$(gcloud config get-value project 2>/dev/null); [ -z "$PROJECT_ID" ] && PROJECT_ID=$DEVSHELL_PROJECT_ID
  [ -n "$PROJECT_ID" ] || { o_bad "No project detected."; return 1; }
  o_info "Project: $PROJECT_ID"

  o_step "Enabling the API Keys and Speech-to-Text APIs"
  if gcloud services enable apikeys.googleapis.com speech.googleapis.com --project=$PROJECT_ID --quiet >/tmp/orbit_run.log 2>&1; then o_ok "apikeys.googleapis.com and speech.googleapis.com enabled"; else o_bad "Could not enable the APIs"; tail -n 4 /tmp/orbit_run.log | sed 's/^/        /'; return 1; fi
  sleep 20

  o_step "Task 1: API key restricted to Cloud Speech-to-Text API"
  if orbit_key; then
    o_info "Found an existing key restricted to speech.googleapis.com, reusing it"
  else
    for i in 1 2 3; do
      o_info "Creating the key (attempt $i of 3)"
      gcloud services api-keys create --project=$PROJECT_ID --display-name="orbit-speech-key" --api-target=service=speech.googleapis.com --quiet >/tmp/orbit_key.log 2>&1 && break
      tail -n 3 /tmp/orbit_key.log | sed 's/^/        /'; sleep 20
    done
    sleep 15
    orbit_key && o_ok "API key created" || { o_bad "Key not found after creation"; return 1; }
  fi

  API_KEY=$(gcloud services api-keys get-key-string "$KEYNAME" --format="value(keyString)" 2>/dev/null)
  [ -n "$API_KEY" ] || { o_bad "Could not read the key string"; return 1; }
  export API_KEY
  o_ok "API_KEY exported in this shell (${API_KEY:0:6}... hidden)"

  o_step "Final audit"
  ORBIT_FAILS=0
  SVC=$(gcloud services api-keys describe "$KEYNAME" --format="value(restrictions.apiTargets[0].service)" 2>/dev/null)
  [ "$SVC" = "speech.googleapis.com" ] && o_ok "Key restriction: Cloud Speech-to-Text API ($SVC)" || o_bad "Key restriction is '$SVC'"
  gcloud services list --enabled --project=$PROJECT_ID --filter="config.name=speech.googleapis.com" --format="value(config.name)" 2>/dev/null | grep -q speech && o_ok "Speech-to-Text API is enabled" || o_bad "Speech-to-Text API is not enabled"
  sleep 30
  echo
  if [ $ORBIT_FAILS -eq 0 ]; then echo "${MAGENTA}${BOLD}>> Click 'Check my progress' for 'Create an API Key', then run Command 2 of 3.${RESET}"; else echo "${RED}${BOLD}>> $ORBIT_FAILS check(s) failed. Fix the FAIL lines above (or send them to me).${RESET}"; fi
}
orbit_stage1
RESET=

\033[0m'; BOLD=

\033[1m'; CYAN=

\033[1;36m'; BLUE=

\033[1;34m'; GREEN=

\033[1;32m'; YELLOW=

\033[1;33m'; RED=

\033[1;31m'; MAGENTA=

\033[1;35m'; WHITE=

\033[1;37m'; ORANGE=

\033[38;5;208m'
set +H
echo "${MAGENTA}${BOLD}[ ORBIT OF OPS ]${RESET} ${ORANGE}${BOLD}Stage 2 of 3${RESET} ${WHITE}::${RESET} ${GREEN}${BOLD}Request File and English Call (Tasks 2-3)${RESET}"

o_step() { echo; echo "${CYAN}${BOLD}▶ $*${RESET}"; }
o_ok()   { echo "  ${GREEN}${BOLD}[ OK ]${RESET} ${GREEN}$*${RESET}"; }
o_info() { echo "  ${BLUE}${BOLD}[INFO]${RESET} ${WHITE}$*${RESET}"; }
o_warn() { echo "  ${YELLOW}${BOLD}[WARN]${RESET} ${YELLOW}$*${RESET}"; }
o_bad()  { echo "  ${RED}${BOLD}[FAIL]${RESET} ${RED}$*${RESET}"; }

orbit_key() {
  KEYNAME=$(gcloud services api-keys list --project=$PROJECT_ID --format=json 2>/dev/null | python3 -c 'import sys,json; d=json.load(sys.stdin); print(next((k["name"] for k in d if any(t.get("service")=="speech.googleapis.com" for t in k.get("restrictions",{}).get("apiTargets",[]))), ""))' 2>/dev/null)
  [ -n "$KEYNAME" ]
}

orbit_call() {
  local i
  for i in $(seq 1 12); do
    curl -s -X POST -H "Content-Type: application/json" --data-binary @request.json "https://speech.googleapis.com/v1/speech:recognize?key=${API_KEY}" > result.json
    grep -q '"transcript"' result.json && return 0
    if grep -qE "SERVICE_DISABLED|has not been used" result.json; then o_warn "Speech API not active yet ($i of 12), enabling and waiting"; gcloud services enable speech.googleapis.com --project=$PROJECT_ID --quiet >/dev/null 2>&1; sleep 20
    elif grep -qiE "API key not valid|API_KEY_INVALID|API_KEY_SERVICE_BLOCKED|PERMISSION_DENIED" result.json; then o_info "API key is not active yet ($i of 12), waiting 15 s"; sleep 15
    else o_bad "Unexpected API response:"; head -c 400 result.json | sed 's/^/        /'; echo; return 1; fi
  done
  o_bad "No transcript after 12 attempts. Last response:"; head -c 400 result.json | sed 's/^/        /'; echo; return 1
}

orbit_upload() {
  local OBJ=$1
  if gcloud storage cp result.json gs://${PROJECT_ID}-speech/$OBJ --quiet >/tmp/orbit_run.log 2>&1; then o_ok "Uploaded result.json to gs://${PROJECT_ID}-speech/$OBJ"; else o_bad "Upload failed"; tail -n 4 /tmp/orbit_run.log | sed 's/^/        /'; return 1; fi
  gcloud storage ls gs://${PROJECT_ID}-speech/$OBJ >/dev/null 2>&1 && o_ok "Verified: $OBJ is in the bucket" || { o_bad "$OBJ not found in the bucket"; return 1; }
}

orbit_stage2() {
  PROJECT_ID=$(gcloud config get-value project 2>/dev/null); [ -z "$PROJECT_ID" ] && PROJECT_ID=$DEVSHELL_PROJECT_ID
  cd ~ || return 1
  o_step "Loading the API key from Command 1"
  orbit_key || { o_bad "No Speech-restricted API key found. Run Command 1 first."; return 1; }
  API_KEY=$(gcloud services api-keys get-key-string "$KEYNAME" --format="value(keyString)" 2>/dev/null)
  [ -n "$API_KEY" ] || { o_bad "Could not read the key string"; return 1; }
  export API_KEY
  o_ok "API_KEY exported (${API_KEY:0:6}... hidden)"

  o_step "Checking the bucket gs://${PROJECT_ID}-speech"
  if gcloud storage buckets describe gs://${PROJECT_ID}-speech >/dev/null 2>&1; then
    o_ok "Bucket exists"
  else
    LOC=$(gcloud compute project-info describe --project=$PROJECT_ID --format="value(commonInstanceMetadata.items.filter(key:google-compute-default-region).extract(value).flatten())" 2>/dev/null | head -n 1); [ -z "$LOC" ] && LOC=US
    o_warn "Bucket is missing, creating it in $LOC"
    gcloud storage buckets create gs://${PROJECT_ID}-speech --location=$LOC --project=$PROJECT_ID --quiet >/tmp/orbit_run.log 2>&1 && o_ok "Bucket created" || { o_bad "Could not create the bucket"; tail -n 4 /tmp/orbit_run.log | sed 's/^/        /'; return 1; }
    sleep 10
  fi

  o_step "Task 2: writing request.json (English)"
cat << 'EOF' > request.json
{
  "config": {
      "encoding":"FLAC",
      "languageCode": "en-US"
  },
  "audio": {
      "uri":"gs://cloud-samples-data/speech/brooklyn_bridge.flac"
  }
}
EOF
  python3 -m json.tool request.json >/dev/null 2>&1 && o_ok "request.json is valid JSON ($(pwd)/request.json)" || { o_bad "request.json is not valid JSON"; return 1; }

  o_step "Task 3: calling the Speech-to-Text API (English)"
  orbit_call || return 1
  T=$(python3 -c 'import json; r=json.load(open("result.json"))["results"][0]["alternatives"][0]; print(r["transcript"], "| confidence", r["confidence"])' 2>/dev/null)
  o_ok "Transcript: $T"
  echo "$T" | grep -qi "brooklyn bridge" || { o_bad "The transcript does not mention the Brooklyn Bridge, not uploading it"; return 1; }

  o_step "Uploading the English result"
  orbit_upload result_en.json || return 1
  sleep 10
  echo
  echo "${MAGENTA}${BOLD}>> Click 'Check my progress' for 'Create your Speech API request' and 'Call the Speech API for English language', then run Command 3 of 3.${RESET}"
}
orbit_stage2
RESET=

\033[0m'; BOLD=

\033[1m'; CYAN=

\033[1;36m'; BLUE=

\033[1;34m'; GREEN=

\033[1;32m'; YELLOW=

\033[1;33m'; RED=

\033[1;31m'; MAGENTA=

\033[1;35m'; WHITE=

\033[1;37m'; ORANGE=

\033[38;5;208m'
set +H
echo "${MAGENTA}${BOLD}[ ORBIT OF OPS ]${RESET} ${ORANGE}${BOLD}Stage 3 of 3${RESET} ${WHITE}::${RESET} ${GREEN}${BOLD}French Transcription (Task 4)${RESET}"

o_step() { echo; echo "${CYAN}${BOLD}▶ $*${RESET}"; }
o_ok()   { echo "  ${GREEN}${BOLD}[ OK ]${RESET} ${GREEN}$*${RESET}"; }
o_info() { echo "  ${BLUE}${BOLD}[INFO]${RESET} ${WHITE}$*${RESET}"; }
o_warn() { echo "  ${YELLOW}${BOLD}[WARN]${RESET} ${YELLOW}$*${RESET}"; }
o_bad()  { echo "  ${RED}${BOLD}[FAIL]${RESET} ${RED}$*${RESET}"; }

orbit_key() {
  KEYNAME=$(gcloud services api-keys list --project=$PROJECT_ID --format=json 2>/dev/null | python3 -c 'import sys,json; d=json.load(sys.stdin); print(next((k["name"] for k in d if any(t.get("service")=="speech.googleapis.com" for t in k.get("restrictions",{}).get("apiTargets",[]))), ""))' 2>/dev/null)
  [ -n "$KEYNAME" ]
}

orbit_call() {
  local i
  for i in $(seq 1 12); do
    curl -s -X POST -H "Content-Type: application/json" --data-binary @request.json "https://speech.googleapis.com/v1/speech:recognize?key=${API_KEY}" > result.json
    grep -q '"transcript"' result.json && return 0
    if grep -qE "SERVICE_DISABLED|has not been used" result.json; then o_warn "Speech API not active yet ($i of 12), enabling and waiting"; gcloud services enable speech.googleapis.com --project=$PROJECT_ID --quiet >/dev/null 2>&1; sleep 20
    elif grep -qiE "API key not valid|API_KEY_INVALID|API_KEY_SERVICE_BLOCKED|PERMISSION_DENIED" result.json; then o_info "API key is not active yet ($i of 12), waiting 15 s"; sleep 15
    else o_bad "Unexpected API response:"; head -c 400 result.json | sed 's/^/        /'; echo; return 1; fi
  done
  o_bad "No transcript after 12 attempts. Last response:"; head -c 400 result.json | sed 's/^/        /'; echo; return 1
}

orbit_upload() {
  local OBJ=$1
  if gcloud storage cp result.json gs://${PROJECT_ID}-speech/$OBJ --quiet >/tmp/orbit_run.log 2>&1; then o_ok "Uploaded result.json to gs://${PROJECT_ID}-speech/$OBJ"; else o_bad "Upload failed"; tail -n 4 /tmp/orbit_run.log | sed 's/^/        /'; return 1; fi
  gcloud storage ls gs://${PROJECT_ID}-speech/$OBJ >/dev/null 2>&1 && o_ok "Verified: $OBJ is in the bucket" || { o_bad "$OBJ not found in the bucket"; return 1; }
}

orbit_stage3() {
  PROJECT_ID=$(gcloud config get-value project 2>/dev/null); [ -z "$PROJECT_ID" ] && PROJECT_ID=$DEVSHELL_PROJECT_ID
  cd ~ || return 1
  o_step "Loading the API key from Command 1"
  orbit_key || { o_bad "No Speech-restricted API key found. Run Command 1 first."; return 1; }
  API_KEY=$(gcloud services api-keys get-key-string "$KEYNAME" --format="value(keyString)" 2>/dev/null)
  [ -n "$API_KEY" ] || { o_bad "Could not read the key string"; return 1; }
  export API_KEY
  o_ok "API_KEY exported (${API_KEY:0:6}... hidden)"
  gcloud storage ls gs://${PROJECT_ID}-speech/result_en.json >/dev/null 2>&1 && o_ok "result_en.json is already in the bucket" || o_warn "result_en.json is not in the bucket. Run Command 2 first if Task 3 is not scored yet."

  o_step "Task 4: writing request.json (French)"
cat << 'EOF' > request.json
{
  "config": {
      "encoding":"FLAC",
      "languageCode": "fr"
  },
  "audio": {
      "uri":"gs://cloud-samples-data/speech/corbeau_renard.flac"
  }
}
EOF
  python3 -m json.tool request.json >/dev/null 2>&1 && o_ok "request.json is valid JSON" || { o_bad "request.json is not valid JSON"; return 1; }

  o_step "Calling the Speech-to-Text API (French)"
  orbit_call || return 1
  T=$(python3 -c 'import json; r=json.load(open("result.json"))["results"][0]["alternatives"][0]; print(r["transcript"], "| confidence", r["confidence"])' 2>/dev/null)
  o_ok "Transcript: $T"
  echo "$T" | grep -qi "corbeau" || { o_bad "The transcript does not contain 'corbeau', not uploading it"; return 1; }

  o_step "Uploading the French result"
  orbit_upload result_fr.json || return 1
  sleep 10
  echo
  echo "${MAGENTA}${BOLD}>> Click 'Check my progress' for 'Call the Speech API for French language'.${RESET}"
  echo "${ORANGE}${BOLD}Congratulations. GSP048 is complete - brought to you by Orbit of Ops.${RESET}"
}
orbit_stage3

# Subscribe to Orbit of Ops https://www.youtube.com/@orbitofops/videos