HTTP: Login to MediaWiki API with post fails (works with python)

Why can I login with python (module requests), but not with HTTP.jl?

The MediaWiki API requires a login token, a bot user name and password. See python-code example. Bot user name looks like “user@juliahttp”. The password consists of numbers an ordinary characters.The same is true for the token, but it ends in “+\”. token: "“c6c2ae9a34ec56a212a1143ff440fb985eeb2049+\”
So the REPL prints out:
grafik

The Python code reads:

PARAMS_1 = {
    'action':"login",
    'lgname':bot,
    'lgpassword':botpwd,
    'lgtoken':LOGIN_TOKEN,
    'format':"json"
}

R = S.post(URL, data=PARAMS_1)

DATA = R.json()

And you get:
{'login': {'result': 'Success', 'lguserid': 3, 'lgusername': 'User'}}

I did this in julia:

params = ["action=login",
          "lgname=$(bot)",
          "lgpassword=$(pwd)", 
          "lgtoken=$(logintoken)",
          "format=json"]

data = join(params, "&")
    
response = HTTP.request("POST", URL,
                        ["Content-Type" => "application/x-www-form-urlencoded"],
                        data)

I get a JSON response with a warning, that I should not try to get a token with action=login. So data is interpreted in some way. I get the same result, if I send a wrong password.

I applied HTTP.URIs.escapeuri to the bot user name and to the token. I get the same response. Thanks for a hint!

You probably want to send the data in the request body as JSON instead of a query string

using JSON
data = Dict("action" => "login",
    ...
    "format" => "json"
)

response = HTTP.post(URL,
    ["Content-Type" => "application/json"],
    JSON.json(data))

println(JSON.parse(String(response.body)))

Unfortunately the API does not accept such a request and responds with a default HTML error message.

You can try to use the query keyword together with a Dict (much like your python code):

params = Dict(
    "action" => "login",
    "lgname" => bot,
    ...
)

HTTP.request("POST", URL; query=params)

This is cool! However, it appends the parameters to the URL, but they are expected in the POST body in this case.

I set up a little server as described in the documentation of HTTP.jl and saw that the python body and the julia body are the same. Then I set cookies=true in the request to get the login token, et voilà, that was it.

Some background info.

Thanks a lot for your comments!

You can post with HTTP.Form(Dict())