Skip to content

Commit

Permalink
Add flow endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
ljtill committed Jan 24, 2025
1 parent 689ee65 commit da583bd
Show file tree
Hide file tree
Showing 23 changed files with 343 additions and 292 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"image": "mcr.microsoft.com/devcontainers/base:noble",
"features": {
"ghcr.io/ljtill/features/task:latest": {
"version": "3.40.1"
"version": "3.41.0"
}
},
"customizations": {
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ jobs:
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}

- name: Build Flows
id: flow-build
run: task flow-build

- name: Deploy Flows
id: flow-deploy
run: task flow-deploy
Expand Down
13 changes: 11 additions & 2 deletions .task/app.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "3.40.1"
version: "3.41.0"

tasks:
app-build:
Expand Down Expand Up @@ -107,14 +107,23 @@ tasks:
--src-path "$ZIP_PATH" \
--type zip
app-logs:
desc: Show application logs.
silent: true
aliases:
- al
dir: infra
cmds:
- az webapp log tail -g $(terraform output -raw resource_group) -n $(terraform output -raw webapp_name)

api-run:
desc: Launch local API instance.
silent: true
dir: app/api
deps:
- task: deps-setup
aliases:
- ar
dir: app/api
cmds:
- echo -e "\033[0;32mLaunching API...\033[0m"
- .venv/bin/python3 -m uvicorn main:app --reload
126 changes: 75 additions & 51 deletions .task/flow.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: "3.40.1"
version: "3.41.0"

tasks:
flow-deploy:
flow-deploy-review:
desc: Deploy flows to AI Foundry.
silent: true
deps:
Expand All @@ -12,9 +12,10 @@ tasks:
cmds:
- cmd: |
NAME_ARGUMENT={{if .FLOW_NAME}}"--set display_name="{{.FLOW_NAME}}{{else}}{{end}}
pushd ../infra > /dev/null
eval "$(terraform output -json | jq -r 'to_entries | .[] | "export ADR_" + (.key | ascii_upcase) + "=\"" + .value.value + "\"" ')"
popd > /dev/null
pushd ../infra
RESOURCE_GROUP=$(terraform output -raw resource_group)
APP_NAME=$(terraform output -raw webapp_name)
popd
pfazure flow create \
--flow ai_doc_review \
Expand All @@ -33,14 +34,15 @@ tasks:
cmds:
- cmd: |
NAME_ARGUMENT={{if .FLOW_NAME}}"--set display_name="{{.FLOW_NAME}}{{else}}{{end}}
pushd ../infra > /dev/null
eval "$(terraform output -json | jq -r 'to_entries | .[] | "export ADR_" + (.key | ascii_upcase) + "=\"" + .value.value + "\"" ')"
popd > /dev/null
pushd ../infra
RESOURCE_GROUP=$(terraform output -raw resource_group)
AI_HUB_PROJECT_NAME=$(terraform output -raw ai_hub_project_name)
popd
pfazure flow create \
--flow ai_doc_review/agent_template \
--workspace-name "$ADR_AI_HUB_PROJECT_NAME" \
--resource-group "$ADR_RESOURCE_GROUP" \
--workspace-name "$AI_HUB_PROJECT_NAME" \
--resource-group "$RESOURCE_GROUP" \
$NAME_ARGUMENT
flow-deploy-eval:
Expand All @@ -54,62 +56,84 @@ tasks:
cmds:
- cmd: |
NAME_ARGUMENT={{if .FLOW_NAME}}"--set display_name="{{.FLOW_NAME}}{{else}}{{end}}
pushd ../infra > /dev/null
eval "$(terraform output -json | jq -r 'to_entries | .[] | "export ADR_" + (.key | ascii_upcase) + "=\"" + .value.value + "\"" ')"
popd > /dev/null
pushd ../infra
RESOURCE_GROUP=$(terraform output -raw resource_group)
AI_HUB_PROJECT_NAME=$(terraform output -raw ai_hub_project_name)
popd
pfazure flow create \
--flow ai_doc_review_eval \
--workspace-name "$ADR_AI_HUB_PROJECT_NAME" \
--resource-group "$ADR_RESOURCE_GROUP" \
--workspace-name "$AI_HUB_PROJECT_NAME" \
--resource-group "$RESOURCE_GROUP" \
--set type=evaluation
$NAME_ARGUMENT
flow-deploy-endpoint:
flow-build:
desc: Build flow artifacts.
silent: true
deps:
- task: deps-setup
aliases:
- fb
dir: flows
cmds:
- echo -e "\033[0;32mBuilding flow artifacts...\033[0m"
- python3 -m venv .venv
- .venv/bin/pip3 install -r requirements.txt
- .venv/bin/pip3 install -r ./ai_doc_review/requirements.txt
- .venv/bin/pip3 install -r ./ai_doc_review_eval/requirements.txt
- .venv/bin/pip3 install keyrings.alt

flow-deploy:
desc: Deploy to ML endpoints.
silent: true
deps:
- task: deps-setup
aliases:
- fde
dir: flows/ai_doc_review
dir: flows
cmds:
- cmd: |
pushd ../../infra > /dev/null
eval "$(terraform output -json | jq -r 'to_entries | .[] | "export ADR_" + (.key | ascii_upcase) + "=\"" + .value.value + "\"" ')"
popd > /dev/null
echo -e "\033[0;32mUploading flow...\033[0m"
TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT
cp -r ../../common/ common/
cp ./deployment.yaml ./sub_deployment.yaml
export MODEL_VERSION=$(az ml model create --workspace-name "$ADR_AI_HUB_PROJECT_NAME" --resource-group "$ADR_RESOURCE_GROUP" --file model.yaml --query version -o tsv)
cp -a ai_doc_review "$TEMP_DIR/"
rm -rf "$TEMP_DIR/ai_doc_review/common"
cp -a ../common "$TEMP_DIR/ai_doc_review/common"
pushd $TEMP_DIR/ai_doc_review
zip -q -r --symlinks "$TEMP_DIR/flow.zip" *
popd
sed -i 's|VAR_MODEL_VERSION|'"$MODEL_VERSION"'|g' sub_deployment.yaml
sed -i 's|VAR_SUBSCRIPTION_ID|'"$ADR_SUBSCRIPTION_ID"'|g' sub_deployment.yaml
sed -i 's|VAR_RESOURCE_GROUP|'"$ADR_RESOURCE_GROUP"'|g' sub_deployment.yaml
sed -i 's|VAR_AI_HUB_PROJECT_NAME|'"$ADR_AI_HUB_PROJECT_NAME"'|g' sub_deployment.yaml
sed -i 's|VAR_ENDPOINT_NAME|'"$ADR_AML_ENDPOINT_NAME"'|g' sub_deployment.yaml
sed -i 's|VAR_AZURE_OPENAI_ENDPOINT|'"$ADR_AZURE_OPENAI_ENDPOINT"'|g' sub_deployment.yaml
sed -i 's|VAR_IDENTITY_CLIENT_ID|'"$ADR_IDENTITY_CLIENT_ID"'|g' sub_deployment.yaml
sed -i 's|VAR_DOCUMENT_INTELLIGENCE_ENDPOINT|'"$ADR_DOCUMENT_INTELLIGENCE_ENDPOINT"'|g' sub_deployment.yaml
sed -i 's|VAR_STORAGE_URL_PREFIX|'"$ADR_STORAGE_URL_PREFIX"'|g' sub_deployment.yaml
pushd ../infra
RESOURCE_GROUP=$(terraform output -raw resource_group)
FLOW_NAME=$(terraform output -raw flowapp_name)
popd
az ml online-deployment show \
--name ai-doc-review-deployment \
--endpoint-name "$ADR_AML_ENDPOINT_NAME" \
--workspace-name "$ADR_AI_HUB_PROJECT_NAME" \
--resource-group "$ADR_RESOURCE_GROUP" \
&& az ml online-deployment update \
--file sub_deployment.yaml \
--workspace-name "$ADR_AI_HUB_PROJECT_NAME" \
--resource-group "$ADR_RESOURCE_GROUP" \
|| az ml online-deployment create \
--file sub_deployment.yaml \
--workspace-name "$ADR_AI_HUB_PROJECT_NAME" \
--resource-group "$ADR_RESOURCE_GROUP" \
--all-traffic
ZIP_PATH="$TEMP_DIR/flow.zip"
az webapp deploy \
-g $RESOURCE_GROUP \
-n $FLOW_NAME \
--src-path "$ZIP_PATH" \
--type zip
az ml online-endpoint update \
--name $ADR_AML_ENDPOINT_NAME \
--traffic "ai-doc-review-deployment=100" \
--workspace-name "$ADR_AI_HUB_PROJECT_NAME" \
--resource-group "$ADR_RESOURCE_GROUP"
flow-run:
desc: Launch local flow instance.
silent: true
deps:
- task: deps-setup
aliases:
- fr
dir: flows/ai_doc_review
cmds:
- echo -e "\033[0;32mLaunching flow...\033[0m"
- pf flow serve --source ./ --port 8080 --host localhost

flow-logs:
desc: Show logs for ML endpoint.
silent: true
aliases:
- fle
dir: infra
cmds:
- az webapp log tail --name $(terraform output -raw flowapp_name) --resource-group $(terraform output -raw resource_group)
2 changes: 1 addition & 1 deletion .task/infra.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "3.40.1"
version: "3.41.0"

tasks:
infra-init:
Expand Down
23 changes: 4 additions & 19 deletions Taskfile.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "3.40.1"
version: "3.41.0"

dotenv: [".env", "flows/.env", "{{.HOME}}/.env"]

Expand Down Expand Up @@ -46,11 +46,6 @@ tasks:
echo "Error: mkcert is not installed. Please install mkcert to continue."
exit 1
fi
- |
if ! command -v pfazure > /dev/null; then
echo "Error: pfazure is not installed. Please install pfazure to continue."
exit 1
fi
- |
if ! command -v git > /dev/null; then
echo "Error: git is not installed. Please install git to continue."
Expand Down Expand Up @@ -125,7 +120,7 @@ tasks:
sudo curl -fsSL https://raw.githubusercontent.com/tj/n/master/bin/n -o /opt/n
sudo bash /opt/n install 22 > /dev/null
else
NODE_VERSION=$(node -v | sed 's/v//;s/\..*//')
NODE_VERSION=$(node -v | sed "s/v//;s/\..*//")
if [ "$NODE_VERSION" -ne 22 ]; then
echo -e "\033[0;33mUpdating node...\033[0m"
cd "$(mktemp -d)" || exit 1
Expand All @@ -146,17 +141,6 @@ tasks:
chmod +x mkcert
sudo mv mkcert /usr/local/bin/mkcert
fi
- |
if ! command -v pf > /dev/null; then
echo -e "\033[0;32mInstalling promptflow...\033[0m"
cd "$(mktemp -d)" || exit 1
sudo mkdir -p /opt/python3/venvs/promptflow
sudo python3 -m venv /opt/python3/venvs/promptflow
sudo /opt/python3/venvs/promptflow/bin/pip3 install promptflow promptflow-tools promptflow-azure --quiet
sudo ln -s /opt/python3/venvs/promptflow/bin/pf /usr/local/bin/pf
sudo ln -s /opt/python3/venvs/promptflow/bin/pfazure /usr/local/bin/pfazure
fi
deps-setup:
desc: Setup toolchain dependencies.
Expand All @@ -178,6 +162,7 @@ tasks:
feature_state=$(az feature show --name AllowNSPInPublicPreview --namespace Microsoft.Network --query 'properties.state' -o tsv)
if [ "$feature_state" == "NotRegistered" ]; then
echo "Registering feature 'AllowNSPInPublicPreview'..."
echo "Registering feature '
AllowNSPInPublicPreview'..."
az feature register --name AllowNSPInPublicPreview --namespace Microsoft.Network --only-show-errors
fi
10 changes: 6 additions & 4 deletions app/api/.env.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@
AAD_CLIENT_ID="${AAD_CLIENT_ID}"
AAD_TENANT_ID="${AAD_TENANT_ID}"
AAD_USER_IMPERSONATION_SCOPE_ID="${AAD_USER_IMPERSONATION_SCOPE_ID}"
AZURE_CLIENT_ID="${AZURE_CLIENT_ID}"

# Cosmos DB configuration
COSMOS_URL="${COSMOS_URL}"
DATABASE_NAME="${DATABASE_NAME}"

# Azure ML configuration
# Flow configuration
SUBSCRIPTION_ID="${SUBSCRIPTION_ID}"
RESOURCE_GROUP="${RESOURCE_GROUP}"
AI_HUB_PROJECT_NAME="${AI_HUB_PROJECT_NAME}"
AI_HUB_REGION="${AI_HUB_REGION}"
AML_ENDPOINT_NAME="${AML_ENDPOINT_NAME}"
AML_STREAMING_BATCH_SIZE=10
FLOW_STREAMING_BATCH_SIZE=100
FLOW_ENDPOINT_NAME="${FLOW_ENDPOINT_NAME}"
FLOW_APP_NAME="${FLOW_APP_NAME}"

# App logging
APPINSIGHTS_INSTRUMENTATION_KEY="${APPINSIGHTS_INSTRUMENTATION_KEY}"
Expand All @@ -26,4 +28,4 @@ LOG_LEVEL="INFO"
DEBUG=True

# To Mount the UI at the root path
SERVE_STATIC=False # Set to True or False
SERVE_STATIC=False # Set to True or False
5 changes: 3 additions & 2 deletions app/api/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ class Settings(BaseSettings):
resource_group: str = ""
ai_hub_project_name: str = ""
ai_hub_region: str = ""
aml_endpoint_name: str = ""
aml_streaming_batch_size: int = 10
flow_endpoint_name: str = ""
flow_app_name: str = ""
flow_streaming_batch_size: int = 100
appinsights_instrumentation_key: str = ""
log_level: str = "INFO"
model_config = SettingsConfigDict(env_file=".env")
Expand Down
5 changes: 3 additions & 2 deletions app/api/database/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ def __init__(self, container_name) -> None:
self.container_name = container_name

# Initialize the Cosmos client
self.client = CosmosClient(self.cosmos_url, DefaultAzureCredential())
default_credential = DefaultAzureCredential()
self.client = CosmosClient(self.cosmos_url, default_credential)

def get_client(self) -> CosmosClient:
"""Return the initialized Cosmos client."""
Expand All @@ -20,7 +21,7 @@ def get_client(self) -> CosmosClient:
def get_database_name(self) -> str:
"""Return the database name."""
return self.database_name

def get_container_name(self) -> str:
"""Return the container name."""
return self.container_name
16 changes: 6 additions & 10 deletions app/api/dependencies.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import os
from services.aml_client import AMLClient
from database.issues_repository import IssuesRepository
from services.issues_service import IssuesService
from azure.identity import DefaultAzureCredential
from azure.ai.ml import MLClient
from azure.identity import DefaultAzureCredential, ClientAssertionCredential
from config.config import settings


def get_issues_service() -> IssuesService:
return IssuesService(IssuesRepository(), get_aml_client())

def get_aml_client():
credential = DefaultAzureCredential()
mlclient = MLClient(
credential,
settings.subscription_id,
settings.resource_group,
settings.ai_hub_project_name
)
return AMLClient(mlclient)
default_credential = DefaultAzureCredential()
credential = ClientAssertionCredential(settings.aad_tenant_id, os.environ.get('FLOW_CLIENT_ID'), lambda: default_credential.get_token("api://AzureADTokenExchange/.default").token)

return AMLClient(credential)
Loading

0 comments on commit da583bd

Please sign in to comment.