Перейти к основному содержимому

SOAP

SOAP (Simple Object Access Protocol) – это XML-протокол для обмена структурированными сообщениями между системами через сети. Он используется для создания веб-сервисов, обеспечивая стандартизированный способ взаимодействия приложений, работающих на разных платформах и языках программирования.

Основные компоненты SOAP:

  1. Сообщение SOAP: Это XML-документ, который содержит три основных части:
    • Envelope: Корневой элемент сообщения, определяющий версию протокола SOAP.
    • Header: Опциональный элемент, содержащий метаданные о сообщении, такие как аутентификация, маршрутизация и обработка ошибок.
    • Body: Основной блок данных, включающий запрос или ответ от сервиса.
  2. Транспортный уровень: SOAP может использовать различные транспортные протоколы, такие как HTTP, SMTP, JMS и другие. Наиболее распространенным является HTTP.
  3. Кодирование данных: В SOAP данные могут кодироваться двумя способами:
    • Literal Encoding: Данные передаются в виде простого текста без строгого соблюдения схемы.
    • Encoded Encoding: Использует правила кодирования SOAP для передачи сложных типов данных.
  4. WSDL (Web Services Description Language): Описывает интерфейс веб-сервиса, включая операции, типы сообщений и привязки к транспортным уровням.

Пример структуры SOAP-сообщения:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header>
<!-- Метаданные -->
</soap:Header>
<soap:Body>
<m:GetStockPrice xmlns:m="some-namespace">
<m:StockSymbol>IBM</m:StockSymbol>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>

Пример структуры SOAP-сообщения:

from lxml import etree

envelope = etree.Element(
'{http://www.w3.org/2003/05/soap-envelope}Envelope',
nsmap={'soap': 'http://www.w3.org/2003/05/soap-envelope'}
)
header = etree.SubElement(envelope, '{http://www.w3.org/2003/05/soap-envelope}Header')
body = etree.SubElement(envelope, '{http://www.w3.org/2003/05/soap-envelope}Body')
get_stock_price = etree.SubElement(body, '{some-namespace}GetStockPrice')
stock_symbol = etree.SubElement(get_stock_price, '{some-namespace}StockSymbol')
stock_symbol.text = 'IBM'

print(etree.tostring(envelope, pretty_print=True).decode('utf-8'))

Реализация SOAP-сервиса:

  1. Создание и публикация SOAP-сервиса:
from zeep import Client
from zeep.wsdl import Types
from flask import Flask, request, make_response

app = Flask(__name__)

@app.route('/StockQuoteService', methods=['POST'])
def stock_quote_service():
body = request.data.decode('utf-8')
client = Client('your_wdsl_url_here')

# Парсинг входящего SOAP-запроса
envelope = client.get_element('{http://schemas.xmlsoap.org/soap/envelope/}Envelope')(body)
operation_name = list(envelope.Body._value_)[0].tag.split(':')[-1]

if operation_name == 'getStockPrice':
symbol = envelope.Body.getStockPrice.symbol.text

# Логика получения цены акций
price = 100.0

response_envelope = client.create_message(client.service, f'{operation_name}Response', {'return': price})
response_xml = client.create_xml(response_envelope)

return make_response(response_xml, 200)

if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)

Вызов метода GetSystemDateAndTime в ONVIF:

  1. Запрос:
from zeep import Client

client = Client('http://your_onvif_device_ip:80/onvif/device_service?wsdl')
response = client.service.GetSystemDateAndTime(IncludeNTP=True)

print(response)

Эти примеры демонстрируют использование SOAP в Python 3 с библиотекой zeep.