Search code examples
pythonapiflaskelmflask-restful

Why does my API request returns empty values on each POST arguments?


While on localhost, I have downloaded Flask-Cors. I tried sending few requests to flask server as the code below the entire code is on github.

unfortunately i can't get any data using POST request.

here is my ELM code.

module Update exposing (update)
import Http
import Json.Decode exposing (..)

import Types exposing (..)



update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
    case msg of Username str -> ({ model | loginUserName = str}, Cmd.none)
                Password str -> ({ model | loginPassword = str}, Cmd.none)
                Login -> (model, login model.loginUserName model.loginPassword)
                LoginResult (Ok username) -> ({ model | user = LoggedInUser { userName = username}},
                                              Cmd.none)
                LoginResult (Err _) -> (model, Cmd.none)
                Logout -> (model, Cmd.none)


login : String -> String -> Cmd Msg
login username password =
    let url = "http://0.0.0.0:8080/api/user/login"
        request = Http.get url decodeLogin
    in Http.send LoginResult request


decodeLogin: Decoder String
decodeLogin = at ["username"] string

-- Or
--decodeLogin : Decoder String
--decodeLogin = decodeString (field "username" string)

The rest of the code is at Github

Here is my Flask endpoint for the API

@app.route("/api/user/login/", methods=["GET", "POST"])
def login(*args, **kwargs):
    print 'Got request for login'
    print args
    print kwargs
    print request.args
    print request.args.get("username")
    print request.values.get("username")
    print request.method
    print request.form['username']

    response = {'username': 'Erik'}

    dict = request.args
    for key in dict:
        print 'form key ' + dict[key]

    return jsonify(response)

The rest of this code is also at this link.


Solution

  • It looks like your server is expecting the body of the POST to be in multiple key=val format, rather than in JSON. You can use multipartBody to achieve this:

    import Http exposing (..)
    
    login : String -> String -> Cmd Msg
    login username password =
        let url = "http://0.0.0.0:8080/api/user/login"
            body =
                multipartBody
                    [ stringPart "username" username
                    , stringPart "password" password
                    ]
            request = Http.post url body decodeLogin
        in Http.send LoginResult request