Home > database >  Python - aiohttp API response content is "StreamReader" type instead of JSON
Python - aiohttp API response content is "StreamReader" type instead of JSON

Time:01-26

I'm learning the aiohttp library with Python 3.10 for making HTTP GET requests, and am practicing it with the GitHub v3 REST API. Here's my code for a basic request:

# Python Standard Library imports
import asyncio
import sys

# External library imports
import aiohttp

# GitHub API v3 REST endpoint for licenses
GITHUB_URL: str = "https://api.github.com/licenses"
# GitHub query headers
GITHUB_HEADERS: dict = {
    "Accept": "application/vnd.github.v3 json"
}

async def main():

    async with aiohttp.ClientSession() as session:
        async with session.get(GITHUB_URL, headers = GITHUB_HEADERS) as GitHub_response:

            print(GitHub_response.content)

if __name__ == "__main__": 

    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

    sys.exit(0)

The code runs without errors, but the critical print(GitHub_response.content line gives me:

<StreamReader 2037 bytes eof>

Which is not what I expected. And what is a StreamReader object anyway???

What I expected was the JSON output which the curl command curl -H "Accept: application/vnd.github.v3 json" "https://api.github.com/licenses would give me, which looks like:

[
  {
    "key": "agpl-3.0",
    "name": "GNU Affero General Public License v3.0",
    "spdx_id": "AGPL-3.0",
    "url": "https://api.github.com/licenses/agpl-3.0",
    "node_id": "MDc6TGljZW5zZTE="
  },
  {
    "key": "bsd-2-clause",
    "name": "BSD 2-Clause \"Simplified\" License",
    "spdx_id": "BSD-2-Clause",
    "url": "https://api.github.com/licenses/bsd-2-clause",
    "node_id": "MDc6TGljZW5zZTQ="
  },
.....

I tried replacing my print() line with print(GitHub_response.json()), but that gave me:

<coroutine object ClientResponse.json at 0x7f7e452b5e00>

So it is still not the JSON I was expecting.

What did I do wrong? And how do I fix my Python code so that I get the actual JSON response with aiohttp?

Thank you.

P.S. I tried doing the above with the Python requests library. The content of the response in this case is a bytes object which I had to decode("utf8") first before using json.dumps() from the json library to turn it into actual JSON. Not sure if this information is helpful for figuring out what I messed up when using aiohttp.

CodePudding user response:

"content" is an instance of StreamReader. This provides a coroutine "read" that reads returns the content as string. Insert the following example into your code and you should get the expected result.

 x = await GitHub_response.content.read()
 print(x)
  •  Tags:  
  • Related