I have the following XML which I am sending to the target web application using SOAPUI and it works.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsu="http://www.docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soapenv:Header/>
<soapenv:Body>
<RequestMessage xmlns="http://www.ercot.com/schema/2007-06/nodal/ews/message">
<Header>
<Verb>create</Verb>
<Noun>OutageSet</Noun>
<ReplayDetection>
<Nonce>72465</Nonce>
<Created>2022-12-27T00:40:00-07:00</Created>
</ReplayDetection>
<Revision>004</Revision>
<Source>TAEPTC</Source>
<!--Optional:-->
<UserID>API_OutplanOSITCC</UserID>
</Header>
<Payload>
<OutageSet xmlns="http://www.ercot.com/schema/2007-06/nodal/ews">
<Outage>
<OutageInfo>
<outageType>PL</outageType>
<Requestor>
<name>API_OutplanOSITCC</name>
<userFullName>APIOutplanOSITCC</userFullName>
</Requestor>
<Disclaimer>tempdisclaimer</Disclaimer>
<disclaimerAck>true</disclaimerAck>
</OutageInfo>
<TransmissionOutage>
<operatingCompany>TAEPTC</operatingCompany>
<equipmentName>1589</equipmentName>
<equipmentIdentifier>_{072D6FCA-D121-49E7-AC9D-CDF5D4DB3D70}</equipmentIdentifier>
<transmissionType>DSC</transmissionType>
<fromStation>AIRLINE</fromStation>
<outageState>O</outageState>
<emergencyRestorationTime>1</emergencyRestorationTime>
<natureOfWork>OE</natureOfWork>
</TransmissionOutage>
<Schedule>
<plannedStart>2023-01-16T10:00:00</plannedStart>
<plannedEnd>2023-01-17T10:00:00</plannedEnd>
<earliestStart>2023-01-16T10:00:00</earliestStart>
<latestEnd>2023-01-17T12:00:00</latestEnd>
</Schedule>
</Outage>
</OutageSet>
</Payload>
</RequestMessage>
</soapenv:Body>
</soapenv:Envelope>
I am trying to generate the XML using python's zeep module and for that I have the modifeid xml and converting that to dict using xmltodict module.
Below is the XMLtoDIct code sinppet -
import xmltodict
import pprint
import json
my_xml = """
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsu="http://www.docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soapenv:Header/>
<soapenv:Body>
<RequestMessage xmlns="http://www.ercot.com/schema/2007-06/nodal/ews/message">
<Header>
<Verb>create</Verb>
<Noun>OutageSet</Noun>
<ReplayDetection>
<Nonce>72465</Nonce>
<Created>2022-12-27T00:40:00-07:00</Created>
</ReplayDetection>
<Revision>004</Revision>
<Source>TAEPTC</Source>
<!--Optional:-->
<UserID>API_OutplanOSITCC</UserID>
</Header>
<Payload>
<OutageSet xmlns="http://www.ercot.com/schema/2007-06/nodal/ews">
<Outage>
<OutageInfo>
<outageType>PL</outageType>
<Requestor>
<name>API_OutplanOSITCC</name>
<userFullName>APIOutplanOSITCC</userFullName>
</Requestor>
<Disclaimer>tempdisclaimer</Disclaimer>
<disclaimerAck>true</disclaimerAck>
</OutageInfo>
<TransmissionOutage>
<operatingCompany>TAEPTC</operatingCompany>
<equipmentName>1589</equipmentName>
<equipmentIdentifier>_{072D6FCA-D121-49E7-AC9D-CDF5D4DB3D70}</equipmentIdentifier>
<transmissionType>DSC</transmissionType>
<fromStation>AIRLINE</fromStation>
<outageState>O</outageState>
<emergencyRestorationTime>1</emergencyRestorationTime>
<natureOfWork>OE</natureOfWork>
</TransmissionOutage>
<Schedule>
<plannedStart>2023-01-16T10:00:00</plannedStart>
<plannedEnd>2023-01-17T10:00:00</plannedEnd>
<earliestStart>2023-01-16T10:00:00</earliestStart>
<latestEnd>2023-01-17T12:00:00</latestEnd>
</Schedule>
</Outage>
</OutageSet>
</Payload>
</RequestMessage>
</soapenv:Body>
</soapenv:Envelope>
"""
my_dict = xmltodict.parse(my_xml, process_namespaces= True)
#pp = pprint.PrettyPrinter(indent=2)
print(my_dict)
Below is the dict after conversion -
{'http://schemas.xmlsoap.org/soap/envelope/:Envelope': {'http://schemas.xmlsoap.org/soap/envelope/:Header': None, 'http://schemas.xmlsoap.org/soap/envelope/:Body': {'http://www.ercot.com/schema/2007-06/nodal/ews/message:RequestMessage': {'http://www.ercot.com/schema/2007-06/nodal/ews/message:Header': {'http://www.ercot.com/schema/2007-06/nodal/ews/message:Verb': 'create', 'http://www.ercot.com/schema/2007-06/nodal/ews/message:Noun': 'OutageSet', 'http://www.ercot.com/schema/2007-06/nodal/ews/message:ReplayDetection': {'http://www.ercot.com/schema/2007-06/nodal/ews/message:Nonce': '72465', 'http://www.ercot.com/schema/2007-06/nodal/ews/message:Created': '2022-12-27T00:40:00-07:00'}, 'http://www.ercot.com/schema/2007-06/nodal/ews/message:Revision': '004', 'http://www.ercot.com/schema/2007-06/nodal/ews/message:Source': 'TAEPTC', 'http://www.ercot.com/schema/2007-06/nodal/ews/message:UserID': 'API_OutplanOSITCC'}, 'http://www.ercot.com/schema/2007-06/nodal/ews/message:Payload': {'http://www.ercot.com/schema/2007-06/nodal/ews:OutageSet': {'http://www.ercot.com/schema/2007-06/nodal/ews:Outage': {'http://www.ercot.com/schema/2007-06/nodal/ews:OutageInfo': {'http://www.ercot.com/schema/2007-06/nodal/ews:outageType': 'PL', 'http://www.ercot.com/schema/2007-06/nodal/ews:Requestor': {'http://www.ercot.com/schema/2007-06/nodal/ews:name': 'API_OutplanOSITCC', 'http://www.ercot.com/schema/2007-06/nodal/ews:userFullName': 'APIOutplanOSITCC'}, 'http://www.ercot.com/schema/2007-06/nodal/ews:Disclaimer': 'tempdisclaimer', 'http://www.ercot.com/schema/2007-06/nodal/ews:disclaimerAck': 'true'}, 'http://www.ercot.com/schema/2007-06/nodal/ews:TransmissionOutage': {'http://www.ercot.com/schema/2007-06/nodal/ews:operatingCompany': 'TAEPTC', 'http://www.ercot.com/schema/2007-06/nodal/ews:equipmentName': '1589', 'http://www.ercot.com/schema/2007-06/nodal/ews:equipmentIdentifier': '_{072D6FCA-D121-49E7-AC9D-CDF5D4DB3D70}', 'http://www.ercot.com/schema/2007-06/nodal/ews:transmissionType': 'DSC', 'http://www.ercot.com/schema/2007-06/nodal/ews:fromStation': 'AIRLINE', 'http://www.ercot.com/schema/2007-06/nodal/ews:outageState': 'O', 'http://www.ercot.com/schema/2007-06/nodal/ews:emergencyRestorationTime': '1', 'http://www.ercot.com/schema/2007-06/nodal/ews:natureOfWork': 'OE'}, 'http://www.ercot.com/schema/2007-06/nodal/ews:Schedule': {'http://www.ercot.com/schema/2007-06/nodal/ews:plannedStart': '2023-01-16T10:00:00', 'http://www.ercot.com/schema/2007-06/nodal/ews:plannedEnd': '2023-01-17T10:00:00', 'http://www.ercot.com/schema/2007-06/nodal/ews:earliestStart': '2023-01-16T10:00:00', 'http://www.ercot.com/schema/2007-06/nodal/ews:latestEnd': '2023-01-17T12:00:00'}}}}}}}}
however, when I am passing this dict to the request data like below -
request_data = {'http://www.ercot.com/schema/2007-06/nodal/ews/message:RequestMessage': {'http://www.ercot.com/schema/2007-06/nodal/ews/message:Header': {'http://www.ercot.com/schema/2007-06/nodal/ews/message:Verb': 'create', 'http://www.ercot.com/schema/2007-06/nodal/ews/message:Noun': 'OutageSet', 'http://www.ercot.com/schema/2007-06/nodal/ews/message:ReplayDetection': {'http://www.ercot.com/schema/2007-06/nodal/ews/message:Nonce': '72465', 'http://www.ercot.com/schema/2007-06/nodal/ews/message:Created': '2022-12-27T00:40:00-07:00'}, 'http://www.ercot.com/schema/2007-06/nodal/ews/message:Revision': '004', 'http://www.ercot.com/schema/2007-06/nodal/ews/message:Source': 'TAEPTC', 'http://www.ercot.com/schema/2007-06/nodal/ews/message:UserID': 'API_OutplanOSITCC'}, 'http://www.ercot.com/schema/2007-06/nodal/ews/message:Payload': {'http://www.ercot.com/schema/2007-06/nodal/ews:OutageSet': {'http://www.ercot.com/schema/2007-06/nodal/ews:Outage': {'http://www.ercot.com/schema/2007-06/nodal/ews:OutageInfo': {'http://www.ercot.com/schema/2007-06/nodal/ews:outageType': 'PL', 'http://www.ercot.com/schema/2007-06/nodal/ews:Requestor': {'http://www.ercot.com/schema/2007-06/nodal/ews:name': 'API_OutplanOSITCC', 'http://www.ercot.com/schema/2007-06/nodal/ews:userFullName': 'APIOutplanOSITCC'}, 'http://www.ercot.com/schema/2007-06/nodal/ews:Disclaimer': 'tempdisclaimer', 'http://www.ercot.com/schema/2007-06/nodal/ews:disclaimerAck': 'true'}, 'http://www.ercot.com/schema/2007-06/nodal/ews:TransmissionOutage': {'http://www.ercot.com/schema/2007-06/nodal/ews:operatingCompany': 'TAEPTC', 'http://www.ercot.com/schema/2007-06/nodal/ews:equipmentName': '1589', 'http://www.ercot.com/schema/2007-06/nodal/ews:equipmentIdentifier': '_{072D6FCA-D121-49E7-AC9D-CDF5D4DB3D70}', 'http://www.ercot.com/schema/2007-06/nodal/ews:transmissionType': 'DSC', 'http://www.ercot.com/schema/2007-06/nodal/ews:fromStation': 'AIRLINE', 'http://www.ercot.com/schema/2007-06/nodal/ews:outageState': 'O', 'http://www.ercot.com/schema/2007-06/nodal/ews:emergencyRestorationTime': '1', 'http://www.ercot.com/schema/2007-06/nodal/ews:natureOfWork': 'OE'}, 'http://www.ercot.com/schema/2007-06/nodal/ews:Schedule': {'http://www.ercot.com/schema/2007-06/nodal/ews:plannedStart': '2023-01-16T10:00:00', 'http://www.ercot.com/schema/2007-06/nodal/ews:plannedEnd': '2023-01-17T10:00:00', 'http://www.ercot.com/schema/2007-06/nodal/ews:earliestStart': '2023-01-16T10:00:00', 'http://www.ercot.com/schema/2007-06/nodal/ews:latestEnd': '2023-01-17T12:00:00'}}}}}}
print("Call URL")
print(client.service.MarketTransactions(**request_data))
I am getting the below error -
Creating client.
zeep.transports: Loading remote data from: http://www.w3.org/2001/xml.xsd
Making request.
Call URL
Traceback (most recent call last):
File "C:\Users\SGUPTA\PycharmProjects\ERCOT\ERCOT_Test.py", line 110, in <module>
print(client.service.MarketTransactions(**request_data))
File "C:\Users\SGUPTA\PycharmProjects\ERCOT\venv\lib\site-packages\zeep\proxy.py", line 46, in __call__
return self._proxy._binding.send(
File "C:\Users\SGUPTA\PycharmProjects\ERCOT\venv\lib\site-packages\zeep\wsdl\bindings\soap.py", line 123, in send
envelope, http_headers = self._create(
File "C:\Users\SGUPTA\PycharmProjects\ERCOT\venv\lib\site-packages\zeep\wsdl\bindings\soap.py", line 73, in _create
serialized = operation_obj.create(*args, **kwargs)
File "C:\Users\SGUPTA\PycharmProjects\ERCOT\venv\lib\site-packages\zeep\wsdl\definitions.py", line 222, in create
return self.input.serialize(*args, **kwargs)
File "C:\Users\SGUPTA\PycharmProjects\ERCOT\venv\lib\site-packages\zeep\wsdl\messages\soap.py", line 73, in serialize
body_value = self.body(*args, **kwargs)
File "C:\Users\SGUPTA\PycharmProjects\ERCOT\venv\lib\site-packages\zeep\xsd\elements\element.py", line 58, in __call__
instance = self.type(*args, **kwargs)
File "C:\Users\SGUPTA\PycharmProjects\ERCOT\venv\lib\site-packages\zeep\xsd\types\complex.py", line 63, in __call__
return self._value_class(*args, **kwargs)
File "C:\Users\SGUPTA\PycharmProjects\ERCOT\venv\lib\site-packages\zeep\xsd\valueobjects.py", line 106, in __init__
items = _process_signature(self._xsd_type, args, kwargs)
File "C:\Users\SGUPTA\PycharmProjects\ERCOT\venv\lib\site-packages\zeep\xsd\valueobjects.py", line 241, in _process_signature
raise TypeError(
TypeError: {http://www.ercot.com/schema/2007-06/nodal/ews/message}RequestMessage() got an unexpected keyword argument 'http://www.ercot.com/schema/2007-06/nodal/ews/message:RequestMessage'. Signature: `Header: {http://www.ercot.com/schema/2007-06/nodal/ews/message}HeaderType, Request: {http://www.ercot.com/schema/2007-06/nodal/ews/message}RequestType, Payload: {http://www.ercot.com/schema/2007-06/nodal/ews/message}PayloadType`
Process finished with exit code 1
is this because of the namespaces in both RequestMessage and Outageset nodes?
Here is my complete code -
from zeep.wsse.signature import BinarySignature
from zeep.wsse import utils
from datetime import datetime, timedelta
import contextlib
import os
import requests
from requests_pkcs12 import Pkcs12Adapter
from zeep.transports import Transport
from zeep import Client, Settings
from pathlib import Path
from tempfile import NamedTemporaryFile
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption
from cryptography.hazmat.primitives.serialization.pkcs12 import load_key_and_certificates
import random
import logging.config
# USE THE MOST VERBOSE LOGGING LEVEL
logging.config.dictConfig({
'version': 1,
'formatters': {
'verbose': {
'format': '%(name)s: %(message)s'
}
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose',
},
},
'loggers': {
'zeep.transports': {
'level': 'DEBUG',
'propagate': True,
'handlers': ['console'],
},
}
})
class BinarySignatureTimestamp(BinarySignature):
def apply(self, envelope, headers):
security = utils.get_security_header(envelope)
created = datetime.utcnow()
expired = created + timedelta(seconds=1 * 60)
timestamp = utils.WSU('Timestamp')
timestamp.append(utils.WSU('Created', created.replace(microsecond=0).isoformat() + 'Z'))
timestamp.append(utils.WSU('Expires', expired.replace(microsecond=0).isoformat() + 'Z'))
security.append(timestamp)
super().apply(envelope, headers)
return envelope, headers
def verify(self, envelope):
return envelope
#contextlib.contextmanager
def pfx_to_pem(pfx_path, pfx_password):
''' Decrypts the .pfx file to be used with requests. '''
pfx = Path(pfx_path).read_bytes()
private_key, main_cert, add_certs = load_key_and_certificates(pfx, pfx_password.encode('utf-8'), None)
with NamedTemporaryFile(suffix='.pem', delete=False) as t_pem:
with open(t_pem.name, 'wb') as pem_file:
pem_file.write(private_key.private_bytes(Encoding.PEM, PrivateFormat.PKCS8, NoEncryption()))
pem_file.write(main_cert.public_bytes(Encoding.PEM))
for ca in add_certs:
pem_file.write(ca.public_bytes(Encoding.PEM))
yield t_pem.name
def generate_nonce(length=15):
"""Generate pseudorandom number."""
return ''.join([str(random.randint(0, 9)) for i in range(length)])
# CERTIFICATES PATHS
api_p12_key = os.path.join('C:\\Users\\SGUPTA\\ALL\\Projects\\AEPE2\\API Outplan OSI TCC MOTE.p12')
api_certificate = os.path.join('C:\\Users\\SGUPTA\\ALL\\Projects\\AEPE2\\OSITCC.crt')
api_pfx_key = os.path.join('C:\\Users\\SGUPTA\\ALL\\Projects\\AEPE2\\API Outplan OSI TCC MOTE.pfx')
# SETUP
wsdl_file = os.path.join('C:\\Users\\SGUPTA\\ALL\\Projects\\AEPE2\\Nodal.wsdl')
api_base_url = "https://testmisapi.ercot.com"
session = requests.Session()
session.mount(api_base_url,
Pkcs12Adapter(pkcs12_filename=api_p12_key, pkcs12_password='HIDDEN'))
session.verify = None
transport = Transport(session=session)
settings = Settings(forbid_entities=False)
# CREATE CLIENT
print("Creating client.")
with pfx_to_pem(pfx_path=api_pfx_key, pfx_password='AEP') as pem_fle:
client = Client(wsdl=wsdl_file, settings=settings, transport=transport,
wsse=BinarySignatureTimestamp(pem_fle, api_certificate, "AEP"))
print("Making request.")
request_data = {'http://www.ercot.com/schema/2007-06/nodal/ews/message:RequestMessage': {'http://www.ercot.com/schema/2007-06/nodal/ews/message:Header': {'http://www.ercot.com/schema/2007-06/nodal/ews/message:Verb': 'create', 'http://www.ercot.com/schema/2007-06/nodal/ews/message:Noun': 'OutageSet', 'http://www.ercot.com/schema/2007-06/nodal/ews/message:ReplayDetection': {'http://www.ercot.com/schema/2007-06/nodal/ews/message:Nonce': '72465', 'http://www.ercot.com/schema/2007-06/nodal/ews/message:Created': '2022-12-27T00:40:00-07:00'}, 'http://www.ercot.com/schema/2007-06/nodal/ews/message:Revision': '004', 'http://www.ercot.com/schema/2007-06/nodal/ews/message:Source': 'TAEPTC', 'http://www.ercot.com/schema/2007-06/nodal/ews/message:UserID': 'API_OutplanOSITCC'}, 'http://www.ercot.com/schema/2007-06/nodal/ews/message:Payload': {'http://www.ercot.com/schema/2007-06/nodal/ews:OutageSet': {'http://www.ercot.com/schema/2007-06/nodal/ews:Outage': {'http://www.ercot.com/schema/2007-06/nodal/ews:OutageInfo': {'http://www.ercot.com/schema/2007-06/nodal/ews:outageType': 'PL', 'http://www.ercot.com/schema/2007-06/nodal/ews:Requestor': {'http://www.ercot.com/schema/2007-06/nodal/ews:name': 'API_OutplanOSITCC', 'http://www.ercot.com/schema/2007-06/nodal/ews:userFullName': 'APIOutplanOSITCC'}, 'http://www.ercot.com/schema/2007-06/nodal/ews:Disclaimer': 'tempdisclaimer', 'http://www.ercot.com/schema/2007-06/nodal/ews:disclaimerAck': 'true'}, 'http://www.ercot.com/schema/2007-06/nodal/ews:TransmissionOutage': {'http://www.ercot.com/schema/2007-06/nodal/ews:operatingCompany': 'TAEPTC', 'http://www.ercot.com/schema/2007-06/nodal/ews:equipmentName': '1589', 'http://www.ercot.com/schema/2007-06/nodal/ews:equipmentIdentifier': '_{072D6FCA-D121-49E7-AC9D-CDF5D4DB3D70}', 'http://www.ercot.com/schema/2007-06/nodal/ews:transmissionType': 'DSC', 'http://www.ercot.com/schema/2007-06/nodal/ews:fromStation': 'AIRLINE', 'http://www.ercot.com/schema/2007-06/nodal/ews:outageState': 'O', 'http://www.ercot.com/schema/2007-06/nodal/ews:emergencyRestorationTime': '1', 'http://www.ercot.com/schema/2007-06/nodal/ews:natureOfWork': 'OE'}, 'http://www.ercot.com/schema/2007-06/nodal/ews:Schedule': {'http://www.ercot.com/schema/2007-06/nodal/ews:plannedStart': '2023-01-16T10:00:00', 'http://www.ercot.com/schema/2007-06/nodal/ews:plannedEnd': '2023-01-17T10:00:00', 'http://www.ercot.com/schema/2007-06/nodal/ews:earliestStart': '2023-01-16T10:00:00', 'http://www.ercot.com/schema/2007-06/nodal/ews:latestEnd': '2023-01-17T12:00:00'}}}}}}
print("Call URL")
print(client.service.MarketTransactions(**request_data))
The same code is working when I am calling another webservice just by sending the header(does not have a namespace) in the request data like below -
from zeep.wsse.signature import BinarySignature
from zeep.wsse import utils
from datetime import datetime, timedelta
import contextlib
import os
import requests
from requests_pkcs12 import Pkcs12Adapter
from zeep.transports import Transport
from zeep import Client, Settings
from pathlib import Path
from tempfile import NamedTemporaryFile
from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption
from cryptography.hazmat.primitives.serialization.pkcs12 import load_key_and_certificates
import random
import logging.config
# USE THE MOST VERBOSE LOGGING LEVEL
logging.config.dictConfig({
'version': 1,
'formatters': {
'verbose': {
'format': '%(name)s: %(message)s'
}
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose',
},
},
'loggers': {
'zeep.transports': {
'level': 'DEBUG',
'propagate': True,
'handlers': ['console'],
},
}
})
class BinarySignatureTimestamp(BinarySignature):
def apply(self, envelope, headers):
security = utils.get_security_header(envelope)
created = datetime.utcnow()
expired = created + timedelta(seconds=1 * 60)
timestamp = utils.WSU('Timestamp')
timestamp.append(utils.WSU('Created', created.replace(microsecond=0).isoformat()+'Z'))
timestamp.append(utils.WSU('Expires', expired.replace(microsecond=0).isoformat()+'Z'))
security.append(timestamp)
super().apply(envelope, headers)
return envelope, headers
def verify(self, envelope):
return envelope
#contextlib.contextmanager
def pfx_to_pem(pfx_path, pfx_password):
''' Decrypts the .pfx file to be used with requests. '''
pfx = Path(pfx_path).read_bytes()
private_key, main_cert, add_certs = load_key_and_certificates(pfx, pfx_password.encode('utf-8'), None)
with NamedTemporaryFile(suffix='.pem', delete=False) as t_pem:
with open(t_pem.name, 'wb') as pem_file:
pem_file.write(private_key.private_bytes(Encoding.PEM, PrivateFormat.PKCS8, NoEncryption()))
pem_file.write(main_cert.public_bytes(Encoding.PEM))
for ca in add_certs:
pem_file.write(ca.public_bytes(Encoding.PEM))
yield t_pem.name
def generate_nonce(length=15):
"""Generate pseudorandom number."""
return ''.join([str(random.randint(0, 9)) for i in range(length)])
# CERTIFICATES PATHS
api_p12_key = os.path.join('C:\\Users\\SGUPTA\\ALL\\Projects\\AEPE2\\API Outplan OSI TCC MOTE.p12')
api_certificate = os.path.join('C:\\Users\\SGUPTA\\ALL\\Projects\\AEPE2\\OSITCC.crt')
api_pfx_key = os.path.join('C:\\Users\\SGUPTA\\ALL\\Projects\\AEPE2\\API Outplan OSI TCC MOTE.pfx')
# SETUP
wsdl_file = os.path.join('C:\\Users\\SGUPTA\\ALL\\Projects\\AEPE2\\Nodal.wsdl')
api_base_url = "https://testmisapi.ercot.com"
session = requests.Session()
session.mount(api_base_url,
Pkcs12Adapter(pkcs12_filename=api_p12_key, pkcs12_password='AEP'))
session.verify = None
transport = Transport(session=session)
settings = Settings(forbid_entities=False)
# CREATE CLIENT
print("Creating client.")
with pfx_to_pem(pfx_path=api_pfx_key, pfx_password='hidden') as pem_fle:
client = Client(wsdl=wsdl_file, settings=settings, transport=transport,
wsse=BinarySignatureTimestamp(pem_fle, api_certificate, "AEP"))
print("Making request.")
request_data = {
"Header": {
"Verb": "get",
"Noun": "SystemStatus",
"ReplayDetection": {
"Nonce": generate_nonce(),
"Created": "2022-11-10T15:34:00-06:00"},
"Revision": "1",
"Source": "API Outplan OSI TCC",
"UserID": "API_OutplanOSITCC",
}
}
print("Call URL")
print(client.service.MarketInfo(**request_data))
Could anyone please advise how to fix this and what needs to be changed?
Thanks
Sugata
I try to get JSON Object from source, but getting only errors.
Now I'm trying to understand what I'm doing wrong.
This code works well with other resources.
Maybe It`s not problem with code, but with web-source.
import sys
import json
from PyQt5.QtCore import QByteArray, QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineCore import QWebEngineHttpRequest
from PyQt5.QtWebEngineWidgets import QWebEnginePage, QWebEngineSettings
from pprint import pprint
def on_load_finished():
"""Handle response"""
engine.toPlainText(handle_to_html) # get json
def handle_to_html(html):
"""Handle html"""
print(html)
QApplication.quit()
if __name__ == "__main__":
app = QApplication(sys.argv)
engine = QWebEnginePage()
url = "https://sportsapi.betway.com/api/Events/V2/GetEvents"
request = QWebEngineHttpRequest(url=QUrl(url), method=QWebEngineHttpRequest.Post)
request.setHeader(QByteArray(b"Content-Type"), QByteArray(b"application/json"))
payload = {
"LanguageId": 1,
"ClientTypeId": 2,
"BrandId": 3,
"JurisdictionId": 1,
"ClientIntegratorId": 1,
"ExternalIds": [9032262, 9038528, 9037778],
"MarketCName": "win-draw-win",
"ScoreboardRequest": {"ScoreboardType": 3, "IncidentRequest": {}},
"BrowserId": 3,
"OsId": 3,
"ApplicationVersion": "",
"BrowserVersion": "97.0.4692.99",
"OsVersion": "NT 10.0",
"SessionId": "null",
"TerritoryId": 227,
"CorrelationId": "06779075-21e2-4ba8-8e91-d71a981621fe",
"VisitId": "d1088cdf-13a8-42d0-be90-b34fd1332c36",
"ViewName": "sports",
"JourneyId": "833a4c0c-3354-499f-9d52-949df6d159f9",
}
request.setPostData(bytes(json.dumps(payload), "utf-8"))
engine.load(request)
engine.loadFinished.connect(on_load_finished)
app.exec_()
Errors are looks like
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Message>An error has occurred.</Message>
</Error>
Maybe It`s not problem with code, but with web-source.
I can't handle this below.
XMLParseError: Unexpected element 'metadata', expected 'id' error.
I also try strict=False settings but that time zeep returned as none.
from zeep import Client
import zeep
wsdl = 'https://api.n11.com/ws/CategoryService.wsdl'
cl = Client(wsdl=wsdl)
request_data = {"auth":{'appKey' : ***,
'appSecret' : **},'categoryId':int(1003221),"pagingData":{'pageSize':1,'currentPage':0}}
print(cl.service.GetCategoryAttributes(**request_data))
Thanks.
I faced the same problem with the same API. My solution is changing zeep's settings.
You should use xsd_ignore_sequence_order=True.
I hope it's not too late.
settings = Settings(strict=False, xml_huge_tree=True, xsd_ignore_sequence_order=True)
read more:
https://docs.python-zeep.org/en/master/settings.html#module-zeep.settings
Solution:
firstly, to check logs:
import logging.config
logging.config.dictConfig({
'version': 1,
'formatters': {
'verbose': {
'format': '%(name)s: %(message)s'
}
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose',
},
},
'loggers': {
'zeep.transports': {
'level': 'DEBUG',
'propagate': True,
'handlers': ['console'],
},
}
})
Second:
from zeep import Client
from zeep.plugins import HistoryPlugin
wsdl = 'https://api.n11.com/ws/CategoryService.wsdl'
from zeep import Client, Settings
settings = Settings(strict=False, xml_huge_tree=True)
history = HistoryPlugin()
from zeep.transports import Transport
transport = Transport(timeout=10)
key={'appKey' : '**',
'appSecret' : '**',
}
cat= {'categoryId':1003221}
dat= {'pageSize':1,'currentPage':1}
client = Client(wsdl=wsdl, transport=transport, plugins=[history], settings=settings)
with client.settings(raw_response=False,strict=False, xml_huge_tree=True):
response = client.service.GetCategoryAttributes(key,1003221,pagingData=dat)
#assert response.status_code == 200
#assert response.content
#node = client.create_message(client.service, 'GetCategoryAttributes',key,1003221,pagingData=dat)
from lxml import etree
try:
for hist in [history.last_sent, history.last_received]:
print(etree.tostring(hist["envelope"], encoding="unicode", pretty_print=True))
except (IndexError, TypeError):
# catch cases where it fails before being put on the wire
pass
lastly, you can parse with bs4 for xml content:
from bs4 import BeautifulSoup
soup = BeautifulSoup(ass, 'lxml')
soup.find('category').find('metadata')
I am trying to get via Python the plain text result from the gmaps / places API. There is a Google Python Libary but wanted to use the real API via a normel requests or urllib call.
import requests
import json
import urllib3
#tried:
sUrl1 = 'https://maps.googleapis.com/maps/api/place/textsearch/json?query=kindergarten&location=50.73464,12.52528&radius=50000&fields=formatted_address,name&key=[myapikey]'
sUrl2 = 'https://maps.googleapis.com/maps/api/place/textsearch/json?query=kindergarten&location=50.73464'+ r',' + '12.52528&radius=50000&fields=formatted_address'+ r',' + 'name&key=[myapikey]'
sUrl3 = 'https://maps.googleapis.com/maps/api/place/textsearch/json?query=kindergarten&location=50.73464'+ r',' + '12.52528&radius=50000&fields=formatted_address'+ r',' + 'name&key=[myapikey]&verify=false'
sUrl4 = 'https://maps.googleapis.com/maps/api/place/textsearch/json?query=kindergarten&location=50.73464;12.52528&radius=50000&fields=formatted_address;name&key=[myapikey]'
print (requests.get(sUrl1).text)
print (requests.get(sUrl2).text)
print (requests.get(sUrl3).text)
print (requests.get(sUrl4).text)
Did the same for urllib3, and tried to give it as params but always get this:
{
"html_attributions" : [],
"results" : [],
"status" : "ZERO_RESULTS"
}
When i click on the links (print (sUrl1 or sUrl2 or sUrl3 or sUrl4) ) - I get a wonderful result.
In my API Key there is a "-" but if this is the problem?
Do i need some more headers?
What is the problem?
Can you help?
Thanks
If you add headers it works!
Code for Textsearch - works fine - needed to add headers
headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'de,en-US;q=0.7,en;q=0.3',
'Connection': 'keep-alive' ,
'Host': 'maps.googleapis.com',
'Referer': 'maps.googleapis.com',
'TE': 'Trailers',
'Upgrade-Insecure-Requests': '1'
}
urlparams = {
u'query': u'xxx Berlin XXX',
u'location': str(lat)+","+str(long),
u'radius': u'10',
u'fields': u'place_id',
u'key': u'[mySecretKey]'
}
response = requests.get('https://maps.googleapis.com/maps/api/place/textsearch/json', params=urlparams,headers=headers)
myjson = json.loads(response.text)
print (myjson)
place_id = myjson['results'][0]['place_id']