Anvil.http.request: Invalid JSON in response

Hi all,

I’m having an issue with http.anvil.response using ‘json=True’. I’m using the function to call an API hosted on Google Script, which returns valid JSON when tested through Postman, and when called through Anvil I log the output on the Google side and it is a valid JSON object being sent back from the http.anvil.response.

Yet still http.anvil.response will always return “Invalid JSON in response” with no further information, is there further documentation on what the function will accept as a valid response?

EDIT: I’ve added a debug function to return a test object, here’s the code:

def get_report_data(service, date):
  access_token = anvil.google.auth.get_user_access_token()
  response = anvil.http.request(url="https://script.google.com/scriptplaceholder/dev",
    method="POST",
    data={
      "name": "debug123"
    },
    headers={'Authorization': 'Bearer ' + access_token},
    json=True
    )

When this request is sent from Postman it successfully returns

{"secret": "topsecret", "time": 1234, "totp": "youronetimepassword"}

And when sent from Anvil I can see in the Google logs that it is returning a JSON object:

jsonPayload: {

serviceContext: {1}

message: "{"secret": "topsecret", "time": 1234, "totp": "youronetimepassword"}"

}

EDIT2: I’ve had a look at ‘/libanvil/anvil/http.py, line 51’ and this function which is returning the error:

        try:
            b = resp["content"].get_bytes()
            # Ew. microjson barfs if we give it a "unicode" object.
            # We only use microjson in the old 2.7 sandbox, so
            # this can go away soon.
            if not isinstance(b, str):
                b = b.decode()
            resp["content"] = json_mod.loads(b)
        except:
            raise HttpError(resp["status"], resp["content"], "Invalid JSON in response")

    if resp["status"] < 200 or resp["status"] > 299:
        raise HttpError(resp["status"], resp["content"])

If I recreate this in my Anvil code (encode the response to Bytes (.get_bytes), then back to String (.decode()):

jsonResponse='{"secret": "topsecret", "time": 1234, "totp": "youronetimepassword"}'

jsonBytes=bytes(jsonResponse, 'utf-8')
print(type(jsonBytes))
print(jsonBytes)

jsonString=str(jsonBytes)
print(type(jsonString))
print(jsonString)

json.loads(jsonString)

json.loads throws an error while loading jsonString, but can load jsonBytes without issue. Are there any code examples of anvil.http.request working with json=True or is this a bug?

Hi @Gathre and welcome to the forum!

Would be helpful to know a bit more about the issue so I can take a look for you.

Could you try hitting the endpoint without the json=True and outputting the contents of the Media Object that’s returned?

Could you also let me know which Python version you’re using in your Server Modules?

Thanks for your reply! The server module is using ‘Basic Python 3’. If I send without json=True I receive the Google Error page HTML, with the error SyntaxError: Unexpected token a in JSON at position 1.

I have downloaded the Anvil runtime to run a copy of my site locally so I can see what /libanvil/anvil/http.py is recieving and outputting, with json=True http.py returns a Google error page with Your client has issued a malformed or illegal request. and so then gives the Invalid JSON in response error

1 Like