1. مقدمة
في هذا الدرس التطبيقي حول الترميز، ستنشئ تطبيقًا يستخدم البحث المتّجه لاقتراح وضعيات يوغا.
خلال هذا الدرس التطبيقي حول الترميز، ستتّبع نهجًا خطوة بخطوة على النحو التالي:
- استخدام مجموعة بيانات حالية من Hugging Face تتضمّن وضعيات اليوغا (بتنسيق JSON)
- حسِّن مجموعة البيانات بإضافة وصف حقل آخر يستخدم Gemini لإنشاء أوصاف لكل وضعية.
- استخدِم Langchain لإنشاء مستند، واستخدِم عملية الدمج مع Firestore Langchain لإنشاء المجموعة والتضمينات في Firestore.
- أنشئ فهرسًا مركّبًا في Firestore للسماح بالبحث المتّجهي.
- استخدِم "البحث المتّجه" في تطبيق Flask يجمع كل شيء معًا كما هو موضّح أدناه:

المهام التي ستنفذها
- تصميم تطبيق ويب وإنشاؤه ونشره يستخدم "البحث المتّجه" لاقتراح وضعيات يوغا
ما ستتعلمه
- كيفية استخدام Gemini لإنشاء محتوى نصي، وفي سياق هذا الدرس التطبيقي حول الترميز، إنشاء أوصاف لوضعيات اليوغا
- كيفية استخدام Langchain Document Loader for Firestore لتحميل السجلات من مجموعة بيانات محسّنة من Hugging Face إلى Firestore مع Vector Embeddings
- كيفية استخدام Langchain Vector Store for Firestore للبحث عن البيانات استنادًا إلى طلب بلغة طبيعية
- كيفية استخدام واجهة برمجة التطبيقات Google Cloud Text to Speech API لإنشاء محتوى صوتي
المتطلبات
- متصفّح الويب Chrome
- حساب Gmail
- مشروع على السحابة الإلكترونية تم تفعيل الفوترة فيه
يستخدم هذا الدرس التطبيقي حول الترميز، المصمَّم للمطوّرين من جميع المستويات (بما في ذلك المبتدئين)، لغة Python في تطبيق المثال. ومع ذلك، لا يُشترط معرفة لغة Python لفهم المفاهيم المقدَّمة.
2. قبل البدء
إنشاء مشروع
- في Google Cloud Console، في صفحة اختيار المشروع، اختَر أو أنشِئ مشروعًا على Google Cloud.
- تأكَّد من تفعيل الفوترة لمشروعك على السحابة الإلكترونية. تعرَّف على كيفية التحقّق مما إذا كانت الفوترة مفعَّلة في مشروع .
- ستستخدم Cloud Shell، وهي بيئة سطر أوامر تعمل في Google Cloud ومحمّلة مسبقًا بأداة bq. انقر على "تفعيل Cloud Shell" في أعلى "وحدة تحكّم Google Cloud".

- بعد الاتصال بـ Cloud Shell، يمكنك التأكّد من أنّك قد تم التحقّق من هويتك وأنّه تم ضبط المشروع على رقم تعريف مشروعك باستخدام الأمر التالي:
gcloud auth list
- نفِّذ الأمر التالي في Cloud Shell للتأكّد من أنّ أمر gcloud يعرف مشروعك.
gcloud config list project
- إذا لم يتم ضبط مشروعك، استخدِم الأمر التالي لضبطه:
gcloud config set project <YOUR_PROJECT_ID>
- فعِّل واجهات برمجة التطبيقات المطلوبة من خلال الأمر الموضّح أدناه. قد تستغرق هذه العملية بضع دقائق، لذا يُرجى الانتظار.
gcloud services enable firestore.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
cloudfunctions.googleapis.com \
aiplatform.googleapis.com \
texttospeech.googleapis.com
عند تنفيذ الأمر بنجاح، من المفترض أن تظهر لك رسالة مشابهة للرسالة الموضّحة أدناه:
Operation "operations/..." finished successfully.
يمكنك بدلاً من استخدام أمر gcloud، البحث عن كل منتج في وحدة التحكّم أو استخدام هذا الرابط.
في حال عدم توفّر أي واجهة برمجة تطبيقات، يمكنك تفعيلها في أي وقت أثناء عملية التنفيذ.
راجِع المستندات لمعرفة أوامر gcloud وطريقة استخدامها.
استنساخ المستودع وضبط إعدادات البيئة
الخطوة التالية هي استنساخ مستودع الرموز النموذجية الذي سنشير إليه في بقية الدرس العملي. بافتراض أنّك في Cloud Shell، أدخِل الأمر التالي من الدليل الرئيسي:
git clone https://github.com/rominirani/yoga-poses-recommender-python
لتشغيل المحرِّر، انقر على "فتح المحرِّر" في شريط الأدوات في نافذة Cloud Shell. انقر على شريط القوائم في أعلى يمين الصفحة واختَر "ملف" (File) → "فتح مجلد" (Open Folder) كما هو موضّح أدناه:

اختَر مجلد yoga-poses-recommender-python، وسيتم فتح المجلد مع الملفات التالية كما هو موضّح أدناه:

علينا الآن إعداد متغيرات البيئة التي سنستخدمها. انقر على ملف config.template.yaml، وسيظهر لك المحتوى كما هو موضّح أدناه:
project_id: your-project-id
location: us-central1
gemini_model_name: gemini-1.5-flash-002
embedding_model_name: text-embedding-004
image_generation_model_name: imagen-3.0-fast-generate-002
database: (default)
collection: poses
test_collection: test-poses
top_k: "3"
يُرجى تعديل قيم project_id وlocation وفقًا لما اخترته أثناء إنشاء مشروع Google Cloud ومنطقة قاعدة بيانات Firestore. من المفترض أن تكون قيم location هي نفسها لكل من مشروع Google Cloud وقاعدة بيانات Firestore، مثل us-central1.
لأغراض هذا الدرس التطبيقي حول الترميز، سنستخدم القيم التي تم ضبطها مسبقًا (باستثناء project_id وlocation بالطبع، اللذين عليك ضبطهما وفقًا لإعداداتك).
يُرجى حفظ هذا الملف باسم config.yaml في المجلد نفسه الذي تم حفظ ملف config.template.yaml فيه.
الخطوة الأخيرة الآن هي إنشاء بيئة Python سنستخدمها محليًا مع إعداد جميع تبعيات Python لنا. اطّلِع على الملف pyproject.toml الذي يحتوي على التفاصيل نفسها، ويتم عرض محتواه أدناه:
dependencies = [
"datasets>=3.2.0",
"flask>=3.1.0",
"google-cloud-aiplatform>=1.78.0",
"google-cloud-texttospeech>=2.24.0",
"langchain-community>=0.3.15",
"langchain-core>=0.3.31",
"langchain-google-community>=2.0.4",
"langchain-google-firestore>=0.5.0",
"langchain-google-vertexai>=2.0.7",
"pydantic-settings>=2.7.1",
"pyyaml>=6.0.2",
"tenacity>=9.0.0",
]
تمّت بالفعل إضافة إصدارات محددة من هذه التبعيات في requirements.txt.. باختصار، علينا إنشاء بيئة Python افتراضية تتضمّن تبعيات حزمة Python في requirements.txt ليتم تثبيتها في البيئة الافتراضية. لإجراء ذلك، انتقِل إلى Command Palette (Ctrl+Shift+P) في بيئة تطوير Cloud Shell المتكاملة واكتب Python: Create Environment. اتّبِع الخطوات القليلة التالية لاختيار ملف Virtual Environment(venv) وPython 3.x interpreter وملف requirements.txt.
بعد إنشاء البيئة، علينا تفعيلها باستخدام الأمر التالي
source .venv/bin/activate
من المفترض أن يظهر (.venv) في وحدة التحكّم. مثلاً -> (.venv) yourusername@cloudshell:
رائع! نحن الآن على استعداد للانتقال إلى مهمة إعداد قاعدة بيانات Firestore.
3- إعداد Firestore
Cloud Firestore هي قاعدة بيانات مستنِدة إلى مستندات وبدون خادم تتم إدارتها بالكامل، وسنستخدمها كخادم خلفي لبيانات تطبيقنا. يتم تنظيم البيانات في Cloud Firestore في مجموعات من المستندات.
تهيئة قاعدة بيانات Firestore
انتقِل إلى صفحة Firestore في Cloud Console.
إذا لم يسبق لك إعداد قاعدة بيانات Firestore في المشروع، أنشئ قاعدة بيانات default من خلال النقر على Create Database. أثناء إنشاء قاعدة البيانات، استخدِم القيم التالية:
- وضع Firestore:
Native. - اختَر نوع الموقع الجغرافي
Regionواختَر الموقع الجغرافيus-central1للمنطقة. - بالنسبة إلى "قواعد الأمان"، اختَر
Test rules. - إنشاء قاعدة البيانات

في القسم التالي، سنضع الأساس لإنشاء مجموعة باسم poses في قاعدة بيانات Firestore التلقائية. ستحتوي هذه المجموعة على بيانات نموذجية (مستندات) أو معلومات عن وضعيات اليوغا، وسنستخدمها بعد ذلك في تطبيقنا.
بهذا نكون قد انتهينا من قسم إعداد قاعدة بيانات Firestore.
4. إعداد مجموعة بيانات وضعيات اليوغا
مهمتنا الأولى هي إعداد مجموعة بيانات "وضعيات اليوغا" التي سنستخدمها في التطبيق. سنبدأ بمجموعة بيانات حالية من Hugging Face ثم نحسّنها بمعلومات إضافية.
يمكنك الاطّلاع على مجموعة بيانات Hugging Face لوضعيات اليوغا. يُرجى العِلم أنّه على الرغم من أنّ هذا الدرس التطبيقي حول الترميز يستخدِم إحدى مجموعات البيانات، يمكنك في الواقع استخدام أي مجموعة بيانات أخرى واتّباع الأساليب نفسها الموضّحة لتحسين مجموعة البيانات.

إذا انتقلنا إلى قسم Files and versions، يمكننا الحصول على ملف بيانات JSON لجميع الوضعيات.

لقد نزّلنا الملف yoga_poses.json وقدّمناه لك. اسم هذا الملف هو yoga_poses_alldata.json وهو موجود في المجلد /data.
انتقِل إلى ملف data/yoga_poses.json في Cloud Shell Editor وألقِ نظرة على قائمة عناصر JSON، حيث يمثّل كل عنصر JSON وضعية يوغا. لدينا إجمالي 3 سجلّات، ويظهر سجلّ نموذجي أدناه:
{
"name": "Big Toe Pose",
"sanskrit_name": "Padangusthasana",
"photo_url": "https://pocketyoga.com/assets/images/full/ForwardBendBigToe.png",
"expertise_level": "Beginner",
"pose_type": ["Standing", "Forward Bend"]
}
والآن، حانت الفرصة لنقدّم لك Gemini وكيف يمكننا استخدام النموذج التلقائي نفسه لإنشاء حقل description له.
في "محرِّر Cloud Shell"، انتقِل إلى الملف generate-descriptions.py. يظهر محتوى هذا الملف أدناه:
import json
import time
import logging
import vertexai
from langchain_google_vertexai import VertexAI
from tenacity import retry, stop_after_attempt, wait_exponential
from settings import get_settings
settings = get_settings()
logging.basicConfig(
level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
)
# Initialize Vertex AI SDK
vertexai.init(project=settings.project_id, location=settings.location)
logging.info("Done Initializing Vertex AI SDK")
@retry(
stop=stop_after_attempt(5),
wait=wait_exponential(multiplier=1, min=4, max=10),
)
def generate_description(pose_name, sanskrit_name, expertise_level, pose_types):
"""Generates a description for a yoga pose using the Gemini API."""
prompt = f"""
Generate a concise description (max 50 words) for the yoga pose: {pose_name}
Also known as: {sanskrit_name}
Expertise Level: {expertise_level}
Pose Type: {", ".join(pose_types)}
Include key benefits and any important alignment cues.
"""
try:
model = VertexAI(model_name=settings.gemini_model_name, verbose=True)
response = model.invoke(prompt)
return response
except Exception as e:
logging.info(f"Error generating description for {pose_name}: {e}")
return ""
def add_descriptions_to_json(input_file, output_file):
"""Loads JSON data, adds descriptions, and saves the updated data."""
with open(input_file, "r") as f:
yoga_poses = json.load(f)
total_poses = len(yoga_poses)
processed_count = 0
for pose in yoga_poses:
if pose["name"] != " Pose":
start_time = time.time() # Record start time
pose["description"] = generate_description(
pose["name"],
pose["sanskrit_name"],
pose["expertise_level"],
pose["pose_type"],
)
end_time = time.time() # Record end time
processed_count += 1
end_time = time.time() # Record end time
time_taken = end_time - start_time
logging.info(
f"Processed: {processed_count}/{total_poses} - {pose['name']} ({time_taken:.2f} seconds)"
)
else:
pose["description"] = ""
processed_count += 1
logging.info(
f"Processed: {processed_count}/{total_poses} - {pose['name']} ({time_taken:.2f} seconds)"
)
# Adding a delay to avoid rate limit
time.sleep(30)
with open(output_file, "w") as f:
json.dump(yoga_poses, f, indent=2)
def main():
# File paths
input_file = "./data/yoga_poses.json"
output_file = "./data/yoga_poses_with_descriptions.json"
# Add descriptions and save the updated JSON
add_descriptions_to_json(input_file, output_file)
if __name__ == "__main__":
main()
سيضيف هذا التطبيق حقل description جديدًا إلى كل سجلّ JSON لوضعية اليوغا. سيتم الحصول على الوصف من خلال طلب إلى نموذج Gemini، حيث سنقدّم له الطلب اللازم. تتم إضافة الحقل إلى ملف JSON وكتابة الملف الجديد في ملف data/yoga_poses_with_descriptions.json.
في ما يلي الخطوات الرئيسية:
- في الدالة
main()، ستجد أنّها تستدعي الدالةadd_descriptions_to_jsonوتوفّر ملف الإدخال وملف الإخراج المتوقّع. - تنفّذ الدالة
add_descriptions_to_jsonما يلي لكل سجلّ JSON، أي معلومات منشور Yoga: - يستخرج هذا النص
pose_nameوsanskrit_nameوexpertise_levelوpose_types. - يتم استدعاء الدالة generate_description التي تنشئ طلبًا ثم تستدعي فئة النموذج Langchain VertexAI للحصول على نص الرد.
- يُضاف نص الاستجابة هذا بعد ذلك إلى عنصر JSON.
- بعد ذلك، تتم كتابة قائمة JSON المعدَّلة للعناصر في ملف الوجهة.
لننفّذ هذا التطبيق. افتح نافذة محطة طرفية جديدة (Ctrl+Shift+C) وأدخِل الأمر التالي:
python generate-descriptions.py
إذا طُلب منك تقديم أي تفويض، يُرجى المتابعة وتقديم التفويض.
ستلاحظ أنّ التطبيق يبدأ في التنفيذ. لقد أضفنا تأخيرًا لمدة 30 ثانية بين السجلات لتجنُّب أي حصص للحدّ الأقصى لمعدّل النقل قد تكون متوفرة في حسابات Google Cloud الجديدة، لذا يُرجى الانتظار.
في ما يلي مثال على عملية تنفيذ قيد التقدّم:

بعد تحسين جميع السجلات الثلاثة باستخدام طلب Gemini، سيتم إنشاء ملف data/yoga_poses_with_description.json. يمكنك الاطّلاع على ذلك.
أصبحنا الآن جاهزين لملف البيانات، والخطوة التالية هي فهم كيفية تعبئة قاعدة بيانات Firestore به، بالإضافة إلى إنشاء التضمينات.
5- استيراد البيانات إلى Firestore وإنشاء تضمينات متّجهة
لدينا ملف data/yoga_poses_with_description.json، وعلينا الآن ملء قاعدة بيانات Firestore به، والأهم من ذلك، إنشاء عمليات التضمين المتجهة لكل سجلّ. ستكون "التضمينات المتجهة" مفيدة لاحقًا عندما نحتاج إلى إجراء بحث عن التشابه باستخدام طلب بحث المستخدم المقدَّم بلغة طبيعية.
سنستخدم مكوّنات Langchain Firestore لتنفيذ العملية المذكورة أعلاه.
في ما يلي الخطوات التي يجب اتّباعها لإجراء ذلك:
- سنحوّل قائمة كائنات JSON إلى قائمة كائنات Langchain Document. سيتضمّن كل مستند سمتَين:
page_contentوmetadata. سيحتوي عنصر البيانات الوصفية على عنصر JSON الكامل الذي يتضمّن سمات مثلnameوdescriptionوsanskrit_nameوما إلى ذلك. وستكونpage_contentعبارة عن نص سلسلة سيكون عبارة عن دمج لبعض الحقول. - بعد الحصول على قائمة بعناصر
Document، سنستخدم فئةFirestoreVectorStoreLangchain، وتحديدًا طريقةfrom_documentsمع قائمة المستندات هذه واسم المجموعة (نستخدم المتغيّرTEST_COLLECTIONالذي يشير إلىtest-poses) وفئة Vertex AI Embedding وتفاصيل الاتصال بـ Firestore (اسمPROJECT_IDوDATABASE). سيؤدي ذلك إلى إنشاء المجموعة وإنشاء حقلembeddingلكل سمة.
في ما يلي رمز import-data.py (تم اقتطاع أجزاء من الرمز للاختصار):
...
def create_langchain_documents(poses):
"""Creates a list of Langchain Documents from a list of poses."""
documents = []
for pose in poses:
# Convert the pose to a string representation for page_content
page_content = (
f"name: {pose.get('name', '')}\n"
f"description: {pose.get('description', '')}\n"
f"sanskrit_name: {pose.get('sanskrit_name', '')}\n"
f"expertise_level: {pose.get('expertise_level', 'N/A')}\n"
f"pose_type: {pose.get('pose_type', 'N/A')}\n"
).strip()
# The metadata will be the whole pose
metadata = pose
document = Document(page_content=page_content, metadata=metadata)
documents.append(document)
logging.info(f"Created {len(documents)} Langchain documents.")
return documents
def main():
all_poses = load_yoga_poses_data_from_local_file(
"./data/yoga_poses_with_descriptions.json"
)
documents = create_langchain_documents(all_poses)
logging.info(
f"Successfully created langchain documents. Total documents: {len(documents)}"
)
embedding = VertexAIEmbeddings(
model_name=settings.embedding_model_name,
project=settings.project_id,
location=settings.location,
)
client = firestore.Client(project=settings.project_id, database=settings.database)
vector_store = FirestoreVectorStore.from_documents(
client=client,
collection=settings.test_collection,
documents=documents,
embedding=embedding,
)
logging.info("Added documents to the vector store.")
if __name__ == "__main__":
main()
لننفّذ هذا التطبيق. افتح نافذة محطة طرفية جديدة (Ctrl+Shift+C) وأدخِل الأمر التالي:
python import-data.py
إذا سارت الأمور على ما يرام، من المفترض أن تظهر لك رسالة مشابهة للرسالة أدناه:
2025-01-21 14:50:06,479 - INFO - Added documents to the vector store.
للتأكّد من إدراج السجلات بنجاح وإنشاء عمليات التضمين، انتقِل إلى صفحة Firestore في Cloud Console.

انقر على قاعدة البيانات (الافتراضية)، من المفترض أن يؤدي ذلك إلى عرض المجموعة test-poses ومستندات متعددة ضمن هذه المجموعة. كل مستند هو وضعية يوغا واحدة.

انقر على أيّ من المستندات للتحقّق من الحقول. بالإضافة إلى الحقول التي استوردناها، ستجد أيضًا الحقل embedding، وهو حقل متّجه تم إنشاؤه تلقائيًا لك من خلال فئة Langchain VertexAIEmbeddings التي استخدمناها، والتي قدّمنا فيها نموذج text-embedding-004 Vertex AI Embedding.

بعد تحميل السجلات إلى قاعدة بيانات Firestore مع تضمين عمليات التضمين، يمكننا الانتقال إلى الخطوة التالية والاطّلاع على كيفية إجراء "بحث عن التشابه بين المتجهات" في Firestore.
6. استيراد وضعيات اليوغا الكاملة إلى مجموعة "قاعدة بيانات Firestore"
سننشئ الآن المجموعة poses، وهي قائمة كاملة تضم 160 وضعية يوغا، وقد أنشأنا ملف استيراد قاعدة بيانات يمكنك استيراده مباشرةً. يتم ذلك لتوفير الوقت في المختبر. إنّ عملية إنشاء قاعدة البيانات التي تحتوي على الوصف والتضمينات هي نفسها التي رأيناها في القسم السابق.
استورِد قاعدة البيانات باتّباع الخطوات الموضّحة أدناه:
- أنشئ حزمة في مشروعك باستخدام الأمر
gsutilالموضّح أدناه. استبدِل المتغيّر<PROJECT_ID>في الأمر أدناه برقم تعريف مشروع Google Cloud.
gsutil mb -l us-central1 gs://<PROJECT_ID>-my-bucket
- بعد إنشاء الحزمة، علينا نسخ عملية تصدير قاعدة البيانات التي أعددناها إلى هذه الحزمة، قبل أن نتمكّن من استيرادها إلى قاعدة بيانات Firebase. استخدِم الأمر الموضّح أدناه:
gsutil cp -r gs://yoga-database-firestore-export-bucket/2025-01-27T05:11:02_62615 gs://<PROJECT_ID>-my-bucket
بعد أن توفّرت لدينا البيانات المطلوب استيرادها، يمكننا الانتقال إلى الخطوة الأخيرة من عملية استيراد البيانات إلى قاعدة بيانات Firebase (default) التي أنشأناها.
- استخدِم أمر gcloud الموضّح أدناه:
gcloud firestore import gs://<PROJECT_ID>-my-bucket/2025-01-27T05:11:02_62615
سيستغرق الاستيراد بضع ثوانٍ، وبعد اكتماله، يمكنك التحقّق من صحة قاعدة بيانات Firestore والمجموعة من خلال الانتقال إلى https://console.cloud.google.com/firestore/databases، واختيار قاعدة بيانات default والمجموعة poses كما هو موضّح أدناه:

بهذا نكون قد أكملنا إنشاء مجموعة Firestore التي سنستخدمها في تطبيقنا.
7. إجراء بحث عن التشابه بين المتجهات في Firestore
لإجراء بحث عن التشابه بين المتجهات، سنستقبل طلب البحث من المستخدم. يمكن أن يكون مثال هذا الطلب هو "Suggest me some exercises to relieve back pain".
اطّلِع على الملف search-data.py. الدالة الرئيسية التي يجب الاطّلاع عليها هي دالة البحث، كما هو موضّح أدناه. بشكل عام، ينشئ هذا الإجراء فئة تضمين سيتم استخدامها لإنشاء التضمين الخاص بطلب بحث المستخدم. ثم يستخدم الفئة FirestoreVectorStore لاستدعاء الدالة similarity_search.
def search(query: str):
"""Executes Firestore Vector Similarity Search"""
embedding = VertexAIEmbeddings(
model_name=settings.embedding_model_name,
project=settings.project_id,
location=settings.location,
)
client = firestore.Client(project=settings.project_id, database=settings.database)
vector_store = FirestoreVectorStore(
client=client, collection=settings.collection, embedding_service=embedding
)
logging.info(f"Now executing query: {query}")
results: list[Document] = vector_store.similarity_search(
query=query, k=int(settings.top_k), include_metadata=True
)
for result in results:
print(result.page_content)
قبل تشغيل هذا الرمز مع بعض الأمثلة على طلبات البحث، عليك أولاً إنشاء فهرس مركّب في Firestore، وهو أمر ضروري لنجاح طلبات البحث. إذا شغّلت التطبيق بدون إنشاء الفهرس، سيظهر خطأ يشير إلى ضرورة إنشاء الفهرس أولاً مع الأمر اللازم لإنشائه.
يظهر أدناه الأمر gcloud لإنشاء الفهرس المركّب:
gcloud firestore indexes composite create --project=<YOUR_PROJECT_ID> --collection-group=poses --query-scope=COLLECTION --field-config=vector-config='{"dimension":"768","flat": "{}"}',field-path=embedding
سيستغرق اكتمال الفهرس بضع دقائق لأنّه يتضمّن أكثر من 150 سجلاً في قاعدة البيانات. بعد اكتمال العملية، يمكنك الاطّلاع على الفهرس باستخدام الأمر الموضّح أدناه:
gcloud firestore indexes composite list
من المفترض أن يظهر الفهرس الذي أنشأته للتو في القائمة.
جرِّب الأمر التالي الآن:
python search-data.py --prompt "Recommend me some exercises for back pain relief"
من المفترض أن تظهر لك بعض الاقتراحات. في ما يلي نموذج لعملية التنفيذ:
2025-01-21 15:48:51,282 - INFO - Now executing query: Recommend me some exercises for back pain relief
name: Supine Spinal Twist Pose
description: A gentle supine twist (Supta Matsyendrasana), great for beginners. Releases spinal tension, improves digestion, and calms the nervous system. Keep shoulders flat on the floor and lengthen the spine.
sanskrit_name: Supta Matsyendrasana
expertise_level: Beginner
pose_type: ['Supine', 'Twist']
name: Cow Pose
description: Cow Pose (Bitilasana) is a gentle backbend, stretching the chest, shoulders, and abdomen. Maintain a neutral spine, lengthen the tailbone, and avoid hyperextension. Benefits include improved posture and stress relief.
sanskrit_name: Bitilasana
expertise_level: Beginner
pose_type: ['Arm Leg Support', 'Back Bend']
name: Locust I Pose
description: Locust Pose I (Shalabhasana A) strengthens the back, glutes, and shoulders. Lie prone, lift chest and legs simultaneously, engaging back muscles. Keep hips grounded and gaze slightly forward.
sanskrit_name: Shalabhasana A
expertise_level: Intermediate
pose_type: ['Prone', 'Back Bend']
بعد إعداد هذه الميزة، نكون قد فهمنا كيفية استخدام "قاعدة بيانات المتجهات" في Firestore لتحميل السجلات وإنشاء التضمينات وإجراء "بحث عن التشابه في المتجهات". يمكننا الآن إنشاء تطبيق ويب يدمج البحث المتّجه في واجهة أمامية للويب.
8. تطبيق الويب
يتوفّر تطبيق الويب Python Flask في الملف main.py، ويتوفّر ملف HTML للواجهة الأمامية في templates/index.html.
ننصحك بإلقاء نظرة على كلا الملفين. ابدأ أولاً بملف main.py الذي يحتوي على معالج /search، والذي يتلقّى الطلب الذي تم تمريره من ملف index.html HTML للواجهة الأمامية. يؤدي ذلك إلى استدعاء طريقة البحث التي تجري عملية البحث عن التشابه بين المتجهات التي تناولناها في القسم السابق.
بعد ذلك، يتم إرسال الردّ إلى index.html مع قائمة الاقتراحات. تعرض index.html الاقتراحات بعد ذلك على شكل بطاقات مختلفة.
تشغيل التطبيق محليًا
افتح نافذة محطة طرفية جديدة (Ctrl+Shift+C) أو أي نافذة محطة طرفية حالية وأدخِل الأمر التالي:
python main.py
في ما يلي نموذج للتنفيذ:
* Serving Flask app 'main'
* Debug mode: on
2025-01-21 16:02:37,473 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:8080
* Running on http://10.88.0.4:8080
2025-01-21 16:02:37,473 - INFO - Press CTRL+C to quit
2025-01-21 16:02:37,474 - INFO - * Restarting with stat
2025-01-21 16:02:41,462 - WARNING - * Debugger is active!
2025-01-21 16:02:41,484 - INFO - * Debugger PIN: 440-653-555
بعد تشغيل التطبيق، انتقِل إلى عنوان URL الخاص بالصفحة الرئيسية للتطبيق من خلال النقر على زر "معاينة الويب" الموضّح أدناه:

يجب أن يظهر لك الملف index.html الذي تم عرضه كما هو موضّح أدناه:

قدِّم نموذجًا لطلب البحث (مثال : Provide me some exercises for back pain relief) وانقر على الزر Search. من المفترض أن يؤدي ذلك إلى استرداد بعض الاقتراحات من قاعدة البيانات. سيظهر لك أيضًا زر Play Audio، والذي سينشئ بثًا صوتيًا استنادًا إلى الوصف، ويمكنك الاستماع إليه مباشرةً.

9- (اختياري) النشر على Google Cloud Run
ستكون خطوتنا الأخيرة هي نشر هذا التطبيق على Google Cloud Run. يظهر أمر النشر أدناه، لذا تأكَّد قبل نشره من استبدال قيم المتغير (<<YOUR_PROJECT_ID>>) بالقيم الخاصة بمشروعك. هذه هي القيم التي ستتمكّن من استردادها من ملف config.yaml.
gcloud run deploy yogaposes --source . \
--port=8080 \
--allow-unauthenticated \
--region=us-central1 \
--platform=managed \
--project=<<YOUR_PROJECT_ID>> \
--env-vars-file=config.yaml
نفِّذ الأمر أعلاه من المجلد الجذر للتطبيق. قد يُطلب منك أيضًا تفعيل واجهات Google Cloud APIs، وإقرارك بالموافقة على أذونات مختلفة، لذا يُرجى إجراء ذلك.
ستستغرق عملية النشر حوالي 5 إلى 7 دقائق، لذا يُرجى الانتظار.

بعد نشر التطبيق بنجاح، سيوفّر الناتج عن عملية النشر عنوان URL لخدمة Cloud Run. سيكون بالتنسيق التالي:
Service URL: https://yogaposes-<<UNIQUEID>.us-central1.run.app
انتقِل إلى عنوان URL العام هذا، ومن المفترض أن ترى تطبيق الويب نفسه الذي تم نشره وتشغيله بنجاح.

يمكنك أيضًا الانتقال إلى Cloud Run من وحدة تحكّم Google Cloud وستظهر لك قائمة الخدمات في Cloud Run. يجب أن تكون خدمة yogaposes إحدى الخدمات (إن لم تكن الخدمة الوحيدة) المُدرَجة هناك.

يمكنك الاطّلاع على تفاصيل الخدمة، مثل عنوان URL والإعدادات والسجلات وغير ذلك، من خلال النقر على اسم الخدمة المحدّد (yogaposes في حالتنا).

بهذا نكون قد أكملنا عملية تطوير تطبيق الويب الخاص باقتراح وضعيات اليوغا ونشره على Cloud Run.
10. تهانينا
تهانينا، لقد أنشأت بنجاح تطبيقًا يحمّل مجموعة بيانات إلى Firestore، وينشئ التضمينات، ويجري عملية "البحث عن التشابه المتّجهي" استنادًا إلى طلبات المستخدمين.