flask with aiomysql runtime error: event loop closed

32 views Asked by At

I'm using flask[async] with the support of async operation along with the aiomysql. So for the very first call, it does return me the response which is working perfectly well. But when the second request comes in I got the error stem from the aiomysql indicating event loop is closed.

I did some research and found this https://github.com/sqlalchemy/sqlalchemy/discussions/5994 but seems not really helping it. Any idea for this?

Code:

Routes:

@app.route("/api/v1/Post/getPost", methods=["POST"])
async def getAllPost(**kwargs):
    try:
        response = {
            "data": None,
            "message": None,
            "error": None
        }
        
        try:
            data = request.get_json()
            log.info("Logging with {}".format(data))
        except json.JSONDecodeError as e:
            response["error"], response["message"] = "BadRequest", "Invalid JSON"
            log.error(f"json file error {e}")
            return jsonify(response), HTTPStatus.BAD_REQUEST  
        
        # Call router
        routeResponse = await post.getAllPost(data)
        response["data"] = routeResponse["data"]
        response["message"] = routeResponse["message"]
        response["error"] = routeResponse["error"]
        return custom_make_response(response, routeResponse["HTTPStatus"], **kwargs)
        
    except Exception as e:
        response["error"], response["message"] = "InternalServerError", str(e)
        log.error(f"Internal server error : {e}")
        return jsonify(response), HTTPStatus.INTERNAL_SERVER_ERROR

getAllPost function

`async def getAllPost(data):
    try:
        response = {
            "data": None,
            "message": None,
            "error": None,
            "HTTPStatus": None
        }
        
        log.info("Getting All Existing Post")
        userID = data.get("userId")
        mediaType = data.get("mediaType")
        groupID = data.get("groupId")
        # db = Database.get_database()
        db = await DatabaseAsync.get_database()
        
        # postResponse, resultPostImages, resultPostUserLikes, resultPostAllUserLikes = db.get_post(userID, mediaType, groupID)
        postResponse, resultPostImages, resultPostUserLikes, resultPostAllUserLikes = await db.get_post(userID, mediaType, groupID)
....
return reponse`

db class and i/o operation

`    def __init__(self):
        pass

    async def initialize_pool(self):
        self.pool = await aiomysql.create_pool(
            user="fakedb",
            password="fakedb",
            host="localhost",
            db="fakedb",
            port=3306,
            minsize=1,
            maxsize=5
        )

    @staticmethod
    async def get_database():
        if DatabaseAsync.instance is None:
            db = DatabaseAsync()
            await db.initialize_pool()
            DatabaseAsync.instance = db
        return DatabaseAsync.instance
async def get_post(self, userID, mediaType, groupID = None, postID = None):
        response = {
            "data" : None,
            "message" : None,
            "error" : None,
            "HTTPStatus" : None
        }

        try:
            # query preparation
            ....

            conn = await self.pool.acquire()
            cur = await conn.cursor(aiomysql.DictCursor)

            # Fetch the required post ID for joining images
            await cur.execute(queryPostImages)
            resultPostImages = await cur.fetchall()
            requiredPostID = ""
            for post in resultPostImages:
                queryPostId = str(post['postID']) + ","
                requiredPostID += queryPostId
            
            if (len(requiredPostID) > 0):
                # Fetch current user liked post
                await cur.execute(queryPostUserLikes)
                resultPostUserLikes = await cur.fetchall()
                
                if groupID is not None and postID is None:
                    # Fetch all liked user
                    queryPostAllUserLikes = queryPostAllUserLikes.format(requiredPostID[:-1])
                elif postID is None:
                    queryPostAllUserLikes = queryPostAllUserLikes.format(requiredPostID[:-1], '')

                await cur.execute(queryPostAllUserLikes)
                resultPostAllUserLikes = await cur.fetchall()
            
            # release conn and close it
            await cur.close()
            self.pool.release(conn)
            
            response["message"], response["HTTPStatus"], response["error"] = "SUCCESS", HTTPStatus.OK, False
            return response, resultPostImages, resultPostUserLikes, resultPostAllUserLikes
                
        except (Exception) as e:
            traceback.print_exc()
            response["message"], response["error"], response["HTTPStatus"] = "INTERNAL SERVER ERROR", str(e), HTTPStatus.INTERNAL_SERVER_ERROR
            return response          `

Error:

`Traceback (most recent call last):
  File "C:\Users\MJ\Documents\kaijaz\projects\comm\backend\dbasync.py", line 88, in get_post
    await cur.execute(queryPostImages)
  File "C:\Users\MJ\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiomysql\cursors.py", line 239, in execute
    await self._query(query)
  File "C:\Users\MJ\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiomysql\cursors.py", line 457, in _query
    await conn.query(q)
  File "C:\Users\MJ\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiomysql\connection.py", line 468, in query
    await self._execute_command(COMMAND.COM_QUERY, sql)
  File "C:\Users\MJ\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiomysql\connection.py", line 724, in _execute_command
    self._write_bytes(prelude + sql[:chunk_size - 1])
  File "C:\Users\MJ\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiomysql\connection.py", line 669, in _write_bytes
    return self._writer.write(data)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\MJ\AppData\Local\Programs\Python\Python311\Lib\asyncio\streams.py", line 332, in write
    self._transport.write(data)
  File "C:\Users\MJ\AppData\Local\Programs\Python\Python311\Lib\asyncio\proactor_events.py", line 365, in write
    self._loop_writing(data=bytes(data))
  File "C:\Users\MJ\AppData\Local\Programs\Python\Python311\Lib\asyncio\proactor_events.py", line 401, in _loop_writing
    self._write_fut = self._loop._proactor.send(self._sock, data)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'send'
Traceback (most recent call last):
  File "C:\Users\MJ\Documents\kaijaz\projects\comm\backend\routes\post.py", line 38, in getAllPost
    if item['image_data'] is not None:
       ~~~~^^^^^^^^^^^^^^
TypeError: string indices must be integers, not 'str'
Traceback (most recent call last):
  File "C:\Users\MJ\Documents\kaijaz\projects\comm\backend\dbasync.py", line 110, in get_post
    self.pool.release(conn)
  File "C:\Users\MJ\AppData\Local\Programs\Python\Python311\Lib\site-packages\aiomysql\pool.py", line 230, in release
    fut = self._loop.create_task(self._wakeup())
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\MJ\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 434, in create_task
    self._check_closed()
  File "C:\Users\MJ\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 519, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed
C:\Users\MJ\Documents\kaijaz\projects\comm\backend\dbasync.py:118: RuntimeWarning: coroutine 'Pool._wakeup' was never awaited
  return response`

Any help is appreciated, thanks

0

There are 0 answers