Skip to content

Commit 07db793

Browse files
authored
Merge pull request #130 from mozilla-mobile/rpapa-llm-cloudrun
llm-cloudrun poc
2 parents 08cedcf + 287aa7c commit 07db793

File tree

8 files changed

+164
-2
lines changed

8 files changed

+164
-2
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Manual POC run (pull artifacts from GCS)
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
use_prod_service_url:
7+
description: "Call the Cloud Run service after downloading artifacts?"
8+
required: false
9+
type: boolean
10+
default: false
11+
12+
permissions:
13+
contents: read
14+
15+
env:
16+
# ---- Update these if needed ----
17+
GCP_PROJECT_ID: moz-testops-tools
18+
SERVICE_URL: https://llm-tool-620861480696.us-central1.run.app
19+
# GCS object URIs you shared:
20+
CRASH_URI: gs://testops-llm-artifacts/crashes/minidumps/examples/crash_example.txt
21+
ANR_URI: gs://testops-llm-artifacts/anr/examples/anr_example.txt
22+
LOCAL_ARTIFACT_DIR: artifacts
23+
24+
jobs:
25+
manual-run:
26+
runs-on: ubuntu-latest
27+
28+
steps:
29+
- name: Checkout repository
30+
uses: actions/checkout@v4
31+
32+
# Auth via JSON key (what you asked for)
33+
- name: Authenticate to Google Cloud (JSON key)
34+
uses: google-github-actions/auth@v2
35+
with:
36+
credentials_json: ${{ secrets.GCP_SA_VERTEX_AI }}
37+
38+
- name: Setup gcloud
39+
uses: google-github-actions/setup-gcloud@v2
40+
with:
41+
project_id: ${{ env.GCP_PROJECT_ID }}
42+
43+
- name: Set gcloud project (quiet)
44+
run: |
45+
gcloud --quiet config set project "$GCP_PROJECT_ID"
46+
47+
- name: Download artifacts from GCS
48+
run: |
49+
mkdir -p "${LOCAL_ARTIFACT_DIR}"
50+
gcloud storage cp "${CRASH_URI}" "${LOCAL_ARTIFACT_DIR}/crash_example.txt"
51+
gcloud storage cp "${ANR_URI}" "${LOCAL_ARTIFACT_DIR}/anr_example.txt"
52+
echo "Downloaded files:"
53+
ls -la "${LOCAL_ARTIFACT_DIR}"
54+
55+
# Optional: call your private Cloud Run service (only if you toggle the input)
56+
- name: (Optional) Invoke secured Cloud Run service
57+
if: ${{ inputs.use_prod_service_url == true }}
58+
run: |
59+
# Fetch an ID token for the SERVICE_URL audience and call the service
60+
TOKEN="$(gcloud auth print-identity-token --audiences="${SERVICE_URL}")"
61+
curl -i -H "Authorization: Bearer ${TOKEN}" "${SERVICE_URL}" || true
62+

.gitignore

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
node_modules
22
android-performance/node_modules
33
actions-runner
4+
5+
# Ignore editor and cache files
6+
.DS_Store
7+
*.pyc
8+
__pycache__
9+
*.sw?
10+
.*.sw?
11+
4913
12+
13+
Dockerfile.*
14+
docker-compose.*
15+
416
backup-tools/*.csv
517
backup-tools/backup*.json
6-
backup-tools/__pychache__/
7-
*.pyc
18+
backup-tools/__pycache__/

llm-cloud-run/.dockerignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Vim artifacts
2+
*.sw?
3+
.*.sw?
4+
*
5+
4913
6+
7+
.DS_Store

llm-cloud-run/Dockerfile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM python:3.10-slim
2+
3+
WORKDIR /app
4+
5+
RUN pip install fastapi uvicorn google-cloud-aiplatform vertexai
6+
7+
COPY main.py .
8+
9+
EXPOSE 8080
10+
11+
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]

llm-cloud-run/README_DEPLOY.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
1. Enable required services:
2+
gcloud services enable run.googleapis.com aiplatform.googleapis.com
3+
4+
2. Submit your container image:
5+
gcloud builds submit --tag gcr.io/YOUR_PROJECT_ID/llm-runner
6+
7+
3. Deploy to Cloud Run:
8+
gcloud run deploy llm-runner \
9+
--image gcr.io/YOUR_PROJECT_ID/llm-runner \
10+
--platform managed \
11+
--region us-central1 \
12+
--allow-unauthenticated
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Postprocess with LLM
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
postprocess-with-llm:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: Set up GCP credentials
11+
run: echo "${{ secrets.GCP_CREDENTIALS }}" > key.json
12+
13+
- name: Authenticate and call Cloud Run
14+
run: |
15+
gcloud auth activate-service-account --key-file=key.json
16+
gcloud config set project YOUR_PROJECT_ID
17+
TOKEN=$(gcloud auth print-access-token)
18+
19+
PROMPT=$(cat path/to/prompt.txt | jq -Rs .)
20+
CONTENT=$(cat path/to/artifact.txt | jq -Rs .)
21+
22+
RESPONSE=$(curl -s -X POST https://llm-runner-abcdef-uc.a.run.app/ \
23+
-H "Authorization: Bearer $TOKEN" \
24+
-H "Content-Type: application/json" \
25+
-d "{\"prompt\": $PROMPT, \"content\": $CONTENT}")
26+
27+
echo "LLM response:"
28+
echo "$RESPONSE"

llm-cloud-run/main.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from fastapi import FastAPI
2+
from pydantic import BaseModel
3+
from vertexai.preview.generative_models import GenerativeModel
4+
import vertexai
5+
import os
6+
7+
app = FastAPI()
8+
9+
vertexai.init(project=os.getenv("GCP_PROJECT"), location="us-central1")
10+
11+
class LLMRequest(BaseModel):
12+
prompt: str
13+
content: str
14+
15+
@app.post("/")
16+
async def analyze(request: LLMRequest):
17+
full_prompt = f"{request.prompt.strip()}\n\n{request.content.strip()}"
18+
model = GenerativeModel("gemini-1.5-pro")
19+
response = model.generate_content(
20+
full_prompt,
21+
generation_config={
22+
"temperature": 0.3,
23+
"max_output_tokens": 1024
24+
}
25+
)
26+
return {"output": response.text}

llm-cloud-run/requirements.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fastapi
2+
uvicorn[standard]
3+
google-cloud-aiplatform
4+
google-cloud-storage
5+
pydantic

0 commit comments

Comments
 (0)