สร้าง Python CLI คุย Gemini แบบไม่กลัวล่ม: เน้น Resilience
สวัสดีครับ
โปรแกรมเมอร์อย่างเราๆ เนี่ย พอต้องทำงานกับ API บ่อยๆ นะครับ โดยเฉพาะพวก External API อย่าง Gemini API ของ Google เนี่ย สิ่งหนึ่งที่สำคัญไม่แพ้การเขียนโค้ดให้มันทำงานได้ ก็คือการทำให้มัน ทนทาน (Resilience) ต่อความผิดพลาดต่างๆ นะครับ ไม่ว่าจะเน็ตล่ม หรือ API ล่ม หรือติด Rate Limit
วันนี้ผมจะพามาดูวิธีสร้าง Python CLI ง่ายๆ ที่คุยกับ Gemini API พร้อมใส่เรื่อง Resilience เข้าไปกันครับ
1. โครงสร้าง CLI แบบง่ายๆ
ขั้นแรกสุด เรามาดูโครงสร้างโปรเจกต์ CLI กันก่อนครับ ผมจะใช้ argparse มาจัดการ Argument ง่ายๆ นะครับ
# main.py
import argparse
def main():
parser = argparse.ArgumentParser(description="CLI สำหรับคุยกับ Gemini API แบบ Resilient")
parser.add_argument("--prompt", type=str, required=True, help="ข้อความที่คุณต้องการส่งให้ Gemini")
args = parser.parse_args()
print(f"กำลังส่งข้อความ: {args.prompt} ให้ Gemini...")
# ส่วนนี้เดี๋ยวเราจะใส่โค้ดคุยกับ Gemini ครับ
if __name__ == "__main__":
main()
เวลาเรียกใช้งานก็แบบนี้เลยครับ: python main.py --prompt "สวัสดี Gemini"
2. เชื่อมต่อ Gemini API
ก่อนอื่นนะครับ ติดตั้งไลบรารี google-generativeai ก่อนเลย pip install google-generativeai
แล้วก็เพิ่มโค้ดส่วนนี้เข้าไปใน main.py เพื่อให้ CLI เราคุยกับ Gemini ได้ครับ อย่าลืมตั้งค่า GOOGLE_API_KEY ด้วยนะครับ
# main.py (เพิ่มส่วนนี้เข้าไป)
import google.generativeai as genai
import os
genai.configure(api_key=os.environ.get("GOOGLE_API_KEY"))
model = genai.GenerativeModel('gemini-pro')
def call_gemini(prompt):
try:
response = model.generate_content(prompt)
return response.text
except Exception as e:
print(f"เกิดข้อผิดพลาดในการเรียก Gemini: {e}")
return None
def main(): # ในฟังก์ชัน main() แก้ไขส่วนเรียกใช้งาน
# ... (ส่วน argparse เหมือนเดิม)
gemini_response = call_gemini(args.prompt)
if gemini_response:
print("\
คำตอบจาก Gemini:")
print(gemini_response)
else:
print("ไม่สามารถรับคำตอบจาก Gemini ได้ครับ")
ตอนนี้ CLI ของเราก็คุยกับ Gemini ได้แล้วครับ ลองรันดู GOOGLE_API_KEY='YOUR_API_KEY' python main.py --prompt "เล่าเรื่องสั้น 1 ย่อหน้า"
3. เพิ่มความ Resilient ด้วย Retry และ Context Manager
เพื่อให้โปรแกรมเราทนทานขึ้น เวลา API มีปัญหาชั่วคราว เราจะใช้ tenacity เข้ามาช่วยเรื่อง Retry นะครับ และใช้ context manager จัดการการบันทึก Log เวลาเกิดข้อผิดพลาด
ติดตั้ง tenacity ก่อนเลย: pip install tenacity
จากนั้นมาปรับโค้ด call_gemini กันครับ ผมจะใช้ retry decorator จาก tenacity และสร้าง Context Manager ง่ายๆ สำหรับ Log Error นะครับ
# main.py (เพิ่ม import และแก้ไขฟังก์ชัน)
from tenacity import retry, stop_after_attempt, wait_fixed, retry_if_exception_type
import contextlib
import datetime
# Context Manager สำหรับบันทึก Log (ตัวอย่างง่ายๆ)
@contextlib.contextmanager
def error_logger(log_file="error_log.txt"):
f = open(log_file, "a", encoding="utf-8")
try:
yield f
finally:
f.close()
# Retry decorator
@retry(stop=stop_after_attempt(3), wait=wait_fixed(2),
retry=retry_if_exception_type(Exception))
def call_gemini_resilient(prompt):
print("--- พยายามเรียก Gemini API...")
response = model.generate_content(prompt)
return response.text
def main(): # ในฟังก์ชัน main() แก้ไขส่วนเรียกใช้งาน
# ... (ส่วน argparse และ configure Gemini เหมือนเดิม)
with error_logger() as log:
try:
gemini_response = call_gemini_resilient(args.prompt)
print("\
คำตอบจาก Gemini:")
print(gemini_response)
except Exception as e:
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log.write(f"[{timestamp}] เกิดข้อผิดพลาดหลังจากพยายามหลายครั้ง: {e}\
")
print("ไม่สามารถรับคำตอบจาก Gemini ได้ครับ (ตรวจสอบ error_log.txt)")
คำอธิบายโค้ด: * @retry(...): จะพยายามเรียก call_gemini_resilient ซ้ำ 3 ครั้ง (หยุดเมื่อสำเร็จหรือครบ 3 ครั้ง) โดยจะรอ 2 วินาทีระหว่างการ retry ถ้าเกิด Exception ใดๆ ขึ้น * error_logger: เป็น Context Manager ง่ายๆ ที่ผมสร้างขึ้นมาเพื่อเปิดไฟล์ error_log.txt ไว้เขียนข้อผิดพลาด พอจบ Block with ไฟล์ก็จะถูกปิดอัตโนมัติครับ
ลองรันดูนะครับ ถ้า API มีปัญหาชั่วคราว มันจะลองใหม่ให้เอง GOOGLE_API_KEY='YOUR_API_KEY' python main.py --prompt "เขียนโค้ด Python สำหรับ Merge Sort"
ถ้าเกิดปัญหาแล้วมัน Retry จนครบ ก็จะบันทึก Log ลง error_log.txt ให้ด้วยครับ
สรุปนะครับ
การสร้าง CLI ที่เชื่อมต่อกับ External API อย่าง Gemini เนี่ย การใส่เรื่อง Resilience เข้าไปเป็นสิ่งสำคัญมากๆ เลยนะครับ ไม่ใช่แค่ทำให้โปรแกรมเราไม่ล่มง่ายๆ แต่ยังช่วยให้ User Experience ดีขึ้นด้วย เพราะบางทีปัญหาแค่ชั่วคราว เราก็ไม่ต้องให้ผู้ใช้ต้องมานั่งรันใหม่เอง
เพื่อนๆ ลองเอาเทคนิคนี้ไปปรับใช้กับโปรเจกต์ของตัวเองดูได้เลยนะครับ ไม่ว่าจะกับ Gemini หรือ API อื่นๆ ครับ
อ้างอิง: * Google Gemini API Docs * Tenacity Library
cii3.net