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

1. مقدمه

e5b98fd4e417c877.png

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

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

کاری که خواهی کرد

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

چیزی که یاد خواهید گرفت

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

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

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

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

2. Gemini Code Assist را راه اندازی کنید

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

Gemini Code Assist را در Cloud Shell IDE فعال کنید

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

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

6f5ce865fc7a3ef5.png

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

709e6c8248ac7d88.png

Gemini Code Assist آماده استفاده است!

3. Firestore را راه اندازی کنید

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

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

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

f1535e14c9beeec6.png

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

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

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

راه اندازی پایگاه داده Firestore

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

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

  • حالت Firestore: 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 را مطابق شکل زیر انتخاب کنید. :

d3e294d46ba29cd5.png

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

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

ما یک نمونه برنامه (یک برنامه Python Flask) ایجاد خواهیم کرد که در بقیه قسمت های کد لبه استفاده خواهیم کرد. این برنامه در جلسات ارائه شده در یک کنفرانس فنی جستجو می کند.

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

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

f151759c156c124e.png

  1. لیستی از گزینه ها ظاهر می شود. از لیست زیر بر روی New Application کلیک کنید.

91ea9836f38b7f74.png

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

aaa3725b17ce27cf.png

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

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

با این کار، صفحه چت Code Assist در داخل Cloud Shell IDE ظاهر می شود و می توانید با Code Assist چت کنید.

14ad103efaa0ddaa.png

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

6. طراحی 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 Specification برای جستجو در جلسات از طریق پارامترهای مختلف پرس و جو ایجاد کند. نمونه مشخصات در زیر آورده شده است:

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 با استفاده از "گزینه درج در فایل فعلی" (دکمه + ) کپی کنید و فایل را در Cloud Shell IDE باز نگه دارید.

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

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

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

اکنون از 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.

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

کد برنامه Python Flask ارائه شده باید مشابه کد زیر باشد:

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() را برای استفاده از پورت 8080، آدرس میزبان 0.0.0.0 و همچنین در حالت Debug در طول اجرای محلی تغییر دهیم. در اینجا راهی برای انجام این کار وجود دارد. ابتدا، بیایید خط را برجسته کنیم/انتخاب کنیم:

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

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

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

اولین قدم ایجاد یک محیط مجازی پایتون با وابستگی های بسته Python در requirement.txt برای نصب در محیط مجازی خواهد بود. برای انجام این کار، به پالت فرمان (Ctrl+Shift+P) در Cloud Shell IDE بروید و در محیط Create Python تایپ کنید. برای انتخاب یک محیط مجازی (venv) ، مفسر Python 3.x و فایل requirement.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 های زیر مشاهده کنید. ما فرض می کنیم که سرور توسعه شما بر روی پورت 8080 اجرا می شود. اگر نه، لطفاً آن را به شماره پورت مناسب تغییر دهید.

  • 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> 

8. Refactoring کد

به‌جای اینکه 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 را از مرحله قبل به یاد بیاورید.

9. با مجموعه 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 ها برای بازیابی جلسات خاص یا همه جلسات برای یک دسته معین همانطور که در مراحل قبلی توضیح داده شد، پرس و جو کنید.

10. توضیح کد

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

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

11. Web Application را ایجاد کنید

اکنون که API را تولید کرده‌ایم و آن را با یک مجموعه Firestore زنده ادغام کرده‌ایم، اجازه دهید یک front-end مبتنی بر وب برای برنامه ایجاد کنیم. صفحه اصلی وب ما در حال حاضر عملکرد خود را به حداقل می رساند، یعنی می تواند جلساتی را جستجو کند که به یک دسته خاص تعلق دارند. به خاطر داشته باشید که ما یک مسیر 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 اضافه کنید، به طوری که هر کاربری که از URL اصلی یا پایه بازدید می کند، صفحه اصلی را دریافت می کند. اگر آن اطلاعات را ذکر نکرد، در مورد آن بپرسید یا از قطعه زیر استفاده کنید:

@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 قرار گیرد. شما این پوشه را در دسترس خواهید یافت زیرا ما یک برنامه کاربردی بر اساس الگوی Flask در ابتدای این کد لبه ایجاد کرده بودیم. در نتیجه، یک فایل index.html موجود است و شما باید به سادگی محتویات آن را با فایل جدیدی که در اینجا ایجاد شده است جایگزین کنید. Code Assist همچنین به وارد کردن render_template در فایل app.py شما اشاره می کند.

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

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

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

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

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

8ca586acc4536879.png

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

165faded790a6c.png

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

12. Test Case Generation

ما Session 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 وجود ندارد.

.

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

13. توسعه آزمایش محور

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

به فایل tests.py بروید (با فرض اینکه فایل tests.py را درست کرده اید تا همه تست ها قبول شوند). Ask 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* مناسب را در موارد تست واحد پایتون داشته باشید.

14. استقرار در 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 را فعال کنید، لطفا ادامه دهید و اجازه دهید.

مراحل استقرار حدود 2 دقیقه طول می کشد، بنابراین لطفا صبور باشید.

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

c5322d0fd3e0f616.png

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

15. (اختیاری) از Cloud Logging استفاده کنید

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

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

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

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

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

2472e1ccaf8a217d.png

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

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

در مرحله بعدی یک قطعه کد است که نشان می دهد چگونه ما کد را برای پیاده سازی لاگ ادغام کردیم:

...
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

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

914f1fb6cac30a89.png

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

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

7fc9783910fa92cc.png

16. تبریک می گویم

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

بعدش چی؟

برخی از این کدها را بررسی کنید...

اسناد مرجع