title: About the maximum recursion error in FastAPI
body: <p>I am building an application using FastAPI+Sqlalchemy+Mysql, and when I do a stress test,I get an Asgi exception error:</p>
  <pre class="lang-py prettyprint-override"><code>[ERROR] Exception in ASGI application, 
  RecursionError: maximum recursion depth exceeded while calling a Python object.
  </code></pre>
  <p>I can definitely have :</p>
  <ol>
  <li>I did not call any recursive function</li>
  <li>I have tried both alchemy and mysql_connector to query the database
  but the error still exists.</li>
  </ol>
  <p>The code is here:</p>
  <h3>My main.py as follows</h3>
  <pre class="lang-py prettyprint-override"><code>def create_app()-&gt;FastAPI:
      app = FastAPI(debug = False)
  
      register_cors(app)
  
      app.include_router(admin_router)
  
      register_exception(app)
     
      register_token_validate(app)
  
      return app
  
  
  ***def register_cors(app:FastAPI):
      @app.middleware(&quot;http&quot;)
      async def cors(request:Request, call_next):
          app.add_middleware(
              CORSMiddleware,
              allow_origins=[&quot;*&quot;],
              allow_credentials=True,
              allow_methods=[&quot;*&quot;],
              allow_headers=[&quot;*&quot;],      
          )
          response = await call_next(request)
          response.headers[&quot;access-control-allow-credentials&quot;] = &quot;true&quot;
          response.headers[&quot;access-control-allow-origin&quot;] = &quot;*&quot;
          response.headers[&quot;access-control-allow-methods&quot;] = &quot;*&quot;
          return response***
  
  def register_exception(app:FastAPI):
  
      @app.exception_handler(RequestValidationError)
      async def validation_exception_handler(request: Request, exc: RequestValidationError):
          errType = (exc.errors())[0][&quot;type&quot;]
          detail = (exc.errors())[0]
          type = errType.split(&quot;.&quot;)
          if type[0] == &quot;value_error&quot;:
              return JSONResponse(
                  status_code=422,
                  content={&quot;code&quot;: 422,&quot;msg&quot;: &quot;value error&quot;, &quot;errinfo_type&quot;:detail}
              )
          elif type[0] == &quot;type_error&quot;:
              return JSONResponse(
                  status_code=422,
                  content={&quot;code&quot;: 422,&quot;msg&quot;: &quot;type error&quot;, &quot;errinfo_type&quot;:detail}
              )
          else:          
              return JSONResponse(
                  status_code=422,
                  content={&quot;code&quot;: 422,&quot;msg&quot;: &quot;server error&quot;, &quot;errinfo_type&quot;:detail}
              )
  
  
      @app.exception_handler(Exception)
      async def all_exception_handler(request: Request, exc: Exception):
          return JSONResponse(
              status_code=500,
              content={&quot;code&quot;: 500,&quot;msg&quot;: &quot;server error&quot;, &quot;errinfo_type&quot;:None}
          )
  
  def register_token_validate(app: FastAPI):
      @app.middleware(&quot;http&quot;)
      async def token_validate(request: Request, call_next):
          excludeUrlL = [
              &quot;/v1/login&quot;,
              &quot;/docs&quot;,
              &quot;/redoc&quot;
          ]
  
          if (request.url.path not in excludeUrlL) and (request.method != &quot;OPTIONS&quot;): 
              res = security.validate_token(request.headers.get(&quot;token&quot;), request.headers.get(&quot;request_time&quot;))   
              if res['status'] == &quot;success&quot;: 
                  response = await call_next(request)
                  response.headers[&quot;access-control-allow-credentials&quot;] = &quot;true&quot;
                  response.headers[&quot;access-control-allow-origin&quot;] = &quot;*&quot;
                  response.headers[&quot;access-control-allow-methods&quot;] = &quot;*&quot;
                  return response
              elif res['status'] == &quot;failed&quot;: 
                  return JSONResponse(
                      status_code=401,
                      content={&quot;code&quot;: 401,&quot;msg&quot;: &quot;token expired&quot;}
                  ) 
              elif res['status'] == &quot;updated&quot;: 
                  response = await call_next(request)
                  response.headers[&quot;token&quot;] = res['payload']
                  response.headers[&quot;access-control-allow-credentials&quot;] = &quot;true&quot;
                  response.headers[&quot;access-control-allow-origin&quot;] = &quot;*&quot;
                  response.headers[&quot;access-control-expose-headers&quot;] = &quot;token&quot;
                  response.headers[&quot;access-control-allow-methods&quot;] = &quot;*&quot;
                  return response
          else:
              response = await call_next(request)
              response.headers[&quot;access-control-allow-credentials&quot;] = &quot;true&quot;
              response.headers[&quot;access-control-allow-origin&quot;] = &quot;*&quot;
              response.headers[&quot;access-control-allow-methods&quot;] = &quot;*&quot;
              return response
  
  app = create_app()
  
  if __name__ == &quot;__main__&quot;:
      import uvicorn
      uvicorn.run(app=&quot;main:app&quot;, host=&quot;0.0.0.0&quot;, port=8000, reload=True, debug=False)
  </code></pre>
  <p>security.py</p>
  <pre class="lang-py prettyprint-override"><code>
  #!/usr/bin/env python
  # -*- coding: utf-8 -*-
  
  from datetime import datetime, timedelta, tzinfo
  from db.DbSession import session
  from sqlalchemy import text
  
  from config import config
  from core.logger import logger
  from core import util
  import pytz
  
  
  def validate_token(token, request_time):
      if not token:
          return {&quot;status&quot;:&quot;failed&quot;, &quot;payload&quot;:None, &quot;msg&quot;: &quot;token is required&quot;}
  
      if not request_time:
          return {&quot;status&quot;:&quot;failed&quot;, &quot;payload&quot;:None, &quot;msg&quot;: &quot;request_time is required&quot;}
  
      sql = &quot;select id, mobile, token, expired_time,  last_request_time from my_user_table where token = :token limit 1&quot;
      rp = session.execute(text(sql), {&quot;token&quot;:token})
      res = [dict(r.items()) for r in rp]
  
      if not res:
          return {&quot;status&quot;:&quot;failed&quot;, &quot;payload&quot;:None, &quot;msg&quot;: &quot;token error&quot;}
  
      nowStamp =  datetime.now().timestamp()
      expired_timeStamp = res[0]['expired_time'].timestamp()
  
      if nowStamp &gt; expired_timeStamp:
          return {&quot;status&quot;:&quot;failed&quot;, &quot;payload&quot;:None, &quot;msg&quot;: &quot;token is expired&quot;}
  
      if (int(request_time) - int(res[0]['last_request_time'])) &gt; 600:
          return {&quot;status&quot;:&quot;updated&quot;, &quot;payload&quot;:token, &quot;msg&quot;: &quot;token is updated&quot;}
      else:
          return {&quot;status&quot;:&quot;success&quot;, &quot;payload&quot;:None, &quot;msg&quot;: &quot;token is valid&quot;}
  
  
  </code></pre>
  <p>session.py</p>
  <pre class="lang-py prettyprint-override"><code>from sqlalchemy import create_engine
  from sqlalchemy.orm import Session
  from sqlalchemy.pool import NullPool
  
  engine = create_engine(config.DbUrl, echo = False, poolclass=NullPool)
  session = Session(engine)
  </code></pre>
  <p>api.py</p>
  <pre class="lang-py prettyprint-override"><code>@router.get(&quot;/v1/getCompany&quot;, summary=&quot;get company information&quot;)
  async def getCompany(id:int):
      sql = &quot;select * from my_company_table c where c.id = :id&quot;    
      rp = session.execute(text(sql), {&quot;id&quot;:id})
      res = [dict(r.items()) for r in rp]   
      session.commit() 
      return util.resp_200(200, 'get company information success', res)
  </code></pre>
  <p>When I call this interface <code>/v1/getCompany</code> continuously, I get the above error</p>
  <pre><code>[ERROR] Exception in ASGI application
  Traceback (most recent call last):
    File &quot;/root/.cache/pypoetry/virtualenvs/facli-zsB1kvQc-py3.8/lib/python3.8/site-packages/uvicorn/protocols/http/h11_impl.py&quot;, line 388, in run_asgi
      result = await app(self.scope, self.receive, self.send)
    File &quot;/root/.cache/pypoetry/virtualenvs/facli-zsB1kvQc-py3.8/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py&quot;, line 45, in __call__
      return await self.app(scope, receive, send)
    File &quot;/root/.cache/pypoetry/virtualenvs/facli-zsB1kvQc-py3.8/lib/python3.8/site-packages/fastapi/applications.py&quot;, line 179, in __call__
      await super().__call__(scope, receive, send)
    File &quot;/root/.cache/pypoetry/virtualenvs/facli-zsB1kvQc-py3.8/lib/python3.8/site-packages/starlette/applications.py&quot;, line 111, in __call__
      await self.middleware_stack(scope, receive, send)
    File &quot;/root/.cache/pypoetry/virtualenvs/facli-zsB1kvQc-py3.8/lib/python3.8/site-packages/starlette/middleware/errors.py&quot;, line 181, in __call__
      raise exc from None
    File &quot;/root/.cache/pypoetry/virtualenvs/facli-zsB1kvQc-py3.8/lib/python3.8/site-packages/starlette/middleware/errors.py&quot;, line 159, in __call__
      await self.app(scope, receive, _send)
    File &quot;/root/.cache/pypoetry/virtualenvs/facli-zsB1kvQc-py3.8/lib/python3.8/site-packages/starlette/middleware/cors.py&quot;, line 86, in __call__
      await self.simple_response(scope, receive, send, request_headers=headers)
    File &quot;/root/.cache/pypoetry/virtualenvs/facli-zsB1kvQc-py3.8/lib/python3.8/site-packages/starlette/middleware/cors.py&quot;, line 142, in simple_response
      await self.app(scope, receive, send)
    File &quot;/root/.cache/pypoetry/virtualenvs/facli-zsB1kvQc-py3.8/lib/python3.8/site-packages/starlette/middleware/cors.py&quot;, line 86, in __call__
      await self.simple_response(scope, receive, send, request_headers=headers)
    File &quot;/root/.cache/pypoetry/virtualenvs/facli-zsB1kvQc-py3.8/lib/python3.8/site-packages/starlette/middleware/cors.py&quot;, line 142, in simple_response
      await self.app(scope, receive, send)
    File &quot;/root/.cache/pypoetry/virtualenvs/facli-zsB1kvQc-py3.8/lib/python3.8/site-packages/starlette/middleware/cors.py&quot;, line 86, in __call__
      await self.simple_response(scope, receive, send, request_headers=headers)
  
     ..........
  
  
    File &quot;/root/.cache/pypoetry/virtualenvs/facli-zsB1kvQc-py3.8/lib/python3.8/site-packages/starlette/middleware/cors.py&quot;, line 86, in __call__
      await self.simple_response(scope, receive, send, request_headers=headers)
    File &quot;/root/.cache/pypoetry/virtualenvs/facli-zsB1kvQc-py3.8/lib/python3.8/site-packages/starlette/middleware/cors.py&quot;, line 142, in simple_response
      await self.app(scope, receive, send)
    File &quot;/root/.cache/pypoetry/virtualenvs/facli-zsB1kvQc-py3.8/lib/python3.8/site-packages/starlette/middleware/cors.py&quot;, line 74, in __call__
      headers = Headers(scope=scope)
    File &quot;/usr/local/lib/python3.8/typing.py&quot;, line 873, in __new__
      obj = super().__new__(cls)
  RecursionError: maximum recursion depth exceeded while calling a Python object
  
  </code></pre>
  <p>I have looked up all the relevant questions, but unfortunately have not found the answers,
  Now I can only suspect that it is a problem with FastAPI or Starlette, who can give me a solution to the problem, thanks a lot.</p>
  <p>After testing, I can solve this problem in this way:<code>sys.setrecursionlimit(9000000)</code>, but I think that this should not be the best solution for this kind of problem</p>