Create a python file main.py. This script leverages the Google Cloud
Translation API, accessed using a container endpoint, to perform
translations.
importosimportrequests# Use requests for HTTP callsfromflaskimportFlask,request,jsonifyapp=Flask(__name__)TRANSLATE_API_URL='https://translation.googleapis.com/language/translate/v2'@app.route('/translate',methods=['POST'])deftranslate_text():try:data=request.get_json()text_to_translate=data.get('text')target_language=data.get('target_language','en')# Default to Englishifnottext_to_translate:returnjsonify({'error':'Missing "text" in request body'}),400params={'key':'${API_KEY}',//insertAPIkey'q':text_to_translate,'target':target_language}response=requests.post(TRANSLATE_API_URL,params=params)response.raise_for_status()# Raise an exception for bad status codes (4xx or 5xx)result=response.json()# The structure of the response from the REST API is slightly different# It's usually: {'data': {'translations': [{'translatedText': '...', 'detectedSourceLanguage': '...'}]}}if'data'inresultand'translations'inresult['data']andlen(result['data']['translations']) > 0:translation_info=result['data']['translations'][0]returnjsonify({'original_text':text_to_translate,'translated_text':translation_info['translatedText'],'detected_source_language':translation_info.get('detectedSourceLanguage')})else:returnjsonify({'error':'Unexpected response format from Translation API','details':result}),500exceptrequests.exceptions.HTTPErrorashttp_err:print(f"HTTP error occurred: {http_err} - {response.text}")returnjsonify({'error':f"Translation API request failed: {http_err}",'details':response.text}),response.status_codeexceptExceptionase:print(f"Error during translation: {e}")returnjsonify({'error':str(e)}),500if__name__=='__main__':port=int(os.environ.get('PORT',8080))app.run(debug=True,host='0.0.0.0',port=port)
Create a docker file that contains the python script:
Sign in to the user cluster
and generate its kubeconfig file with a user identity. Make sure you set the
kubeconfig path as an environment variable:
exportKUBECONFIG=${CLUSTER_KUBECONFIG_PATH}
Create and deploy the Kubernetes Deployment and Service custom resources. To
enable container egress, make sure to include the label
egress.networking.gke.io/enabled: "true", as shown in this example.
Create an SSH tunnel session to the workload that you deployed.
sshuttle-rzone1-org-1-data@GDC_SANDBOX_INSTANCE_NAME--no-latency-control\--ssh-cmd'gcloud compute ssh --project PROJECT_NAME --zone ZONE --tunnel-through-iap'\10.200.0.0/16--dns
Test the service by sending a JSON payload with the text and the target
language to http://${IP}:8080/translate, using a POST request with the
Content-Type header set to application/json. The following curl command
will translate "Hello, world!" to Spanish (es):
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-09-04 UTC."],[],[],null,["# Try out machine translation\n\nThis page walks through an example of using the Vertex AI API to\ntranslate text from one language to another.\n\nIn this example, you deploy the workloads without using GPUs. To deploy using\nGPUs, follow the steps in\n[Deploy GPU container workloads](/distributed-cloud/sandbox/latest/services/gpu#deploy_gpu).\n\nTranslation API\n---------------\n\nThe following sample demonstrates the use of Vertex AI for text\ntranslation.\n\n1. Make sure you set up Vertex AI access as described in [Using Vertex AI](/distributed-cloud/sandbox/latest/services/vertex-ai).\n2. Set up the Python Vertex AI API, by following the instructions in\n the\n [Vertex AI quickstart using client libraries](/vertex-ai/docs/start/client-libraries).\n For more information, see the\n [Vertex AI Python API reference documentation](/python/docs/reference/aiplatform/latest).\n\n3. Create a python file `main.py`. This script leverages the Google Cloud\n Translation API, accessed using a container endpoint, to perform\n translations.\n\n import os\n import requests # Use requests for HTTP calls\n from flask import Flask, request, jsonify\n\n app = Flask(__name__)\n\n TRANSLATE_API_URL = 'https://translation.googleapis.com/language/translate/v2'\n\n @app.route('/translate', methods=['POST'])\n def translate_text():\n\n try:\n data = request.get_json()\n text_to_translate = data.get('text')\n target_language = data.get('target_language', 'en') # Default to English\n\n if not text_to_translate:\n return jsonify({'error': 'Missing \"text\" in request body'}), 400\n\n params = {\n 'key': '${API_KEY}', // insert API key\n 'q': text_to_translate,\n 'target': target_language\n }\n\n response = requests.post(TRANSLATE_API_URL, params=params)\n response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)\n\n result = response.json()\n\n # The structure of the response from the REST API is slightly different\n # It's usually: {'data': {'translations': [{'translatedText': '...', 'detectedSourceLanguage': '...'}]}}\n if 'data' in result and 'translations' in result['data'] and len(result['data']['translations']) \u003e 0:\n translation_info = result['data']['translations'][0]\n return jsonify({\n 'original_text': text_to_translate,\n 'translated_text': translation_info['translatedText'],\n 'detected_source_language': translation_info.get('detectedSourceLanguage')\n })\n else:\n return jsonify({'error': 'Unexpected response format from Translation API', 'details': result}), 500\n\n except requests.exceptions.HTTPError as http_err:\n print(f\"HTTP error occurred: {http_err} - {response.text}\")\n return jsonify({'error': f\"Translation API request failed: {http_err}\", 'details': response.text}), response.status_code\n except Exception as e:\n print(f\"Error during translation: {e}\")\n return jsonify({'error': str(e)}), 500\n\n if __name__ == '__main__':\n port = int(os.environ.get('PORT', 8080))\n app.run(debug=True, host='0.0.0.0', port=port)\n\n4. Create a docker file that contains the python script:\n\n FROM python:3.9-slim\n\n WORKDIR /app\n\n COPY . /app\n\n RUN pip install --no-cache-dir -r requirements.txt\n\n EXPOSE 8080\n ENV PORT 8080\n\n CMD [\"python\", \"main.py\"]\n\n5. Build the Docker image for the translation application:\n\n docker build -t translation-app .\n\n6. Follow instructions at\n [Configure Docker](/distributed-cloud/hosted/docs/latest/gdch/platform-application/deploy-container-workloads#configure-docker)\n to:\n\n 1. Configure docker,\n 2. Create a secret, and\n 3. Upload the image to HaaS (Harbor as a Service).\n7. [Sign in to the user cluster](/distributed-cloud/hosted/docs/latest/gdch/clusters#kubernetes-clusters)\n and generate its kubeconfig file with a user identity. Make sure you set the\n kubeconfig path as an environment variable:\n\n export KUBECONFIG=${CLUSTER_KUBECONFIG_PATH}\n\n8. Create and deploy the Kubernetes Deployment and Service custom resources. To\n enable container egress, make sure to include the label\n `egress.networking.gke.io/enabled: \"true\"`, as shown in this example.\n\n kubectl --kubeconfig ${KUBECONFIG} -n \u003cvar translate=\"no\"\u003eTENANT_PROJECT\u003c/var\u003e \\\n create -f - \u003c\u003cEOF\n apiVersion: apps/v1\n kind: Deployment\n metadata:\n name: translation-deployment-apikey\n spec:\n replicas: 2\n selector:\n matchLabels:\n app: translation-apikey\n template:\n metadata:\n labels:\n app: translation-apikey\n egress.networking.gke.io/enabled: \"true\"\n spec:\n dnsConfig:\n nameservers:\n - 8.8.8.8\n containers:\n - name: translation-app\n image: \u003cvar translate=\"no\"\u003eHARBOR_INSTANCE_URL\u003c/var\u003e/\u003cvar translate=\"no\"\u003eHARBOR_PROJECT\u003c/var\u003e/translation-app:latest\n ports:\n - containerPort: 8080\n imagePullSecrets:\n - name: \u003cvar translate=\"no\"\u003eSECRET\u003c/var\u003e\n\n ---\n apiVersion: v1\n kind: Service\n metadata:\n name: translation-service-apikey\n spec:\n type: LoadBalancer\n selector:\n app: translation-apikey\n ports:\n - protocol: TCP\n port: 80\n targetPort: 8080\n EOF\n\n Replace the following:\n - \u003cvar translate=\"no\"\u003eHARBOR_INSTANCE_URL\u003c/var\u003e: the Harbor instance URL.\n - \u003cvar translate=\"no\"\u003eHARBOR_PROJECT\u003c/var\u003e: the Harbor project.\n - \u003cvar translate=\"no\"\u003eSECRET\u003c/var\u003e: the name of the secret created to store docker credentials.\n9. Verify the pods were created by the deployment:\n\n kubectl --kubeconfig ${KUBECONFIG} get pods -n \u003cvar translate=\"no\"\u003eTENANT_PROJECT\u003c/var\u003e\n\n10. Create a network policy to allow all network traffic to the tenant project:\n\n kubectl --kubeconfig ${KUBECONFIG} -n \u003cvar translate=\"no\"\u003eTENANT_PROJECT\u003c/var\u003e \\\n create -f - \u003c\u003cEOF\n apiVersion: networking.k8s.io/v1\n kind: NetworkPolicy\n metadata:\n annotations:\n name: allow-all\n spec:\n ingress:\n - from:\n - ipBlock:\n cidr: 0.0.0.0/0\n podSelector: {}\n policyTypes:\n - Ingress\n EOF\n\n11. Export the IP address for the service:\n\n export IP=`kubectl --kubeconfig=${KUBECONFIG} get service nginx-service \\\n -n \u003cvar translate=\"no\"\u003eTENANT_PROJECT\u003c/var\u003e -o jsonpath='{.status.loadBalancer.ingress[*].ip}'`\n\n12. Create an SSH tunnel session to the workload that you deployed.\n\n sshuttle -r zone1-org-1-data@GDC_SANDBOX_INSTANCE_NAME --no-latency-control \\\n --ssh-cmd 'gcloud compute ssh --project PROJECT_NAME --zone ZONE --tunnel-through-iap' \\\n 10.200.0.0/16 --dns\n\n13. Test the service by sending a JSON payload with the text and the target\n language to `http://${IP}:8080/translate`, using a POST request with the\n `Content-Type` header set to `application/json`. The following curl command\n will translate \"Hello, world!\" to Spanish (`es`):\n\n curl -X POST -H \"Content-Type: application/json\" -d '{\"text\": \"Hello, world\\\\!\", \"target\\_language\": \"es\"}' http://${IP}:8080/translate"]]