Build and Deploy an AI-Powered Agent Diet Planner with Streamlit, Gemini Pro, Vertex AI and BigQuery

1. מבוא

9370c0f92c692ebb.png

ב-codelab הזה תלמדו איך ליצור ולפרוס סוכן מבוסס-AI לתכנון תפריטים. ממשק משתמש באמצעות Streamlit, מודל LLM באמצעות Gemini Pro 2.5, כלי לתזמור מנועי AI מבוססי-סוכנים באמצעות Vertex AI לפיתוח AI מבוסס-סוכנים, BigQuery לאחסון נתונים ו-Cloud Run לפריסה.

במהלך ה-codelab, תשתמשו בגישה שלב אחר שלב באופן הבא:

  1. הכנת הפרויקט ב-Google Cloud והפעלת כל ממשקי ה-API הנדרשים בו
  2. Build Agentic AI Diet Planner using streamlit, Vertex AI and BigQuery
  3. פריסת האפליקציה ב-Cloud Run

סקירה כללית של הארכיטקטורה

84e3f3620dc4ed68.png

דרישה מוקדמת

  • פרויקט ב-Google Cloud Platform ‏ (GCP) עם חיוב מופעל.
  • ידע בסיסי ב-Python

מה תלמדו

  • How to build Agentic AI Diet Planner using streamlit, Vertex AI and store data to BigQuery
  • איך פורסים את האפליקציה ב-Cloud Run

מה צריך להכין

  • דפדפן האינטרנט Chrome
  • חשבון Gmail
  • פרויקט ב-Cloud עם חיוב מופעל

2. הגדרה בסיסית ודרישות

הגדרת סביבה בקצב עצמי

  1. נכנסים ל-Google Cloud Console ויוצרים פרויקט חדש או משתמשים בפרויקט קיים. אם עדיין אין לכם חשבון Gmail או חשבון Google Workspace, אתם צריכים ליצור חשבון.

fbef9caa1602edd0.png

37d264871000675d.png

5e3ff691252acf41.png

  • שם הפרויקט הוא השם המוצג למשתתפים בפרויקט הזה. זו מחרוזת תווים שלא נמצאת בשימוש ב-Google APIs. תמיד אפשר לעדכן את המיקום.
  • מזהה הפרויקט הוא ייחודי לכל הפרויקטים ב-Google Cloud, והוא קבוע (אי אפשר לשנות אותו אחרי שהוא מוגדר). מסוף Cloud יוצר באופן אוטומטי מחרוזת ייחודית. בדרך כלל לא צריך לדעת מה היא. ברוב המדריכים ללימוד תכנות, תצטרכו להפנות למזהה הפרויקט (בדרך כלל מסומן כ-PROJECT_ID). אם לא אהבתם את המזהה שנוצר, תוכלו ליצור מזהה אקראי אחר. אפשר גם לנסות שם משתמש משלכם ולבדוק אם הוא זמין. אי אפשר לשנות את ההגדרה הזו אחרי השלב הזה, והיא נשארת לאורך הפרויקט.
  • לידיעתכם, יש ערך שלישי, מספר פרויקט, שחלק מממשקי ה-API משתמשים בו. במאמרי העזרה מפורט מידע נוסף על שלושת הערכים האלה.
  1. בשלב הבא, תצטרכו להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבי Cloud או בממשקי API של Cloud. השלמת ה-codelab הזה לא תעלה לכם הרבה, אם בכלל. כדי להשבית את המשאבים ולוודא שלא תחויבו על שימוש בהם אחרי שתסיימו את המדריך הזה, תוכלו למחוק את המשאבים שיצרתם או למחוק את הפרויקט. משתמשים חדשים ב-Google Cloud זכאים לתוכנית תקופת ניסיון בחינם בשווי 300$.

3. לפני שמתחילים

הגדרת פרויקט בענן בכלי Cloud Shell Editor

ב-codelab הזה אנחנו יוצאים מנקודת הנחה שכבר יש לכם פרויקט ב-Google Cloud עם חיוב מופעל. אם עדיין אין לכם חשבון, אתם יכולים לפעול לפי ההוראות שבהמשך כדי להתחיל.

  1. ב-Google Cloud Console, בדף לבחירת הפרויקט, בוחרים או יוצרים פרויקט ב-Google Cloud.
  2. הקפידו לוודא שהחיוב מופעל בפרויקט שלכם ב-Cloud. כך בודקים אם החיוב מופעל בפרויקט
  3. תשתמשו ב-Cloud Shell, סביבת שורת פקודה שפועלת ב-Google Cloud ומגיעה עם bq שנטען מראש. לוחצים על 'הפעלת Cloud Shell' בחלק העליון של מסוף Google Cloud.

26f20e837ff06119.png

  1. אחרי שמתחברים ל-Cloud Shell, בודקים שכבר בוצע אימות ושהפרויקט מוגדר למזהה הפרויקט שלכם באמצעות הפקודה הבאה:
gcloud auth list
  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שפקודת gcloud מכירה את הפרויקט שלכם.
gcloud config list project
  1. אם הפרויקט לא מוגדר, משתמשים בפקודה הבאה כדי להגדיר אותו:
gcloud config set project <YOUR_PROJECT_ID>

אפשר גם לראות את המזהה במסוף.PROJECT_ID

bb98435b79995b15.jpeg

לוחצים עליו וכל הפרויקטים ומזהה הפרויקט יופיעו בצד שמאל.

ffa73dee57de5307.jpeg

  1. מפעילים את ממשקי ה-API הנדרשים באמצעות הפקודה שמוצגת למטה. התהליך הזה יכול להימשך כמה דקות, אז צריך להתאזר בסבלנות.
gcloud services enable aiplatform.googleapis.com \
                           run.googleapis.com \
                           cloudbuild.googleapis.com \
                           cloudresourcemanager.googleapis.com \
                    bigquery.googleapis.com

אם הפקודה תפעל בהצלחה, תוצג הודעה שדומה לזו שמופיעה בהמשך:

Operation "operations/..." finished successfully.

אפשר גם לחפש כל מוצר במסוף או להשתמש בקישור הזה במקום בפקודת gcloud.

אם פספסתם API כלשהו, תמיד תוכלו להפעיל אותו במהלך ההטמעה.

אפשר להיעזר בתיעוד בנושא פקודות ושימוש ב-gcloud.

הגדרת ספריית עבודה של האפליקציה

  1. לוחצים על הלחצן Open Editor (פתיחת העורך) כדי לפתוח את Cloud Shell Editor. כאן אפשר לכתוב את הקוד 6f8e18e89d3198c0.png
  2. מוודאים שהפרויקט ב-Cloud Code מוגדר בפינה הימנית התחתונה (סרגל המצב) של העורך ב-Cloud Shell, כפי שמודגש בתמונה שלמטה, ושהוא מוגדר לפרויקט הפעיל ב-Google Cloud שבו החיוב מופעל. אם מתבקשים, לוחצים על אישור. יכול להיות שיעבור זמן מה אחרי הפעלת Cloud Shell Editor עד שיופיע הכפתור Cloud Code - Sign In. צריך להתאזר בסבלנות.

4e372d87c51afa30.png

בשלב הבא, נכין את סביבת Python

הגדרת הסביבה

הכנת סביבה וירטואלית של Python

השלב הבא הוא הכנת סביבת הפיתוח. ב-codelab הזה נשתמש ב-Python 3.12, ובסביבה וירטואלית של Python כדי לפשט את הצורך ביצירה ובניהול של גרסת Python וסביבה וירטואלית.

  1. אם עדיין לא פתחתם את הטרמינל, פותחים אותו על ידי לחיצה על Terminal (טרמינל) -> New Terminal (טרמינל חדש), או באמצעות מקשי הקיצור Ctrl + Shift + C.

8635b60ae2f45bbc.jpeg

  1. יוצרים תיקייה חדשה ומשנים את המיקום לתיקייה הזו באמצעות הפקודה הבאה
mkdir agent_diet_planner
cd agent_diet_planner
  1. יוצרים סביבת virtualenv חדשה באמצעות הפקודה הבאה
python -m venv .env
  1. מפעילים את virtualenv באמצעות הפקודה הבאה
source .env/bin/activate
  1. יצירת requirements.txt. לוחצים על קובץ ← קובץ טקסט חדש וממלאים את התוכן שבהמשך. אחר כך שומרים אותו כקובץ requirements.txt
streamlit==1.33.0
google-cloud-aiplatform
google-cloud-bigquery
pandas==2.2.2
db-dtypes==1.2.0
pyarrow==16.1.0
  1. לאחר מכן מתקינים את כל הרכיבים התלויים מקובץ requirements.txt באמצעות הפקודה הבאה
pip install -r requirements.txt
  1. מזינים את הפקודה הבאה כדי לבדוק אם כל התלויות של ספריות Python מותקנות
pip list

הגדרת קובצי תצורה

עכשיו צריך להגדיר קובצי הגדרה לפרויקט הזה. קבצים של פרטי כניסה משמשים לאחסון משתנים ופרטי כניסה של חשבון שירות.

  1. השלב הראשון הוא ליצור חשבון שירות. מקלידים 'חשבון שירות' בחיפוש ולוחצים על 'חשבון שירות'. 18c210d5d1e2a666.png
  2. לוחצים על + יצירת חשבון שירות. מזינים את השם של חשבון השירות ולוחצים על 'יצירה והמשך'. 67cad62d367e236a.png
  3. בקטע 'הרשאה', בוחרים בתפקיד 'משתמש בחשבון שירות'. לוחצים על + Add another role (הוספת תפקיד נוסף) ובוחרים את תפקיד ה-IAM : BigQuery Admin (אדמין של BigQuery),‏ Cloud Run Admin (אדמין של Cloud Run),‏ Cloud Run Invoker (הפעלת Cloud Run),‏ Vertex AI Service Agent (סוכן שירות של Vertex AI) ו-Vertex AI User (משתמש Vertex AI). לאחר מכן לוחצים על Done (סיום) be84afdc13678f6c.png.
  4. לוחצים על כתובת האימייל של חשבון השירות, לוחצים על מקש Tab, לוחצים על add key (הוספת מפתח) → Create new key (יצירת מפתח חדש). 50989af3bb9e1538.png
  5. בוחרים באפשרות json ולוחצים על Create (יצירה). שמירת קובץ חשבון השירות הזה באופן מקומי לקראת השלב הבא a4a119672da532da.png
  6. יוצרים תיקייה בשם ‎ .streamlit עם ההגדרות הבאות. לוחצים לחיצה ימנית על העכבר, לוחצים על 'תיקייה חדשה' ומקלידים את שם התיקייה .streamlit
  7. לוחצים לחיצה ימנית בתיקייה .streamlit ואז לוחצים על New File (קובץ חדש) ומזינים את הערך שבהמשך. אחר כך שומרים אותו כקובץ secrets.toml
# secrets.toml (for Streamlit sharing)
# Store in .streamlit/secrets.toml

[gcp]
project_id = "your_gcp_project"
location = "us-central1"

[gcp_service_account]
type = "service_account"
project_id = "your-project-id"
private_key_id = "your-private-key-id"
private_key = '''-----BEGIN PRIVATE KEY-----
YOUR_PRIVATE_KEY_HERE
-----END PRIVATE KEY-----'''
client_email = "your-sa@project-id.iam.gserviceaccount.com"
client_id = "your-client-id"
auth_uri = "https://accounts.google.com/o/oauth2/auth"
token_uri = "https://oauth2.googleapis.com/token"
auth_provider_x509_cert_url = "https://www.googleapis.com/oauth2/v1/certs"
client_x509_cert_url = "https://www.googleapis.com/robot/v1/metadata/x509/your-sa%40project-id.iam.gserviceaccount.com"
  1. מעדכנים את הערך של project_id, private_key_id, private_key, client_email ו-client_id , and auth_provider_x509_cert_url על סמך חשבון השירות שנוצר בשלב הקודם.

הכנת מערך נתונים ב-BigQuery

השלב הבא הוא ליצור מערך נתונים ב-BigQuery כדי לשמור את תוצאות היצירה ב-BigQuery.

  1. מקלידים BigQuery בחיפוש ואז לוחצים על BigQuery.
  2. לוחצים על 2f2e87396859bc74.pngואז על 'יצירת מערך נתונים'.
  3. מזינים את המזהה של מערך הנתונים diet_planner_data ואז לוחצים על 'יצירת מערך נתונים' 2055cda1ee0360bd.png.

4. פיתוח אפליקציות של מתכנני תזונה מבוססי-סוכנים

ניצור ממשק אינטרנט פשוט עם 4 קלט שנראה כך

43b20db2d5f94f38.png

משנים את המשקל, הגובה, הגיל והמגדר על סמך הפרופיל ולוחצים על 'יצירה'. הוא יפעיל את מודל ה-LLM‏ Gemini Pro 2.5 בספריית Vertex AI ויאחסן את התוצאות שנוצרו ב-BigQuery.

הקוד יחולק ל-6 חלקים כדי שלא יהיה ארוך מדי.

יצירת הפונקציה calculate bmi status

  1. לוחצים לחיצה ימנית על התיקייה agent_diet_planner → קובץ חדש → מזינים את שם הקובץ bmi_calc.py ואז מקישים על Enter.
  2. מזינים את הקוד הבא
# Add this function to calculate BMI and health status
def calculate_bmi_status(weight, height):
   """
   Calculate BMI and return status message
   """
   height_m = height / 100  # Convert cm to meters
   bmi = weight / (height_m ** 2)
  
   if bmi < 18.5:
       status = "underweight"
       message = "⚠️ Your BMI suggests you're underweight. Consider increasing calorie intake with nutrient-dense foods."
   elif 18.5 <= bmi < 25:
       status = "normal"
       message = "✅ Your BMI is in the healthy range. Let's maintain this balance!"
   elif 25 <= bmi < 30:
       status = "overweight"
       message = "⚠️ Your BMI suggests you're overweight. Focus on gradual weight loss through balanced nutrition."
   else:
       status = "obese"
       message = "❗ Your BMI indicates obesity. Please consult a healthcare provider for personalized guidance."
  
   return {
       "value": round(bmi, 1),
       "status": status,
       "message": message
   }

יצירת אפליקציות ראשיות של מתכנן תזונה

  1. לוחצים לחיצה ימנית על התיקייה agent_diet_planner → קובץ חדש → מזינים את שם הקובץ app.py ואז מקישים על Enter.
  2. מזינים את הקוד הבא
import os
from google.oauth2 import service_account
import streamlit as st
from google.cloud import bigquery
from vertexai.preview.generative_models import GenerativeModel
import vertexai
import datetime
import time
import pandas as pd
from bmi_calc import calculate_bmi_status

# Get configuration from environment
PROJECT_ID = os.environ.get("GCP_PROJECT_ID", "your_gcp_project_id")
LOCATION = os.environ.get("GCP_LOCATION", "us-central1")

#CONSTANTS Dataset and table in BigQuery
DATASET = "diet_planner_data"
TABLE = "user_plans"

# Initialize Vertex AI
vertexai.init(project=PROJECT_ID, location=LOCATION)

# Initialize BigQuery client
try:
   # For Cloud Run, use default credentials
   bq_client = bigquery.Client()
except:
   # For local development, use service account from secrets
   if "gcp_service_account" in st.secrets:
       service_account_info = dict(st.secrets["gcp_service_account"])
       credentials = service_account.Credentials.from_service_account_info(service_account_info)
       bq_client = bigquery.Client(credentials=credentials, project=PROJECT_ID)
   else:
       st.error("BigQuery client initialization failed")
       st.stop()

מחליפים את הערך your_gcp_project_id במזהה הפרויקט.

יצירת אפליקציות ראשיות לתכנון תזונה לנציגים – setup_bq_tables

בקטע הזה ניצור פונקציה בשם setup_bq_table עם פרמטר קלט אחד bq_client. הפונקציה הזו תגדיר סכימה בטבלת BigQuery ותיצור טבלה אם היא לא קיימת.

ממלאים את הקוד הבא אחרי הקוד הקודם ב-app.py

# Create BigQuery table if not exists
def setup_bq_table(bq_client):
   dataset_id = f"{st.secrets['gcp']['project_id']}.{DATASET}"
   table_id = f"{dataset_id}.{TABLE}"
  
   schema = [
       bigquery.SchemaField("user_id", "STRING", mode="REQUIRED"),
       bigquery.SchemaField("timestamp", "TIMESTAMP", mode="REQUIRED"),
       bigquery.SchemaField("weight", "FLOAT", mode="REQUIRED"),
       bigquery.SchemaField("height", "INTEGER", mode="REQUIRED"),
       bigquery.SchemaField("age", "INTEGER", mode="REQUIRED"),
       bigquery.SchemaField("gender", "STRING", mode="REQUIRED"),
       bigquery.SchemaField("diet_plan", "STRING", mode="REQUIRED")
   ]
  
   try:
       bq_client.get_table(table_id)
   except:
       table = bigquery.Table(table_id, schema=schema)
       bq_client.create_table(table)
       st.toast("BigQuery table created successfully")

יצירת אפליקציות ראשיות של מתכנן תזונה – generate_diet_plan

בקטע הזה ניצור פונקציה בשם generate_diet_plan עם פרמטר קלט אחד. הפונקציה הזו תפעיל את מודל ה-LLM‏ Gemini Pro 2.5 עם הנחיית הגדרה ותיצור תוצאות.

ממלאים את הקוד הבא אחרי הקוד הקודם ב-app.py

# Generate diet plan using Gemini Pro
def generate_diet_plan(params):
   try:
       model = GenerativeModel("gemini-2.5-pro")
       prompt = f"""
       Create a personalized 7-day diet plan for:
       - {params['gender']}, {params['age']} years old
       - Weight: {params['weight']} kg
       - Height: {params['height']} cm
      
       Include:
       1. Daily calorie target
       2. Macronutrient breakdown (carbs, protein, fat)
       3. Meal timing and frequency
       4. Food recommendations
       5. Hydration guidance
      
       Make the plan:
       - Nutritionally balanced
       - Practical for daily use
       - Culturally adaptable
       - With portion size guidance
       """
      
       response = model.generate_content(prompt)
       return response.text
   except Exception as e:
       st.error(f"AI generation error: {str(e)}")
       return None

Create agent diet planner main apps - save_to_bq

בקטע הזה ניצור פונקציה בשם save_to_bq עם 3 פרמטרים של קלט : bq_client, user_id ו-plan. הפונקציה הזו תשמור את תוצאת הגנרציה בטבלת BigQuery

ממלאים את הקוד הבא אחרי הקוד הקודם ב-app.py

# Save user data to BigQuery
def save_to_bq(bq_client, user_id, plan):
   try:
       dataset_id = f"{st.secrets['gcp']['project_id']}.{DATASET}"
       table_id = f"{dataset_id}.{TABLE}"
      
       row = {
           "user_id": user_id,
           "timestamp": datetime.datetime.utcnow().isoformat(),
           "weight": st.session_state.user_data["weight"],
           "height": st.session_state.user_data["height"],
           "age": st.session_state.user_data["age"],
           "gender": st.session_state.user_data["gender"],
           "diet_plan": plan
       }
      
       errors = bq_client.insert_rows_json(table_id, [row])
       if errors:
           st.error(f"BigQuery error: {errors}")
       else:
           return True
   except Exception as e:
       st.error(f"Data saving error: {str(e)}")
       return False

Create agent diet planner main apps - main

בקטע הזה ניצור פונקציה בשם main ללא פרמטר קלט. הפונקציה הזו מטפלת בעיקר בסקריפט של ממשק המשתמש של Streamlit, בהצגת התוצאה שנוצרה, בהצגת תוצאה היסטורית שנוצרה מטבלת BigQuery ובהורדת נתונים לקובץ Markdown.

ממלאים את הקוד הבא אחרי הקוד הקודם ב-app.py

# Streamlit UI
def main():
   st.set_page_config(page_title="AI Diet Planner", page_icon="🍏", layout="wide")
  
   # Initialize session state
   if "user_data" not in st.session_state:
       st.session_state.user_data = None
   if "diet_plan" not in st.session_state:
       st.session_state.diet_plan = None
  
   # Initialize clients
   #bq_client = init_clients()
   setup_bq_table(bq_client)
  
   st.title("🍏 AI-Powered Diet Planner")
   st.markdown("""
   <style>
   .stProgress > div > div > div > div {
       background-color: #4CAF50;
   }
   [data-testid="stForm"] {
       background: #f0f5ff;
       padding: 20px;
       border-radius: 10px;
       border: 1px solid #e6e9ef;
   }
   </style>
   """, unsafe_allow_html=True)
  
   # User input form
   with st.form("user_profile", clear_on_submit=False):
       st.subheader("Your Profile")
       col1, col2 = st.columns(2)
      
       with col1:
           weight = st.number_input("Weight (kg)", min_value=30.0, max_value=200.0, value=70.0)
           height = st.number_input("Height (cm)", min_value=100, max_value=250, value=170)
          
       with col2:
           age = st.number_input("Age", min_value=18, max_value=100, value=30)
           gender = st.selectbox("Gender", ["Man", "Woman"])
      
       submitted = st.form_submit_button("Generate Diet Plan")
      
       if submitted:
           user_data = {
               "weight": weight,
               "height": height,
               "age": age,
               "gender": gender
           }

           st.session_state.user_data = user_data
           # Calculate BMI
           bmi_result = calculate_bmi_status(weight, height)

           # Display BMI results in a visually distinct box
           with st.container():
               st.subheader("📊 Your Health Assessment")
               col1, col2 = st.columns([1, 3])
      
               with col1:
                   st.metric("BMI", bmi_result["value"])
          
               with col2:
                   if bmi_result["status"] != "normal":
                       st.warning(bmi_result["message"])
                   else:
                       st.success(bmi_result["message"])
      
           # Add BMI scale visualization
           st.markdown(f"""
           <div style="background:#f0f2f6;padding:10px;border-radius:10px;margin-top:10px">
           <small>BMI Scale:</small><br>
           <div style="display:flex;height:20px;background:linear-gradient(90deg,
           #4e79a7 0%,
           #4e79a7 18.5%,
           #60bd68 18.5%,
           #60bd68 25%,
           #f28e2b 25%,
           #f28e2b 30%,
           #e15759 30%,
           #e15759 100%);position:relative">
           <div style="position:absolute;left:{min(100, max(0, (bmi_result["value"]/40)*100))}%;top:-5px">

           </div>
           </div>
           <div style="display:flex;justify-content:space-between">
           <span>Underweight (<18.5)</span>
           <span>Healthy (18.5-25)</span>
           <span>Overweight (25-30)</span>
           <span>Obese (30+)</span>
           </div>
           </div>
           """, unsafe_allow_html=True)

           # Store BMI in session state
           st.session_state.bmi = bmi_result         
  
   # Plan generation and display
   if submitted and st.session_state.user_data:
       with st.spinner("🧠 Generating your personalized diet plan using Gemini AI..."):
           #diet_plan = generate_diet_plan(st.session_state.user_data)
           diet_plan = generate_diet_plan({**st.session_state.user_data,"bmi": bmi_result["value"],
                                           "bmi_status": bmi_result["status"]
           })

           if diet_plan:
               st.session_state.diet_plan = diet_plan
              
               # Generate unique user ID
               user_id = f"user_{int(time.time())}"
              
               # Save to BigQuery
               if save_to_bq(bq_client, user_id, diet_plan):
                   st.toast("✅ Plan saved to database!")
  
   # Display generated plan
   if st.session_state.diet_plan:
       st.subheader("Your Personalized Diet Plan")
       st.markdown("---")
       st.markdown(st.session_state.diet_plan)
      
       # Download button
       st.download_button(
           label="Download Plan",
           data=st.session_state.diet_plan,
           file_name="my_diet_plan.md",
           mime="text/markdown"
       )
      
       # Show history
       st.subheader("Your Plan History")
       try:
           query = f"""
               SELECT timestamp, weight, height, age, gender
               FROM `{st.secrets['gcp']['project_id']}.{DATASET}.{TABLE}`
               WHERE user_id LIKE 'user_%'
               ORDER BY timestamp DESC
               LIMIT 5
           """
           history = bq_client.query(query).to_dataframe()
           if not history.empty:
               history["timestamp"] = pd.to_datetime(history["timestamp"])
               st.dataframe(history.style.format({
                   "weight": "{:.1f} kg",
                   "height": "{:.0f} cm"
               }))
           else:
               st.info("No previous plans found")
       except Exception as e:
           st.error(f"History load error: {str(e)}")

if __name__ == "__main__":
   main()

שומרים את הקוד בשם app.py.

5. פריסת אפליקציות באמצעות Cloud Build ב-Cloud Run

עכשיו, ברור שאנחנו רוצים להציג את האפליקציה המדהימה הזו לאחרים. כדי לעשות זאת, אנחנו יכולים לארוז את האפליקציה הזו ולפרוס אותה ב-Cloud Run כשירות ציבורי שאנשים אחרים יכולים לגשת אליו. כדי לעשות את זה, נחזור לארכיטקטורה

84e3f3620dc4ed68.png

קודם צריך ליצור Dockerfile. לוחצים על File->New Text File (קובץ > קובץ טקסט חדש), מעתיקים את הקוד הבא ומדביקים אותו,ואז שומרים אותו כ-Dockerfile.

# Use official Python image
FROM python:3.12-slim

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PORT 8080

# Install system dependencies
RUN apt-get update && \
   apt-get install -y --no-install-recommends \
   build-essential \
   libpq-dev \
   && rm -rf /var/lib/apt/lists/*

# Set working directory
WORKDIR /app

# Copy requirements
COPY requirements.txt .

# Install Python dependencies
RUN pip install --no-cache-dir -r requirements.txt

# Copy application files
COPY . .

# Expose port
EXPOSE $PORT

# Run the application
CMD ["streamlit", "run", "app.py", "--server.port", "8080", "--server.address", "0.0.0.0"]

בשלב הבא ניצור את cloudbuild.yaml כדי לבנות אפליקציות שיהפכו לקובצי אימג' של Docker, להעביר אותן בדחיפה ל-Artifact Registry ולפרוס אותן ב-Cloud Run.

לוחצים על File->New Text File (קובץ > קובץ טקסט חדש), מעתיקים את הקוד הבא, מדביקים אותו ושומרים אותו בשם cloudbuild.yaml

steps:
 # Build Docker image
 - name: 'gcr.io/cloud-builders/docker'
   args: ['build', '-t', 'gcr.io/$PROJECT_ID/diet-planner:$BUILD_ID', '--no-cache',
        '--progress=plain',
        '.']
   id: 'Build'
   timeout: 1200s
   waitFor: ['-']
   dir: '.'
  # Push to Container Registry
 - name: 'gcr.io/cloud-builders/docker'
   args: ['push', 'gcr.io/$PROJECT_ID/diet-planner:$BUILD_ID']
   id: 'Push'
   waitFor: ['Build']
  # Deploy to Cloud Run
 - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
   entrypoint: gcloud
   args:
     - 'run'
     - 'deploy'
     - 'diet-planner-service'
     - '--image=gcr.io/$PROJECT_ID/diet-planner:$BUILD_ID'
     - '--port=8080'
     - '--region=us-central1'
     - '--platform=managed'
     - '--allow-unauthenticated'
     - '--set-env-vars=GCP_PROJECT_ID=$PROJECT_ID,GCP_LOCATION=us-central1'
     - '--cpu=1'
     - '--memory=1Gi'
     - '--timeout=300'
   waitFor: ['Push']

options:
 logging: CLOUD_LOGGING_ONLY
 machineType: 'E2_HIGHCPU_8'
 diskSizeGb: 100

images:
 - 'gcr.io/$PROJECT_ID/diet-planner:$BUILD_ID'

בשלב הזה, כבר יש לנו את כל הקבצים שדרושים כדי ליצור אפליקציות שיהפכו לקובצי אימג' של Docker, להעביר אותם בדחיפה ל-Artifact Registry ולפרוס אותם ב-Cloud Run. עכשיו נבצע את הפריסה. עוברים לטרמינל של Cloud Shell ומוודאים שהפרויקט הנוכחי מוגדר לפרויקט הפעיל שלכם. אם לא, צריך להשתמש בפקודה gcloud configure כדי להגדיר את מזהה הפרויקט:

gcloud config set project [PROJECT_ID]

לאחר מכן, מריצים את הפקודה הבאה כדי ליצור אפליקציות שיהפכו לקובצי אימג' של Docker, להעביר אותן בדחיפה ל-Artifact Registry ולפרוס אותן ב-Cloud Run

gcloud builds submit --config cloudbuild.yaml

הכלי ייצור את קובץ האימג' של Docker על סמך קובץ ה-Dockerfile שסיפקנו קודם, ויעביר אותו בדחיפה ל-Artifact Registry. לאחר מכן נבצע פריסה של האימג' שנוצר ב-Cloud Run. כל התהליך הזה מוגדר בשלבים cloudbuild.yaml.

שימו לב שאנחנו מאפשרים כאן גישה לא מאומתת כי זו אפליקציית הדגמה. מומלץ להשתמש באימות מתאים לאפליקציות הארגוניות ולאפליקציות הייצור.

אחרי שהפריסה מסתיימת, אפשר לבדוק אותה בדף Cloud Run. כדי לעשות את זה, מחפשים את Cloud Run בסרגל החיפוש העליון של Cloud Console ולוחצים על המוצר Cloud Run.

3c460765656fc072.png

אחרי זה אפשר לבדוק את השירות שנפרס שמופיע בדף Cloud Run Service. לוחצים על השירות כדי לקבל את כתובת ה-URL של השירות.

93dc975d3caeab0e.png

כתובת ה-URL של השירות תופיע בסרגל העליון

9325464321c106f8.pngאפשר להשתמש באפליקציה מהחלון במצב אנונימי או מהמכשיר הנייד. הוא כבר אמור להיות פעיל.

6. הסרת המשאבים

כדי לא לצבור חיובים לחשבון Google Cloud על המשאבים שבהם השתמשתם ב-codelab הזה:

  1. במסוף Google Cloud, עוברים לדף Manage resources.
  2. ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
  3. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.
  4. אפשר גם להיכנס אל Cloud Run במסוף, לבחור את השירות שפרסתם ולמחוק אותו.