|
| 1 | +# Lab 5 - Backend API |
| 2 | + |
| 3 | +In the previous lab, a LangChain agent was created armed with tools to do vector lookups and concrete document id lookups via function calling. In this lab, the agent functionality needs to be extracted into a backend api for the frontend application that will allow users to interact with the agent. |
| 4 | + |
| 5 | +The information provided in this section assumes that the dependent infrastructure is deployed and have completed the previous labs in this dev guide. |
| 6 | + |
| 7 | +## Overview |
| 8 | + |
| 9 | +The backend api is a Python FastAPI application that will expose endpoints for the frontend application to interact with. The backend api is a containerized application that will be deployed to [Azure Container Apps](https://learn.microsoft.com/en-us/azure/container-apps/overview). |
| 10 | + |
| 11 | +## Clone the backend repository |
| 12 | + |
| 13 | +Create a folder to house the backend api code. Open a terminal and navigate to the folder. Clone the backend repository. |
| 14 | + |
| 15 | +```bash |
| 16 | +git clone <backend repo url> |
| 17 | +``` |
| 18 | + |
| 19 | +## Run the backend api locally |
| 20 | + |
| 21 | +When developing a backend api, it is often useful to run the application locally to test and debug. This section outlines how to run the backend api locally while watching the file system for code changes. Any detected changes will automatically restart the backend api. |
| 22 | + |
| 23 | +1. Open the backend api folder location in VS Code. |
| 24 | + |
| 25 | +2. Open a **Terminal** window in VS Code (<kbd>CTRL</kbd>+<kbd>`</kbd>). |
| 26 | + |
| 27 | +3. Setup the `.env` file. Copy the `.env.example` file to `.env` and update the values. These are the same environment variables used in the previous labs. |
| 28 | + |
| 29 | + ```bash |
| 30 | + cp .env.example .env |
| 31 | + ``` |
| 32 | + |
| 33 | +4. Using the Terminal window, [create a virtual environment and activate it](https://python.land/virtual-environments/virtualenv). |
| 34 | + |
| 35 | +5. Run the following command to install the dependencies. |
| 36 | + |
| 37 | + ```bash |
| 38 | + pip install -r requirements.txt |
| 39 | + ``` |
| 40 | + |
| 41 | +6. Run the following command to start the backend api in the virtual environment. |
| 42 | + |
| 43 | + ```bash |
| 44 | + uvicorn --host "0.0.0.0" --port 8000 app:app --reload |
| 45 | + ``` |
| 46 | + |
| 47 | +  |
| 48 | + |
| 49 | +7. Open a browser and navigate to `http://localhost:8000/docs` to view the Swagger UI. |
| 50 | + |
| 51 | +  |
| 52 | + |
| 53 | +8. Expand the **GET / Root** endpoint and select **Try it out**. Select **Execute** to send the request. The response should display a status of `ready`. |
| 54 | + |
| 55 | +  |
| 56 | + |
| 57 | +9. Expand the **POST /ai** endpoint and select **Try it out**. In the **Request body** field, enter the following JSON. |
| 58 | + |
| 59 | + ```json |
| 60 | + { |
| 61 | + "session_id": "abc123", |
| 62 | + "prompt": "What was the price of the product with sku `FR-R92B-58`" |
| 63 | + } |
| 64 | + ``` |
| 65 | + |
| 66 | +10. Select **Execute** to send the request. Observe that the response indicates the price as being `$1431.50`. |
| 67 | + |
| 68 | +  |
| 69 | + |
| 70 | +11. In the Terminal window, press <kbd>CTRL</kbd>+<kbd>C</kbd> to stop the backend api. |
| 71 | + |
| 72 | +## Build and run the backend api container locally in Docker Desktop |
| 73 | + |
| 74 | +When deployed to Azure, the backend api will be running in a container. It is important to test the container locally to ensure it is working as expected. Containers are important because they provide a consistent environment for the application to run in. This consistency allows the application to run the same way in development, test, and production environments - whether they be locally or in the cloud. |
| 75 | + |
| 76 | +The backend api contains a `Dockerfile` that defines the container image and is used by Docker to build the container image. The Dockerfile contains instructions for Docker to build the container image. The container image is a snapshot of the application and its dependencies. The container image can be thought of an installer for the application to be deployed as needed in any environment. |
| 77 | + |
| 78 | +The `Dockerfile` for the backend api is shown below. |
| 79 | + |
| 80 | +```dockerfile |
| 81 | +FROM python:3.11 |
| 82 | +
|
| 83 | +WORKDIR /code |
| 84 | +COPY ./requirements.txt /code/requirements.txt |
| 85 | +RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt |
| 86 | +COPY . /code |
| 87 | +
|
| 88 | +EXPOSE 80 |
| 89 | +ENV FORWARDED_ALLOW_IPS * |
| 90 | +
|
| 91 | +CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "80", "--forwarded-allow-ips", "*", "--proxy-headers"] |
| 92 | +``` |
| 93 | + |
| 94 | +Notice the steps of installing the pip dependencies, and running the **uvicorn** command line similar to what was done in the previous section. |
| 95 | + |
| 96 | +1. Ensure Docker Desktop is running. |
| 97 | + |
| 98 | +2. Open a **Terminal** window in VS Code (<kbd>CTRL</kbd>+<kbd>`</kbd>). |
| 99 | +
|
| 100 | +3. If the terminal displays the virtual environment name, deactivate the virtual environment by running the following command. |
| 101 | +
|
| 102 | + ```bash |
| 103 | + deactivate |
| 104 | + ``` |
| 105 | +
|
| 106 | +4. Run the following command to build the container image. Once complete, a message displays the operation has `FINISHED`. |
| 107 | +
|
| 108 | + ```bash |
| 109 | + docker build --pull --rm -f "DOCKERFILE" -t devguidebackendapi:latest "." |
| 110 | + ``` |
| 111 | +
|
| 112 | +  |
| 113 | +
|
| 114 | +5. Lastly, run the container in Docker Desktop using the following command. |
| 115 | +
|
| 116 | + ```bash |
| 117 | + docker run -d -p 4242:80 --name devguide-backend-api devguidebackendapi:latest |
| 118 | + ``` |
| 119 | +
|
| 120 | +  |
| 121 | +
|
| 122 | +6. Open a browser and navigate to `http://localhost:4242/docs` to view the Swagger UI. |
| 123 | +
|
| 124 | +7. Repeat steps 8-10 from the previous section to test the backend api running in a container on Docker Desktop. |
| 125 | +
|
| 126 | +## Deploy the backend api to Azure Container Apps |
| 127 | +
|
| 128 | +### Retrieve the Azure Container Registry login server and admin credentials |
| 129 | +
|
| 130 | +The backend api container image needs to be pushed to an Azure Container Registry (ACR) before it can be deployed to Azure Container Apps. The ACR is a private container registry that will store the container image. Azure Container Apps will pull the container image from the ACR to deploy the backend api. |
| 131 | +
|
| 132 | +1. In the Azure portal, open the provisioned resource group and locate and open the **Container Registry** resource. |
| 133 | +
|
| 134 | +2. Select **Access keys** from the left-hand menu. Record the **Login server** value and the **Username** and **Password** values for later use. |
| 135 | +
|
| 136 | +  |
| 137 | +
|
| 138 | +### Push the backend api container image to the Azure Container Registry |
| 139 | +
|
| 140 | +Earlier, the backend api container image was built locally. Now that the ACR login server and admin credentials are known, the container image can be pushed to the Azure Container Registry. |
| 141 | +
|
| 142 | +1. Return to the terminal window in VS Code. |
| 143 | +
|
| 144 | +2. Run the following command to tag the container image with the ACR login server. Replace the `<login server>` value. This command will silently complete with no output. |
| 145 | +
|
| 146 | + ```bash |
| 147 | + docker tag devguidebackendapi:latest <login server>/devguidebackendapi:v1 |
| 148 | + ``` |
| 149 | +
|
| 150 | +3. Run the following command to log into the ACR. Replace the `<login server>`, `<username>`, and `<password>` values. The message `Login Succeeded` displays when the login is successful. |
| 151 | +
|
| 152 | + ```bash |
| 153 | + docker login <login server> -u <username> -p <password> |
| 154 | + ``` |
| 155 | +
|
| 156 | +4. Once authenticated, push the container image to the ACR using the following command. Replace the `<login server>` value. |
| 157 | +
|
| 158 | + ```bash |
| 159 | + docker push <login server>/devguidebackendapi:v1 |
| 160 | + ``` |
| 161 | +
|
| 162 | +  |
| 163 | +
|
| 164 | +### Deploy the backend api ACR container image to Azure Container Apps |
| 165 | +
|
| 166 | +The last step is to deploy the backend api container image to Azure Container Apps. Azure Container Apps is a fully managed serverless container platform that allows developers to deploy containerized applications without having to manage any infrastructure. |
| 167 | +
|
| 168 | +1. In the Azure portal, open the provisioned resource group and locate and open the **Container App** resource, the name will end in `-api`. Record the name of this resource. |
| 169 | +
|
| 170 | +2. Back in the resource group, locate the **Container Apps Environment** resource, the name will end in `-containerappenv`. Record the name of this resource. |
| 171 | +
|
| 172 | +3. Also record the name of the resource group. |
| 173 | +
|
| 174 | +4. Return to the terminal window in VS Code. |
| 175 | +
|
| 176 | +5. Log into the Azure CLI using the following command. |
| 177 | +
|
| 178 | + ```bash |
| 179 | + az login |
| 180 | + ``` |
| 181 | +
|
| 182 | +6. Optionally set the current subscription to the correct subscription using the following command. |
| 183 | +
|
| 184 | + ```bash |
| 185 | + az account set --subscription <subscription id> |
| 186 | + ``` |
| 187 | +
|
| 188 | +7. Install the Azure Container Apps extension for the CLI using the following command. |
| 189 | +
|
| 190 | + ```bash |
| 191 | + az extension add --name containerapp --upgrade |
| 192 | + ``` |
| 193 | +
|
| 194 | +8. Run the following command to deploy the backend api container image to the existing Azure Container Apps resource. Replace the `<container app name>`, `<login server>`, `<resource group name>`, and `<container app environment name>` values. |
| 195 | +
|
| 196 | + ```bash |
| 197 | + az containerapp up --name <container app name> --image <login server>/devguidebackendapi:v1 --resource-group <resource group name> --environment <container app environment name> --ingress external |
| 198 | + ``` |
| 199 | +
|
| 200 | +  |
| 201 | +
|
| 202 | +9. In the Azure Portal, locate and open the **Container App** resource ending in `-api`. |
| 203 | +
|
| 204 | +10. Notice on the **Overview** screen, there is a failed container revision. This is because the `hello-world` container is running at the same binding address as the backend api container. |
| 205 | +
|
| 206 | +  |
| 207 | +
|
| 208 | +11. View the error from the logs, or optionally select **Log stream** from the left menu, then select the api container log stream. |
| 209 | +
|
| 210 | +  |
| 211 | +
|
| 212 | +12. To rectify this, the `hello-world` container needs to be deleted. Select **Containers** from the left menu, then choose the **Edit and Deploy** button from the toolbar. |
| 213 | +
|
| 214 | +  |
| 215 | +
|
| 216 | +13. On the **Create and deploy new revision** screen, beneath the **Container image** heading, check the box next to the `hello-world` container, then select **Delete**. |
| 217 | +
|
| 218 | +  |
| 219 | +
|
| 220 | +14. Select **Create** to deploy the new revision. In less than a minute, the new revision is deployed. |
| 221 | +
|
| 222 | +15. Refresh the browser, then from the left menu, select **Overview**. Select the **Application URL** link. |
| 223 | +
|
| 224 | +  |
| 225 | +
|
| 226 | +16. The UI should show the status as `ready`. |
| 227 | +
|
| 228 | +  |
| 229 | +
|
| 230 | +17. In the address bar of the browser, append `/docs` to the URL and press <kbd>ENTER</kbd> to view the Swagger UI. |
| 231 | +
|
| 232 | +18. Repeat steps 8-10 from the [Run the backend api locally section](#run-the-backend-api-locally) to test the backend api running in a container on Azure Container Apps. |
| 233 | +
|
| 234 | +Congratulations! You have successfully deployed the backend api to Azure Container Apps where it is ready to service the frontend application. |
0 commit comments