Soap/wsdl/betfair

Hi,

I have been making a foray into the world of SOAP/WSDL etc and having
been encouraged with the success of running the googleapi demo code,
I thought I would have a go with Betfair.

Alas, things are not going well,
and I’m not sure if I’m doing something wrong
or if the library module ‘soap/wsdlDriver’ is faulty
or does not support the BFService.wsdl document.

The login request sequence works great,
but any other requests fail (eg., getAllEventTypes, logout)
because the parameters do not get generated
in the request document which is sent to Betfair,
which seems to indicate a bug in soap/wsdlDriver.rb,
or in the way I have setup the parameters.

I have included the wiredumps for the ‘login’ and ‘getAllEventTypes’
requests
as comments in the code following, and you will see that
the n1:request element for ‘login’ is formatted as per the parameters
passed to login ,
but the one for ‘getAllEventTypes’ is empty.

Any suggestions ?
(I tried to debug the soap code, but it was all beyond my abilities)

Regards,

Tad

#
#http://bdphelp.betfair.com/API4/V1/API4.1aOnlineHelp/wwhelp/wwhimpl/js/html/wwhelp.htm
#
require ‘soap/wsdlDriver’
wsdl_url=“https://api.betfair.com/betex-api-public-ws/v2/BFService.wsdl
puts “>>CONNECT<<”
soap = SOAP::WSDLDriverFactory.new( wsdl_url ).create_rpc_driver
soap.wiredump_file_base,soap.wiredump_dev = “bdp”,STDOUT
puts “------------------------------------------------”
print “>>LOGIN<<”
logindetails={:locationId =>0,
:password =>“mypassword”,
:productId =>82,
:username =>“myusername”,
:vendorSoftwareId=>0
}
response=soap.login(:request=>logindetails) ;
exit unless response.result.errorCode==“OK”

WIREDUMP OUTPUT FROM LOGIN REQUEST :-

#-<?xml version="1.0" encoding="utf-8" ?>
#-<env:Envelope xmlns:xsd=“XML Schema
#- xmlns:env=“http://schemas.xmlsoap.org/soap/envelope/
#- xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”>
#- env:Body
#- <n1:login
xmlns:n1=“http://www.betfair.com/publicapi/BFServiceV2/”>
#- n1:request
#- 0
#- mypassword
#- 82
#- myusername
#- 0
#- </n1:request>
#- </n1:login>
#- </env:Body>
#-</env:Envelope>
puts “------------------------------------------------”

print “>>GET ALL EVENT TYPES<<”
apiRequestHeader={:clientStamp => 0,:sessionToken =>
response.result.header.sessionToken}
response=soap.getAllEventTypes(:request=>{:header=>apiRequestHeader,:locale=>“en”})
exit unless response.result.errorCode==“OK”

WIREDUMP OUTPUT FROM ‘getAllEventTypes’ REQUEST :-

#<?xml version="1.0" encoding="utf-8" ?>
#<env:Envelope xmlns:xsd=“XML Schema

xmlns:env=“http://schemas.xmlsoap.org/soap/envelope/

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”>

env:Body

<n1:getAllEventTypes

xmlns:n1=“http://www.betfair.com/publicapi/BFServiceV2/”>

n1:request

</n1:request>

</n1:getAllEventTypes>

</env:Body>

#</env:Envelope>

puts “------------------------------------------------”
print “>>LOGOUT<<”
apiRequestHeader={:clientStamp => 0,:sessionToken =>
response.result.header.sessionToken}
response=soap.logout(:request=>{:header=>apiRequestHeader})
p [response.result.header.errorCode,response.result.errorCode]
exit unless response.result.errorCode==“OK”
puts “------------------------------------------------”
puts “It all worked OK”

Hi Tad,
I tried myself, but had to stop at the very beginning. These three lines
of code are sufficient to give me problems:

require ‘soap/wsdlDriver’
WSDL_URL = “https://api.betfair.com/betex-api-public-ws/BFService.wsdl
soap = SOAP::WSDLDriverFactory.new(WSDL_URL).createDriver

I get the following:

warning: peer certificate won’t be verified in this SSL session.
Unknown attr {}abstract.
Unknown attr {}nillable.
Unknown attr {}nillable.
Unknown attr {}nillable.
Unknown attr {}abstract.
Unknown attr {}nillable.
Unknown attr {}nillable.
(…)

I am running Ruby 1.8.2 on MacOS 10.4.7 . In general my feeling is that
the SOAP4R library is very immature.

Giacecco

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

Sorry for late reply.

Tad Bochan wrote:

The login request sequence works great,
but any other requests fail (eg., getAllEventTypes, logout)
because the parameters do not get generated
in the request document which is sent to Betfair,
which seems to indicate a bug in soap/wsdlDriver.rb,
or in the way I have setup the parameters.

Hmm. I run your script on development code of soap4r and get the
following wiredump as a request of getAllEventTypes. It seems to work.

<?xml version="1.0" encoding="utf-8" ?>

<env:Envelope xmlns:xsd=“http://www.w3.org/2001/XMLSchema
xmlns:env=“http://schemas.xmlsoap.org/soap/envelope/
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”>
env:Body
<n1:getAllEventTypes
xmlns:n1=“http://www.betfair.com/publicapi/BFServiceV2/”>
n1:request

0
token

en
</n1:request>
</n1:getAllEventTypes>
</env:Body>
</env:Envelope>

Would you please try the latest snapshot tarball at
http://dev.ctor.org/download/ ?

Regards,
// NaHi
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (Cygwin)

iQEVAwUBRPUEox9L2jg5EEGlAQKyvQf8CvlkFB0sGkgErUO2wUDgIZ7UHsMcj+H2
eBtfFP/800AZRSu/rbPyYQPi20wo8CIogWPHhamjIiDWQlMgE/dEPIUyXyTKFoKC
wHWCH9+7Uvgy7rH90qf8iyYjpGjafH7o55eEOr7I+VJc2F1h7bV59XklwJ1We/O/
8dumpTXwwNSnHP7sbEdTjycftWglLSf8IpNWJGiTW5O5QQGbFszCDcc/R+8Fp0W9
j2XJ86qUHMDIzTx8N9ePmF+eQmvS/PQQfOxEyttjJP/tlzbsyGmOiGtKZtDDLU9c
DXny0TU31oLchyekggd2Oc/55sh9xE0Mb7idRs9h7zZNrw2aZigklA==
=h5p7
-----END PGP SIGNATURE-----

I agree with you, and the work Hiroshi is doing is incredible. About the
library’s robustness, probably I like Ruby so much that I feel
frustrated when I realise the community is not coping with supporting
its growth and consolidation in a timely fashion. At the same time, I am
not good enough to contribute.

I will try the development version myself. Bye,

Gianfranco

Tadeusz B. wrote:

Hi Gianfranco,
Thanks for the reply. I was beginning to lose hope.
I am running this on Windows XP with Ruby 1.8.4-20.
I guess that ‘maturity’ only comes with people exposing
the problems, and then getting them fixed.
So, I hope this is just one of the steps on the way
to a more robust Ruby development environment.
I just noticed that Hiroshi tested my code with the
development version of soap4r, and he got it to work,
so I will try to do the same.

Best regards,
Tad.
(If you would like me to, I will let you know what progress I make.)

Gianfranco Cecconi wrote:

Hi Tad,
I tried myself, but had to stop at the very beginning. These three lines
of code are sufficient to give me problems:

require ‘soap/wsdlDriver’
WSDL_URL = “https://api.betfair.com/betex-api-public-ws/BFService.wsdl
soap = SOAP::WSDLDriverFactory.new(WSDL_URL).createDriver

I get the following:

warning: peer certificate won’t be verified in this SSL session.
Unknown attr {}abstract.
Unknown attr {}nillable.
Unknown attr {}nillable.
Unknown attr {}nillable.
Unknown attr {}abstract.
Unknown attr {}nillable.
Unknown attr {}nillable.
(…)

I am running Ruby 1.8.2 on MacOS 10.4.7 . In general my feeling is that
the SOAP4R library is very immature.

Giacecco

Hi Gianfranco,
Thanks for the reply. I was beginning to lose hope.
I am running this on Windows XP with Ruby 1.8.4-20.
I guess that ‘maturity’ only comes with people exposing
the problems, and then getting them fixed.
So, I hope this is just one of the steps on the way
to a more robust Ruby development environment.
I just noticed that Hiroshi tested my code with the
development version of soap4r, and he got it to work,
so I will try to do the same.

Best regards,
Tad.
(If you would like me to, I will let you know what progress I make.)

Gianfranco Cecconi wrote:

Hi Tad,
I tried myself, but had to stop at the very beginning. These three lines
of code are sufficient to give me problems:

require ‘soap/wsdlDriver’
WSDL_URL = “https://api.betfair.com/betex-api-public-ws/BFService.wsdl
soap = SOAP::WSDLDriverFactory.new(WSDL_URL).createDriver

I get the following:

warning: peer certificate won’t be verified in this SSL session.
Unknown attr {}abstract.
Unknown attr {}nillable.
Unknown attr {}nillable.
Unknown attr {}nillable.
Unknown attr {}abstract.
Unknown attr {}nillable.
Unknown attr {}nillable.
(…)

I am running Ruby 1.8.2 on MacOS 10.4.7 . In general my feeling is that
the SOAP4R library is very immature.

Giacecco

Worked for the great part of the evening on this. My feeling is that the
problem is with the web services that require complex types as input, as
the omnipresent apiRequestHeader .

This source:


(…)
print "Trying to keep it alive… "
apiRequestHeader = { :clientStamp => “foo”,
:sessionToken => “bar” }
response = soapDriver.keepAlive(:request => { :header =>
apiRequestHeader })
exit unless response.result.apiVersion != “”
puts “done.”
(…)

makes ruby produce the following message; the parameters have
disappeared!


← “POST /betex-api-public-ws/v2/BFService HTTP/1.1\r\nAccept:
/\r\nContent-Type: text/xml; charset=utf-8\r\nUser-Agent:
SOAP4R/1.5.5\r\nSoapaction: "keepAlive"\r\nContent-Length:
393\r\nHost: api.betfair.com\r\n\r\n”
← “<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope
xmlns:xsd="http://www.w3.org/2001/XMLSchema\”\n
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/\“\n
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance\”>\n env:Body\n
<n1:keepAlive
xmlns:n1="http://www.betfair.com/publicapi/BFServiceV2/\“>\n
n1:request\n </n1:request>\n </n1:keepAlive>\n
</env:Body>\n</env:Envelope>”
→ “HTTP/1.1 200 OK\r\n”
(…)

Is it normal?

Giacecco

Trying with the official (no development) Ruby 1.8.5 and the situation
is much better now. I seem to login successfully, but I’m getting a “no
session” error when logging out. Difficult to say if it is a Ruby issue
now. Do you think we should move this thread somewhere else?

It is also interesting that it doesn’t work if I do not explicitly
specify the URL for version 2 of the WSDL.

The new source is the following:

require ‘soap/wsdlDriver’
WSDL_URL =
https://api.betfair.com/betex-api-public-ws/v2/BFService.wsdl
BETFAIR_USERNAME = “"
BETFAIR_PASSWORD = "

soapDriver = SOAP::WSDLDriverFactory.new(WSDL_URL).create_rpc_driver

puts “Establishing connection to Betfair…”
print "Logging in… "
loginDetails = { :locationId => 0,
:password => BETFAIR_PASSWORD,
:productId => 82,
:username => BETFAIR_USERNAME,
:vendorSoftwareId => 0 }
response = soapDriver.login(:request => loginDetails) ;
exit unless response.result.errorCode == “OK”
puts “succeded.”

print "Logging out… "
apiRequestHeader = { :clientStamp => 0,
:sessionToken =>
response.result.header.sessionToken }
response = soapDriver.logout(:request => { :header => apiRequestHeader
})
p [response.result.header.errorCode, response.result.errorCode]
exit unless response.result.errorCode==“OK”
puts “succeded.”

Hi Gianfranco,
Have you updated the soap module ?
I haven’t had enough web experience to comment on anything being
normal in this game ! :wink:
I spent most of yesterday evening with this, and, thanks to Hiroshi’s
contribution, it works great !
I downloaded the latest tarball as per Hiroshi’s instruction ,
unzipped it, (its a .tar.gz file, so I had some difficulty locating
the right tools for unzipping it in windows … I used 7zip in the end).
Did a ‘ruby install.rb’ in the extracted directory, and VOILA! my script
worked!

I found one small problem for which I have a workaround.
It is because the Betfair xml defines a method called ‘id’

a= status.result.eventTypeItems.eventType.collect do |market|
[market.name,market.id]
end

Unfortunately this name clashes with Ruby’s ‘id’ method as in Object.id
Ruby warns that Object.id is ‘deprecated’ and that you should use
Object.object_id instead. So the wrong value is returned from
‘market.id’.

I don’t know how to get around this problem, other than substituting
‘id=’
for ‘mktid=’ in the xml first, or extracting the data manually.
eg.,
status=soap.getAllEventTypes(:request=>apiRequestHeader)
a= status.result.eventTypeItems.eventType.collect do |s|
b=s.inspect[2…-2].split(“{}”)[1…-1].collect {|x| eval(x)}
[b[1],b[0]]
end
(ugly, eh?)

Anyway, it’s all going in the right direction.
I will keep you posted on any further issues I find.

Cheers,
Tad

Gianfranco Cecconi wrote:

Worked for the great part of the evening on this. My feeling is that the
problem is with the web services that require complex types as input, as
the omnipresent apiRequestHeader .

This source:


(…)
print "Trying to keep it alive… "
apiRequestHeader = { :clientStamp => “foo”,
:sessionToken => “bar” }
response = soapDriver.keepAlive(:request => { :header =>
apiRequestHeader })
exit unless response.result.apiVersion != “”
puts “done.”
(…)

makes ruby produce the following message; the parameters have
disappeared!


← “POST /betex-api-public-ws/v2/BFService HTTP/1.1\r\nAccept:
/\r\nContent-Type: text/xml; charset=utf-8\r\nUser-Agent:
SOAP4R/1.5.5\r\nSoapaction: "keepAlive"\r\nContent-Length:
393\r\nHost: api.betfair.com\r\n\r\n”
← “<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<env:Envelope
xmlns:xsd="http://www.w3.org/2001/XMLSchema\”\n
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/\“\n
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance\”>\n env:Body\n
<n1:keepAlive
xmlns:n1="http://www.betfair.com/publicapi/BFServiceV2/\“>\n
n1:request\n </n1:request>\n </n1:keepAlive>\n
</env:Body>\n</env:Envelope>”
→ “HTTP/1.1 200 OK\r\n”
(…)

Is it normal?

Giacecco

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

Tadeusz B. wrote:

I downloaded the latest tarball as per Hiroshi’s instruction ,
unzipped it, (its a .tar.gz file, so I had some difficulty locating
the right tools for unzipping it in windows … I used 7zip in the end).
Did a ‘ruby install.rb’ in the extracted directory, and VOILA! my script
worked!

OK. I’ll prepare .zip file from the next release.

‘market.id’.
Does market[“id”] work? [name] interface is for avoiding this kind of
name crash. And would you please send me a sample output wiredump of
getAllEventTypes for testing it on my side?

Regards,
// NaHi

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (Cygwin)

iQEVAwUBRPkH4h9L2jg5EEGlAQJRvQf6AmZZjGwayavl0QHyudMBwzQ6I9TGARmu
LRvaIxKSgPHl0BptwABqjca7KX5LHtZLlpR0xn/AjdXMziQn5Io+iZAXSL46x99N
Ec4TZu1csVolOCgqecNrnS/IYAHz9WHPp9GZGC+5EI+iSRJe1PPnYFxwafwDan69
jR4uya3BjsXH6fgQHoRBrlAjHSgpeR+k05gIvdRFYKL0n5FT13jAMr5dOizUMtkv
tHaU788iIKJYG51Osvp7E/35UyhkU/5Ol3vMK1ORcsDEOXyC92NXbPglWgeXpJ2X
JLpVH+4QPWn9IdRPXaEeMgqODfbn2eQ/ry879PMN+14ZHehNubJm0A==
=shtg
-----END PGP SIGNATURE-----

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

Gianfranco Cecconi wrote:

Worked for the great part of the evening on this. My feeling is that the
problem is with the web services that require complex types as input, as
the omnipresent apiRequestHeader .

You are using ruby-1.8.5 + no extra soap4r install, right?

Would you please try it with the latest snapshot tarball of soap4r at
http://dev.ctor.org/download/ ?

Regards,
// NaHi
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (Cygwin)

iQEVAwUBRPkG2B9L2jg5EEGlAQKYIQf+NBBwkL34s0mZvnUlVqJik+it9bWnJmI3
BHImBMXxVA7GpBS3jKCL7Ddss1RCGTxyH8c3QuDTN2GzxUeNm9FlGqEJLdMHO0cX
AfXi0wyR6j9Gb3euYsUpdB+pgzQ9OT+FGt4SCdrTZJH7VGvZWV4qRwCejZTx+uDL
f3rCM8uJHkbZWmrS2d3CfDYE1UU8ImjxNeRqnMz/+CYhb9iK2w1oaGqV/SOsRDBe
0XGoUMzcIzSvVcvsHXqtt+swgKPhKSCQmZQKO1lMBgd5Y1LxKmMdl9C6yBis5T/3
bxqpgJ6PSora1ZC8+F9gYfHX60ZSmlDsHSrKBxbUKIpvWTToSuwWIA==
=2r6e
-----END PGP SIGNATURE-----

Hi Hiroshi (my Hero!)

Yes! event[“id”] worked just great.
I have included the wiredumps as requested.
I discovered a utility called WebServiceStudio20
http://www.schultz.co.nz/Plone/java/WebserviceStudio20.zip/view
which I found to be very useful on this project to
look at the xml generated.
You just point it to the address of the wsdl file.

Thank you very much for your help.
Tad

WIREDUMP for getActiveEventTypes request :-

<?xml version="1.0" encoding="utf-8" ?>

<env:Envelope xmlns:xsd=“http://www.w3.org/2001/XMLSchema
xmlns:env=“http://schemas.xmlsoap.org/soap/envelope/
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”>
env:Body
<n1:getActiveEventTypes
xmlns:n1=“http://www.betfair.com/publicapi/BFServiceV2/”>
n1:request

0
gvBJUBrywxgQuEaTxW3gmNK40ndscv5CRdaeG01z1dv5PF2HRxj5nA==

en
</n1:request>
</n1:getActiveEventTypes>
</env:Body>
</env:Envelope>

WIREDUMP for getActiveEventTypes response

<?xml version="1.0" encoding="UTF-8"?>

<soap:Envelope xmlns:soap=“http://schemas.xmlsoap.org/soap/envelope/
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance
xmlns:n2=“http://www.betfair.com/publicapi/types/v2/
xmlns:xsd=“http://www.w3.org/2001/XMLSchema”>soap:Body<n:getActiveEventTypesResponse
xmlns:n=“http://www.betfair.com/publicapi/BFServiceV2/”><n:Result
xsi:type=“n2:GetEventTypesResp”>OKgvBJUBrywxgQuEaTxW3gmNK40ndscv5CRdaeG01z1dv5PF2HRxj5nA==2006-09-03T15:48:04.766Z<n2:EventType xsi:type=“n2:EventType”>6423American
Football0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>61420Australian Rules0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>7511Baseball0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>7522Basketball0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>6Boxing0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>982477Bridge0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>4968929Combat Sports0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>4Cricket0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>11Cycling0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>3503Darts0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>6231Financial Bets0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>2152880Gaelic Games0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>3Golf0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>4339Greyhound Racing0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>15Greyhound - Todays Card20041615</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>468328Handball0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>7523Hockey0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>7Horse Racing0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>13Horse Racing - Todays Card20040862</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>7524Ice Hockey0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>8Motor Sport0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>315220Poker0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>2378961Politics0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>1477Rugby League0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>5Rugby Union0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>1Soccer0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>14Soccer - Fixtures0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>10Special Bets0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>4726642Surfing0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>2Tennis0</n2:EventType><n2:EventType
xsi:type=“n2:EventType”>2901849Water Polo0</n2:EventType>OK</n:Result></n:getActiveEventTypesResponse></soap:Body></soap:Envelope>