SOAP Client Python zeep Не передаёт указанные headers параметры
Подскажите где искать причину, или как исправить это досадное недоразумение. Формируя клиента для SOAP протокола общения с неким сервисом, создаётся объект zeep.Transport к который передаётся session=requests.Session() который нашпиговывается желаемым набором параметров в headers.
Анализ проводился при помощи подключаемого в zeep.Client плагина, который выводит исходящие запросы и входящие.
Код который билдит клиента:
import requests
import zeep
import zeep.exceptions
from zeep import xsd
import lxml.etree
from lxml import etree
# Плагин для анализа
class SoapLoggingPlugin(zeep.Plugin):
def ingress(self, envelope, http_headers, operation):
print(f"SoapLog Ingress: {lxml.etree.tostring(
envelope,
pretty_print=True,
encoding='utf-8',
).decode()
}"
f"\nSoapLog Ingress Headers: {http_headers}")
return envelope, http_headers
def egress(self, envelope, http_headers, operation, binding_options):
print(f"SoapLog Egress: {lxml.etree.tostring(
envelope,
pretty_print=True,
encoding='utf-8',
).decode()
}"
f"\nSoapLog Egress Headers: {http_headers}")
return envelope, http_headers
soap_logging_plugin = SoapLoggingPlugin()
_session = requests.Session()
token = "Обязательный токен"
requests_headers = {
"FNS-OpenApi-Token": token,
"FNS-OpenApi-UserToken": '',
# "Content-Type": "application/xml; charset=UTF-8",
# "SOAPAction": "urn:SendMessageRequest",
# 'Connection': 'keep-alive',
}
_session.verify = False # Сервер не парится по поводу сертификата
_session.headers.update(requests_headers)
# Прокся обязательна, без неё не пускает на сервер
_session.proxies = {"http": "127.0.0.1:3128", "https": "127.0.0.1:3128"}
zeep_settings = zeep.Settings(strict=False, xml_huge_tree=True) # ,extra_http_headers=requests_headers) Тут можно ещё в одном месте подсунуть заголовки. НО тщетно
_transport = zeep.Transport(session=_session, timeout=30)
_url = get_provider_url() # Простая урл к wsdl схеме
# Сам экземпляр клиента
soap_client = zeep.Client(wsdl=npd_url, settings=zeep_settings, transport=_transport, plugins=[soap_logging_plugin])
Далее строим содержимое параметра для запроса.
message_item = xsd.Element('Message', xsd.ComplexType([xsd.Element('{xmlns:ns0}GetTaxpayerStatusRequestV2', xsd.ComplexType([xsd.Element("Inn", xsd.String())]))]))
message_value = message_item([{"Inn": "1234567890"}])
result_1 = soap_client.service.SendMessage(Message=message_value)
Наблюдаем как нас бреет сервер, покуда не получил токена в headers
// Здесь то что отправляется, сначало тело, затем заголовки
SoapLog Egress: <soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Body>
<ns0:SendMessageRequest xmlns:ns0="urn://x-artefacts-gnivc-ru/inplat/servin/OpenApiAsyncMessageConsumerService/types/1.0">
<ns0:Message>
<ns1:GetTaxpayerStatusRequestV2 xmlns:ns1="xmlns:ns0">
<Inn>1234567890</Inn>
</ns1:GetTaxpayerStatusRequestV2>
</ns0:Message>
</ns0:SendMessageRequest>
</soap-env:Body>
</soap-env:Envelope>
SoapLog Egress Headers: {'SOAPAction': '"urn:SendMessageRequest"', 'Content-Type': 'text/xml; charset=utf-8'}
\\ Здесь то что получаем в ответ...
SoapLog Ingress: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>Не удалось обнаружить требуемые заголовки в переданном запросе</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
SoapLog Ingress Headers: {'Server': 'nginx/1.14.2', 'Date': 'Tue, 19 Mar 2024 07:42:30 GMT', 'Content-Type': 'text/xml; charset=UTF-8', 'Content-Length': '312', 'Connection': 'keep-alive'}
Обратите внимание, заколовки
'SOAPAction': '"urn:SendMessageRequest"',
'Content-Type': 'text/xml; charset=utf-8'
я закоментил в своём наборе, чтобы выяснить кто их подставляет. Zeep формирует SOAPAction от используемого сервиса (soap_client.service.SendMessage()
) и Content-Type что это XML документ
В дебагере отчётливо видно что в памяти в экземпляре клиента в транспорте лежат, установленные выше в коде, заголовки.
Помогите разобраться в причине и найти решение.