Brian I
Brian I

Reputation: 21

Trying to call web service using ironpython and soap

I am trying to send a sync soap message to a webserver using a wsdl file. I created a cs file and dll for the wsdl file to load in IronPython per the instructions in IronPython in action. I have created my soap message(required by the webservice) and I don't think I have constructed my webRequest properly.

Here is my code:

    import clr
clr.AddReference("System")
clr.AddReferenceToFileAndPath("C:\\Temp\MeetingSpaceService.dll")
clr.AddReference("System.Xml")
clr.AddReference("System.Web.Services")

from MeetingSpaceService import MeetingSpaceService
service = MeetingSpaceService()
from System.Net import WebClient
from System.IO import StreamWriter
from System.IO import StreamReader
from  System.IO import StringWriter
import System.Xml
import System.Text
from System import Uri
from System.Xml import XmlTextWriter
from System.Xml import Formatting
from System.Web.Services import *
from System.Net import HttpWebRequest
import System.Object
import System.Array
import System.Byte
from System.Xml import XmlDocument
from System.IO import File
from System.Object import ToString
#from System.ServiceModel.Description import WsdlImporter as wsdl 
from System.Web.Services.Description import (ServiceDescription,     ServiceDescriptionImporter)
from System.Web.Services.Protocols import SoapHttpClientProtocol
from System.IO import MemoryStream
from System.Net import WebClient

readerboard = ''' <?xml version="1.0" encoding="utf-8"?>
</soap:Envelope> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"     xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soap:Header>
  <wsa:Action>http://htng.org/PWSWG/2007/01/DigitalSignage#MeetingSpaceRequest</wsa:Action>
  <wsa:MessageID>urn:uuid:44088898-6926-4537-b1a3-4acc8e9f71d0</wsa:MessageID>
  <wsa:ReplyTo>
     <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
  </wsa:ReplyTo>
  <wsa:To>http://localhost:2025/MeetingSpaceProviderService/Request.asmx</wsa:To>
  <wsse:Security soap:mustUnderstand="1">
     <wsu:Timestamp wsu:Id="Timestamp-e157d58f-6589-4b3e-b2a9-5510dd9f270f">
        <wsu:Created>2011-04-17T15:35:25Z</wsu:Created>
        <wsu:Expires>2012-07-17T15:40:25Z</wsu:Expires>
     </wsu:Timestamp>"
     <wsse:UsernameToken wsu:Id="SecurityToken-843aeb4f-07de-4c78-a438-e051d3baa764">
        <wsse:Username>isacrb</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">is@cr6_662</wsse:Password>
     </wsse:UsernameToken>
  </wsse:Security>

" '''

uriString = "https://ice-services.starwoodhotels.com/readerboard‏"
uri = Uri(uriString)

try: 
webRequest = HttpWebRequest.Create(uri)
webRequest.ContentType = "text/xml;charset=\"utf-8\""
webRequest.Accept = "text/xml"
webRequest.ContentLength = readerboard.Length
webRequest.Timeout = 1000000000
webRequest.Method = "POST"
webRequest.GetRequestStream()
webRequest.Write(readerboard)
webRequest.GetResponse()
except Exception, e:
    print (9) 

I made changes here and now here is what I am getting. the web service is sychnonous so what I believe is happening is that when you send the request the response automatically comes back. At the point of

rqt = webRequest.GetRequestStream() there is around a 1.5 to 2.5 second delay before the next line is read. that mimicks the behavior in SOAPUi where after the message is sent there is usually a second or so delay and then the return XML data shows up in the response box. I am thinking that after the rqt= webRequest I need to somehow read the stream without asking for the response. can I send you the cs file and dll I created to import the WSDL and see what you think. At that point you should be able to access the server and in an IDE see what I am talking about. I appreciate your help. thank you so much.

Here is what happens after the above:

>>> rqt = webRequest.GetRequestStream()
>>> rqt.Write(byte1,0,byte1.Length)
>>>
>>>     #get the response here
>>> rsp = webRequest.GetResponse()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
SystemError: The remote server returned an error: (500) Internal Server Error.
>>>     #create a stream reader to convert the raw response into UTF8 for text
>>> readStream = StreamReader(rsp.GetResponseStream(), System.Text.Encoding.UTF8
)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'rsp' is not defined
>>>     #read the data from the stream into a string
>>> data = readStream.ReadToEnd()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'readStream' is not defined
>>> readStream.Close()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'readStream' is not defined
>>> rsp.Close()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'rsp' is not defined
>>>     #Do stuff with the data here
>>> print data
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'data' is not defined
>>>

Upvotes: 2

Views: 4321

Answers (1)

Andrew Cox
Andrew Cox

Reputation: 10998

You need to add a header when you make the request to denote the SOAPAction.

So something like:

webRequest.Headers.Add('SOAPAction', '"http://myservice.com/1/poll"') 

The full code to call a webservice is below. In this case http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL

import clr

from System.Net import WebClient
from System.IO import StreamReader
import System.Text
from System import Uri
from System.Net import HttpWebRequest

#This is the SOAP Payload 
#Just build it with basic concats
readerboard = """<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GetCityWeatherByZIP xmlns="http://ws.cdyne.com/WeatherWS/">
      <ZIP>10011</ZIP>
    </GetCityWeatherByZIP>
  </soap:Body>
</soap:Envelope>"""


uriString = "http://wsf.cdyne.com/WeatherWS/Weather.asmx"
uri = Uri(uriString)

try: 
    webRequest = HttpWebRequest.Create(uri)
    webRequest.ContentType = "text/xml;charset=\"utf-8\""
    webRequest.Accept = "text/xml"
    webRequest.Timeout = 1000000000
    webRequest.Method = "POST"
    #We set the SOAPAction Header - this tells the end point what service to run
    webRequest.Headers.Add('SOAPAction', '"http://ws.cdyne.com/WeatherWS/GetCityWeatherByZIP"') 

    #we turn the payload into a byte array to allow us to write it to the request stream
    encoding = System.Text.UTF8Encoding();
    byte1 = encoding.GetBytes(readerboard);
    #write the bytes above to the request
    rqt = webRequest.GetRequestStream()
    rqt.Write(byte1,0,byte1.Length)
    #get the response here
    rsp = webRequest.GetResponse()
    #create a stream reader to convert the raw response into UTF8 for text
    readStream = StreamReader(rsp.GetResponseStream(), System.Text.Encoding.UTF8)
    #read the data from the stream into a string
    data = readStream.ReadToEnd()
    readStream.Close()
    rsp.Close()
    #Do stuff with the data here
    print data
except System.Net.WebException, we:
    print "Web Exception:", we.Message
    if we.Status == System.Net.WebExceptionStatus.ProtocolError: 
        print int(we.Response.StatusCode), we.Response.StatusDescription
        print (StreamReader(we.Response.GetResponseStream(), System.Text.Encoding.UTF8)).ReadToEnd()
except Exception, e:
    print e

Upvotes: 2

Related Questions