pamiętnik programisty

11 sty, 2010

SOAP w Pythonie

Zamieszczony przez: pejotr w: Programowanie|Python

soap_pythonMimo że sam język jest uważany za potężny z dostępną dużą ilością bibliotek, to nie do koońca jest to prawda. SOAP w Pythonie niestety ale po prostu leży. Są 2 biblioteki umożliwiające tworzenie webserviców i tak naprawdę 2 które umożliwiają korzystanie z już utworzonych. Ja swoje próby rozpocząłem od soaplib, biblioteki która została porzucona przez twórców, ale w wyniku tzw. forków w miarę często pojawiają się nowe wersje. Niestety był to błąd.

Nowe wersje od niezależnych twórców charakteryzują się większą bądź mniejszą ilością błędów. Najlepszą wersją okazała się wersja cuker soaplib, nie spełniała tylko 1 wymogu – generowania jakiegokolwiek kodu na podstawie WSDL. Jest to pewne nadużycie z mojej strony, biblioteka dostarczyła skrypt o nazwie wsdl2py, ale potrafił on poprawnie sparsować i zinterpretować plik wsdl utworzony tylko przez soaplib, co trzeba przyznać jest lekką „kichą”. Szkoda, biblioteka aktywnie rozwijana, wiązałem z nią spore nadzieje – odpadła.
Suds to druga biblioteka związana z SOAP, aktywnie rozwijana, chwalona za łatwość korzystania, niestety przykłady dotyczą tylko tworzenia klinetów, serwerów poprostu tworzyć się nie da? W połączeniu z soaplib mogł by to być całkiem ciekawy duet.
Biblioteka webserwisów dla Pythona ZSI, w założeniu ma umożliwiać tworzenie i korzystanie z różnych webserviców, niestety projekt został porzucony w 2007 roku. Ale mimo to miłe zaskoczenie, dostarczane skrypty wsdl2py i wsdl2dispatch bez problemu radzą sobie z przykładowy wsdl dostępnymi w internecie. Tworzone są 3 pliki które potem można wykorzystać do implementacji serwera i klienta. Jednakże żeby nie było zbyt miło, serwer dostarczony z biblioteką jest jedno wątkowy. Jeśli operacje obsługi żądania jednego klienta są czasochłonne, to na ten czas serwer nie odpowiada na żądania innych klientów. Fatalna sprawa, ale! światełko w tunelu, ZSI można połączyć z Apache’m poprzez wykorzystanie mod_python ( oczywiście nie mogło być wersji dla python 2.6, na szczęście VS poradziło sobie z kompilacją ). Kolejna ślepa uliczka – jak bym tworzył stronę WWW. Przychodzi żądanie tworzone są wszystkie klasy a po zakończeniu obsługi usuwane – nie tak sobie wyobrażałem mój system rozproszony, zamiast w Pythonie mógłbym go napisać w PHP (sic!). Powrót do ZSI i eureka, ktoś bardziej doświadczony w tym języku dopisał kilka linii kodu do źródła i serwer stał się wielowątkowy! Połączenie idealne, wielowątkowość obsługi żądań, nie niszczenie wszystkiego po zakończeniu obsługi, możliwośc wypisywania komunikatów na ekran konsoli.
Źródło rozwiązania: http://osdir.com/ml/python.pywebsvcs.general/2008-06/msg00019.html . Autor wykorzystał co prawda ZSI-2.1-a1, ale poprawka działa również na ostatniej stabilnej wersji ZSI-2.0

Na wszelki, skopiowany kod poprawki poniżej:

— ZSI-2.1-a1/ZSI/ServiceContainer.py 2007-08-08 00:56:37.000000000 +0200
+++ ServiceContainer.py 2008-06-19 13:50:11.000000000 +0200
@@ -5,6 +5,7 @@

import urlparse, types, os, sys, cStringIO as StringIO, thread,re
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
+from SocketServer import ThreadingMixIn
from ZSI import ParseException, FaultFromException,
FaultFromZSIException, Fault
from ZSI import _copyright, _seqtypes, _get_element_nsuri_name, resolvers
from ZSI import _get_idstr
@@ -30,6 +31,7 @@
SimpleWSResource
SOAPRequestHandler
ServiceContainer
+ ThreadedServiceContainer
„”"
class NoSuchService(Exception): pass
class UnknownRequestException(Exception): pass
@@ -141,12 +143,16 @@
return SendFault(FaultFromException(e, 0, sys.exc_info()[2]), **kw)

-def AsServer(port=80, services=()):
+def AsServer(port=80, services=(), threaded=False):
”’port –
services — list of service instances
+ threaded — in modo multithread ?
”’
address = (”, port)
- sc = ServiceContainer(address, services)
+ if threaded:
+ sc = ThreadedServiceContainer(address, services)
+ else:
+ sc = ServiceContainer(address, services)
sc.serve_forever()

@@ -467,6 +473,11 @@
def removeNode(self, url):
self._nodes.removeNode(url)

+class ThreadedServiceContainer(ThreadingMixIn, ServiceContainer):
+ ”’Multithreaded version of ServiceContainer.
+ ”’
+ pass
+

class SimpleWSResource(ServiceSOAPBinding):

Brak odpowiedzi na "SOAP w Pythonie"

Formularz komentarza

*

O mnie:

pejotrWitam, nazywam się Piotr Doniec, w internecie występuję pod nickami 'pejotr' oraz 'doniczek'. Obecnie jestem studentem 3 roku informatyki na Politechnice Warszawskiej na wydziale Elektroniki i Technik Informacyjnych.

Kategorie