23

Consider:

import logging
import azure.functions as func

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    name = {"test":"jjj"}
    return func.HttpResponse(name)

Above is my Azure function (V2) using Python preview.

If I return

func.HttpResponse(f"{name}")

it works, but if I return a dict object it does not.

The error displayed is:

Exception: TypeError: reponse is expected to be either of str, bytes, or bytearray, got dict

3
  • 1
    Have you tried serializing your dict object to JSON before returning it? Commented Jun 13, 2019 at 22:14
  • @maswadkar Take a look. Though its not exact solution for your problem but help you to get into this what you need to do or your work around. Thanks and happy coding! Commented Jun 14, 2019 at 8:51
  • Did it literally output "reponse" (not "response")? Commented Sep 30, 2021 at 11:10

6 Answers 6

57

You need to convert your dictionary to a JSON string using the built-in JSON library - json.dumps.

Then you can set the MIME type (Content-Type) of your function to application/json. By default Azure functions HttpResponse returns text/plain Content-Type.

import json
import logging
import azure.functions as func

def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    name = {"test":"jjj"}
    return func.HttpResponse(
        json.dumps(name),
        mimetype="application/json",
    )
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! To get more compact JSON, you should do json.dumps(name, separators=(',', ':')
@maswadkar Could you accept this as the answer if it answered your question? It looks like this has been helpful to the community.
8

Better way:

func.HttpResponse.mimetype = 'application/json'
func.HttpResponse.charset = 'utf-8'

return func.HttpResponse(json_object)

1 Comment

Could you elaborate why this is better? It looks like this is modifying global variables in a foreign module, which is an ugly side effect. Also, I'm simply getting a (runtime) TypeError if I don't serialize the json_object myself. And type checking the code with mypy/pyright fails, because the first argument to HttpResponse is typed as str | bytes, so you cannot just pass in your raw data, right? Also, specifying the charset as utf-8 is redundant, because it is the default anyway.
1

First of all, I am not a Python expert. I am just trying to let you know what the issue is all about.

So on Azure function if you look, it would seem its return type is IActionResult. If you decompile it, you would see:

IActionResult IConvertToActionResult.Convert()
    {
      ActionResult result = this.Result;
      if (result != null)
        return (IActionResult) result;
      return (IActionResult) new ObjectResult((object) this.Value)
      {
        DeclaredType = typeof (TValue)
      };
    }

So it expects an object from you rather than a Dictionary or List or any kind of generics type. But if you convert it into an object like OkObjectResult, you wouldn't encounter any compile error. See the example below:

IDictionary<int, string> MyDictionary = new Dictionary<int, string>();
MyDictionary.Add(new KeyValuePair<int, string>(1, "One"));
MyDictionary.Add(new KeyValuePair<int, string>(2, "Two"));

// As we have to return IAction Type, so converting to IAction class
// using OkObjectResult we can even use OkResult
return new MyDictionary;

The above code would encounter your compile error. Because it does not support Dictionary or List Or any generic directly. See the screenshot below:

Enter image description here

See what the error said:

Enter image description here

But if you convert your Dictionary or List Or any generic into an object type, it will resolve your issue for sure. See the below example:

IDictionary<int, string> MyDictionary = new Dictionary<int, string>();
MyDictionary.Add(new KeyValuePair<int, string>(1, "One"));
MyDictionary.Add(new KeyValuePair<int, string>(2, "Two"));

// So have converted MyDictionary into Object type that the compiler deserve. And no compile error encountered.
return new OkObjectResult(MyDictionary);

See the screenshot below:

Enter image description here

Note: If you try to parse your func.HttpResponse(name) into an object then finally return, your problem should resolve. So you can try to add a reference to this package in your project (import json) and try the below code:

import json

name = {"test":"jjj"}

print(json.dumps(name))

Comments

1

The proper way to do this is:

return func.HttpResponse(
   body = name,
   status_code = 200
)

See the documentation for more information on the HttpResponse class.

2 Comments

This is not the solution and raises the same exception as the original post. Exception: TypeError: reponse is expected to be either of str, bytes, or bytearray, got dict
right, the api might have changed, I should have mentioned which version this was for.
0

Try it like this:

 import json

     return func.HttpResponse (
        json.dumps({
        'lat': lat,
        'lon': lon

        })
     )

1 Comment

That is not valid Python by itself (indentation). Is it only a snippet? Can you elaborate in your answer?
0

what about this, create a json object (json dumps creates a json from a dictonary) and return that in the body of your response:

# json object
result = {
    "arg1" : variable1,
    "arg2" : variable2
}
result = json.dumps(result, indent = 4) 

return func.HttpResponse(
        body = result,
        status_code=200
)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.