با Gemini Code Assist، گردش کار توسعه خود را افزایش دهید

۱. مقدمه

e5b98fd4e417c877.png

در این آزمایشگاه کد، خواهید دید که چگونه Gemini Code Assist می‌تواند در مراحل کلیدی چرخه حیات توسعه نرم‌افزار (SDLC) مانند طراحی، ساخت، آزمایش و استقرار، از شما پشتیبانی کند. ما یک برنامه کامل را طراحی و توسعه داده و آن را در Google Cloud مستقر خواهیم کرد.

ما در حال ساخت یک API و برنامه برای جستجو در جلسات یک رویداد فنی خواهیم بود. هر جلسه دارای عنوان، خلاصه، مدت زمان، دسته بندی ها و یک یا چند سخنران خواهد بود.

کاری که انجام خواهید داد

  • طراحی، ساخت، تست و استقرار یک برنامه وب بر اساس مشخصات OpenAPI از ابتدا

آنچه یاد خواهید گرفت

  • نحوه استفاده از Gemini Code Assist برای تولید مشخصات OpenAPI
  • نحوه استفاده از ویژگی‌های تولید کد Gemini Code Assist برای توسعه یک برنامه پایتون Flask برای مشخصات OpenAPI
  • نحوه استفاده از Gemini Code Assist برای تولید یک رابط کاربری وب برای برنامه پایتون Flask
  • نحوه استفاده از Gemini Code Assist برای دریافت راهنمایی در مورد نحوه استقرار برنامه در Google Cloud Run
  • هنگام ساخت و آزمایش برنامه، از ویژگی‌های Gemini Code Assist مانند توضیح کد، تولید موارد آزمایشی استفاده کنید.

آنچه نیاز دارید

  • مرورگر وب کروم
  • یک حساب جیمیل
  • یک پروژه ابری با قابلیت پرداخت صورتحساب
  • Gemini Code Assist برای پروژه ابری شما فعال شده است

این آزمایشگاه برای توسعه‌دهندگان در تمام سطوح، از جمله مبتدیان، در نظر گرفته شده است. اگرچه برنامه نمونه به زبان پایتون است، اما برای درک آنچه اتفاق می‌افتد نیازی به آشنایی با برنامه‌نویسی پایتون ندارید. تمرکز ما بر آشنایی با قابلیت‌های Gemini Code Assist خواهد بود.

۲. راه‌اندازی دستیار کد جمینی

این بخش شامل تمام مواردی است که برای شروع کار با این آزمایشگاه باید انجام دهید.

فعال کردن دستیار کد Gemini در Cloud Shell IDE

ما برای ادامه‌ی آزمایشگاه کد از Cloud Shell IDE، یک محیط توسعه‌ی کاملاً مدیریت‌شده مبتنی بر Code OSS ، استفاده خواهیم کرد. باید Code Assist را در Cloud Shell IDE فعال و پیکربندی کنیم و مراحل آن در زیر آمده است:

  1. به ide.cloud.google.com مراجعه کنید. ممکن است کمی طول بکشد تا IDE ظاهر شود، بنابراین لطفاً صبور باشید و هرگونه گزینه پیش‌فرض تنظیمات را بپذیرید. در صورتی که دستورالعمل‌هایی در مورد راه‌اندازی IDE مشاهده کردید، لطفاً آنها را با تنظیمات پیش‌فرض تکمیل کنید.
  2. همانطور که نشان داده شده است، روی دکمه Cloud Code - Sign in در نوار وضعیت پایین کلیک کنید. افزونه را طبق دستورالعمل تأیید کنید. اگر عبارت "Cloud Code - بدون پروژه" را در نوار وضعیت مشاهده کردید، آن را انتخاب کنید و سپس پروژه خاص Google Cloud را از لیست پروژه‌هایی که قصد دارید با آنها کار کنید، انتخاب کنید.

6f5ce865fc7a3ef5.png

  1. همانطور که نشان داده شده است، روی دکمه Code Assist در گوشه پایین سمت راست کلیک کنید و برای آخرین بار پروژه صحیح Google Cloud را انتخاب کنید. اگر از شما خواسته شد که Cloud AI Companion API را فعال کنید، لطفاً این کار را انجام دهید و به مرحله بعد بروید.
  2. پس از انتخاب پروژه گوگل کلود خود، مطمئن شوید که می‌توانید آن را در پیام وضعیت Cloud Code در نوار وضعیت مشاهده کنید و همچنین Code Assist را در سمت راست، در نوار وضعیت، مطابق شکل زیر فعال کرده باشید:

709e6c8248ac7d88.png

دستیار کد Gemini آماده استفاده است!

۳. نصب فایراستور

کلود فایراستور یک پایگاه داده سند بدون سرور و کاملاً مدیریت‌شده است که ما به عنوان بک‌اند برای داده‌های برنامه خود از آن استفاده خواهیم کرد. داده‌ها در کلود فایراستور در مجموعه‌ای از اسناد ساختار یافته‌اند.

ما باید مجموعه‌ای به نام sessions در پایگاه داده پیش‌فرض Firestore خود ایجاد کنیم. این مجموعه داده‌های نمونه (اسناد) را که بعداً در برنامه خود استفاده خواهیم کرد، در خود نگه می‌دارد.

ترمینال را از داخل Cloud Shell IDE خود از طریق منوی اصلی، مطابق شکل زیر باز کنید:

f1535e14c9beeec6.png

ما باید مجموعه‌ای به نام sessions ایجاد کنیم. این مجموعه لیستی از اسناد نمونه session را در خود جای می‌دهد. هر سند دارای ویژگی‌های زیر خواهد بود:

  1. عنوان : رشته
  2. دسته‌ها : آرایه‌ای از رشته‌ها
  3. بلندگوها : آرایه‌ای از رشته‌ها
  4. مدت زمان : رشته
  5. خلاصه : رشته

بیایید این مجموعه را با داده‌های نمونه پر کنیم، برای این کار فایلی را که حاوی داده‌های نمونه است در یک سطل در پروژه خود کپی می‌کنیم، از آنجا می‌توانیم مجموعه را از طریق دستور gcloud firestore import وارد کنیم.

مقداردهی اولیه پایگاه داده Firestore

از صفحه Firestore در کنسول Cloud دیدن کنید.

اگر قبلاً در پروژه، پایگاه داده Firestore را مقداردهی اولیه نکرده‌اید، پایگاه داده default را ایجاد کنید. در حین ایجاد پایگاه داده، از مقادیر زیر استفاده کنید:

  • حالت فایراستور: Native
  • مکان: نوع مکان را Region انتخاب کنید و منطقه‌ای را که برای برنامه شما مناسب است انتخاب کنید. این مکان را یادداشت کنید زیرا در مرحله بعدی برای مکان سطل به آن نیاز خواهید داشت.
  • پایگاه داده را ایجاد کنید.

504cabdb99a222a5.png

اکنون با دنبال کردن مراحل زیر، مجموعه sessions را ایجاد خواهیم کرد:

  1. با استفاده از دستور gsutil که در زیر آمده است، یک باکت در پروژه خود ایجاد کنید. متغیر <PROJECT_ID> را در دستور زیر با شناسه پروژه Google Cloud خود جایگزین کنید. <BUCKET_LOCATION> را با نام منطقه‌ای که با منطقه جغرافیایی پایگاه داده پیش‌فرض Firestore شما مطابقت دارد (همانطور که در مرحله قبل ذکر شد) جایگزین کنید، این می‌تواند US-WEST1، EUROPE-WEST1، ASIA-EAST1 باشد:
gsutil mb -l <BUCKET-LOCATION> gs://<PROJECT_ID>-my-bucket
  1. حالا که باکت ایجاد شده است، قبل از اینکه بتوانیم خروجی پایگاه داده را به پایگاه داده Firebase وارد کنیم، باید آن را در این باکت کپی کنیم. از دستور زیر استفاده کنید:
gsutil cp -r gs://sessions-master-database-bucket/2024-03-26T09:28:15_95256  gs://<PROJECT_ID>-my-bucket

حالا که داده‌ها را برای وارد کردن داریم، می‌توانیم به مرحله نهایی وارد کردن داده‌ها به پایگاه داده Firebase ( default ) که ایجاد کرده‌ایم، برویم.

  1. از دستور gcloud که در زیر آمده است استفاده کنید:
gcloud firestore import gs://<PROJECT_ID>-my-bucket/2024-03-26T09:28:15_95256

وارد کردن چند ثانیه طول می‌کشد و پس از آماده شدن، می‌توانید پایگاه داده Firestore و مجموعه آن را با مراجعه به https://console.cloud.google.com/firestore/databases تأیید کنید، پایگاه داده default و مجموعه sessions را مطابق شکل زیر انتخاب کنید:

d3e294d46ba29c5.png

این کار ایجاد مجموعه Firestore را که در برنامه خود استفاده خواهیم کرد، تکمیل می‌کند.

۴. ایجاد الگوی برنامه

ما یک برنامه نمونه (یک برنامه پایتون فلاسک) ایجاد خواهیم کرد که در بقیه آزمایشگاه کد از آن استفاده خواهیم کرد. این برنامه در جلسات ارائه شده در یک کنفرانس فنی جستجو خواهد کرد.

این مراحل را دنبال کنید:

  1. روی نام پروژه Google Cloud در نوار وضعیت زیر کلیک کنید.

f151759c156c124e.png

  1. لیستی از گزینه‌ها ظاهر می‌شود. از لیست زیر روی «درخواست جدید» کلیک کنید.

91ea9836f38b7f74.png

  1. برنامه Cloud Run را انتخاب کنید (این زمان اجرا برای برنامه ما خواهد بود).
  2. الگوی برنامه Python (Flask): Cloud Run را انتخاب کنید.
  3. به برنامه یک نام بدهید و آن را در محل دلخواه خود ذخیره کنید.
  4. یک اعلان تأیید می‌کند که برنامه شما ایجاد شده است و یک پنجره جدید با برنامه شما مطابق شکل زیر باز می‌شود. یک فایل README.md باز می‌شود. فعلاً می‌توانید آن نما را ببندید.

aaa3725b17ce27cf.png

۵. تعامل با Gemini Code Assist

برای اهداف این آزمایش، ما از چت کمکی کد Gemini که در Cloud Shell IDE به عنوان بخشی از افزونه Cloud Code در VS Code موجود است، استفاده خواهیم کرد. می‌توانید با کلیک بر روی دکمه Code Assist در نوار ناوبری سمت چپ، آن را اجرا کنید. به دنبال آیکون Code Assist باشید. a489f98a34898727.png در نوار ابزار ناوبری سمت چپ و روی آن کلیک کنید.

این کار باعث می‌شود صفحه چت Code Assist در Cloud Shell IDE باز شود و بتوانید با Code Assist چت کنید.

۱۴ad103efaa0ddaa.png

به آیکون سطل زباله در بالا توجه کنید - این روش شما برای تنظیم مجدد زمینه برای تاریخچه چت Code Assist است. همچنین توجه داشته باشید که این تعامل چت وابسته به فایل(هایی) است که در IDE روی آنها کار می‌کنید.

۶. طراحی API

اولین قدم ما این است که در طول مرحله طراحی از Gemini Code Assist کمک بگیریم. در این مرحله، ما یک مشخصات OpenAPI برای موجودیت‌هایی (جلسات فنی در یک رویداد) که می‌خواهیم در آنها جستجو کنیم، ایجاد خواهیم کرد.

دستور زیر را بدهید:

Generate an Open API spec that will allow me to retrieve all sessions, sessions by category, session by id. Each session has the following attributes: id, title, list of speakers, list of categories, summary and duration.

این باید یک مشخصات OpenAPI برای جستجو در بین جلسات از طریق پارامترهای مختلف پرس و جو ایجاد کند. نمونه مشخصات در زیر آورده شده است:

openapi: 3.0.0
info:
 title: Sessions API
 description: This API allows you to retrieve all sessions, sessions by category, and session by id.
 version: 1.0.0
servers:
 - url: https://sessions.example.com
paths:
 /sessions:
   get:
     summary: Get all sessions
     operationId: getSessions
     responses:
       '200':
         description: OK
         content:
           application/json:
             schema:
               type: array
               items:
                 $ref: '#/components/schemas/Session'
 /sessions/{id}:
   get:
     summary: Get session by id
     operationId: getSessionById
     parameters:
       - name: id
         in: path
         required: true
         description: The id of the session
         schema:
           type: string
     responses:
       '200':
         description: OK
         content:
           application/json:
             schema:
               $ref: '#/components/schemas/Session'
 /sessions/categories/{category}:
   get:
     summary: Get sessions by category
     operationId: getSessionsByCategory
     parameters:
       - name: category
         in: path
         required: true
         description: The category of the sessions
         schema:
           type: string
     responses:
       '200':
         description: OK
         content:
           application/json:
             schema:
               type: array
               items:
                 $ref: '#/components/schemas/Session'
components:
 schemas:
   Session:
     type: object
     properties:
       id:
         type: string
         description: The id of the session
       title:
         type: string
         description: The title of the session
       speakers:
         type: array
         items:
           type: string
         description: The list of speakers for the session
       categories:
         type: array
         items:
           type: string
         description: The list of categories for the session
       summary:
         type: string
         description: The summary of the session
       duration:
         type: string
         description: The duration of the session

می‌توانید متوجه شوید که مشخصات فنی شامل موارد زیر است:

  • یک طرحواره تعریف شده برای نوع Session .
  • چندین مسیر API تعریف شده است:
  • /sessions
  • /sessions/{id}
  • /sessions/categories/{category}

فایلی به نام sessionsapi.yaml در پوشه بالایی ایجاد کنید و محتوا را از پنجره چت Code Assist با استفاده از گزینه "insert in current file" (دکمه + ) کپی کنید و فایل را در Cloud Shell IDE باز نگه دارید.

در این مرحله، می‌توانید به یک ویژگی جالب Gemini Code Assist توجه کنید: استناد . این اطلاعات زمانی که کد تولید شده مستقیماً از منبع دیگری، مانند کد منبع باز موجود، به تفصیل نقل قول می‌کند، در اختیار توسعه‌دهنده قرار می‌گیرد. این اطلاعات، منبع و مجوز را در اختیار توسعه‌دهنده قرار می‌دهد تا تصمیم بگیرد با آن چه کند.

با فرض اینکه محتوای تولید شده مشکلی ندارد، اکنون می‌توانیم از این سند مشخصات برای تولید یک برنامه پایتون فلسک برای آن استفاده کنیم.

۷. برنامه را ایجاد کنید

اکنون از Code Assist می‌خواهیم که برنامه را تولید کند. در حالی که فایل sessionsapi.yaml باز است، دستور زیر را اجرا کنید.

Generate a Python Application using the Flask framework, based on the sessionsapi.yaml file. This application uses a local in memory list of sessions. Do not use any Flask extensions.

این باید اسکلتی برای برنامه پایتون فلسک شما فراهم کند که بر اساس عملکرد و مسیرهایی است که در فایل مشخصات OpenAPI مشخص شده‌اند.

کد برنامه پایتون فلسک که ارائه شده است باید مشابه کد زیر باشد:

from flask import Flask, jsonify, request

app = Flask(__name__)

sessions = [
    {
        "id": "1",
        "title": "Session 1",
        "speakers": ["Speaker 1", "Speaker 2"],
        "categories": ["Category 1", "Category 2"],
        "summary": "This is a summary of session 1.",
        "duration": "1 hour",
    },
    {
        "id": "2",
        "title": "Session 2",
        "speakers": ["Speaker 3", "Speaker 4"],
        "categories": ["Category 3", "Category 4"],
        "summary": "This is a summary of session 2.",
        "duration": "1 hour 30 minutes",
    },
]

@app.route('/sessions', methods=['GET'])
def get_sessions():
    return jsonify(sessions)

@app.route('/sessions/<id>', methods=['GET'])
def get_session_by_id(id):
    session = next((session for session in sessions if session['id'] == id), None)
    if session is None:
        return jsonify({}), 404
    return jsonify(session)

@app.route('/sessions/categories/<category>', methods=['GET'])
def get_sessions_by_category(category):
    sessions_by_category = [session for session in sessions if category in session['categories']]
    return jsonify(sessions_by_category)

if __name__ == '__main__':
    app.run()

یک فایل app.py موجود است که به عنوان بخشی از مرحله قبل تولید شده است. کافیست محتویات آن را با کد تولید شده توسط Code Assist جایگزین کرده و فایل را ذخیره کنید.

ما می‌خواهیم خط app.run() را طوری تغییر دهیم که از پورت ۸۰۸۰، آدرس میزبان ۰.۰.۰.۰ استفاده کند و همچنین در حالت اشکال‌زدایی (Debug mode) در حین اجرای محلی اجرا شود. در اینجا روشی برای انجام این کار ارائه شده است. ابتدا، بیایید خط را هایلایت/انتخاب کنیم:

app.run()

سپس، در رابط چت Code Assist، عبارت زیر را تایپ کنید: Explain this.

این باید توضیح مفصلی از آن خط خاص را نشان دهد، مثالی از آن در زیر نشان داده شده است:

58ec896a32a4fb68.png

حالا، از دستور زیر استفاده کنید:

update the code to run the application on port 8080, host address 0.0.0.0, and in debug mode

کد پیشنهادی تولید شده باید به صورت زیر باشد: :

app.run(host='0.0.0.0', port=8080, debug=True)

به یاد داشته باشید که فایل app.py را با این قطعه کد به‌روزرسانی کنید.

اجرای برنامه به صورت محلی

بیایید اکنون برنامه را به صورت محلی اجرا کنیم تا الزامات برنامه را مطابق آنچه که در ابتدا با آن شروع کرده بودیم، اعتبارسنجی کنیم.

اولین قدم ایجاد یک محیط مجازی پایتون با وابستگی‌های بسته پایتون در requirements.txt است که باید در محیط مجازی نصب شوند. برای انجام این کار، در Cloud Shell IDE به Command Palette (Ctrl+Shift+P) بروید و عبارت Create Python environment را تایپ کنید. چند مرحله بعدی را برای انتخاب یک محیط مجازی (venv) ، مفسر پایتون 3.x و فایل requirements.txt دنبال کنید.

پس از ایجاد محیط، یک پنجره ترمینال جدید (Ctrl+Shift+`) باز کنید و دستور زیر را وارد کنید:

python app.py

نمونه‌ای از اجرا در زیر نشان داده شده است:

(.venv) romin@cloudshell: $ python app.py 
 * Serving Flask app 'app'
 * Debug mode: on
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.3:8080
Press CTRL+C to quit
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 132-247-368

اکنون می‌توانید پیش‌نمایش API را در URLهای زیر مشاهده کنید. ما فرض می‌کنیم که سرور توسعه شما روی پورت ۸۰۸۰ اجرا می‌شود. در غیر این صورت، لطفاً آن را به شماره پورت مناسب تغییر دهید.

  • https://<host-name>:8080/sessions
  • https://<host-name>:8080/sessions/{id}
  • https://<host-name>:8080/sessions/categories/{category}

مراحل زیر را دنبال کنید تا مطمئن شوید که می‌توانید با استفاده از این URLها، داده‌های JSON موجود در فایل app.py را بازیابی کنید:

یک پنجره ترمینال جدید باز کنید و هر یک از دستورات زیر را امتحان کنید:

curl -X GET http://127.0.0.1:8080/sessions
curl -X GET http://127.0.0.1:8080/sessions/<ID>
curl -X GET http://127.0.0.1:8080/sessions/categories/<CATEGORY_NAME> 

۸. بازسازی کد

به جای اینکه app.py حاوی داده‌های JSON نمونه‌ی کد شده باشد، احتمالاً می‌خواهیم این داده‌ها را در یک ماژول دیگر جدا/استخراج کنیم تا بتوانیم جدایی تمیزی بین کد و داده‌ها برقرار کنیم. بیایید این کار را انجام دهیم!

فایل app.py را باز نگه دارید و دستور زیر را اجرا کنید:

Can I improve this code and separate out the sessions data from this app.py file?

این باید به شما چند پیشنهاد در مورد چگونگی انجام این کار بدهد. نمونه پیشنهادی که ما دریافت کردیم و شما هم باید چیزی شبیه به آن دریافت کنید، در زیر نشان داده شده است:

9b9c56cb527dac4c.png

بیایید از این روش پیروی کنیم و داده‌های خود را طبق پیشنهاد Code Assist در یک فایل sessions.py جدا کنیم.

یک فایل جدید با نام sessions.py ایجاد کنید.

، که محتوای آن لیست JSON است، طبق داده‌های تولید شده ما در زیر آمده است:

sessions = [
   {
       "id": "1",
       "title": "Session 1",
       "speakers": ["Speaker 1", "Speaker 2"],
       "categories": ["Category 1", "Category 2"],
       "summary": "This is a summary of session 1.",
       "duration": "1 hour",
   },
   {
       "id": "2",
       "title": "Session 2",
       "speakers": ["Speaker 3", "Speaker 4"],
       "categories": ["Category 3", "Category 4"],
       "summary": "This is a summary of session 2.",
       "duration": "1 hour 30 minutes",
   },
]

فایل app.py اکنون بسیار ساده شده است و در زیر نشان داده شده است:

from flask import Flask, jsonify, request
from sessions import sessions

app = Flask(__name__)

@app.route('/sessions', methods=['GET'])
def get_sessions():
   return jsonify(sessions.sessions)

@app.route('/sessions/<id>', methods=['GET'])
def get_session_by_id(id):
   session = next((session for session in sessions.sessions if session['id'] == id), None)
   if session is None:
       return jsonify({}), 404
   return jsonify(session)

@app.route('/sessions/categories/<category>', methods=['GET'])
def get_sessions_by_category(category):
   sessions_by_category = [session for session in sessions.sessions if category in session['categories']]
   return jsonify(sessions_by_category)

if __name__ == '__main__':
   app.run(host='0.0.0.0', port=8080, debug=True)

مطمئن شوید که هنوز می‌توانید برنامه را به صورت محلی اجرا کنید و API را با این تغییرات اصلاح‌شده اعمال کنید. احتمالاً سرور توسعه پایتون هنوز در حال اجرا است، بنابراین فقط باید دستورات curl را از مرحله قبل فراخوانی کنید.

۹. ادغام با مجموعه Firestore

مرحله بعدی این است که از لیست JSON محلی درون حافظه که برای جلسات خود داریم فاصله بگیریم و برنامه خود را به مجموعه جلسات در پایگاه داده Firestore که در ابتدای این آزمایشگاه کد ایجاد کردیم، متصل کنیم.

فایل sessions.py را باز نگه دارید و دستور زیر را اجرا کنید:

Can you further refactor the sessions.py code to read from a Firestore database that has a collection named sessions. The collection has the same attributes as the session object that we have defined. Use the Python module google-cloud-firestore. 

ما پیشنهاد زیر را برای خواندن تمام جلسات از مجموعه Firestore دریافت کردیم:

import google.cloud.firestore

# Create a Firestore client
db = google.cloud.firestore.Client()

# Get the sessions collection
sessions_collection = db.collection("sessions")

# Create a list of sessions
sessions = []

# Iterate over the documents and add them to the list
for doc in sessions_collection.stream():
   session = doc.to_dict()
   session["id"] = doc.id
   sessions.append(session)

ادامه دهید و کد را در sessions.py وارد کنید.

اگر سرور توسعه Flask را به صورت محلی اجرا می‌کنید، ممکن است برنامه شما با این خطا که ماژول پایتون پیدا نشد، بسته شده باشد.

برای مثال، می‌توانید از Code Assist بپرسید که کدام ماژول پایتون باید به فایل requirements.txt اضافه شود، مانند زیر:

Which Python package needs to be installed to make the firestore code work?

این به شما نام ماژول پایتون (مثلاً google-cloud-firestore ) را می‌دهد. آن را به فایل requirements.txt اضافه کنید.

شما باید محیط پایتون را با ماژول تازه اضافه شده ( google-cloud-firestore ) از نو بسازید. برای انجام این کار، دستور زیر را در پنجره ترمینال موجود وارد کنید:

pip install -r requirements.txt

برنامه را دوباره اجرا کنید (آن را با python app.py مجدداً راه‌اندازی کنید) و به آدرس /sessions مراجعه کنید. اکنون باید اسناد نمونه‌ای را که به مجموعه sessions اضافه کرده‌ایم، دریافت کنید.

975d05e6518f1a6a.png

همانطور که در مراحل قبلی توضیح داده شد، می‌توانید URI های دیگر را برای بازیابی جلسات خاص یا همه جلسات برای یک دسته خاص جستجو کنید.

۱۰. توضیح کد

اکنون زمان مناسبی است که از ویژگی "Explain this" در Gemini Code Assist برای درک بهتر کد استفاده کنید. می‌توانید به هر یک از فایل‌ها بروید یا قطعه کد خاصی را انتخاب کنید و از Code Assist با عبارت زیر بپرسید: Explain this .

به عنوان تمرین، به فایل sessions.py مراجعه کنید و کد مخصوص Firestore را هایلایت کنید و توضیحات کد را در مورد آن دریافت کنید. سعی کنید از این ویژگی در سایر فایل‌های پروژه خود نیز استفاده کنید، نه فقط کد پایتون.

۱۱. ایجاد برنامه وب

حالا که API را ایجاد و با یک مجموعه زنده Firestore ادغام کرده‌ایم، بیایید یک رابط کاربری مبتنی بر وب برای برنامه ایجاد کنیم. رابط کاربری وب ما در حال حاضر عملکرد خود را به حداقل می‌رساند، یعنی می‌تواند جلساتی را که به یک دسته خاص تعلق دارند جستجو کند. به خاطر داشته باشید که ما یک مسیر API برای آن داریم، یعنی /sessions/categories/{category} بنابراین برنامه وب ما باید آن را فراخوانی کرده و نتایج را بازیابی کند.

بیایید مستقیماً به آن بپردازیم. دستور زیر را به Code Assist بدهید:

Generate a web application that allows me to search for sessions by category and uses the Flask application that we created. Please use basic HTML, CSS and JS. Embed all the Javascript and CSS code into a single HTML file only.

این دستور، HTML برنامه وب را به همراه جاوا اسکریپت و CSS تعبیه شده در آن تولید می‌کند. همچنین از شما می‌خواهد که یک مسیر جدید به فایل app.py اضافه کنید تا هر کاربری که از آدرس ریشه یا پایه بازدید می‌کند، به صفحه اصلی هدایت شود. اگر این اطلاعات را ذکر نکرد، در مورد آن سوال کنید یا از قطعه کد زیر استفاده کنید:

@app.route('/')
def index():
   return render_template('index.html')

می‌توانید این را با نام index.html ذخیره کنید، اما ممکن است در مورد محل ذخیره این فایل (یعنی کدام پوشه؟) سوالی داشته باشید. می‌توانیم سوال بعدی را از Code Assist بپرسیم.

Given that I am using the flask framework, where should I put the index.html file?

باید اطلاعات واضحی به شما بدهد که از چارچوب render_template استفاده می‌کند و از این رو فایل index.html باید در داخل پوشه templates قرار گیرد. این پوشه را خواهید یافت زیرا ما در ابتدای این codelab یک برنامه بر اساس الگوی Flask ایجاد کرده‌ایم. در نتیجه، یک فایل index.html موجود است و شما باید به سادگی محتویات آن را با فایل جدیدی که در اینجا تولید شده است جایگزین کنید. Code Assist همچنین به import کردن render_template در فایل app.py اشاره می‌کند.

کد برنامه وب را در فایل index.html ذخیره کنید و به یاد داشته باشید که آن فایل را در پوشه templates قرار دهید.

اجرای برنامه به صورت محلی

بیایید اکنون برنامه را به صورت محلی اجرا کنیم تا الزامات برنامه را مطابق آنچه که در ابتدا با آن شروع کرده بودیم، اعتبارسنجی کنیم.

مطمئن شوید که سرور محلی Flask هنوز در حال اجرا است و هیچ خطایی نشان نمی‌دهد. در صورت بروز خطا، آنها را برطرف کرده و سرور را راه‌اندازی کنید.

پس از راه‌اندازی و اجرا، به آدرس اصلی برنامه مراجعه کنید. باید فایل index.html را مطابق شکل زیر به شما نشان دهد:

8ca586acc4536879.png

یکی از دسته‌بندی‌های موجود در داده‌ها را به عنوان ورودی وارد کنید (مثلاً AI ) و روی دکمه Search کلیک کنید. این کار باید جلسات برچسب‌گذاری شده با دسته‌بندی AI را نمایش دهد.

۱۶۵faded790a6c.png

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

۱۲. تولید موارد آزمایشی

ما API مربوط به سشن‌ها را ایجاد کرده‌ایم و اکنون زمان آن رسیده است که از Gemini Code Assist برای تولید موارد تست واحد برای مسیرهای مختلف API استفاده کنیم.

فایل app.py را باز نگه دارید و دستور زیر را اجرا کنید:

Generate unit test cases for app routes. Use unittest module.

ما پاسخ زیر را دریافت کردیم:

import unittest
from app import app

class FlaskAppTestCase(unittest.TestCase):

    def test_index(self):
        tester = app.test_client()
        response = tester.get('/')
        self.assertEqual(response.status_code, 200)

    def test_get_sessions(self):
        tester = app.test_client()
        response = tester.get('/sessions')
        self.assertEqual(response.status_code, 200)

    def test_get_session_by_id(self):
        tester = app.test_client()
        response = tester.get('/sessions/1')
        self.assertEqual(response.status_code, 200)

    def test_get_sessions_by_category(self):
        tester = app.test_client()
        response = tester.get('/sessions/categories/category1')
        self.assertEqual(response.status_code, 200)

if __name__ == '__main__':
    unittest.main()

یک فایل با نام tests.py با کد بالا ایجاد کنید.

نکته‌ای در مورد تولید موارد آزمون

ممکن است فهرست کدهای متفاوتی نسبت به آنچه در بالا آمده است، مشاهده کنید و این ممکن است در اجرای موارد آزمایشی مشکلاتی ایجاد کند. به عنوان مثال، ما شاهد بودیم که در برخی از اجراهایمان، بخش‌های کلیدی کد زیر از قلم افتاده‌اند:

from app import app

کد بالا برای وارد کردن برنامه Flask موجود که قرار است موارد آزمایشی را روی آن فراخوانی کنیم، لازم است.

if __name__ == '__main__':

`unittest.main()`

کد بالا برای اجرای موارد آزمایشی مورد نیاز است.

توصیه ما این است که به تک تک موارد آزمایشی نگاهی بیندازید، assertEqual و سایر شرایط را در کد تولید شده بررسی کنید تا مطمئن شوید که کار خواهد کرد. از آنجایی که داده‌ها در مجموعه Firestore خارجی هستند، ممکن است به آنها دسترسی نداشته باشد و ممکن است از برخی داده‌های ساختگی استفاده کند که در نتیجه ممکن است آزمایش‌ها با شکست مواجه شوند. بنابراین موارد آزمایشی خود را بر این اساس تغییر دهید یا برخی از موارد آزمایشی را که ممکن است فوراً به آنها نیاز نداشته باشید، کامنت کنید.

به عنوان یک نمایش، ما موارد آزمایشی را با استفاده از دستور زیر اجرا کردیم (مطمئن شوید که سرور توسعه محلی را اجرا می‌کنید زیرا تماس‌ها به نقاط پایانی API محلی انجام می‌شود):

python tests.py

ما به نتیجه خلاصه زیر رسیدیم:

Ran 4 tests in 0.274s

FAILED (failures=2)

این واقعاً درست است زیرا شناسه جلسه در آزمایش سوم صحیح نبود و هیچ دسته‌ای به نام category1 وجود ندارد.

.

بنابراین موارد آزمایش را بر اساس آن تنظیم کنید و آن را آزمایش کنید.

۱۳. توسعه مبتنی بر آزمون

حال بیایید نگاهی به اضافه کردن یک متد جستجوی جدید در API جلسات خود با پیروی از روش توسعه مبتنی بر آزمون (TDD) بیندازیم، که در آن ابتدا موارد آزمون نوشته می‌شوند، سپس به دلیل عدم پیاده‌سازی، با شکست مواجه می‌شوند و سپس با استفاده از Gemini Code Assist پیاده‌سازی از دست رفته تولید می‌شود تا آزمون با موفقیت انجام شود.

به فایل tests.py بروید (با فرض اینکه فایل tests.py را طوری اصلاح کرده‌اید که همه تست‌ها با موفقیت انجام شوند). از Code Assist درخواست کنید تا پیام زیر را ارسال کند:

Generate a new test case to search for sessions by speaker

این به ما پیاده‌سازی مورد آزمایشی زیر را داد که به درستی در فایل tests.py قرار دادیم.

  def test_get_sessions_by_speaker(self):
        tester = app.test_client()
        response = tester.get('/sessions/speakers/speaker1')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json, [sessions.sessions[0], sessions.sessions[1]])

اگر تست‌ها را اجرا کنید، باید خطای زیر را مشاهده کنید:

$ python tests.py 
.F.
======================================================================
FAIL: test_get_sessions_by_speaker (__main__.FlaskAppTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/romin/hello-world-5/tests.py", line 21, in test_get_sessions_by_speaker
    self.assertEqual(response.status_code, 200)
AssertionError: 404 != 200

----------------------------------------------------------------------
Ran 3 tests in 0.010s

FAILED (failures=1)

دلیل این امر آن است که مورد آزمایشی مسیر زیر ( /sessions/speakers/ ) را فراخوانی کرده است و هیچ پیاده‌سازی از آن در app.py وجود ندارد.

بیایید از Code Assist بخواهیم که یک پیاده‌سازی برای ما فراهم کند. به فایل app.py بروید و دستور زیر را به Code Assist بدهید:

Add a new route to search for sessions by a specific speaker

ما پیاده‌سازی زیر را که توسط Code Assist پیشنهاد شده بود، دریافت کردیم و آن را به فایل app.py اضافه کردیم:

@app.route('/sessions/speakers/<speaker>', methods=['GET'])
def get_sessions_by_speaker(speaker):
    sessions_by_speaker = [session for session in sessions.sessions if speaker in session['speakers']]
    return jsonify(sessions_by_speaker)

فایل tests.py دوباره بررسی کنید، ما برای بررسی سریع، مورد آزمایشی خود را به صورت زیر اصلاح کردیم:

   def test_get_sessions_by_speaker(self):
       tester = app.test_client()
       response = tester.get('/sessions/speakers/Romin Irani')
       self.assertEqual(response.status_code, 200)
       self.assertEqual(len(response.json), 1)

تست به خوبی اجرا شد. ما این را به عنوان تمرین برای شما می‌گذاریم تا به موارد تست تولید شده نگاهی بیندازید، آنها را بسته به داده‌هایی که ممکن است در Firestore داشته باشید کمی تغییر دهید و متدهای assert* مناسب را در موارد تست واحد پایتون داشته باشید.

۱۴. استقرار در Google Cloud Run

حالا که از کیفیت توسعه‌مان مطمئن هستیم، قدم آخر، استقرار این برنامه در Google Cloud Run خواهد بود. اما شاید، برای اطمینان بیشتر، بهتر باشد اگر چیزی را فراموش کرده‌ایم از Code Assist بپرسیم. با باز کردن app.py ، دستور زیر را ارسال کنید:

Is there something here I should change before I deploy to production?

خوب شد پرسیدی، چون ما واقعاً فراموش کردیم که پرچم اشکال‌زدایی را روی خاموش تنظیم کنیم:

2f87ed3a811fb218.png

همانطور که اشاره شد، اشکال‌زدایی را خاموش کنید و از Gemini Code Assist برای کمک در مورد دستور gcloud که می‌تواند برای استقرار برنامه در Cloud Run مستقیماً از منبع (بدون نیاز به ساخت یک کانتینر در ابتدا) استفاده شود، درخواست کمک کنید.

دستور زیر را بدهید:

I would like to deploy the application to Cloud Run directly from source. What is the gcloud command to do that?

چند نمونه از دستور بالا را امتحان کنید. یکی دیگر از مواردی که ما امتحان کردیم این بود:

I would like to deploy this application to Cloud Run. I don't want to build a container image locally but deploy directly from source to Cloud Run. What is the gcloud command for that?

در حالت ایده‌آل، باید دستور gcloud زیر را دریافت کنید:

gcloud run deploy sessions --source .

همچنین ممکن است موارد زیر را دریافت کنید:

gcloud run deploy <service-name> --source . \
—-platform managed \
—-allow-unauthenticated

دستور بالا را از پوشه ریشه برنامه اجرا کنید. وقتی از شما region پرسیده شد، us-central1 را انتخاب کنید و وقتی از شما خواسته شد که unauthenticated invocations اجازه دهید، Y انتخاب کنید. همچنین ممکن است از شما خواسته شود که APIهای Google Cloud مانند Artifact Registry، Cloud Build و Cloud Run و مجوز ایجاد مخزن Artifact Registry را فعال کنید، لطفاً این مجوز را بدهید.

مراحل نصب حدود ۲ دقیقه طول می‌کشد، پس صبور باشید.

پس از استقرار موفقیت‌آمیز، آدرس اینترنتی سرویس Cloud Run را مشاهده خواهید کرد. به آن آدرس اینترنتی عمومی مراجعه کنید و باید همان برنامه وب را که با موفقیت مستقر و اجرا شده است، مشاهده کنید.

c5322d0fd3e0f616.png

تبریک می‌گویم، آفرین!

۱۵. (اختیاری) استفاده از ثبت وقایع ابری

می‌توانیم قابلیت ثبت وقایع (logging) را در برنامه خود معرفی کنیم، به طوری که وقایع برنامه در یکی از سرویس‌های ابری گوگل (Cloud Logging) متمرکز شوند. سپس می‌توانیم از ویژگی Observability Gemini برای درک ورودی‌های وقایع نیز استفاده کنیم.

برای انجام این کار، ابتدا باید از یک کتابخانه ثبت وقایع ابری پایتون موجود در گوگل کلود استفاده کنیم و از آن برای ثبت پیام‌های اطلاعاتی، هشدار یا خطا (بسته به سطح گزارش/شدت) استفاده کنیم.

بیایید سعی کنیم ابتدا این را از Code Assist بپرسیم. دستور زیر را امتحان کنید:

How do I use the google-cloud-logging package in Python?

شما باید پاسخی دریافت کنید که اطلاعاتی در مورد آن ارائه می‌دهد، همانطور که در زیر آمده است:

2472e1ccaf8a217d.png

بیایید دستورات ثبت وقایع را به تابعی که جلسات را بر اساس دسته جستجو می‌کند، اضافه کنیم.

ابتدا، بسته پایتون google-cloud-logging را به فایل requirements.txt اضافه کنید.

در ادامه، قطعه کدی آمده است که نحوه‌ی ادغام کد برای پیاده‌سازی ثبت وقایع (logging) را نشان می‌دهد:

...
from google.cloud import logging
...
app = Flask(__name__)

# Create a logger
logger = logging.Client().logger('my-log')

@app.route('/sessions/categories/<category>', methods=['GET'])
def get_sessions_by_category(category):
   logger.log_text(f"Fetching sessions with category {category}")
   sessions_by_category = [session for session in sessions.sessions if category in session['categories']]
   logger.log_text(f'Found {len(sessions_by_category)} sessions with category {category}')
   return jsonify(sessions_by_category)

# # Other App Routes

سرویس را دوباره با استفاده از همان دستور بخش قبل در Cloud Run مستقر کنید و پس از استقرار، چند فراخوانی به نقطه پایانی /sessions/categories/<category> انجام دهید.

به Cloud Console → Logs Explorer بروید

59e297577570695.png

... و شما باید بتوانید مطابق شکل زیر، این دستورات ثبت وقایع را فیلتر کنید:

۹۱۴f1fb6cac30a89.png

می‌توانید روی هر یک از عبارات گزارش کلیک کنید، آن را باز کنید و سپس روی Explain this log entry کلیک کنید، که از Gemini برای توضیح ورودی گزارش استفاده می‌کند. توجه داشته باشید که اگر Gemini را برای Google Cloud فعال نکرده‌اید، از شما خواسته می‌شود که Cloud AI Companion API را فعال کنید. لطفاً طبق دستورالعمل پیش بروید و این کار را انجام دهید.

نمونه پاسخ در زیر آمده است:

7fc9783910fa92cc.png

۱۶. تبریک

تبریک می‌گوییم، شما با موفقیت یک برنامه را از ابتدا ساختید و از Gemini Code Assist در جنبه‌های مختلف SDLC از جمله طراحی، ساخت، آزمایش و استقرار استفاده کردید.

بعدش چی؟

به برخی از این آزمایشگاه‌های کد نگاهی بیندازید...

اسناد مرجع