Python ile OpenAI Chat API Kullanımı: Adım Adım Rehber
Yapay zeka araçlarını üretim ortamına entegre etmek artık bir lüks değil, rekabet avantajı. Ama çoğu rehber ya çok yüzeysel kalıyor ya da “Hello World” seviyesinde bir örnekle bitiyor. Bu yazıda OpenAI’nin Chat API’sini Python ile gerçekten kullanılabilir şekilde nasıl entegre edeceğini, hata yönetimini, maliyet optimizasyonunu ve production-ready kod yazmayı ele alacağız.
Ortam Hazırlığı ve Kurulum
Önce temiz bir Python sanal ortamı oluşturalım. Bu adımı atlama alışkanlığı edinme, özellikle farklı projelerde farklı OpenAI kütüphane versiyonları kullanıyorsan bağımlılık çakışmaları seni çıldırtır.
# Python sanal ortamı oluştur
python3 -m venv openai-env
source openai-env/bin/activate # Linux/macOS
# Windows için: openai-envScriptsactivate
# Gerekli kütüphaneleri kur
pip install openai python-dotenv tiktoken
# Kurulumu doğrula
pip show openai
API anahtarını düz metin olarak koda gömme. Bu hatayı yapanları git history’de görüyoruz ve bu ciddi bir güvenlik açığı. Bunun yerine .env dosyası kullan:
# .env dosyası oluştur
cat > .env << 'EOF'
OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxxxxx
OPENAI_ORG_ID=org-xxxxxxxxxxxxxxxx
EOF
# .gitignore'a ekle
echo ".env" >> .gitignore
İlk API Çağrısı: Temel Yapı
OpenAI’nin yeni openai Python kütüphanesi (v1.0+) eskisiyle kıyaslandığında oldukça farklı bir yapıya sahip. Eğer eski openai.ChatCompletion.create() tarzı kod görüyorsan, o rehber güncelliğini yitirmiş demektir.
import os
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(
api_key=os.getenv("OPENAI_API_KEY"),
organization=os.getenv("OPENAI_ORG_ID")
)
def basit_sohbet(kullanici_mesaji: str) -> str:
"""Tek turlu basit bir sohbet isteği gönderir."""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": "Sen yardımcı bir asistansın. Türkçe cevap ver."
},
{
"role": "user",
"content": kullanici_mesaji
}
],
max_tokens=500,
temperature=0.7
)
return response.choices[0].message.content
# Test
yanit = basit_sohbet("Linux'ta disk kullanımını nasıl izlerim?")
print(yanit)
model: Hangi modeli kullanacağını belirtir. gpt-4o-mini maliyet açısından çoğu senaryo için idealdir. messages: Konuşma geçmişini taşıyan liste. system, user ve assistant rolleri var. max_tokens: Yanıt için maksimum token sayısı. Bunu ayarlamazsan beklenmedik maliyetlerle karşılaşabilirsin. temperature: 0 ile 2 arasında değer alır. Düşük değer daha tutarlı, yüksek değer daha yaratıcı çıktı üretir.
Çok Turlu Sohbet Yönetimi
Chat API’nin güzelliği bağlamı koruyabilmesi. Ama dikkat et, bağlamı sen yönetmek zorundasın. API her çağrıda sıfırdan başlar, önceki konuşmaları bilmez. Bu yüzden konuşma geçmişini kendin tutman gerekiyor.
import os
from openai import OpenAI
from dotenv import load_dotenv
from typing import List, Dict
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
class SohbetYoneticisi:
"""Çok turlu sohbet bağlamını yöneten sınıf."""
def __init__(self, sistem_mesaji: str = "Sen yardımcı bir asistansın."):
self.gecmis: List[Dict] = []
self.sistem_mesaji = sistem_mesaji
def mesaj_gonder(self, kullanici_mesaji: str, model: str = "gpt-4o-mini") -> str:
# Kullanıcı mesajını geçmişe ekle
self.gecmis.append({
"role": "user",
"content": kullanici_mesaji
})
# API'ye gönderilecek tam mesaj listesini hazırla
tam_mesajlar = [
{"role": "system", "content": self.sistem_mesaji}
] + self.gecmis
response = client.chat.completions.create(
model=model,
messages=tam_mesajlar,
max_tokens=1000,
temperature=0.7
)
asistan_yaniti = response.choices[0].message.content
# Asistan yanıtını da geçmişe ekle
self.gecmis.append({
"role": "assistant",
"content": asistan_yaniti
})
return asistan_yaniti
def gecmisi_temizle(self):
"""Sohbet geçmişini sıfırlar."""
self.gecmis = []
def gecmis_uzunlugu(self) -> int:
return len(self.gecmis)
# Kullanım örneği
sohbet = SohbetYoneticisi("Sen bir Linux sistem yönetimi uzmanısın. Teknik ve net cevaplar ver.")
print(sohbet.mesaj_gonder("Nginx reverse proxy nasıl kurulur?"))
print("---")
print(sohbet.mesaj_gonder("Peki SSL sertifikası nasıl eklerim?"))
print("---")
print(f"Toplam mesaj sayısı: {sohbet.gecmis_uzunlugu()}")
Token Yönetimi ve Maliyet Kontrolü
Bu kısım çoğu geliştirici tarafından görmezden gelinir ve sonunda beklenmedik faturalarla karşılaşılır. Token yönetimi production ortamda kritik öneme sahip.
import tiktoken
from openai import OpenAI
import os
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
def token_say(metin: str, model: str = "gpt-4o-mini") -> int:
"""Verilen metin için token sayısını hesaplar."""
try:
encoding = tiktoken.encoding_for_model(model)
except KeyError:
encoding = tiktoken.get_encoding("cl100k_base")
return len(encoding.encode(metin))
def gecmisi_kirp(
gecmis: list,
maks_token: int = 3000,
model: str = "gpt-4o-mini"
) -> list:
"""
Konuşma geçmişini token limitine göre kırpar.
En eski mesajları siler, sistem mesajını korur.
"""
toplam_token = sum(token_say(m["content"], model) for m in gecmis)
while toplam_token > maks_token and len(gecmis) > 2:
# En eski user/assistant çiftini sil
gecmis.pop(0)
if gecmis and gecmis[0]["role"] == "assistant":
gecmis.pop(0)
toplam_token = sum(token_say(m["content"], model) for m in gecmis)
return gecmis
def kullanim_raporu(response) -> dict:
"""API yanıtından kullanım istatistiklerini çıkarır."""
kullanim = response.usage
return {
"girdi_token": kullanim.prompt_tokens,
"cikti_token": kullanim.completion_tokens,
"toplam_token": kullanim.total_tokens
}
# Test
mesaj = "Python ile Docker API nasıl kullanılır? Detaylı açıkla."
token_sayisi = token_say(mesaj)
print(f"Mesaj token sayısı: {token_sayisi}")
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": mesaj}],
max_tokens=500
)
rapor = kullanim_raporu(response)
print(f"Girdi: {rapor['girdi_token']} token")
print(f"Çıktı: {rapor['cikti_token']} token")
print(f"Toplam: {rapor['toplam_token']} token")
Hata Yönetimi: Production’da Olmazsa Olmaz
API çağrıları her zaman başarılı olmaz. Rate limit’e takılabilirsin, ağ sorunu yaşayabilirsin veya API geçici olarak erişilemez olabilir. Bunları düzgün handle etmezsen uygulaman çöktüğünde saat 3’te uyandırılırsın.
import time
import logging
from openai import OpenAI, RateLimitError, APITimeoutError, APIConnectionError, APIStatusError
import os
from dotenv import load_dotenv
load_dotenv()
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
def api_cagri_yap(
mesajlar: list,
model: str = "gpt-4o-mini",
maks_deneme: int = 3,
bekleme_suresi: float = 1.0
) -> str | None:
"""
Exponential backoff ile hata yönetimli API çağrısı.
"""
for deneme in range(maks_deneme):
try:
response = client.chat.completions.create(
model=model,
messages=mesajlar,
max_tokens=1000,
timeout=30.0
)
return response.choices[0].message.content
except RateLimitError as e:
bekleme = bekleme_suresi * (2 ** deneme)
logger.warning(f"Rate limit aşıldı. {bekleme}s bekleniyor... (Deneme {deneme + 1}/{maks_deneme})")
time.sleep(bekleme)
except APITimeoutError:
logger.error(f"API zaman aşımı. Deneme {deneme + 1}/{maks_deneme}")
if deneme < maks_deneme - 1:
time.sleep(bekleme_suresi)
except APIConnectionError as e:
logger.error(f"Bağlantı hatası: {e}. Deneme {deneme + 1}/{maks_deneme}")
if deneme < maks_deneme - 1:
time.sleep(bekleme_suresi * 2)
except APIStatusError as e:
if e.status_code == 429:
bekleme = bekleme_suresi * (2 ** deneme)
logger.warning(f"429 Too Many Requests. {bekleme}s bekleniyor...")
time.sleep(bekleme)
elif e.status_code >= 500:
logger.error(f"Sunucu hatası ({e.status_code}). Deneme {deneme + 1}")
time.sleep(bekleme_suresi)
else:
logger.error(f"API Hatası: {e.status_code} - {e.message}")
return None
logger.error(f"Maksimum deneme sayısına ulaşıldı ({maks_deneme}). İstek başarısız.")
return None
# Test
mesajlar = [{"role": "user", "content": "Merhaba, nasılsın?"}]
yanit = api_cagri_yap(mesajlar)
if yanit:
print(f"Yanıt: {yanit}")
else:
print("API çağrısı başarısız oldu.")
Streaming ile Gerçek Zamanlı Yanıt
Uzun yanıtlar için kullanıcıyı bekletmek kötü bir deneyim. Streaming kullanarak yanıtı parça parça gösterebilirsin, tıpkı ChatGPT’nin yaptığı gibi.
import os
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
def streaming_yanit(kullanici_mesaji: str, model: str = "gpt-4o-mini") -> str:
"""
Streaming modunda API'den yanıt alır ve ekrana yazar.
Tam yanıtı string olarak döner.
"""
print("Asistan: ", end="", flush=True)
tam_yanit = ""
with client.chat.completions.stream(
model=model,
messages=[
{"role": "system", "content": "Sen yardımcı bir teknik asistansın."},
{"role": "user", "content": kullanici_mesaji}
],
max_tokens=1000
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
tam_yanit += text
print() # Yeni satır
return tam_yanit
# Test
yanit = streaming_yanit("Kubernetes pod'larını nasıl izlerim? Temel komutları ver.")
print(f"nToplam karakter sayısı: {len(yanit)}")
Gerçek Dünya Senaryosu: Log Analiz Asistanı
Şimdi bunları bir araya getirelim. Sistem yöneticileri için gerçekten işe yarayan bir araç: log dosyalarını analiz eden bir asistan.
import os
import re
from pathlib import Path
from openai import OpenAI
from dotenv import load_dotenv
import logging
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
logger = logging.getLogger(__name__)
def log_dosyasi_oku(dosya_yolu: str, son_n_satir: int = 100) -> str:
"""Log dosyasının son N satırını okur."""
try:
yol = Path(dosya_yolu)
if not yol.exists():
return f"Dosya bulunamadı: {dosya_yolu}"
with open(yol, 'r', encoding='utf-8', errors='ignore') as f:
satirlar = f.readlines()
return ''.join(satirlar[-son_n_satir:])
except PermissionError:
return f"İzin hatası: {dosya_yolu} dosyasına erişilemiyor."
except Exception as e:
return f"Okuma hatası: {str(e)}"
def hassas_bilgi_temizle(log_metni: str) -> str:
"""Log metninden IP, email gibi hassas bilgileri maskeler."""
# IP adresleri
log_metni = re.sub(
r'b(?:d{1,3}.){3}d{1,3}b',
'X.X.X.X',
log_metni
)
# Email adresleri
log_metni = re.sub(
r'b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Z|a-z]{2,}b',
'[email protected]',
log_metni
)
return log_metni
def log_analiz_et(
log_metni: str,
analiz_turu: str = "genel"
) -> str:
"""
Log metnini AI ile analiz eder.
analiz_turu: 'genel', 'hata', 'guvenlik', 'performans'
"""
sistem_mesajlari = {
"genel": "Sen bir Linux sistem yönetimi uzmanısın. Log dosyalarını analiz ederek önemli olayları, hataları ve anormallikleri tespit et.",
"hata": "Sen bir hata analizi uzmanısın. Log'lardaki ERROR ve CRITICAL mesajlarına odaklan, olası nedenleri ve çözüm önerilerini sun.",
"guvenlik": "Sen bir siber güvenlik uzmanısın. Log'larda güvenlik ihlali, yetkisiz erişim girişimi veya şüpheli aktivite belirtilerini ara.",
"performans": "Sen bir sistem performans uzmanısın. Log'lardaki yavaşlık, timeout ve kaynak kullanım sorunlarını tespit et."
}
sistem_mesaji = sistem_mesajlari.get(analiz_turu, sistem_mesajlari["genel"])
kullanici_prompt = f"""Aşağıdaki log çıktısını analiz et ve şunları belirt:
1. Kritik sorunlar (varsa)
2. Uyarılar ve dikkat edilmesi gerekenler
3. Genel sistem durumu değerlendirmesi
4. Önerilen aksiyonlar
LOG ÇIKTISI:
{log_metni}
Yanıtını madde madde ve açık Türkçe ile ver."""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": sistem_mesaji},
{"role": "user", "content": kullanici_prompt}
],
max_tokens=1500,
temperature=0.3 # Analiz için düşük temperature daha tutarlı
)
return response.choices[0].message.content
def log_asistani_calistir(dosya_yolu: str, analiz_turu: str = "genel"):
"""Ana log analiz iş akışını çalıştırır."""
print(f"Log dosyası okunuyor: {dosya_yolu}")
ham_log = log_dosyasi_oku(dosya_yolu, son_n_satir=200)
temiz_log = hassas_bilgi_temizle(ham_log)
print(f"Analiz türü: {analiz_turu}")
print("AI analizi yapılıyor...n")
analiz = log_analiz_et(temiz_log, analiz_turu)
print("ANALIZ SONUCU:")
print("=" * 50)
print(analiz)
print("=" * 50)
return analiz
# Örnek kullanım
# log_asistani_calistir("/var/log/nginx/error.log", "hata")
# log_asistani_calistir("/var/log/auth.log", "guvenlik")
# log_asistani_calistir("/var/log/syslog", "genel")
# Test için sahte log verisi
test_log = """
2024-01-15 14:23:01 ERROR nginx: connect() failed (111: Connection refused) while connecting to upstream
2024-01-15 14:23:01 ERROR nginx: connect() failed (111: Connection refused) while connecting to upstream
2024-01-15 14:23:15 WARNING disk: /dev/sda1 kullanımı %87 seviyesine ulaştı
2024-01-15 14:24:00 INFO nginx: worker process started
2024-01-15 14:25:33 ERROR mysql: Too many connections
2024-01-15 14:26:00 CRITICAL systemd: service postgresql failed to start
"""
print(log_analiz_et(test_log, "hata"))
Yapılandırma ve Model Seçimi
Farklı görevler için doğru modeli seçmek hem maliyet hem de performans açısından kritik:
gpt-4o-mini: Basit sınıflandırma, metin özetleme, rutin sorular için idealdir. En düşük maliyetli seçenek. gpt-4o: Karmaşık analiz, kod inceleme, çok adımlı akıl yürütme gerektiren görevler için kullan. gpt-4-turbo: Büyük bağlam penceresi gereken durumlarda, örneğin uzun doküman analizi için tercih edilir. temperature=0: Kod üretimi ve faktüel sorular için. Tutarlı ve tekrarlanabilir çıktı. temperature=0.7: Genel sohbet ve açıklama görevleri için denge noktası. temperature=1.0+: Yaratıcı yazı veya beyin fırtınası için. Tahmin edilemez ama yaratıcı.
# Hangi modellere erişimin olduğunu kontrol et
python3 - << 'EOF'
import os
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
modeller = client.models.list()
gpt_modeller = [m.id for m in modeller.data if "gpt" in m.id]
gpt_modeller.sort()
print("Erişilebilir GPT modeller:")
for model in gpt_modeller:
print(f" - {model}")
EOF
Sonuç
OpenAI Chat API’yi Python ile entegre etmek göründüğünden çok daha katmanlı bir konu. Temel API çağrısını yapmak 10 satır kod meselesi, ama bunu production’a taşımak; hata yönetimi, token kontrolü, bağlam yönetimi ve maliyet optimizasyonu gerektiriyor.
Bu yazıda ele aldığımız konular pratikte sana şunları kazandırır: Güvenli kimlik bilgisi yönetimi ile API anahtarı sızıntısı riskini ortadan kaldırırsın. Exponential backoff ve hata yönetimi ile uygulamanın geçici API sorunlarında ayakta kalmasını sağlarsın. Token takibi ile faturanın sonunda sürprizle karşılaşmazsın. Streaming ile kullanıcı deneyimini ciddi ölçüde iyileştirirsin.
Log analiz senaryosu başlangıç noktası. Bunu Grafana alert’leriyle, Slack bildirimleriyle veya otomatik ticket oluşturmayla birleştirebilirsin. Sysadmin iş yükünün büyük bir kısmını, özellikle tekrarlayan log okuma ve hata analizi görevlerini, bu tür araçlarla otomatikleştirebilirsin.
Bir sonraki adım olarak function calling ve structured outputs konularına bakmanı öneririm. API’ye belirli bir JSON formatında yanıt vermesini söyleyebiliyorsun; bu da otomasyon pipeline’larına entegrasyon için çok daha güçlü bir yapı sunuyor.
