Salta el contingut

APIs SOAP amb Python

SOAP (Simple Object Access Protocol) és un protocol de comunicació basat en XML per intercanviar informació entre aplicacions a través de la xarxa. A diferència de REST (que és un estil arquitectònic), SOAP és un protocol estandarditzat per la W3C.


SOAP vs REST

Característica SOAP REST
Format de dades XML JSON, XML, text...
Protocol Protocol estricte (W3C) Estil arquitectònic
WSDL Obligatori No existeix
Seguretat WS-Security integrat HTTPS + tokens
Complexitat Alta Baixa
Ús típic Serveis bancaris, empresarials APIs web modernes

WSDL

El WSDL (Web Services Description Language) és un document XML que descriu els serveis que ofereix un servidor SOAP: quines operacions hi ha, quins paràmetres accepten i quin format retornen.

Un servidor SOAP exposa el WSDL normalment a l'URL:

http://servidor/servei?wsdl

Crear un servidor SOAP amb spyne

pip install spyne lxml
from spyne import Application, rpc, ServiceBase, Integer, Unicode
from spyne.protocol.soap import Soap11
from spyne.server.wsgi import WsgiApplication

class CalculadoraService(ServiceBase):

    @rpc(Integer, Integer, _returns=Integer)
    def suma(ctx, a, b):
        return a + b

    @rpc(Integer, Integer, _returns=Integer)
    def resta(ctx, a, b):
        return a - b

    @rpc(Unicode, _returns=Unicode)
    def saluda(ctx, nom):
        return f'Hola, {nom}!'

application = Application(
    [CalculadoraService],
    tns='calculadora.soap',
    in_protocol=Soap11(validator='lxml'),
    out_protocol=Soap11()
)

wsgi_app = WsgiApplication(application)

if __name__ == '__main__':
    from wsgiref.simple_server import make_server
    server = make_server('127.0.0.1', 8000, wsgi_app)
    print('Servidor SOAP en marxa a http://127.0.0.1:8000')
    print('WSDL disponible a http://127.0.0.1:8000/?wsdl')
    server.serve_forever()

Consumir un servei SOAP amb zeep

zeep és la llibreria Python més popular per consumir serveis SOAP:

pip install zeep

Exemple bàsic

from zeep import Client

# Connectar al servidor SOAP usant el WSDL
client = Client('http://127.0.0.1:8000/?wsdl')

# Cridar operacions del servei
resultat = client.service.suma(10, 5)
print(f"10 + 5 = {resultat}")

resultat = client.service.resta(10, 5)
print(f"10 - 5 = {resultat}")

salutacio = client.service.saluda("Maria")
print(salutacio)

Inspeccionar el WSDL

from zeep import Client

client = Client('http://127.0.0.1:8000/?wsdl')

# Veure tots els serveis i operacions disponibles
print(client)

Exemple: servidor SOAP de conversió de temperatures

from spyne import Application, rpc, ServiceBase, Float
from spyne.protocol.soap import Soap11
from spyne.server.wsgi import WsgiApplication

class TemperaturaService(ServiceBase):

    @rpc(Float, _returns=Float)
    def celsius_a_fahrenheit(ctx, celsius):
        return celsius * 9 / 5 + 32

    @rpc(Float, _returns=Float)
    def fahrenheit_a_celsius(ctx, fahrenheit):
        return (fahrenheit - 32) * 5 / 9

application = Application(
    [TemperaturaService],
    tns='temperatura.soap',
    in_protocol=Soap11(validator='lxml'),
    out_protocol=Soap11()
)

wsgi_app = WsgiApplication(application)

if __name__ == '__main__':
    from wsgiref.simple_server import make_server
    server = make_server('127.0.0.1', 8000, wsgi_app)
    server.serve_forever()

Client per al servei de temperatures

from zeep import Client

client = Client('http://127.0.0.1:8000/?wsdl')

celsius = 100.0
fahrenheit = client.service.celsius_a_fahrenheit(celsius)
print(f"{celsius}°C = {fahrenheit}°F")

fahrenheit = 212.0
celsius = client.service.fahrenheit_a_celsius(fahrenheit)
print(f"{fahrenheit}°F = {celsius}°C")

Missatge SOAP — estructura XML

Un missatge SOAP és un document XML amb tres parts:

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:calc="calculadora.soap">

    <soapenv:Header/>  <!-- opcional -->

    <soapenv:Body>
        <calc:suma>
            <calc:a>10</calc:a>
            <calc:b>5</calc:b>
        </calc:suma>
    </soapenv:Body>

</soapenv:Envelope>
Part Descripció
Envelope Element arrel obligatori
Header Capçalera opcional (autenticació, etc.)
Body Contingut de la petició o resposta
Fault Informació d'error (dins de Body)

Material addicional

Podeu consultar el document python_soap_server.pdf per veure exemples addicionals de servidors SOAP amb Python.


Recursos