Skip to content

13. [IMPOTS] alıştırması, WEB hizmeti ile

4.2, 4.3, 8 ve 10. paragraflarda daha önce ele aldığımız [IMPOTS] alıştırmasına geri dönüyoruz.

13.1. Sunucu

Aşağıdaki istemci-sunucu mimarisini ele alıyoruz:

Sunucu tarafında yine üç katmanlı bir mimari kullanacağız. [dao] katmanı, 10. paragrafta SGBD ve MySQL ile birlikte kullanılan ImpotsMySQL sınıfı tarafından uygulanacaktır. [metier] katmanı, daha önce incelediğimiz [ImpotsMetier] sınıfı tarafından uygulanacaktır. Geriye sadece web hizmetini yazmak kalıyor. Bu hizmet, müşterilerinden params= evet,2,200000 biçiminde bir params parametresi alır; burada ilk öğe vergi mükellefinin evli olup olmadığını, ikinci öğe çocuk sayısını, üçüncü öğe ise yıllık maaşını belirtir.

Web hizmeti şu şekildedir (impots_web_01):


#!D:\Programlar\ActivePython\Python2.7.2\python.exe

# -*- coding=Utf-8 -*-
# Impots* sınıfları modülünün içe aktarılması
from impots import *
import cgi,cgitb,re

# hata ayıklama bilgilerinin görüntülenmesine izin verilir
cgitb.enable()
sys.stderr=sys.stdout

# ------------------------------------------------ 
# vergi web hizmeti
# ------------------------------------------------ 

# vergi hesaplaması için gerekli veriler, mysqL TABLE
# tablolarına yerleştirilmiştir. Tablonun yapısı aşağıdaki gibidir
# sınırlar decimal(10,2), coeffR decimal(6,2), coeffN decimal(10,2)
# vergi mükelleflerine ait parametreler (medeni durum, çocuk sayısı, yıllık maaş)
# müşteri tarafından params=medeni durum, çocuk sayısı, yıllık maaş biçiminde gönderilir
# sonuçlar (medeni durum, çocuk sayısı, yıllık maaş, ödenecek vergi) müşteriye geri gönderilir
# <vergi>değer</vergi> biçiminde
# veya parametreler geçersizse <hata>msg</hata> biçiminde

# sunucu, müşteriye biçimlendirilmemiş metin gönderir
print "Content-Type: text/plain\n"

# sabitlerin tanımı
USER="root"
PWD=""
HOTE="localhost"
BASE="dbimpots"
TABLE="impots"


# [metier] katmanı oluşturulur
# Python'da oturum desteği bulunmuyor gibi görünüyor
# PHP'te, iş nesnesini saklamak için bir oturum kullanılırdı
# burada, nesne her zaman veritabanındaki verilerden oluşturuluyor MySQL

# katman örneklendirme [metier]
try:
    metier=ImpotsMetier(ImpotsMySQL(HOTE,USER,PWD,BASE,TABLE))
except (IOError, ImpotsError) as infos:
    print ("<erreur>Une erreur s'est produite : {0}</erreur>".format(infos))
    sys.exit()

# istemci tarafından sunucuya gönderilen satırı alıyoruz
params=cgi.FieldStorage().getlist('params')
# parametre yoksa hata verilir
if not params:
  print "<erreur>Le parametre [params] est absent<erreur>"
  sys.exit()

# params parametresini işliyoruz  
items=params[0].strip().lower().split(',')
# Sadece 3 alan olmalıdır
if len(items)!=3:
  print "<erreur>[%s] : nombre de parametres invalide</erreur>" % (params[0])
  sys.exit()
# ilk parametre (medeni durum) "evet" veya "hayır" olmalıdır
marie=items[0].strip()
if marie!="oui" and marie != "non":
  print "<erreur>[%s] : 1er parametre invalide</erreur>\n"% (params[0])
  sys.exit()
# ikinci parametre (çocuk sayısı) bir tamsayı olmalıdır
match=re.match(r"^\s*(\d+)\s*$",items[1])
if not match:
  print "<erreur>[%s] : 2ieme parametre invalide</erreur>\n"% (params[0])
  sys.exit()
enfants=int(match.groups()[0])
# üçüncü parametre (maaş) bir tamsayı olmalıdır
match=re.match(r"^\s*(\d+)\s*$",items[2])
if not match:
  print "<erreur>[%s] : 3ieme parametre invalide</erreur>\n"% (params[0])
  sys.exit()
salaire=int(match.groups()[0])
# vergi hesaplanır
impot=metier.calculer(marie,enfants,salaire)
# sonuç döndürülür
print "<impot>%s</impot>\n" % (impot)
# son

Notlar:

    1. satır: impots.py dosyasındaki nesneler içe aktarılır;
    1. satır: Bir CGI betiğinin hata ayıklaması sorunlu olabilir. cgitb modülü, hata durumunda çökmenin nedenini gönderir. Bunun için standart hata çıktısını (sys.stderr) standart çıktıya (sys.stdout) yönlendirmek gerekir (10. satır);
    1. satır: Gönderilen belgenin türünü belirleyen HTTP başlığı; burada biçimlendirilmemiş bir metin söz konusudur. Web hizmeti, yanıtını tek bir metin satırı olarak geri gönderir:
    2. Hata varsa <erreur>message</erreur>;
    3. <impot>valeur</impot>; burada valeur, vergi tutarıdır.
    1. satır: [dao] ve [metier] katmanlarının oluşturulması;
  • satır 44-46: oluşturma sırasında hata oluşursa, komut dosyası yanıtını gönderir ve sonlanır;
  • satır 49-53: 'params' parametresi alınır. Eğer yoksa, komut dosyası yanıtını gönderir ve sonlanır;
  • satır 56: 'oui,2,200000' parametresi, items dizisinde 3 alana ayrılır;
  • satır 58-77: 3 alanın geçerliliği kontrol edilir. Hata varsa, komut dosyası yanıtını gönderir ve sonlanır;
    1. satır: vergi hesaplanır;
  • satır 81: ve müşteriye gönderilir.

Bir web tarayıcısında şu sonuçlar elde edilir:

13.2. Programlanmış bir müşteri


Program (client_impots_web_01)


# -*- coding=utf-8 -*-

import httplib,urllib,re

# sabitler
HOST="localhost"
URL="/cgi-bin/impots_web_01b.py"
data=("oui,2,200000","non,2,200000","oui,3,200000","non,3,200000","x,y,z,t","x,2,200000", "oui,x,200000","oui,2,x");

# bağlantı
connexion=httplib.HTTPConnection(HOST)
# takip
#connexion.set_debuglevel(1)
# sunucuya gönderilecek veriler üzerinde döngü yapılıyor
for params in data:
    # parametreler sunucuya gönderilmeden önce kodlanmalıdır
    parametres = urllib.urlencode({'params': params})
    # isteğin gönderilmesi
    connexion.request("POST",URL,parametres)
    # yanıtın işlenmesi (metin satırı)
    reponse=connexion.getresponse().read()
    lignes=reponse.split("\n")
    # metin satırı şu biçimdedir
    # <impot>xxx</impot>
    # veya <hata>xxx</hata>
    impot=re.match(r"^<impot>(\S+)</impot>\s*$",lignes[0])
    if impot:
        print "params=%s, impot=%s" % (params,impot.groups()[0])
    else:
        erreur=re.match(r"^<erreur>(.+)</erreur>\s*$",lignes[0])
        if erreur:
            print "params=%s, erreur=%s" % (params,erreur.groups()[0])
        else:
            print lignes
# bağlantının kapatılması
connexion.close()

13.3. Résultats

1
2
3
4
5
6
7
8
params=oui,2,200000, impot=22504.0
params=non,2,200000, impot=33388.0
params=oui,3,200000, impot=16400.0
params=non,3,200000, impot=22504.0
params=x,y,z,t, erreur=[x,y,z,t] : nombre de parametres invalide
params=x,2,200000, erreur=[x,2,200000] : 1er parametre invalide
params=oui,x,200000, erreur=[oui,x,200000] : 2ieme parametre invalide
params=oui,2,x, erreur=[oui,2,x] : 3ieme parametre invalide