From 4b1fd9646b8bed7ddf9f5c6df9f56be604af1cce Mon Sep 17 00:00:00 2001 From: Zhuang <54096296+DevOps-zhuang@users.noreply.github.com> Date: Wed, 17 May 2023 18:27:08 +0800 Subject: [PATCH 1/8] Update azureblobstorage.py updat the blob endpoint to core.chinacloudapi.cn, which is the Azure China blob endpoint --- code/utilities/azureblobstorage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/utilities/azureblobstorage.py b/code/utilities/azureblobstorage.py index 4c82e02..04e7885 100644 --- a/code/utilities/azureblobstorage.py +++ b/code/utilities/azureblobstorage.py @@ -10,7 +10,7 @@ def __init__(self, account_name: str = None, account_key: str = None, container_ self.account_name : str = account_name if account_name else os.getenv('BLOB_ACCOUNT_NAME') self.account_key : str = account_key if account_key else os.getenv('BLOB_ACCOUNT_KEY') - self.connect_str : str = f"DefaultEndpointsProtocol=https;AccountName={self.account_name};AccountKey={self.account_key};EndpointSuffix=core.windows.net" + self.connect_str : str = f"DefaultEndpointsProtocol=https;AccountName={self.account_name};AccountKey={self.account_key};EndpointSuffix=core.chinacloudapi.cn" self.container_name : str = container_name if container_name else os.getenv('BLOB_CONTAINER_NAME') self.blob_service_client : BlobServiceClient = BlobServiceClient.from_connection_string(self.connect_str) From 5feddc4b519ad767b5e1a504e9e4996719916b1d Mon Sep 17 00:00:00 2001 From: Zhuang <54096296+DevOps-zhuang@users.noreply.github.com> Date: Fri, 19 May 2023 15:20:25 +0800 Subject: [PATCH 2/8] add two yaml files for K8S use add two files. the config-template.yml is to create a config file named env-configmap then for all-in-one.yml, it will create deployment and service to expose this deployment. --- all-in-one.yml | 48 +++++++++++++++++++++++++++++++++++++++++++++ config-template.yml | 33 +++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 all-in-one.yml create mode 100644 config-template.yml diff --git a/all-in-one.yml b/all-in-one.yml new file mode 100644 index 0000000..9df97ba --- /dev/null +++ b/all-in-one.yml @@ -0,0 +1,48 @@ +apiVersion: apps/v1 +kind: Deployment +apiVersion: apps/v1 +kind: Deployment +metadata: + name: azure-openai-front-01 +spec: + replicas: 1 + selector: + matchLabels: + app: azure-openai-front-01 + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + minReadySeconds: 5 + template: + metadata: + labels: + app: azure-openai-front-01 + spec: + containers: + - name: web + image: openai.azurecr.cn/oai-embeddings:latest + ports: + - containerPort: 8088 + envFrom: + - configMapRef: + name: env-configmap + - name: batch + image: fruocco/oai-batch:latest + ports: + - containerPort: 80 + envFrom: + - configMapRef: + name: env-configmap +--- +apiVersion: v1 +kind: Service +metadata: + name: azure-openai-front-01 +spec: + type: LoadBalancer + ports: + - port: 8088 + targetPort: 8088 + selector: + app: azure-openai-front-01 \ No newline at end of file diff --git a/config-template.yml b/config-template.yml new file mode 100644 index 0000000..f04a990 --- /dev/null +++ b/config-template.yml @@ -0,0 +1,33 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: env-configmap +data: + OPENAI_ENGINE: davinci + OPENAI_DEPLOYMENT_TYPE: Text + OPENAI_EMBEDDINGS_ENGINE: text-embedding-ada-002 + OPENAI_EMBEDDINGS_ENGINE_DOC: text-embedding-ada-002 + OPENAI_EMBEDDINGS_ENGINE_QUERY: text-embedding-ada-002 + OPENAI_API_BASE: "https://cog-pfj4y3k2moyjw.openai.azure.com/" + OPENAI_API_KEY: "[update to your key]" + OPENAI_TEMPERATURE: "0.7" + OPENAI_MAX_TOKENS: "-1" + REDIS_ADDRESS: "[update to your address]" + REDIS_PORT: "6379" + REDIS_PASSWORD: redis-stack-password + BLOB_ACCOUNT_NAME: storage4openai + BLOB_ACCOUNT_KEY: "[update to your key]" + BLOB_CONTAINER_NAME: embedding + QUEUE_NAME: doc-processing + FORM_RECOGNIZER_ENDPOINT: "https://formreader.cognitiveservices.azure.cn/" + FORM_RECOGNIZER_KEY: "[update to your key]" + CHUNK_SIZE: "500" + CHUNK_OVERLAP: "100" + TRANSLATE_ENDPOINT: "https://api.translator.azure.cn/" + TRANSLATE_KEY: "[update to your key]" + TRANSLATE_REGION: chinanorth3 + VNET_DEPLOYMENT: "false" + NUMBER_OF_EMBEDDINGS_FOR_QNA: "3" + CONVERT_ADD_EMBEDDINGS_URL: "http://batch/api/BatchStartProcessing" + AzureWebJobsStorage: "DefaultEndpointsProtocol=https;AccountName=storage4openai;AccountKey=[update to your key];EndpointSuffix=core.chinacloudapi.cn" + QUESTION_PROMPT: "Please reply to the question using only the information present in the text above. If you can't find it, reply 'Not in the text'.\nQuestion: _QUESTION_\nAnswer:" \ No newline at end of file From 795797cb884882ee4898d81b397c1cee6e478389 Mon Sep 17 00:00:00 2001 From: Zhuang <54096296+DevOps-zhuang@users.noreply.github.com> Date: Sat, 20 May 2023 14:49:48 +0800 Subject: [PATCH 3/8] Update README.md to support K8S deploy 1, add K8S Yaml files, it includes the configmap/deploy/service 2, customized the container, so that both batch and web containers can be within the same pod. because they both use port 80. so we have to update it. --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index 97a9e2d..ac7e3d2 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,9 @@ A simple web application for a OpenAI-enabled document search. This repo uses Az ![Architecture](docs/architecture.png) # IMPORTANT NOTE (OpenAI generated) +1) We did some changes to make it work in Azure china, which is also named 21v Azure. because the OpenAI service, all other related service are available in Azure China. so we can deply the Apps to Azure china, it will call the OpenAI servicec hosted in Global Azure. +2) To make it more simply, we generate the K8S file, in includes the configmap/deployment/service yaml. for the original .env file, we generated a similar configmap file to save all the config colume, then te deplyment yaml fill will use it. + We have made some changes to the data format in the latest update of this repo.
The new format is more efficient and compatible with the latest standards and libraries. However, we understand that some of you may have existing applications that rely on the previous format and may not be able to migrate to the new one immediately. @@ -25,6 +28,7 @@ You have multiple options to run the code: - [Run everything locally in Python with Conda (WebApp only)](#run-everything-locally-in-python-with-conda-webapp-only) - [Run everything locally in Python with venv](#run-everything-locally-in-python-with-venv) - [Run WebApp locally in Docker against an existing Redis deployment](#run-webapp-locally-in-docker-against-an-existing-redis-deployment) +- [Run WebApp locally in K8S against an existing Redis deployment](#run-webapp-locally-in-K8S-against-an-existing-redis-deployment) ## Deploy on Azure (WebApp + Azure Cache for Redis Enterprise + Batch Processing) [![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fruoccofabrizio%2Fazure-open-ai-embeddings-qna%2Fmain%2Finfrastructure%2FdeploymentACRE.json) @@ -169,6 +173,24 @@ docker run --env-file .env -p 8080:80 your_docker_registry/your_docker_image:you Note: You can use - WebApp.Dockerfile to build the Web Application - BatchProcess.Dockerfile to build the Azure Function for Batch Processing +- +## Run WebApp locally in K8S against an existing Redis deployment + +### needed - Build the Docker image yourself, since we upate the code to cordinate with the Azure China blob endpoinsts. (only needed when you use Azure China) + +```code (already updated for this Azure china branch) +1) For WebApp.Dockerfile, update the exposed port from 80 to 8088. since 80 is already used by the batch service. since batch and web containers will be in the same pod. they can't use the same exposed port. (in my example, they can't, and I am some douting for the difference between pod and host when using docker-compose, which docker-compose can support since it can map container port to different host port) +2) code\utilities\azureblobstorage.py, go to line 13, update the EndpointSuffix=core.chinacloudapi.cn + +```console +docker build . -f WebApp.Dockerfile -t your_docker_registry/your_docker_image:your_tag +docker push your_docker_registry/your_docker_image:your_tag + +...K8S part +generate a configmap file based on the `.env` as described in as described in [Environment variables](#environment-variables) +kubectl apply -f myconfigmap.yml +#update the all-in-one.yml file to use own docker containers. +kubectl apply -f all-in-one.yml ## Environment variables From 4279111f0058052350d5effffa321d5a83966089 Mon Sep 17 00:00:00 2001 From: Zhuang <54096296+DevOps-zhuang@users.noreply.github.com> Date: Mon, 22 May 2023 22:47:26 +0800 Subject: [PATCH 4/8] Update azureblobstorage.py # comment and update it to support both global azure and Azure China, they are of different blob end point suffix. --- code/utilities/azureblobstorage.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/code/utilities/azureblobstorage.py b/code/utilities/azureblobstorage.py index 04e7885..ab42380 100644 --- a/code/utilities/azureblobstorage.py +++ b/code/utilities/azureblobstorage.py @@ -4,13 +4,17 @@ from dotenv import load_dotenv class AzureBlobStorageClient: - def __init__(self, account_name: str = None, account_key: str = None, container_name: str = None): + def __init__(self, account_name: str = None, account_key: str = None, blob_endPoint_suffix: str = None, container_name: str = None): load_dotenv() self.account_name : str = account_name if account_name else os.getenv('BLOB_ACCOUNT_NAME') self.account_key : str = account_key if account_key else os.getenv('BLOB_ACCOUNT_KEY') - self.connect_str : str = f"DefaultEndpointsProtocol=https;AccountName={self.account_name};AccountKey={self.account_key};EndpointSuffix=core.chinacloudapi.cn" + self.blob_endPoint_suffix : str = blob_endPoint_suffix if blob_endPoint_suffix else os.getenv('BLOB_ENDPOINT_SUFFIX') + # comment and update it to support both global azure and Azure China, they are of different blob end point suffix. + # self.connect_str : str = f"DefaultEndpointsProtocol=https;AccountName={self.account_name};AccountKey={self.account_key};EndpointSuffix=core.chinacloudapi.cn" + self.connect_str : str = f"DefaultEndpointsProtocol=https;AccountName={self.account_name};AccountKey={self.account_key};EndpointSuffix={blob_endPoint_suffix}" + self.container_name : str = container_name if container_name else os.getenv('BLOB_CONTAINER_NAME') self.blob_service_client : BlobServiceClient = BlobServiceClient.from_connection_string(self.connect_str) From fceaa4e9760be980f536c4929e0c6271dd9346a4 Mon Sep 17 00:00:00 2001 From: Zhuang <54096296+DevOps-zhuang@users.noreply.github.com> Date: Mon, 22 May 2023 22:49:10 +0800 Subject: [PATCH 5/8] Update .env.template add one column to support both Azure China and Global Azure BLOB_ENDPOINT_SUFFIX=core.windows.net --- .env.template | 1 + 1 file changed, 1 insertion(+) diff --git a/.env.template b/.env.template index e9383b2..f5f3c0f 100644 --- a/.env.template +++ b/.env.template @@ -14,6 +14,7 @@ REDIS_ARGS=--requirepass $REDIS_PASSWORD BLOB_ACCOUNT_NAME=YOUR_AZURE_BLOB_STORAGE_ACCOUNT_NAME BLOB_ACCOUNT_KEY=YOUR_AZURE_BLOB_STORAGE_ACCOUNT_KEY BLOB_CONTAINER_NAME=YOUR_AZURE_BLOB_STORAGE_CONTAINER_NAME +BLOB_ENDPOINT_SUFFIX=core.windows.net QUEUE_NAME=doc-processing FORM_RECOGNIZER_ENDPOINT=YOUR_AZURE_FORM_RECOGNIZER_ENDPOINT FORM_RECOGNIZER_KEY=YOUR_AZURE_FORM_RECOGNIZER_KEY From fac47df8d9184480963056d36cb579c81ed6924c Mon Sep 17 00:00:00 2001 From: Zhuang <54096296+DevOps-zhuang@users.noreply.github.com> Date: Mon, 22 May 2023 22:55:57 +0800 Subject: [PATCH 6/8] Update README.md update the mark file to display it correctly. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ac7e3d2..9f88952 100644 --- a/README.md +++ b/README.md @@ -181,17 +181,19 @@ Note: You can use ```code (already updated for this Azure china branch) 1) For WebApp.Dockerfile, update the exposed port from 80 to 8088. since 80 is already used by the batch service. since batch and web containers will be in the same pod. they can't use the same exposed port. (in my example, they can't, and I am some douting for the difference between pod and host when using docker-compose, which docker-compose can support since it can map container port to different host port) 2) code\utilities\azureblobstorage.py, go to line 13, update the EndpointSuffix=core.chinacloudapi.cn +``` ```console docker build . -f WebApp.Dockerfile -t your_docker_registry/your_docker_image:your_tag docker push your_docker_registry/your_docker_image:your_tag +``` ...K8S part generate a configmap file based on the `.env` as described in as described in [Environment variables](#environment-variables) kubectl apply -f myconfigmap.yml #update the all-in-one.yml file to use own docker containers. kubectl apply -f all-in-one.yml - +``` ## Environment variables Here is the explanation of the parameters: From ebbcfceec9797fb3351e683145f72e25429ded3a Mon Sep 17 00:00:00 2001 From: Zhuang <54096296+DevOps-zhuang@users.noreply.github.com> Date: Mon, 22 May 2023 22:57:32 +0800 Subject: [PATCH 7/8] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f88952..09f21b5 100644 --- a/README.md +++ b/README.md @@ -188,7 +188,7 @@ docker build . -f WebApp.Dockerfile -t your_docker_registry/your_docker_image:yo docker push your_docker_registry/your_docker_image:your_tag ``` -...K8S part +```K8S part generate a configmap file based on the `.env` as described in as described in [Environment variables](#environment-variables) kubectl apply -f myconfigmap.yml #update the all-in-one.yml file to use own docker containers. From e9c1d40c15cd702f2de82a6efaa29d7b9c7065ce Mon Sep 17 00:00:00 2001 From: Zhuang <54096296+DevOps-zhuang@users.noreply.github.com> Date: Mon, 22 May 2023 23:04:37 +0800 Subject: [PATCH 8/8] Update config-template.yml BLOB_ENDPOINT_SUFFIX: "core.windows.net" --- config-template.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config-template.yml b/config-template.yml index f04a990..30267dd 100644 --- a/config-template.yml +++ b/config-template.yml @@ -17,6 +17,7 @@ data: REDIS_PASSWORD: redis-stack-password BLOB_ACCOUNT_NAME: storage4openai BLOB_ACCOUNT_KEY: "[update to your key]" + BLOB_ENDPOINT_SUFFIX: "core.windows.net" BLOB_CONTAINER_NAME: embedding QUEUE_NAME: doc-processing FORM_RECOGNIZER_ENDPOINT: "https://formreader.cognitiveservices.azure.cn/" @@ -30,4 +31,4 @@ data: NUMBER_OF_EMBEDDINGS_FOR_QNA: "3" CONVERT_ADD_EMBEDDINGS_URL: "http://batch/api/BatchStartProcessing" AzureWebJobsStorage: "DefaultEndpointsProtocol=https;AccountName=storage4openai;AccountKey=[update to your key];EndpointSuffix=core.chinacloudapi.cn" - QUESTION_PROMPT: "Please reply to the question using only the information present in the text above. If you can't find it, reply 'Not in the text'.\nQuestion: _QUESTION_\nAnswer:" \ No newline at end of file + QUESTION_PROMPT: "Please reply to the question using only the information present in the text above. If you can't find it, reply 'Not in the text'.\nQuestion: _QUESTION_\nAnswer:"