Month: Şubat 2009

Nasıldır: Ptyhon ile web servis istemcisine bağlanıp işlem yapmak

Posted by – 27 Şub 2009

Merhabalar son 2-3 gündür Python ile web servis ilişkisini istemci yönünden incelemekteyim. Yazımıza kavramları açıklayarak başlayalım. Web servis nedir? W3C tarafından yapılan resmi tanımıyla web servis, bilgisayarlar arasında ağ üzerinden haberleşmeyi sağlayan, xml tabanlı mesajlaşma sistemidir. Internet uygulamlarında istemci ve sunucu için hayli yararlı bir sistemdir. İstemci, sunucunun belirlediği formatta gönderdiği isteğine yine sunucunun belirlediği formatta xml bir cevap alır. Bu yöntem bilgiye ulaşımı ve onu kullanmayı kolaylaştırır.XML web servisinin erişim standardı SOAP adı verilen “Simple Object Access Protocol” (Basit Nesne Erişim Protokolü) protokolüne dayanır.

Günümüzde e-ticaret uygulmalarında(gittigidiyor vs.), bankacılık hizmetlerinde(sanal pos işlemleri), kamu kurumlarında(TCMB- döviz bilgileri) ve daha bir çok noktada kullanılmaktadır.

Ben niçin bu araştırmayı yaptım? Geliştimesinde yer aldığım bir projede sanalpos işlemleri için çeşitli bankların api sistemlerini inceliyor ve projeme dahil ediyorum. Sanal pos apisini incelediğim bankalara xml isteğini iki şekilde göndermekteyim. Birincisi xml stringi linke ekleyerek diğerinde ise SoapClient yardımıyla. Birinci yöntemde xml istek stringini biz hazırlıyoruz diğerinde ise soap client hazırlıyor.

Web programlama dillerinin SoapClient kütüphaneleri mevcuttur(php:SoapClient, python: zsi, soaplib, SOAPpy). Ana konumuz Python’da SoapClient ile nasıl bir servise istek gönderilir ve cevap alınırdır. Ptyhon’da SOAPpy ve ZSI modüllerini inceledim. Erişmek istediğim web servis .NET ile hazırlanmış bir web servistir. SOAPpy de yaşadığım problem web servisin benden beklediği parametreleri gönderiyor olmama rağmen servisin bu parametrelere erişmemesi ve bana beklediği parametreyi göndermediğim için uyarı vermesiydi. Aşağıda örneğini verdiğim SOAPpy modüllü client ile önce proxy yaratılıyor daha sonra gönderilecek parametrelerin sıralaması belirtiliyor ve en sonunda da ilgili metot parametreler ile cağırılıyor. Aşağıdaki örnek kodlarda gerçek değerler kullanmamaktayım bu yüzden bilinmeyenler ile ilgili kısa açıklamalar yazdım.

name* = Web servis uygulamasının adıdır.
metot* = Çağrılan metot ismi
soapaction* = name*_services.py  dosyasında ilgili metot için cağrılan binding metodundaki soapaction bilgisidir.
url* = web servisin url bilgisi
wsdl* = url* + “?wsdl”

SOAPpy ile:
wsdl = wsdl*
config = SOAPConfig()
Config.debug = 1 # soap client tarafından oluşturulan xml isteği debug=1 ile ekrandan görüntülenir
server = WSDL.Proxy(wsdl, config)
config.argsOrdering = {metot*: (’param1′,’param2′)}
result = server.metot*(param1=0, param2=1)
print result

SOAPpy ile .NET web servisinin benden beklediği param2 parametresi nedenini bilmediğim bir şekilde servis tarafından alınmadı. Bu konuda bilgisi olan arkadaşlar beni bilgilendirirse sevinirim.

ZSI:

İlk olarak kendimize çalışacağımız bir çalışma klasörü yaratmalıyız.
Daha sonra komut satırından(Linux-shell)
python /usr/bin/wsdl2py -u wsdl* >> name*_services_types.py name*_services.py

Bu komut ile ulaşmaya çalıştığımız web servisin servis bilgilerini içeren dosyaları yaratılıyor. Yaratılan dosyalardaki çağırmak istediğimiz metod bilgilerini koda dahil ediyoruz. Verilen linke bağlanılıyor,  parametreleri hazırlanıyor ve çağrılmak istenen metota gönderiliyor. Bu işlemlerden sonra web servisten dönen cevabı alıyoruz. Dönen cevap hazırlanan web servis metoduna göre farklı veri yapılarında(dizi, sözlük string) olabilir.
from name*_services import metot*SoapIn, metot*SoapOut
from ZSI.client import Binding
import sys

serverPath = url*

mybind = Binding(url= serverPath)
msg = metotSoapIn()
msgresp = metotSoapOut()
msg._param1 = 0
msg._param2 = 0

mybind.Send(serverPath, metot*, msg, soapaction=soapaction*)
response = mybind.Receive(msgresp)
result = response._metot*Result
print result
Kaynaklar: http://users.skynet.be/pascalbotte/rcx-ws-doc/zsi.htm#WSDL2PY