Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access an API via Julia HTTP

Tags:

http

julia

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.
like image 234
DaKlingons Avatar asked Feb 10 '19 03:02

DaKlingons


Video Answer


2 Answers

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.

like image 88
Przemyslaw Szufel Avatar answered Sep 22 '22 17:09

Przemyslaw Szufel


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.

like image 38
DaKlingons Avatar answered Sep 24 '22 17:09

DaKlingons