Kurs
Uygulama Programlama Arabirimleri (API’ler) yazılım aracılardır. Görevleri, uygulamaların birbiriyle iletişim kurmasına izin vermektir. Bu görünmez aracılar, farkında olsanız da olmasanız da günlük hayatta karşınıza çıkar. Örneğin, bugün bir anlık mesaj gönderdiyseniz bir API kullandınız.
Daha özel olarak, API’ler insanların kod kullanarak veri göndermesine ve almasına olanak tanır. Ancak, API’lerin veri almak için kullanılması daha yaygındır. Örneğin, bu blog yazısını okuyabiliyorsunuz çünkü web tarayıcınız bu sayfayı oluşturan verileri DataCamp sunucusundan aldı.
Fakat web sunucuları rastgele veri göndermez. Bu, bir restorana gidip garsonun size rastgele bir yemek getirmesine benzerdi. Sunucunun veri göndermeden önce bir isteğin iletilmesi gerekir. Bu, restorandaki garson için de geçerlidir; bir API’den veri almak istiyorsanız sunucuya bir API isteği gönderirsiniz ve o da uygun verilerle yanıt verir.
Bu yazıda, requests kitaplığının bazı temel bileşenlerini adım adım ele alacak ve başlamanıza yardımcı olacak bazı kod örnekleri sunacağız. requests kitaplığı öğrenmeye değerdir çünkü Python’da HTTP istekleri göndermenin fiilî endüstri standardıdır. Göreceğiniz üzere, istek oluşturmanın tüm zorluklarını yalın bir API’nin arkasında izole eder; böylece hizmetlerle iletişime ve uygulamanızda veri tüketmeye odaklanabilirsiniz.
Bu eğitimdeki kodu çevrimiçi olarak çalıştırın ve düzenleyin
Kodu çalıştırPython requests Modülünü Kullanarak GET ve POST İstekleri Yapma
Aceleniz mi var? İşte basit bir GET ve POST isteği yapmak için Python söz dizimi:
1. GET isteği
import requests
# The API endpoint
url = "https://jsonplaceholder.typicode.com/posts/1"
# A GET request to the API
response = requests.get(url)
# Print the response
print(response.json())
2. POST isteği
import requests
# The API endpoint
url = "https://jsonplaceholder.typicode.com/posts"
# Data to be sent
data = {
"userID": 1,
"title": "Making a POST request",
"body": "This is the data we created."
}
# A POST request to the API
response = requests.post(url, json=data)
# Print the response
print(response.json())
REST API’leri ve HTTP Temellerini Anlamak
API’lerin yazılım aracısı olduğunu belirledik. Başka bir deyişle, diğer uygulamalara belirli verilere ve yöntemlere erişim tanıyan bir yazılım arayüzü türü olarak düşünebilirsiniz.
API’leri oluşturmak için kullanılan en popüler mimarilerden biri, REpresentational State Transfer (REST) desenidir. REST mimari tasarımı, istemci ve sunucunun birbirinden bağımsız ve birbirinden habersiz şekilde uygulanabilmesini sağlar. Bu da her iki taraftaki kodun, diğerini nasıl etkileyeceği konusunda endişe etmeden değiştirilebileceği anlamına gelir.
Dolayısıyla REST API’leri, yazılımlar arasındaki iletişimi basitleştirmeyi amaçlayan bir dizi yönergeyi takip eder; böylece verilere erişme süreci daha doğrudan ve mantıklı hale gelir. Bu yönergeleri bilmiyorsanız endişelenmeyin; başlamak için bunları bilmenize gerek yok – bilmeniz gereken, verilerin REST hizmetlerinden nasıl sunulduğudur.
REST web hizmetlerindeki veriler, bir HTTP isteği gönderilerek erişilebilen herkese açık bir URL üzerinden internete sunulur.
HTTP İstek Yöntemlerine Genel Bakış
Restoran benzetmesine geri dönelim; restoranda yemek söylemek için garson yanınıza gelir ve siz ne istediğinizi söylersiniz. Garson, isteğinizi aşçıya iletir; aşçı yemeği hazırlar ve garsona verir, o da size getirir. Başka bir deyişle, isteğiniz iletilmeden aşçı yemeğinizi pişirmez.
REST API’lerinde de durum aynıdır: İşlem yapmadan önce HTTP istek yöntemlerini dinlerler. HTTP, bir kaynak için API’nin hangi işlemleri gerçekleştireceğini söyleyen bir dizi istek yöntemi tanımlar. Verilen uç noktadaki kaynaklarla nasıl etkileşime geçileceğini belirtir.
Birçok HTTP yöntemi vardır, ancak REST API’lerinde yaygın olarak kullanılan beşi şunlardır:
| HTTP Yöntemi | Açıklama |
|---|---|
| GET | Veri alma |
| POST | Veri oluşturma |
| PUT | Mevcut veriyi güncelleme |
| PATCH | Mevcut veriyi kısmen güncelleme |
| DELETE | Veri silme |
Veri analizi ve veri biliminde en çok GET isteklerini yapmanız muhtemeldir. Bunun nedeni, belirli veri setlerine erişmek için gerekli yöntem olmasıdır. Bunun hakkında daha fazla bilgi için DataCamp’in Intermediate Importing Data in Python kursuna göz atın.
Bir web sunucusuna istek yaptığınızda, API bir yanıt döndürür. Bu yanıtla birlikte bir HTTP durum kodu gelir. Durum kodunun amacı, yanıt hakkında ek bilgi sağlayarak istemcinin alınan yanıtın türünü bilmesini sağlamaktır.
API Uç Noktaları Nedir?
Bir URL, bir web sunucusundaki hangi verilerle etkileşime girdiğinizi tanımlar. Bir web sayfası URL’sinin tek bir sayfaya bağlı olması gibi, bir uç nokta URL’si de bir API içindeki belirli kaynaklara bağlıdır. Bu nedenle bir uç nokta, bir API’nin sunucusundaki belirli bir kaynakla ilgili sorguları aldığı dijital bir konum olarak tanımlanabilir — iletişim kanalının diğer ucu gibi düşünebilirsiniz.
Daha fazla bağlam eklemek gerekirse, REST API’leri, istemci uygulamaların web hizmetinin kaynaklarına erişmek için istekte bulunabileceği bir dizi herkese açık URL sunar. REST API’nin sunduğu bu herkese açık URL’ler “uç noktalar” olarak adlandırılır.
HTTP İsteklerini Yapmak için Python Kullanma
Python requests modülü geliştiricilerin REST API’lerle etkileşim kurmak için kod yazmasına olanak tanır. Sorgu dizelerini URL’lere elle ekleme, PUT ve POST verilerini form-encode etme gibi bu tür görevlerle birlikte gelen karmaşıklıklarla uğraşmak zorunda kalmadan Python kullanarak HTTP istekleri göndermeyi mümkün kılar.
Python’da HTTP istekleri yapmak için fiilî standart olarak kabul edilmesine rağmen, requests modülü Python’un standart kütüphanesinin bir parçası değildir – ayrıca kurulmalıdır.
Requests modülünü kurmanın en basit yolu pip ile kurmaktır:
python -m pip install requests
Farklı projeler için gereken Python paketlerinin sanal ortamlar kullanılarak yönetilmesi her zaman önerilir; böylece paketler yalıtılmış olur ve bir projedeki paketler diğer projelerdeki sistem araçlarına müdahale edip onları bozmaz – küresel olarak kurulmak yerine.
Artık requests modülünü kurduğumuza göre, nasıl çalıştığını görelim. Bu DataLab çalışma kitabındaki kodu adım adım takip edin.
Python’da GET isteği yapmak
GET’in, REST API’leriyle çalışırken en sık karşılaşacağınız HTTP istek yöntemlerinden biri olduğunu zaten belirtmiştik. Sunuculardan veri almanızı sağlar.
GET’in salt-okunur bir işlem olduğunu, yani yalnızca mevcut kaynaklara erişim için uygun olduğunu ve bunları değiştirmek için kullanılmaması gerektiğini unutmamak önemlidir.
Requests modülünün nasıl çalıştığını göstermek için, test ve prototipleme amacıyla serbestçe kullanılabilen bir sahte API olan JSONPlaceholder’ı kullanacağız.
import requests
# The API endpoint
url = "https://jsonplaceholder.typicode.com/posts/1"
# A GET request to the API
response = requests.get(url)
# Print the response
response_json = response.json()
print(response_json)
"""
{'userId': 1, 'id': 1, 'title': 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', 'body': 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto'}
"""
Yukarıdaki kodda şunları yaptık:
-
Veri alınacak API uç noktasını tanımladık.
-
Belirlenen uç noktadan veri almak için
requests.get(url)yöntemini kullandık. -
response.json()yöntemini kullanarak yanıt verilerini bir sözlük nesnesinde sakladık; bunun yalnızca sonuç JSON formatında olduğundan çalıştığını unutmayın – aksi halde bir hata oluşurdu. -
Son adım olarak JSON yanıt verilerini yazdırdık.
API’den dönen durum kodunu da şu şekilde kontrol edebiliriz:
# Print status code from original response (not JSON)
print(response.status_code)
"""
200
"""
Python’da bir GET isteğine argümanlar da gönderebilirsiniz. Bunu yapmak için yukarıdaki kodu biraz değiştirmemiz gerekir. Yeni kod şu şekilde görünüyor:
# The API endpoint
url = "https://jsonplaceholder.typicode.com/posts/"
# Adding a payload
payload = {"id": [1, 2, 3], "userId":1}
# A get request to the API
response = requests.get(url, params=payload)
# Print the response
response_json = response.json()
for i in response_json:
print(i, "\n")
"""
{'userId': 1, 'id': 1, 'title': 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit', 'body': 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto'}
{'userId': 1, 'id': 2, 'title': 'qui est esse', 'body': 'est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla'}
{'userId': 1, 'id': 3, 'title': 'ea molestias quasi exercitationem repellat qui ipsa sit aut', 'body': 'et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut'}
"""
Farklı olarak yaptıklarımız şunlar:
-
API uç noktasını değiştirdik. Sonda artık
1olmadığını fark edin. -
Yükü (payload) bir sözlükte tanımladık.
-
Yükü,
requests.get()yöntemininparamargümanına aktardık. -
Bu bir liste nesnesi döndürdü; bu yüzden liste üzerinde döngü kurup her bir öğeyi yeni satırda yazdırdık.
Python’da POST isteği yapmak
GET istekleri veri almanızı sağlar; POST istekleri ise yeni veri oluşturmanıza olanak tanır. JSONPlaceholder sunucusunda nasıl yeni veri oluşturabileceğimize bakalım.
# Define new data to create
new_data = {
"userID": 1,
"id": 1,
"title": "Making a POST request",
"body": "This is the data we created."
}
# The API endpoint to communicate with
url_post = "https://jsonplaceholder.typicode.com/posts"
# A POST request to tthe API
post_response = requests.post(url_post, json=new_data)
# Print the response
post_response_json = post_response.json()
print(post_response_json)
"""
{'userID': 1, 'id': 101, 'title': 'Making a POST request', 'body': 'This is the data we created.'}
"""
Yukarıdaki kodda şu adımları uyguladık:
-
JSONPlaceholder API’sine eklemek istediğimiz yeni bir kaynak oluşturduk.
-
Yeni veriyi
POSTedeceğimiz uç noktayı tanımladık. -
requests.post()yöntemiyle birPOSTisteği gönderdik.post()yöntemindejsonparametresini ayarladığımıza dikkat edin; bunu, belirtilen URL’ye açıkça bir JSON nesnesi gönderdiğimizi API’ye bildirmek için yapıyoruz. -
response.json()yöntemiyle yanıt verilerini bir sözlük nesnesinde sakladık. -
Son adım olarak JSON yanıt verilerini yazdırdık.
Ama, durun!
Sıradaki kodu okumadan önce, API’nin hangi durum kodunu döndüreceğini düşünmek için 20 saniye ayırın.
Unutmayın: bu kez yalnızca almak yerine yeni bir kaynak oluşturduk.
Tamam, geliyor…
# Print status code from original response (not JSON)
print(post_response.status_code)
"""
201
"""
Python HTTP İsteklerinde İleri Konular
Python ile HTTP istekleri yapmak genellikle basittir; ancak bazen daha gelişmiş bir kurulum gerekebilir ya da sorunlarla karşılaşmak kaçınılmaz olabilir. İşte karşılaşabileceğiniz bazı zorluklar ve bunları nasıl çözebileceğiniz.
HTTP isteklerini kimlik doğrulama
Şimdiye kadar REST API ile etkileşimlerimiz oldukça basitti. JSONPlaceholder API’si, etkileşime başlamanız için herhangi bir kimlik doğrulama gerektirmez. Ancak, özellikle hassas verilerle uğraşırken, erişim verilmeden önce belirli uç noktalar için kimlik doğrulaması gerekebilecek birçok durum vardır.
Örneğin, GitHub’da entegrasyonlar oluşturmak, veri almak ve iş akışlarınızı otomatikleştirmek istiyorsanız, bunu GitHub REST API ile yapabilirsiniz. Ancak, doğrulanmış kullanıcılar hakkında genel ve özel bilgilerin alınması gibi GitHub REST API’de kimlik doğrulaması gerektiren birçok işlem vardır.
Python requests modülünü kullanarak basit bir çözüm yolu şöyle olabilir:
from requests.auth import HTTPBasicAuth
private_url = "https://api.github.com/user"
github_username = "username"
token = "token"
private_url_response = requests.get(
url=private_url,
auth=HTTPBasicAuth(github_username, token)
)
private_url_response.status_code
"""
200
"""
Yukarıdaki kodda şunları yaptık:
-
HTTPBasicAuthnesnesinirequests.auth’tan içe aktardık. Bu nesne, HTTP temel kimlik doğrulamasını verilen istek nesnesine ekler — özünde bir web sitesine kullanıcı adı ve şifre yazmakla aynıdır. -
Erişilecek özel URL uç noktasını tanımladık.
-
Bir GitHub kullanıcı adıyla bir değişken oluşturduk – gizlilik için kullanıcı adını anonimleştirdik.
-
Kimlik doğrulama için bir kişisel erişim jetonu ile bir GitHub değişkeni oluşturduk.
-
Uç noktamızdan verileri alıp
private_url_responsedeğişkeninde depoladık. -
Durum kodunu görüntüledik.
HTTP istek hatalarını ele alma
Bir API’ye yapılan isteklerin beklendiği gibi gitmediği durumlar vardır. İstemci ya da sunucu tarafında rol oynayabilecek çeşitli etkenler olabilir. Nedenden bağımsız olarak sonuç aynıdır: istek başarısız olur.
REST API’lerini kullanırken kodunuzu dayanıklı hale getirmek her zaman iyi bir fikirdir. Ancak sağlam kod yazmadan önce, işler plana göre gitmediğinde bildirilen hataları nasıl yöneteceğinizi anlamanız gerekir.
Bu gösterim için JSONPlaceholder API’sine dönelim. Önce biraz kod yazacağız, ardından neler olduğunu açıklayacağız.
# A deliberate typo is made in the endpoint "postz" instead of "posts"
url = "https://jsonplaceholder.typicode.com/postz"
# Attempt to GET data from provided endpoint
try:
response = requests.get(url)
response.raise_for_status()
# If the request fails (404) then print the error.
except requests.exceptions.HTTPError as error:
print(error)
"""
404 Client Error: Not Found for url: https://jsonplaceholder.typicode.com/postz
"""
Yukarıdaki kodda:
-
Veri almak için JSONPlaceholder uç noktasını tanımladık, ancak URL’yi oluştururken bilerek bir yazım hatası yaptık – bu, 404 hatası verecektir.
-
Python’un yerleşik istisna yakalama yapısını kullanarak JSONPlaceholder uç noktasını ziyaret etmeye çalışırken oluşan hataları
tryveexceptbloklarıyla yakaladık. Hata oluştuğunda birHTTPErrornesnesi döndürmek için kullanılan yönteminraise_for_status()olduğuna dikkat edin. -
Ve son olarak, oluşan hatayı yazdırdık.
Bu örnekte 404 durum kodlarını nasıl ele alacağımızı gösterdik, ancak aynı format herhangi bir HTTP durum kodunu ele almak için de kullanılabilir.
Çok fazla yönlendirmeyle başa çıkma
3xx biçimindeki HTTP durum kodları, istemcinin yönlendirildiğini ve isteği tamamlamak için ek işlemler yapması gerektiğini gösterir. Ancak bu, zaman zaman sonsuz bir yönlendirme döngüsüne yol açabilir.
Python’un requests modülü, bu sorunu şu şekilde ele almak için TooManyRedirects nesnesini sağlar:
"""
Note: The code here will not raise an error
but the structure is how you would hand a case where there
are multiple redirects
"""
url = "https://jsonplaceholder.typicode.com/posts"
try:
response = requests.get(url)
response.raise_for_status()
except requests.exceptions.TooManyRedirects as error:
print(error)
Maksimum yönlendirme sayısını HTTP istek yönteminizin bir parametresi olarak da ayarlayabilirsiniz:
# Solution 2
url = "https://jsonplaceholder.typicode.com/posts"
session = requests.Session()
session.max_redirects = 3
response = session.get(url)
Başka bir seçenek de yönlendirmeleri tamamen devre dışı bırakmaktır:
# Solution 3
url = "https://jsonplaceholder.typicode.com/posts"
session = requests.Session()
session.allow_redirects = False
response = session.get(url)
HTTP isteklerinde bağlantı hatalarını ele alma
Sunucuya istek göndermeye çalışırken karşılaşabileceğiniz başka tür hatalar da vardır. Sunucudan yanıt alamamanızın çeşitli nedenleri olabilir (örn. DNS hatası, bağlantı reddi, internet bağlantısı sorunları vb.), ancak sonuç aynıdır: bir bağlantı hatası oluşur.
Bu sorunları yakalayıp uygun şekilde ele almak için requests modülünün ConnectionError istisna nesnesini kullanabilirsiniz.
Kod şu şekilde görünecektir:
"""
Note: The code here will not raise an error
but the structure is how you would hand a case where there
is a connection error.
"""
url = "https://jsonplaceholder.typicode.com/posts"
try:
response = requests.get(url)
except requests.ConnectionError as error:
print(error)
HTTP isteklerinde zaman aşımını ele alma
API sunucusu bağlantınızı kabul edip, izin verilen süre içinde isteğinizi tamamlayamazsa “zaman aşımı hatası” alırsınız.
Bu durumu, requests.get() yöntemindeki timeout parametresini aşırı küçük bir sayıya ayarlayarak nasıl ele alacağımızı göstereceğiz; bu bir hata oluşturacak ve biz de bu hatayı requests.Timeout nesnesini kullanarak ele alacağız.
url = "https://jsonplaceholder.typicode.com/posts"
try:
response = requests.get(url, timeout=0.0001)
except requests.Timeout as error:
print(error)
Zaman aşımı hataları için en basit çözüm, daha uzun zaman aşımı değerleri belirlemektir. Diğer çözümler arasında isteklerinizi optimize etmek, betiklerinize yeniden deneme döngüsü eklemek veya eşzamanlı olmayan API çağrıları yapmak yer alabilir – bu teknik, yazılımınızın uzun sürebilecek bir işlemi başlatırken tamamlanmasını beklemek yerine diğer olaylara yanıt verebilmesini sağlar.
Özet
Bu eğitimde, API’lerin ne olduğunu ele aldık ve REST adı verilen yaygın bir API mimarisini inceledik. Ayrıca HTTP yöntemlerine ve Python requests kitaplığını kullanarak web hizmetleriyle nasıl etkileşim kurabileceğimize baktık.
Veri bilimi becerilerinizi geliştirmek için şu kurslara göz atın:
SSS
Python HTTP isteklerinde özel başlıkları (headers) nasıl ele alırsınız?
HTTP isteklerinize özel başlıklar eklemek için isteğinizdeki headers parametresine bir sözlük geçebilirsiniz. Örneğin:
import requests
url = "https://jsonplaceholder.typicode.com/posts"
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
response = requests.get(url, headers=headers)
print(response.json())
requests modülünde bir session nesnesi kullanmanın faydaları nelerdir?
requests modülünde bir Session nesnesi kullanmanın birkaç faydası vardır:
- Kalıcı Bağlantılar: Birden çok istek boyunca bağlantıyı korur, performansı artırır.
- Oturum Genelinde Ayarlar: Oturum üzerinden yapılan tüm istekler için başlıkları, çerezleri ve parametreleri bir kez ayarlamanıza olanak tanır.
- Çerez Kalıcılığı: Çerezleri otomatik olarak ele alır ve istekler arasında kalıcı kılar.
İşte bir örnek:
import requests
session = requests.Session()
session.headers.update({"Authorization": "Bearer YOUR_ACCESS_TOKEN"})
response = session.get("https://jsonplaceholder.typicode.com/posts")
print(response.json())
Python’da bir POST isteğiyle dosya nasıl gönderilir?
Bir POST isteğiyle dosya göndermek için files parametresine bir sözlük geçebilirsiniz. Örneğin:
import requests
url = "https://example.com/upload"
file_path = "/path/to/your/file.txt"
with open(file_path, 'rb') as file:
files = {'file': file}
response = requests.post(url, files=files)
print(response.status_code)
requests modülünü proxy kullanacak şekilde nasıl yapılandırabilirsiniz?
requests modülünde proxy yapılandırmasını, proxies parametresine bir sözlük geçirerek yapabilirsiniz. Örneğin:
import requests
url = "https://jsonplaceholder.typicode.com/posts"
proxies = {
"http": "http://10.10.1.10:3128",
"https": "http://10.10.1.10:1080",
}
response = requests.get(url, proxies=proxies)
print(response.json())
Python requests modülüyle HTTP istekleri yaparken zaman aşımını nasıl ele alırsınız?
Zaman aşımını, isteğinizde saniye cinsinden bir değer alan timeout parametresini belirterek ele alabilirsiniz. Örneğin:
import requests
url = "https://jsonplaceholder.typicode.com/posts"
try:
response = requests.get(url, timeout=5) # 5 saniye sonra zaman aşımı
print(response.json())
except requests.Timeout:
print("İstek zaman aşımına uğradı")
