s3rius / FastAPI-template

Feature rich robust FastAPI template.
MIT License
1.9k stars 164 forks source link

Request object isn't passed as argument #96

Closed devNaresh closed 2 years ago

devNaresh commented 2 years ago

Thanks for this package. I have created graphql app using template but getting below error. It seems fastapi doesn't pass request object.

ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 184, in run_asgi
    result = await self.app(self.scope, self.asgi_receive, self.asgi_send)
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
    return await self.app(scope, receive, send)
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/fastapi/applications.py", line 261, in __call__
    await super().__call__(scope, receive, send)
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/starlette/applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/starlette/middleware/errors.py", line 146, in __call__
    await self.app(scope, receive, send)
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/starlette/exceptions.py", line 58, in __call__
    await self.app(scope, receive, send)
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
    raise e
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
    await self.app(scope, receive, send)
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/starlette/routing.py", line 656, in __call__
    await route.handle(scope, receive, send)
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/starlette/routing.py", line 315, in handle
    await self.app(scope, receive, send)
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/starlette/routing.py", line 77, in app
    await func(session)
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/fastapi/routing.py", line 264, in app
    solved_result = await solve_dependencies(
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/fastapi/dependencies/utils.py", line 498, in solve_dependencies
    solved_result = await solve_dependencies(
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/fastapi/dependencies/utils.py", line 498, in solve_dependencies
    solved_result = await solve_dependencies(
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/fastapi/dependencies/utils.py", line 498, in solve_dependencies
    solved_result = await solve_dependencies(
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/fastapi/dependencies/utils.py", line 523, in solve_dependencies
    solved = await solve_generator(
  File "/Users/test/Library/Caches/pypoetry/virtualenvs/fastapi-graphql-practice-1UuEp-7G-py3.10/lib/python3.10/site-packages/fastapi/dependencies/utils.py", line 443, in solve_generator
    cm = asynccontextmanager(call)(**sub_values)
  File "/Users/test/.pyenv/versions/3.10.2/lib/python3.10/contextlib.py", line 314, in helper
    return _AsyncGeneratorContextManager(func, args, kwds)
  File "/Users/test/.pyenv/versions/3.10.2/lib/python3.10/contextlib.py", line 103, in __init__
    self.gen = func(*args, **kwds)
TypeError: get_db_session() missing 1 required positional argument: 'request'
INFO:     connection open
INFO:     connection closed
s3rius commented 2 years ago

Thanks for using this project and raising the issue.

I'll take a closer look.

s3rius commented 2 years ago

That's strange. But I can't reproduce it. I've generated a new project with sqlalchemy and graphql. But it works as expected.

❯ curl -H "Content-Type: application/json" http://localhost:8000/graphql --data-raw '{"query": "query{getDummyModels(limit:10){id}}"}'
{"data":{"getDummyModels":[]}}

Which version of fastapi_template are you using?

devNaresh commented 2 years ago

i am using fastapi-template==3.3.5

s3rius commented 2 years ago

Could you provide me more context for this problem?

Which project configuration are you using? Where do you load your dependency?

s3rius commented 2 years ago

I guess I found it.

Does this error affect requests or it's just appears in logs?

devNaresh commented 2 years ago

Yes, I have created project using below config

api_type == graphql
db == sqllite
orm == sqlalchemy
ci == None
kube == true
routers == true

Directory structure

.
├── __init__.py
├── __main__.py
├── conftest.py
├── db
│   ├── base.py
│   ├── dao
│   │   ├── __init__.py
│   │   └── dummy_dao.py
│   ├── dependencies.py
│   ├── meta.py
│   ├── models
│   │   ├── __init__.py
│   │   └── dummy_model.py
│   └── utils.py
├── services
│   └── __init__.py
├── settings.py
├── static
│   └── docs
│       ├── redoc.standalone.js
│       ├── swagger-ui-bundle.js
│       └── swagger-ui.css
├── tests
│   ├── __init__.py
│   ├── test_dummy.py
│   ├── test_echo.py
│   └── test_fastapi_graphql_practice.py
└── web
    ├── __init__.py
    ├── api
    │   ├── __init__.py
    │   ├── monitoring
    │   │   ├── __init__.py
    │   │   └── views.py
    │   └── router.py
    ├── application.py
    ├── gql
    │   ├── __init__.py
    │   ├── context.py
    │   ├── dummy
    │   │   ├── __init__.py
    │   │   ├── mutation.py
    │   │   ├── query.py
    │   │   └── schema.py
    │   ├── echo
    │   │   ├── __init__.py
    │   │   ├── mutation.py
    │   │   └── query.py
    │   └── router.py
    └── lifetime.py

using vscode to run server with below config

  {
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Module",
            "type": "python",
            "request": "launch",
            "module": "fastapi_graphql_practice",
            "justMyCode": true
        }
    ]
}

No custom changes, it's the same code which is generated by template. I hope this help. Let me know incase you need additional info.

devNaresh commented 2 years ago

I guess I found it.

Does this error affect requests or it's just appears in logs?

I haven't tested it extensively. I just opened graphql UI and checked docs with logs. I saw it on logs, so tried to fixed it.

s3rius commented 2 years ago

I found it. It's an issue of strawberry-graphql. This error message appears in logs every time I open graphiql UI. But it doesn't affect request handling.

s3rius commented 2 years ago

I guess it can be reported directly to strawberry-graphql.

This is my traceback for this error.

TypeError: get_redis_connection() missing 1 required positional argument: 'request'
  File "fastapi/applications.py", line 261, in __call__
    await super().__call__(scope, receive, send)
  File "starlette/applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "starlette/middleware/errors.py", line 146, in __call__
    await self.app(scope, receive, send)
  File "starlette/middleware/base.py", line 22, in __call__
    await self.app(scope, receive, send)
  File "starlette/exceptions.py", line 58, in __call__
    await self.app(scope, receive, send)
  File "fastapi/middleware/asyncexitstack.py", line 21, in __call__
    raise e
  File "fastapi/middleware/asyncexitstack.py", line 18, in __call__
    await self.app(scope, receive, send)
  File "starlette/routing.py", line 656, in __call__
    await route.handle(scope, receive, send)
  File "starlette/routing.py", line 315, in handle
    await self.app(scope, receive, send)
  File "starlette/routing.py", line 77, in app
    await func(session)
  File "fastapi/routing.py", line 264, in app
    solved_result = await solve_dependencies(
  File "fastapi/dependencies/utils.py", line 498, in solve_dependencies
    solved_result = await solve_dependencies(
  File "fastapi/dependencies/utils.py", line 498, in solve_dependencies
    solved_result = await solve_dependencies(
  File "fastapi/dependencies/utils.py", line 498, in solve_dependencies
    solved_result = await solve_dependencies(
  File "fastapi/dependencies/utils.py", line 523, in solve_dependencies
    solved = await solve_generator(
  File "fastapi/dependencies/utils.py", line 443, in solve_generator
    cm = asynccontextmanager(call)(**sub_values)
  File "contextlib.py", line 296, in helper
    return _AsyncGeneratorContextManager(func, args, kwds)
  File "contextlib.py", line 87, in __init__
    self.gen = func(*args, **kwds)

It can affect literally any dependency in custom context.

s3rius commented 2 years ago

I guess we can close this issue or if you find the solution, I can add it to the template.

devNaresh commented 2 years ago

Yes, we can close it if it's an upstream issue. If you have opened any issue on strawberry-graphql, can you link it here?

s3rius commented 2 years ago

I haven't opened any issue in straweberry yet.

ljnsn commented 2 years ago

Hi, I'm running into this issue as well, has an issue already been opened in strawberry?

s3rius commented 2 years ago

Hi there. I found no issues for this problem in strawberry-graphql repository. So I created one.

ljnsn commented 2 years ago

Until this is issue is solved, you can get rid of the error messages by changing the dependency slightly:

https://github.com/s3rius/FastAPI-template/blob/98f07cd0f9cc697ce5e64721c0a6505860729aba/fastapi_template/template/%7B%7Bcookiecutter.project_name%7D%7D/%7B%7Bcookiecutter.project_name%7D%7D/db_sa/dependencies.py#L7-L20

 async def get_db_session(request: Request = None) -> AsyncGenerator[AsyncSession, None]: 
     """ 
     Create and get database session. 

     :param request: current request. 
     :yield: database session. 
     """ 
     if request is None:
         yield None
         return

     session: AsyncSession = request.app.state.db_session_factory() 

     try:  # noqa: WPS501 
         yield session 
     finally: 
         await session.commit() 
         await session.close() 
s3rius commented 1 year ago

Hi to everyone. Straweberry graphql team has started to work on this issue.

You can subscribe to updates here

I'll make an update when this problem is fixed.