Python CLI กับ Gemini API: จัดการ Context ให้เฉียบคม ไม่กลัวข้อมูลหาย

สวัสดีครับ

บทความนี้ ผมจะมาแนะนำ การเขียน Python CLI ครับ ที่ใช้งาน Gemini API แบบที่ แบบไม่กลัวข้อมูลจะหายนะครับ และยังช่วยเพิ่มความทนทานให้โปรแกรมเราด้วยนะ เราจะใช้ context manager เข้ามาช่วยจัดการส่วนนี้กันนะครับ ลองดูตัวอย่างกันครับ

ตัวอย่างที่ 1: โค๊ด Python CLI เบื้องต้น ง่ายๆ เลยครับ

นี่คือโครงสร้าง CLI พื้นฐานที่เราจะใช้เป็นตัวเริ่มต้นนะครับ แบบยังไม่มีการจัดการ Log หรือไฟล์อะไรเลยนะ

import argparse

def main():
    parser = argparse.ArgumentParser(description="CLI เพื่อเรียกใช้ Gemini API")
    parser.add_argument("--query", type=str, help="คำถามสำหรับ Gemini")
    args = parser.parse_args()

    if args.query:
        print(f"กำลังจะส่งคำถาม: \\"{args.query}\\" ไปยัง Gemini...")
        # ตรงนี้คือส่วนที่เราจะเรียก Gemini API จริงๆ นะครับ
        # สมมติว่าได้คำตอบมา
        response = f"สวัสดีครับ! นี่คือคำตอบจาก Gemini สำหรับ \\"{args.query}\\""
        print(response)
    else:
        print("กรุณาใส่ --query ด้วยนะครับ เช่น: python app.py --query \\"คุณคือใคร\\"")

if __name__ == "__main__":
    main()

วิธีรันก็แบบนี้เลยครับ: python your_cli_app.py --query "แนะนำการเขียนโค้ดภาษา Python หน่อย"

ตัวอย่างที่ 2: เพิ่ม Context Manager เพื่อจัดการ Log และเพิ่มความ Resilience

จากนั้น เราจะมาเพิ่ม Context Manager ครับ เพื่อจัดการไฟล์ Log หรือจัดการ Token API ต่างๆ ของเราให้ดียิ่งขึ้น\ แบบนี้จะช่วยให้มั่นใจได้ว่าไฟล์จะถูกปิดอย่างถูกต้องเสมอ ไม่ว่าจะเกิด Error อะไรขึ้นมาก็ตามนะครับ โปรแกรมเราก็จะมีความ resilience หรือทนทานขึ้นมาทันทีเลยครับ

import argparse
import datetime
import time # เพิ่มมาเพื่อจำลอง delay หรือ Error

class GeminiLogManager:
    def __init__(self, log_file_name="gemini_cli.log"):
        self.log_file_name = log_file_name
        self.file_handle = None

    def __enter__(self):
        try:
            self.file_handle = open(self.log_file_name, 'a', encoding='utf-8')
            self.file_handle.write(f"[{datetime.datetime.now()}] >>> เริ่มทำงาน CLI >>>\
")
            return self.file_handle
        except IOError as e:
            print(f"ไม่สามารถเปิดไฟล์ log ได้ครับ: {e}")
            # ถ้าเปิดไม่ได้ ก็ปล่อยให้โปรแกรมพังไป ดีกว่าทำงานโดยไม่มี log
            raise

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.file_handle:
            if exc_type:
                # ถ้ามี Error เกิดขึ้น
                self.file_handle.write(f"[{datetime.datetime.now()}] !!! เกิดข้อผิดพลาด: {exc_val} !!!\
")
            self.file_handle.write(f"[{datetime.datetime.now()}] <<< จบทำงาน CLI <<<
")
            self.file_handle.close()
        # ไม่ต้อง re-raise ถ้าเราไม่ต้องการให้ Error propagation
        # return False หมายถึงยอมให้ exception propagate ต่อไป
        # return True หมายถึง exception ถูก handle แล้ว ไม่ต้อง propagate
        return False # เราอยากให้ error แสดงออกไปที่ console ด้วยครับ

def main():
    parser = argparse.ArgumentParser(description="CLI สำหรับเรียก Gemini API พร้อม Log")
    parser.add_argument("--query", type=str, help="คำถามสำหรับ Gemini")
    parser.add_argument("--fail", action="store_true", help="จำลอง Error สำหรับทดสอบ")
    args = parser.parse_args()

    with GeminiLogManager() as log_file:
        log_file.write(f"[{datetime.datetime.now()}] รับคำสั่ง: query='{args.query}', fail_test={args.fail}\
")

        if args.query:
            print(f"กำลังประมวลผลคำถาม: \\"{args.query}\\"...")
            log_file.write(f"[{datetime.datetime.now()}] กำลังเรียก Gemini API...\
")

            try:
                if args.fail:
                    raise ValueError("จำลองข้อผิดพลาดในการเรียก Gemini API ครับ!")

                # สมมติการเรียก Gemini API จริงๆ
                time.sleep(1) # จำลองเวลาหน่วง
                # response_from_gemini = call_gemini_api(args.query) # ต้องใช้ gemini client จริงๆ
                response_from_gemini = f"นี่คือคำตอบจาก Gemini สำหรับ: \\"{args.query}\\" ครับ"

                log_file.write(f"[{datetime.datetime.now()}] ได้รับคำตอบ: {response_from_gemini}\
")
                print(f"✅ คำตอบ: {response_from_gemini}")
            except Exception as e:
                log_file.write(f"[{datetime.datetime.now()}] ❌ เกิดข้อผิดพลาดระหว่างเรียก API: {e}\
")
                print(f"❌ เกิดข้อผิดพลาดในการเรียก Gemini API ครับ: {e}")
        else:
            log_file.write(f"[{datetime.datetime.now()}] ไม่ได้รับคำสั่ง --query\
")
            print("กรุณาใส่ --query ด้วยนะครับ ตัวอย่าง: python app.py --query \\"สภาพอากาศวันนี้\\"")

if __name__ == "__main__":
    main()

ลองรันดูนะครับ: 1. python your_cli_app_with_log.py --query "เล่าเรื่องสั้นให้ฟังหน่อย" 2. python your_cli_app_with_log.py --query "ทดสอบ Error" --fail แล้วก็ลองเปิดไฟล์ gemini_cli.log ดูครับ จะเห็นว่ามันบันทึกทุกขั้นตอนเลยนะครับ แม้ตอน Error ก็ยังบันทึกได้

จากโค๊ดด้านบน ผมคิดว่าเพื่อนๆ เห็นนะครับ ว่าการใช้ context manager ทำให้การจัดการทรัพยากรพวกไฟล์ Log ง่ายขึ้นเยอะเลยครับ โปรแกรม Python CLI ของเราก็จะมีความ resilience หรือทนทานขึ้นมาก ไม่ต้องกลัว Error ตอนจัดการไฟล์เลยนะครับ และยังช่วย optimization การเขียนโค้ดให้สะอาด และดูแลรักษาง่ายขึ้นด้วยครับ

สรุปนะครับ การที่เราใช้ context manager ช่วยให้ Python CLI ของเราทำงานกับ Gemini API ได้อย่างมี resilience มากขึ้น และก็ยังช่วย optimization การจัดการทรัพยากรด้วยนะครับ เพื่อนๆ ลองนำไปปรับใช้ดูนะครับ

ผู้เขียน cii3.net

Read more

PSG vs Monaco: ศึก 100 นัดเดือด ลีกเอิง และบทเรียนที่ปาร์ค เดส์ แพร็งซ์

PSG vs Monaco: ศึก 100 นัดเดือด ลีกเอิง และบทเรียนที่ปาร์ค เดส์ แพร็งซ์

สรุปผลและวิเคราะห์เกมเดือด PSG พบ Monaco ในลีกเอิงนัดที่ 25 ซึ่งเป็นการพบกันครั้งที่ 100 ในประวัติศาสตร์ลีก ความพ่ายแพ้ 1-3 คาบ้านของ PSG และบทบาทของ Akliouche พร้อมผลกระทบต่อเส้นทางแชมเปี้ยนส์ลีก

By ทีมงาน devdog
บาเยิร์นผงาดไร้เคน! ถล่มกลัดบัค 4-1 โชว์ความลึกของทีมก่อนลุยศึก UCL

บาเยิร์นผงาดไร้เคน! ถล่มกลัดบัค 4-1 โชว์ความลึกของทีมก่อนลุยศึก UCL

บาเยิร์น มิวนิค โชว์ฟอร์มแกร่ง แม้ไม่มีแฮร์รี่ เคน ถล่ม โบรุสเซีย มึนเชนกลัดบัค 4-1 ก่อนเตรียมลุยศึกแชมเปียนส์ลีกกับอตาลันต้า!

By ทีมงาน devdog
PSG: มหาอำนาจลูกหนังฝรั่งเศส กับศึกดวลเดือดโมนาโก และเป้าหมายสู่บัลลังก์ยุโรป

PSG: มหาอำนาจลูกหนังฝรั่งเศส กับศึกดวลเดือดโมนาโก และเป้าหมายสู่บัลลังก์ยุโรป

เจาะลึกเส้นทาง PSG สู่มหาอำนาจลูกหนัง วิเคราะห์สถานการณ์ลีกเอิง เตรียมพร้อมศึกใหญ่กับโมนาโก พร้อมความมุ่งมั่นสู่แชมป์ยุโรป

By ทีมงาน devdog
ลาลีกา: มนต์เสน่ห์ฟุตบอลสเปน, นวัตกรรมเรโทร, และบิ๊กแมตช์แห่งอนาคต

ลาลีกา: มนต์เสน่ห์ฟุตบอลสเปน, นวัตกรรมเรโทร, และบิ๊กแมตช์แห่งอนาคต

สำรวจลาลีกา ฟุตบอลสเปนอันทรงเสน่ห์ พร้อมไฮไลต์บิ๊กแมตช์ 2025/26 นวัตกรรมสัปดาห์เรโทร และบทบาทต่อวัฒนธรรมและเศรษฐกิจ.

By ทีมงาน devdog