Issues with anvil.http.request (POST)

What I’m trying to do:
just trying to make a POST request

What I’ve tried and what’s not working:
It works with python requests module but not with anvil.http.request

Am i doing it wrong??

It is in server side.


@anvil.server.callable
def login_with_api(username, password):
  url = f"https://<secret-api>?method=service.auth.get_token&appid={APPID}"
  data = {
    "username": username,
    "password": password,
    "sign": SIGN,
    "appid": APPID
  }
  res = anvil.http.request(url=url, data=data, json=True)
  print("===anvil request===", res)
  
  res = requests.post(url, data)
  print("===python requests===", str(res.content))


I would prefer not to share a clone, the app is for a client.

The request.post(url,data) will, for data passed in as dictionaries, If you don’t specify headers in content-type The type of , default to application/x-www-form-urlencode

Maybe try to not set json=True in the anvil request to mimic what you’re doing with the python requests.

removing json=True doesn’t seem to work in this case…

  res = anvil.http.request(url=url, data=data)
  print("===anvil request===", str(res.get_bytes()))
  
  res = requests.post(url, data)
  print("===python requests===", str(res.content))

OUTPUT:

===anvil request=== b'{"code":201,"msg":"appid \xe6\x97\xa0\xe6\x95\x88","data":[]}'
===python requests=== b'{"code":200,"msg":"Token \xe8\x8e\xb7\xe5\x8f\x96\xe6\x88\x90\xe5\x8a\x9f.","data":{"token":"6b843d3035a42187222dda18160fbc8e1ce718e9","expirse":1659993229}}'

setting the header also doesn’t help…

res = anvil.http.request(url=url, data=data, headers={'content-type':'application/x-www-form-urlencode'})

still getting 201

I would pass the data to an anvil endpoint to see what the endpoint is receiving and diff the two.

Possibly stupid question, if you’re doing this server side and Python’s requests works, why not just use it? Are you trying to work this into code that will function client side, where you need anvil.http.request? Or just curious as to what’s different between the two?

I have another api that i need to use in client side.

This one is the login api,
next one comes into play after login.

I can use requests. maybe i need to call my second api also from server side. it just takes two trips

client to server, server to api, server to client

whereas from client i can totally avoid calling anvil server which is rather slow.

1 Like

here is a clone link with a new http endpoint

https://anvil.works/build#clone:C2AJOMWUDNKZ5OT4=IF4UQE3JRVHBPNCMKCJ7VGTZ

@anvil.server.http_endpoint('/post_test', enable_cors=True, cross_site_session=True)
def anvil_api_post():
  data = anvil.server.request.body_json
  body = anvil.server.request.body
  form_params = anvil.server.request.form_params
  
  print("===data received: ", data)
  print("===body received: ", str(body.get_bytes() if body else None))
  print("===form params received: ", form_params)
  
  return anvil.server.HttpResponse(200, f"data is {data} \n body is {body.get_bytes() if body else None}\n form params {form_params}")
  
  

making a POST call to this endpoint from anvil raises 500
making a GET call to this endpoint from anvil doesn’t raise error

making GET/POST using post man works!

you need to specifiy the methods accepted by the endpoint

@anvil.server.http_endpoint('/post_test',methods=["POST"])

postman must be accounting for this somehow.

Going back to the original code, your anvil.http.request call is making a GET request (the default), while your requests call is making a POST request. Maybe try making a POST request with anvil.http.request as per the docs and see if that helps: Anvil Docs | Making HTTP requests

1 Like

I was testing with POST, it’s in the first screenshot I posted.
wasn’t working. Then I tried GET to see if the call works.

I could not make it work with anvil.http.request.
Seems like requests in server code is my only option here.

Also noticed that, POSTing data to an anvil.http endpoint using anvil.http.request unpacks the data dictionary and sends 'em as keyword args, raising unexpected keyword arg exception.

I plan to dig a little deeper into this, after I’m done with the deadline :neutral_face:

Yeah, I’d think the issue is getting the data into the right form for anvil.http.request to pass it to the endpoint in the right way. Hopefully someone who uses anvil.http.request regularly can chime in on this.