İçeriğe geç
Educora
İleri18 dk26 / 42

Web API'leri ve requests kütüphanesi

HTTP nasıl çalışır: metotlar, durum kodları, başlıklar ve JSON. `requests` ile GET ve POST istekleri, `params`, `headers`, `timeout`, `raise_for_status`, hata yönetimi ve API anahtarlarının güvenli saklanması.

Kendini test et
Bu derste öğreneceklerin
  • Bir HTTP isteğinin ve yanıtının parçalarını, temel metotları ve durum kodlarını açıklamak
  • requests ile parametreli GET ve JSON gövdeli POST istekleri göndermek
  • Zaman aşımı, raise_for_status ve istisnalarla sağlam kod yazmak, API anahtarlarını gizli tutmak

Telefonundaki hava durumu, bir bankanın döviz kurları, haritadaki bir rota: programlar bu verilerin hepsini sunuculardan API (Application Programming Interface) aracılığıyla alır. Educora uygulamaları da dersleri sitenin API'sinden yükler. Bir web API'si basit bir anlaşmadır: belirli bir adrese HTTP isteği gönderirsin, sunucu da genellikle JSON bir yanıt döndürür. Python'da bunun en popüler aracı requests kütüphanesidir.

Kısaca HTTP

Bir istek dört parçadan oluşur: metot (ne yapılacağı), URL (nereye), başlıklar (ek bilgi: biçim, anahtar) ve gövde (gönderilen veri, örneğin JSON). Bir yanıt ise durum kodu, başlıklar ve gövdeden oluşur. URL'deki ? işaretinden sonraki kısım sorgu parametreleridir (query string): ?city=Baku&units=metric.

Text
GET /v1/weather?city=Baku&units=metric HTTP/1.1
Host: api.example.com
Accept: application/json

HTTP/1.1 200 OK
Content-Type: application/json

{"city": "Baku", "temp": 24.5, "wind": 7.2, "description": "sunny"}
Bir istek ve yanıt “içeriden” böyle görünür. api.example.com, belgeler için ayrılmış örnek bir adrestir; dersteki tüm yanıtlar temsilîdir.
MetotAnlamıÖrnek
GETveri okumakGET /v1/tasks
POSTyeni bir nesne oluşturmakPOST /v1/tasks
PUT / PATCHnesneyi tamamen / kısmen güncellemekPATCH /v1/tasks/42
DELETEnesneyi silmekDELETE /v1/tasks/42
KodAnlamı
200, 201, 204başarılı: OK, oluşturuldu, içerik yok
301, 302yönlendirme — başka bir adrese bak
400, 401, 403, 404istemci hatası: hatalı istek, giriş yok, yetki yok, bulunamadı
429çok fazla istek — sınır aşıldı, bekle
500, 503sunucu hatası, hizmet kullanılamıyor

requests ile istekler

Kütüphaneyi bilgisayarına kur: pip install requests. Tarayıcıdaki Python ağ istekleri gönderemez; bu yüzden bu dersin kodu burada çalıştırılamaz, onu kendi bilgisayarında dene. requests.get bir yanıt nesnesi döndürür: status_code, headers, text, json(). Parametreleri URL'ye elle yapıştırma: params sözlüğü onları doğru kodlar; örneğin “Sumqayıt” Sumqay%C4%B1t olur.

Python
import requests

url = 'https://api.example.com/v1/weather'
params = {'city': 'Baku', 'units': 'metric'}
headers = {'Accept': 'application/json'}

response = requests.get(url, params=params, headers=headers, timeout=10)
print(response.status_code)
print(response.url)
print(response.headers['Content-Type'])
data = response.json()
print(data['city'], data['temp'])
Beklenen çıktı
200
https://api.example.com/v1/weather?city=Baku&units=metric
application/json
Baku 24.5
response.json() JSON gövdesini bir Python sözlüğüne çevirir. Çıktı bir örnektir: gerçek bir API farklı bir sıcaklık döndürür.

Yeni bir nesne oluşturmak için POST göndeririz. json= argümanı sözlüğü JSON'a çevirir ve Content-Type: application/json başlığını kendisi ekler. Başarılı bir oluşturmada sunucu genellikle 201 kodunu ve yeni nesneyi (kimliğiyle birlikte) döndürür.

Python
import requests

new_task = {'title': 'Finish the pandas lesson', 'done': False}
r = requests.post('https://api.example.com/v1/tasks', json=new_task, timeout=10)
print(r.status_code)
print(r.json())
print(r.request.headers['Content-Type'])
Beklenen çıktı
201
{'id': 42, 'title': 'Finish the pandas lesson', 'done': False}
application/json

Hatalar, zaman aşımları ve raise_for_status

Dikkat: 404 ya da 500 yanıtı requests için bir hata değildir; kod sessizce devam eder. raise_for_status(), 4xx ve 5xx kodlarında HTTPError fırlatır. Ağ sorunları ise ayrı istisnalardır: Timeout, ConnectionError; hepsi requests.exceptions.RequestException sınıfından türer.

Python
import requests

def get_json(url, **params):
    try:
        r = requests.get(url, params=params, timeout=5)
        r.raise_for_status()
        return r.json()
    except requests.exceptions.Timeout:
        print('The server did not answer in time')
    except requests.exceptions.HTTPError as e:
        print('HTTP error:', e.response.status_code)
    except requests.exceptions.RequestException as e:
        print('Network problem:', type(e).__name__)
    return None

print(get_json('https://api.example.com/v1/weather', city='Atlantis'))
Beklenen çıktı
HTTP error: 404
None
Özel istisnalar genel olandan (RequestException) önce yazılır; aksi hâlde onlara hiç sıra gelmez.

API anahtarlarının güvenliği

Çoğu API seni bir anahtarla (API anahtarı, token) tanır. Anahtar bir parola gibidir: onu bilen herkes senin adına istek gönderebilir, limitini tüketebilir, hatta masraf çıkarabilir. Kurallar:

  • Anahtarı asla kodun içine yazma ve Git'e commit etme; onu bir ortam değişkeninde sakla.
  • Bir .env dosyası kullanıyorsan onu .gitignore dosyasına ekle.
  • API izin veriyorsa anahtarı URL'de değil, başlıkta gönder: URL'ler kayıtlarda ve tarayıcı geçmişinde kalır.
  • Gizli bir anahtarı tarayıcı ya da mobil uygulama koduna koyma; herhangi bir kullanıcı onu çıkarabilir. Bu tür istekleri kendi sunucun üzerinden gönder.
  • Bir anahtar sızdıysa onu hemen iptal et ve yenisini oluştur.
Terminal
# Linux / macOS
export WEATHER_API_KEY='paste-your-key-here'

# Windows PowerShell
$env:WEATHER_API_KEY = 'paste-your-key-here'
Değişken yalnızca mevcut terminal oturumunda yaşar; kalıcı olarak saklamak için işletim sisteminin ayarlarını ya da bir .env dosyasını kullan.
Python
import os
import requests

api_key = os.environ.get('WEATHER_API_KEY')
if not api_key:
    raise SystemExit('Set the WEATHER_API_KEY environment variable first')

session = requests.Session()
session.headers.update({'Authorization': f'Bearer {api_key}'})
r = session.get('https://api.example.com/v1/weather', params={'city': 'Baku'}, timeout=10)
r.raise_for_status()
print(r.json()['description'])
Beklenen çıktı
sunny
Anahtar kodun dışında kalır; Session onu her isteğin başlığına kendisi ekler. Başlığın tam adı (Authorization, X-API-Key vb.) API'nin belgelerinde yazar.

Önemli noktalar

  • HTTP isteği: metot, URL, başlıklar, gövde; yanıt: durum kodu, başlıklar, gövde (çoğu zaman JSON).
  • GET okur, POST oluşturur, PUT/PATCH günceller, DELETE siler; 2xx başarı, 4xx istemci, 5xx sunucu hatasıdır.
  • requests.get(url, params=..., headers=..., timeout=...) ve requests.post(url, json=...); sonuç r.json() ile alınır.
  • Her zaman timeout ver ve raise_for_status() çağır; istisnaları özelden genele doğru yakala.
  • API anahtarı bir ortam değişkeninde saklanır, başlıkta gönderilir ve asla Git'e girmez; sızarsa iptal edilir.

Kendini test et

10 soru. Her doğru cevap XP kazandırır.

1 / 10
Sunucu 404 döndürdü. requests.get(...) ne yapar?