ساختن و پیاده‌سازی «برنامه‌ریز رژیم غذایی با عامل هوشواره‌ای» با Streamlit،‏ Gemini Pro،‏ Vertex AI، و BigQuery

۱. مقدمه

9370c0f92c692ebb.png

در این codelab، با نحوه ساختن و پیاده‌سازی «برنامه‌ریز رژیم غذایی هوشوراه‌ای» آشنا می‌شوید. برای میانای کاربر بااستفاده از Streamlit، مدل LLM بااستفاده از Gemini Pro 2.5، هماهنگ‌کننده موتور هوشواره عامل‌گرا بااستفاده از Vertex AI برای توسعه هوشواره عامل‌گرا، BigQuery برای ذخیره داده‌ها، و Cloud Run برای استقرار.

درطول این codelab، از رویکرد گام‌به‌گام زیر استفاده خواهید کرد:

  1. پروژه Google Cloud خود را آماده کنید و همه «میاناهای برنامه‌سازی کاربردی» موردنیاز را در آن «فعال کنید»
  2. ساختن «برنامه‌ریز رژیم غذایی با هوشواره عامل‌گرا» بااستفاده از Streamlit،‏ Vertex AI، و BigQuery
  3. برنامه را در Cloud Run مستقر کنید

نمای کلی معماری

84e3f3620dc4ed68.png

پیش‌نیاز

  • پروژه Google Cloud Platform (GCP) با صورت‌حساب فعال.
  • آشنایی اولیه با Python

آنچه خواهید آموخت

  • نحوه ساختن «برنامه‌ریز رژیم غذایی با هوشواره عامل‌گرا» بااستفاده از Streamlit،‏ Vertex AI، و ذخیره داده‌ها در BigQuery
  • نحوه مستقر کردن برنامه در Cloud Run

آنچه نیاز خواهید داشت

  • مرورگر وب Chrome
  • حساب Gmail
  • «پروژه ابری» با صورت‌حساب فعال

۲. راه‌اندازی پایه و الزامات

راه‌اندازی محیط خودگام

  1. به سیستم کنسول Google Cloud وارد شوید و پروژه جدیدی ایجاد کنید یا از پروژه موجودی استفاده کنید. اگر ازقبل حساب Gmail یا Google Workspace ندارید، باید حسابی ایجاد کنید.

fbef9caa1602edd0.png37d264871000675d.png5e3ff691252acf41.png

  • «نام پروژه» نام نمایشی شرکت‌کنندگان این پروژه است. این رشته کاراکتری است که Google APIs از آن استفاده نمی‌کند. همیشه می‌توانید آن را به‌روز کنید.
  • «شناسه پروژه» در همه پروژه‌های Google Cloud یکتا است و تغییرناپذیر است (پس‌از تنظیم شدن نمی‌تواند تغییر کند). ‫Cloud Console رشته‌ای یکتا را به‌طور خودکار تولید می‌کند؛ معمولاً برایتان مهم نیست که این رشته چیست. در اکثر دستورالعمل‌های گام‌به‌گام، باید به «شناسه پروژه» خود (که معمولاً با PROJECT_ID مشخص می‌شود) ارجاع دهید. اگر شناسه تولیدشده را نمی‌پسندید، می‌توانید شناسه تصادفی دیگری تولید کنید. یا می‌توانید نام کاربری خودتان را امتحان کنید و ببینید دردسترس است یا نه. پس‌از این مرحله نمی‌توان آن را تغییر داد و برای مدت پروژه باقی می‌ماند.
  • برای اطلاع شما، مقدار سومی وجود دارد، «شماره پروژه»، که برخی‌از میاناهای برنامه‌سازی کاربردی از آن استفاده می‌کنند. در مستندات درباره هر سه این مقادیر بیشتر بدانید.
  1. سپس، برای استفاده از منابع/میاناهای برنامه‌سازی کاربردی Cloud، باید صورت‌حساب را فعال کنید. اجرای این دستورالعمل گام‌به‌گام هزینه زیادی ندارد، یا اصلاً هزینه‌ای ندارد. برای خاموش کردن منابع و جلوگیری از ایجاد صورت‌حساب فراتر از این آموزش گام‌به‌گام، می‌توانید منابعی را که ایجاد کرده‌اید حذف کنید یا پروژه را حذف کنید. کاربران جدید Google Cloud واجدشرایط برنامه دوره آزمایشی رایگان ۳۰۰ دلاری هستند.

۳. قبل‌از شروع

راه‌اندازی پروژه Cloud در «ویرایشگر Cloud Shell»

این codelab فرض می‌کند که ازقبل پروژه Google Cloud با صورت‌حساب فعال دارید. اگر هنوز آن را ندارید، می‌توانید دستورالعمل‌های زیر را برای شروع دنبال کنید.

  1. در کنسول Google Cloud، در صفحه انتخابگر پروژه، یک پروژه Google Cloud را انتخاب یا ایجاد کنید.
  2. مطمئن شوید که صورت‌حساب برای پروژه Cloud شما فعال است. با نحوه بررسی فعال بودن صورت‌حساب در یک پروژه آشنا شوید .
  3. از Cloud Shell، محیط خط فرمان که در Google Cloud اجرا می‌شود و ازقبل با bq بارگذاری شده است، استفاده خواهید کرد. در بالای کنسول Google Cloud، روی «فعال‌سازی Cloud Shell» کلیک کنید.

26f20e837ff06119.png

  1. پس‌از اتصال به Cloud Shell، بااستفاده از فرمان زیر بررسی می‌کنید که ازقبل اصالت‌سنجی شده‌اید و پروژه روی شناسه پروژه شما تنظیم شده است:
gcloud auth list
  1. برای تأیید اینکه فرمان gcloud از پروژه شما مطلع است، فرمان زیر را در Cloud Shell اجرا کنید.
gcloud config list project
  1. اگر پروژه‌تان تنظیم نشده است، از فرمان زیر برای تنظیم آن استفاده کنید:
gcloud config set project <YOUR_PROJECT_ID>

یا می‌توانید شناسه PROJECT_ID را در کنسول ببینید

bb98435b79995b15.jpeg

روی آن کلیک کنید و همه پروژه‌تان و شناسه پروژه را در سمت راست خواهید دید

ffa73dee57de5307.jpeg

  1. میاناهای برنامه‌سازی کاربردی موردنیاز را ازطریق فرمان نشان‌داده‌شده در زیر فعال کنید. این کار ممکن است چند دقیقه طول بکشد، بنابراین لطفاً صبور باشید.
gcloud services enable aiplatform.googleapis.com \
                           run.googleapis.com \
                           cloudbuild.googleapis.com \
                           cloudresourcemanager.googleapis.com \
                    bigquery.googleapis.com

پس‌از اجرای موفقیت‌آمیز فرمان، باید پیامی مشابه پیام زیر را ببینید:

Operation "operations/..." finished successfully.

جایگزین دستور gcloud ازطریق کنسول با جستجوی هر محصول یا بااستفاده از این پیوند است.

اگر هریک از «میاناهای برنامه‌سازی کاربردی» ازدست رفت، همیشه می‌توانید آن را درطول اجرای آن فعال کنید.

برای دستورات و استفاده از gcloud، به اسناد مراجعه کنید.

تنظیم کردن دایرکتوری کاری برنامه

  1. روی دکمه «باز کردن ویرایشگر» کلیک کنید، این کار «ویرایشگر Cloud Shell» را باز می‌کند، می‌توانیم کد خود را اینجا بنویسیم 6f8e18e89d3198c0.png
  2. مطمئن شوید پروژه Cloud Code در گوشه پایین سمت راست (نوار وضعیت) ویرایشگر Cloud Shell تنظیم شده باشد، همان‌طور که در تصویر زیر برجسته شده است و روی پروژه فعال Google Cloud تنظیم شده باشد که در آن صورت‌حساب فعال باشد. درصورت درخواست، مجوز دهید. پس‌از مقداردهی اولیه «ویرایشگر Cloud Shell»، ممکن است مدتی طول بکشد تا دکمه Cloud Code - Sign In (کد ابری - ورود به سیستم) ظاهر شود، لطفاً صبور باشید.

4e372d87c51afa30.png

در مرحله بعد، محیط پایتون خود را آماده می‌کنیم

راه‌اندازی محیط

آماده کردن محیط مجازی Python

مرحله بعدی آماده‌سازی محیط توسعه است. در این codelab از Python 3.12 استفاده خواهیم کرد و از python virtualenv برای ساده کردن نیاز به ایجاد و مدیریت نسخه Python و محیط مجازی استفاده خواهیم کرد

  1. اگر هنوز پایانه را باز نکرده‌اید، با کلیک کردن روی پایانه -> پایانه جدید آن را باز کنید، یا از 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. فرمان زیر را تایپ کنید تا بررسی کنید آیا همه وابستگی‌های کتابخانه‌های پایتون نصب شده‌اند یا نه
pip list

راه‌اندازی فایل‌های پیکربندی

اکنون باید فایل‌های پیکربندی را برای این پروژه راه‌اندازی کنیم. از فایل‌های پیکربندی برای ذخیره کردن متغیرها و اطلاعات اعتباری حساب سرویس استفاده می‌شود.

  1. اولین گام ایجاد حساب سرویس است. حساب سرویس را در جستجو تایپ کنید و سپس روی حساب سرویس کلیک کنید. 18c210d5d1e2a666.png
  2. روی + ایجاد حساب سرویس کلیک کنید. نام حساب «خدمات ورودی» را وارد کنید، سپس روی «ایجاد و ادامه» کلیک کنید. 67cad62d367e236a.png
  3. در مجوز، نقش «کاربر حساب سرویس» را انتخاب کنید. روی «+ افزودن نقش دیگر» کلیک کنید و نقش IAM را انتخاب کنید: «سرپرست BigQuery»، «سرپرست Cloud Run»، «فراخواننده Cloud Run»، و «عامل سرویس Vertex AI»، سپس روی «انجام شد» کلیک کنید 6givcjd8pof60.png
  4. روی ایمیل حساب خدمات کلیک کنید، روی کلید برگه کلیک کنید، روی افزودن کلید → ایجاد کلید جدید کلیک کنید. 50989af3bb9e1538.png
  5. ‫json را انتخاب کنید و سپس روی «ایجاد» کلیک کنید. فایل حساب سرویس را برای مرحله بعدی در محلی ذخیره کنید a4a119672da532da.png
  6. پوشه‌ای به‌نام .streamlit با پیکربندی زیر بسازید. روی موشواره کلیک راست کنید، روی «پوشه جدید» کلیک کنید و نام پوشه را تایپ کنید .streamlit
  1. در پوشه .streamlit کلیک راست کنید، سپس روی «فایل جدید» کلیک کنید و مقدار زیر را وارد کنید. سپس آن را به‌عنوان 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 کلیک کنید

۴. ساختن برنامه‌های «برنامه‌ریز رژیم غذایی عامل»

میانای وب ساده‌ای با ۴ ورودی می‌سازیم که به این شکل است

43b20db2d5f94f38.png

وزن، قد، سن، و جنسیت را براساس نمایه‌تان تغییر دهید، سپس روی «تولید کردن» کلیک کنید. این آموزش مدل LLM Gemini Pro 2.5 را در کتابخانه Vertex AI فراخوانی می‌کند و نتایج تولیدشده را در BigQuery ذخیره می‌کند.

کد به ۶ بخش تقسیم می‌شود تا خیلی طولانی نباشد.

تابع 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

ایجاد برنامه‌های اصلی عامل برنامه‌ریز رژیم غذایی - save_to_bq

در این بخش، تابعی به‌نام save_to_bq با ۳ پارامتر ورودی ایجاد خواهیم کرد : 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

ایجاد برنامه‌های اصلی برنامه‌ریز رژیم غذایی نماینده - اصلی

در این بخش، تابعی به‌نام main بدون پارامتر ورودی ایجاد خواهیم کرد. این تابع بیشتر با دستورگان واسط کاربر streamlit، نمایش نتیجه تولیدشده، نمایش نتیجه تولیدشده تاریخی از جدول bigquery، و بارگیری داده‌ها در فایل نشانه‌گذاری سروکار دارد.

کد را با کد زیر که بعداز کد قبلی در 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 ذخیره کنید.

۵. استفاده از ساخت ابری برای استقرار برنامه‌ها در 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 تبدیل شوند، به ثبت مصنوعات ارسال شوند، و در Cloud Run مستقر شوند، بیایید آن را مستقر کنیم. به «پایانه Cloud Shell» بروید و مطمئن شوید پروژه فعلی روی پروژه فعال شما پیکربندی شده است. اگر پیکربندی نشده است، از دستور gcloud configure برای تنظیم شناسه پروژه استفاده کنید:

gcloud config set project [PROJECT_ID]

سپس، فرمان زیر را اجرا کنید تا برنامه‌ها را بسازید و به تصاویر docker تبدیل کنید، آن را به ثبت مصنوعات ارسال کنید، و در Cloud Run مستقر کنید

gcloud builds submit --config cloudbuild.yaml

این دستور براساس Dockerfile که قبلاً ارائه کرده‌ایم، محتوی Docker را می‌سازد و آن را به Artifact Registry ارسال می‌کند. پس‌از آن، تصویر ساخته‌شده را در Cloud Run مستقر خواهیم کرد. کل این فرایند در cloudbuild.yaml مرحله تعریف شده است.

توجه داشته باشید که در اینجا دسترسی غیرتأییدشده را مجاز می‌کنیم زیرا این یک برنامه نمایشی است. توصیه می‌شود از اصالت‌سنجی مناسب برای برنامه‌های سازمانی و تولید استفاده کنید.

پس‌از تکمیل استقرار، می‌توانیم آن را در صفحه Cloud Run بررسی کنیم، Cloud Run را در نوار جستجوی بالای کنسول ابری جستجو کنیم و روی محصول Cloud Run کلیک کنیم

3c460765656fc072.png

پس‌از آن می‌توانید سرویس مستقرشده را که در صفحه «سرویس Cloud Run» فهرست شده است بازرسی کنید، روی سرویس کلیک کنید تا بتوانیم نشانی وب سرویس را دریافت کنیم

93dc975d3caeab0e.png

نشانی وب سرویس در نوار بالا خواهد بود

9325464321c106f8.pngمی‌توانید از پنجره «ناشناس» یا دستگاه همراهتان از برنامه استفاده کنید. باید ازقبل زنده باشد.

‫۶. مرتب‌سازی

برای جلوگیری از کسر هزینه از حساب Google Cloud خود برای منابع استفاده‌شده در این کدآزمایی، این مراحل را دنبال کنید:

  1. در کنسول Google Cloud، به صفحه مدیریت منابع بروید.
  2. در فهرست پروژه، پروژه‌ای را که می‌خواهید حذف کنید انتخاب کنید، و سپس روی حذف کلیک کنید.
  3. در چارگوش گفتگو، شناسه پروژه را تایپ کنید، و سپس روی خاموش کردن کلیک کنید تا پروژه حذف شود.
  4. یا می‌توانید به Cloud Run در کنسول بروید، سرویسی را که به‌تازگی مستقر کرده‌اید انتخاب کنید و آن را حذف کنید.