问题
Access the Betfair Exchange API using Julia
I've been using Julia for about 2mths now, and have recently been trying to use Julia to access the Betfair API. Note about this service are here. https://docs.developer.betfair.com/display/1smk3cen4v3lu3yomq5qye0ni/Getting+Started
Whilst I can get the Python example working (& I have an appKey & sessionToken though not shown), I've not been able to successfully translate this Python into Julia.
In example below I get a StatusError 400 response (which is the closest I've gotten). Other attempts indicated Bound issues probably from the Python example using {} and ' which Ive attempted to then translate.
I've looked at other Stackflow questions, but found they don't have the complexity associated with this example.
Wondering if anyone has any thoughts. Thanks in advance
using HTTP
url="https://api.betfair.com/exchange/betting/json-rpc/v1"
header = "\"X-Application\" : \"appKey\", \"X-Authentication\" : \"sessionToken\" ,\"content-type\" : \"application/json\" "
jsonrpc_req="\"jsonrpc\": \"2.0\", \"method\": \"SportsAPING/v1.0/listEventTypes\", \"params\": {\"filter\":{ }}, \"id\": 1"
response = HTTP.post(url, data=[jsonrpc_req], headers=[header])
println(response.text)
Expected Results. In Python, I get a summary of Betfair Sports and Market's.
{"jsonrpc":"2.0","result":[{"eventType":{"id":"1","name":"Soccer"},"marketCount":10668},{"eventType":{"id":"2","name":"Tennis"},"marketCount":4590},{"eventType":{"id":"3","name":"Golf"},"marketCount":43},{"eventType":{"id":"4","name":"Cricket"},"marketCount":394},{"eventType":{"id":"5","name":"Rugby Union"},"marketCount":37},{"eventType":{"id":"1477","name":"Rugby League"},"marketCount":24},{"eventType":{"id":"6","name":"Boxing"},"marketCount":27},{"eventType"
...etc...
Currently get
HTTP.ExceptionRequest.StatusError(400, HTTP.Messages.Response:
400 Bad Request.
回答1:
While the interaction with a particular REST service is a problem-specific issue here are the general guidelines.
Firstly, you need to properly format headers
- HTTP.jl manual reads: "headers can be any collection where [string(k) => string(v) for (k,v) in headers]
yields Vector{Pair}
."
Since we do not have Betfair API key let's have a look on a more generic example using https://postman-echo.com/
which is a free simple API testing that simply returns as JSON whatever it gets as the input.
using HTTP
using JSON
headers = (("X-Application","appKey"),("X-Authentication","sessionToken"),
("content-type","application/json"))
url="https://postman-echo.com/post"
req = Dict("jsonrpc" => "2.0", "params" => Dict("filet" => Dict()))
response = HTTP.post(url, headers, JSON.json(req))
response_text = String(response.body)
json_obj = JSON.parse()
Now let us parse the output from postman-echo.com
:
julia> display(JSON.parse(response_text))
Dict{String,Any} with 7 entries:
"headers" => Dict{String,Any}("x-forwarded-port"=>"443","host"=>"postman-echo.com","x-application"=>"appKey","content-type"… "json" => Dict{String,Any}("params"=>Dict{String,Any}("filet"=>Dict{String,Any}()),"jsonrpc"=>"2.0")
"files" => Dict{String,Any}()
"args" => Dict{String,Any}()
"data" => Dict{String,Any}("params"=>Dict{String,Any}("filet"=>Dict{String,Any}()),"jsonrpc"=>"2.0")
"url" => "https://postman-echo.com/post"
"form" => Dict{String,Any}()
You can easily adopt the above code to any RESTful JSON API.
回答2:
Thanks Przemyslaw Szufel for your response. After a few more days of frustration, I managed to get the first part of the API working using the Excel/VBA sample here: https://github.com/betfair/API-NG-Excel-Toolkit (my translations of the Python examples did not work). Your comment helped in terms of understanding how to structure multiple headers, and using Dict( =>) rather than string for the manipulations I attempted above.
using HTTP
using JSON
const ListEventTypesMethod = "listEventTypes"
const AppKey = "appKey"
const Session = "sessionToken"
function SendRequest(Url, AppKey, Session, Data)
headers = (("X-Application", AppKey),
("content-type", "application/json"),
("Accept", "application/json"),
("X-Authentication", Session))
HTTP.get(Url,headers,JSON.json(Data))
end
function ParseJsonRpcResponseToCollection(Response)
ParseJsonRpcResponseToCollection = JSON.parse(Response)
end
function GetJsonRpcUrl()
GetJsonRpcUrl = "https://api.betfair.com/exchange/betting/json-rpc/v1/"
end
function MakeJsonRpcRequestString(Method, RequestString)
#MakeJsonRpcRequestString = "{""jsonrpc"": ""2.0"", ""method"": ""SportsAPING/v1.0/" & Method & """, ""params"": " & RequestString & ", ""id"": 1}"
MakeJsonRpcRequestString = Dict("jsonrpc" => "2.0", "method" =>"SportsAPING/v1.0/"*Method, "params" => RequestString, "id"=> 1 )
end
function GetListEventTypesRequestString()
#GetListEventTypesRequestString = "{""filter"":{}}"
GetListEventTypesRequestString=Dict("filter" =>Dict())
end
Request = MakeJsonRpcRequestString(ListEventTypesMethod, GetListEventTypesRequestString())
ListEventTypesResponse = SendRequest(GetJsonRpcUrl(), AppKey, Session, Request)
Response
HTTP/1.1 200 OK Date: Sun, 17 Feb 2019 17:28:08 GMT Server: Cougar - 4.4.2 (Cougar 2 mode) Cache-Control: no-cache Content-Type: application/json Vary: Accept-Encoding, User-Agent Content-Length: 1850
{"jsonrpc":"2.0","result":[{"eventType":{"id":"1","name":"Soccer"},"marketCount":6553},{"eventType":{"id":"2","name":"Tennis"},"marketCount":5511},{"eventType":{"id":"3","name":"Golf"},"marketCount":34} etc...
Hope this helps others as well.
来源:https://stackoverflow.com/questions/54612993/how-to-access-an-api-via-julia-http