Skip to content

does not work with strawberry graphql library #71

@Alireza-Bodaghi

Description

@Alireza-Bodaghi

i am using fastapi with strawberry graphql library. when i add limiter to the graphql router, i get and error regarding:
AttributeError: 'APIWebSocketRoute' object has no attribute 'methods'

code:

router.include_router(
    graphql_app,
    prefix="/graphql",
    dependencies=[
        Depends(
            RateLimiter(
                times=get_settings().RATE_LIMIT_COFFICIENT,
                seconds=1,
                identifier=graphql_identifier,
            ),
        ),
        Depends(
            RateLimiter(
                times=get_settings().RATE_LIMIT_COFFICIENT * 20,
                minutes=1,
                identifier=graphql_identifier,
            ),
        ),
        Depends(
            RateLimiter(
                times=get_settings().RATE_LIMIT_COFFICIENT * 100,
                hours=1,
                identifier=graphql_identifier,
            ),
        ),
    ],
)

error log:

uvicorn.protocols.http.httptools_impl:run_asgi - Exception in ASGI application

Traceback (most recent call last):

  File "<string>", line 1, in <module>
  File "/home/user/.pyenv/versions/3.9.16/lib/python3.9/multiprocessing/spawn.py", line 116, in spawn_main
    exitcode = _main(fd, parent_sentinel)
               │     │   └ 5
               │     └ 8
               └ <function _main at 0x7f5ae1e138b0>
  File "/home/user/.pyenv/versions/3.9.16/lib/python3.9/multiprocessing/spawn.py", line 129, in _main
    return self._bootstrap(parent_sentinel)
           │    │          └ 5
           │    └ <function BaseProcess._bootstrap at 0x7f5ae1def940>
           └ <SpawnProcess name='SpawnProcess-2' parent=439317 started>
  File "/home/user/.pyenv/versions/3.9.16/lib/python3.9/multiprocessing/process.py", line 315, in _bootstrap
    self.run()
    │    └ <function BaseProcess.run at 0x7f5ae885bf70>
    └ <SpawnProcess name='SpawnProcess-2' parent=439317 started>
  File "/home/user/.pyenv/versions/3.9.16/lib/python3.9/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
    │    │        │    │        │    └ {'config': <uvicorn.config.Config object at 0x7f5ae884bb80>, 'target': <bound method Server.run of <uvicorn.server.Server obj...
    │    │        │    │        └ <SpawnProcess name='SpawnProcess-2' parent=439317 started>
    │    │        │    └ ()
    │    │        └ <SpawnProcess name='SpawnProcess-2' parent=439317 started>
    │    └ <function subprocess_started at 0x7f5ae1a30160>
    └ <SpawnProcess name='SpawnProcess-2' parent=439317 started>
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/uvicorn/subprocess.py", line 76, in subprocess_started
    target(sockets=sockets)
    │              └ [<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 8000)>]
    └ <bound method Server.run of <uvicorn.server.Server object at 0x7f5ae884bc40>>
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/uvicorn/server.py", line 60, in run
    return asyncio.run(self.serve(sockets=sockets))
           │       │   │    │             └ [<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 8000)>]
           │       │   │    └ <function Server.serve at 0x7f5ae1ad4940>
           │       │   └ <uvicorn.server.Server object at 0x7f5ae884bc40>
           │       └ <function run at 0x7f5ae1d18ee0>
           └ <module 'asyncio' from '/home/user/.pyenv/versions/3.9.16/lib/python3.9/asyncio/__init__.py'>
  File "/home/user/.pyenv/versions/3.9.16/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
           │    │                  └ <coroutine object Server.serve at 0x7f5ae19e2ec0>
           │    └ <cyfunction Loop.run_until_complete at 0x7f5ae17dac70>
           └ <uvloop.Loop running=True closed=False debug=False>
> File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/uvicorn/protocols/http/httptools_impl.py", line 372, in run_asgi
    result = await app(self.scope, self.receive, self.send)
                   │   │    │      │    │        │    └ <function RequestResponseCycle.send at 0x7f5ae178e940>
                   │   │    │      │    │        └ <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7f5acaa49b80>
                   │   │    │      │    └ <function RequestResponseCycle.receive at 0x7f5ae178e9d0>
                   │   │    │      └ <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7f5acaa49b80>
                   │   │    └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
                   │   └ <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7f5acaa49b80>
                   └ <uvicorn.middleware.proxy_headers.ProxyHeadersMiddleware object at 0x7f5ae17d8f40>
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 75, in __call__
    return await self.app(scope, receive, send)
                 │    │   │      │        └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7f5acaa49b...
                 │    │   │      └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7f5acaa...
                 │    │   └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
                 │    └ <fastapi.applications.FastAPI object at 0x7f5ae150d2e0>
                 └ <uvicorn.middleware.proxy_headers.ProxyHeadersMiddleware object at 0x7f5ae17d8f40>
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/fastapi/applications.py", line 208, in __call__
    await super().__call__(scope, receive, send)
                           │      │        └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7f5acaa49b...
                           │      └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7f5acaa...
                           └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/starlette/applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
          │    │                │      │        └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7f5acaa49b...
          │    │                │      └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7f5acaa...
          │    │                └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
          │    └ <starlette.middleware.errors.ServerErrorMiddleware object at 0x7f5acaa496a0>
          └ <fastapi.applications.FastAPI object at 0x7f5ae150d2e0>
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/starlette/middleware/errors.py", line 181, in __call__
    raise exc from None
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/starlette/middleware/errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
          │    │   │      │        └ <function ServerErrorMiddleware.__call__.<locals>._send at 0x7f5acaa4b5e0>
          │    │   │      └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7f5acaa...
          │    │   └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
          │    └ <starlette.middleware.cors.CORSMiddleware object at 0x7f5acaa49670>
          └ <starlette.middleware.errors.ServerErrorMiddleware object at 0x7f5acaa496a0>
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/starlette/middleware/cors.py", line 78, in __call__
    await self.app(scope, receive, send)
          │    │   │      │        └ <function ServerErrorMiddleware.__call__.<locals>._send at 0x7f5acaa4b5e0>
          │    │   │      └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7f5acaa...
          │    │   └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
          │    └ <elasticapm.contrib.starlette.ElasticAPM object at 0x7f5acaa493d0>
          └ <starlette.middleware.cors.CORSMiddleware object at 0x7f5acaa49670>
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/elasticapm/contrib/starlette/__init__.py", line 199, in __call__
    await self.app(scope, _request_receive or receive, wrapped_send)
          │    │   │      │                   │        └ <function ServerErrorMiddleware.__call__.<locals>._send at 0x7f5acaa4b310>
          │    │   │      │                   └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.httptools_impl.RequestResponseCycle object at 0x7f5acaa...
          │    │   │      └ <function ElasticAPM.__call__.<locals>.request_receive at 0x7f5acaa4b700>
          │    │   └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
          │    └ <app.monitoring.prometheus_middleware.PrometheousMiddleware object at 0x7f5acaa49220>
          └ <elasticapm.contrib.starlette.ElasticAPM object at 0x7f5acaa493d0>
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/starlette/middleware/base.py", line 25, in __call__
    response = await self.dispatch_func(request, self.call_next)
                     │    │             │        │    └ <function BaseHTTPMiddleware.call_next at 0x7f5ae0770310>
                     │    │             │        └ <app.monitoring.prometheus_middleware.PrometheousMiddleware object at 0x7f5acaa49220>
                     │    │             └ <starlette.requests.Request object at 0x7f5acaa49f40>
                     │    └ <bound method PrometheousMiddleware.dispatch of <app.monitoring.prometheus_middleware.PrometheousMiddleware object at 0x7f5ac...
                     └ <app.monitoring.prometheus_middleware.PrometheousMiddleware object at 0x7f5acaa49220>

  File "app/monitoring/prometheus_middleware.py", line 11, in dispatch
    response = await success_counter(request=request, call_next=call_next)
                     │                       │                  └ <bound method BaseHTTPMiddleware.call_next of <app.monitoring.prometheus_middleware.PrometheousMiddleware object at 0x7f5acaa...
                     │                       └ <starlette.requests.Request object at 0x7f5acaa49f40>
                     └ <function success_counter at 0x7f5ad06dae50>

  File "app/monitoring/helper/prometheus_rest_counter.py", line 21, in success_counter
    response = await call_next(request)
                     │         └ <starlette.requests.Request object at 0x7f5acaa49f40>
                     └ <bound method BaseHTTPMiddleware.call_next of <app.monitoring.prometheus_middleware.PrometheousMiddleware object at 0x7f5acaa...

  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/starlette/middleware/base.py", line 45, in call_next
    task.result()
    │    └ <method 'result' of '_asyncio.Task' objects>
    └ <Task finished name='Task-4' coro=<BaseHTTPMiddleware.call_next.<locals>.coro() done, defined at /home/user/.pyenv/versions/v...
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/starlette/middleware/base.py", line 38, in coro
    await self.app(scope, receive, send)
          │    │   │      │        └ <bound method Queue.put of <Queue at 0x7f5acaa81100 maxsize=0 tasks=1>>
          │    │   │      └ <function ElasticAPM.__call__.<locals>.request_receive at 0x7f5acaa4b700>
          │    │   └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
          │    └ <starlette.exceptions.ExceptionMiddleware object at 0x7f5acaa49250>
          └ <app.monitoring.prometheus_middleware.PrometheousMiddleware object at 0x7f5acaa49220>
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
    raise exc from None
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
          │    │   │      │        └ <function ExceptionMiddleware.__call__.<locals>.sender at 0x7f5acaa4b8b0>
          │    │   │      └ <function ElasticAPM.__call__.<locals>.request_receive at 0x7f5acaa4b700>
          │    │   └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
          │    └ <fastapi.routing.APIRouter object at 0x7f5ae150d280>
          └ <starlette.exceptions.ExceptionMiddleware object at 0x7f5acaa49250>
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/starlette/routing.py", line 580, in __call__
    await route.handle(scope, receive, send)
          │     │      │      │        └ <function ExceptionMiddleware.__call__.<locals>.sender at 0x7f5acaa4b8b0>
          │     │      │      └ <function ElasticAPM.__call__.<locals>.request_receive at 0x7f5acaa4b700>
          │     │      └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
          │     └ <function Route.handle at 0x7f5ae0f9bf70>
          └ <fastapi.routing.APIRoute object at 0x7f5acad98f70>
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/starlette/routing.py", line 241, in handle
    await self.app(scope, receive, send)
          │    │   │      │        └ <function ExceptionMiddleware.__call__.<locals>.sender at 0x7f5acaa4b8b0>
          │    │   │      └ <function ElasticAPM.__call__.<locals>.request_receive at 0x7f5acaa4b700>
          │    │   └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
          │    └ <function request_response.<locals>.app at 0x7f5acad918b0>
          └ <fastapi.routing.APIRoute object at 0x7f5acad98f70>
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/starlette/routing.py", line 52, in app
    response = await func(request)
                     │    └ <starlette.requests.Request object at 0x7f5acaa81280>
                     └ <function get_request_handler.<locals>.app at 0x7f5acad91820>
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/fastapi/routing.py", line 216, in app
    solved_result = await solve_dependencies(
                          └ <function solve_dependencies at 0x7f5ae0750550>
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/fastapi/dependencies/utils.py", line 550, in solve_dependencies
    solved = await call(**sub_values)
                   │      └ {'request': <starlette.requests.Request object at 0x7f5acaa81280>, 'response': <starlette.responses.Response object at 0x7f5a...
                   └ <fastapi_limiter.depends.RateLimiter object at 0x7f5acaebd2b0>
  File "/home/user/.pyenv/versions/venv/lib/python3.9/site-packages/fastapi_limiter/depends.py", line 41, in __call__
    if route.path == request.scope["path"] and request.method in route.methods:
       │     │       │       │                 │       │         └ <fastapi.routing.APIWebSocketRoute object at 0x7f5acada1d60>
       │     │       │       │                 │       └ <property object at 0x7f5ae0fec1d0>
       │     │       │       │                 └ <starlette.requests.Request object at 0x7f5acaa81280>
       │     │       │       └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8000), 'cl...
       │     │       └ <starlette.requests.Request object at 0x7f5acaa81280>
       │     └ '/graphql'
       └ <fastapi.routing.APIWebSocketRoute object at 0x7f5acada1d60>

AttributeError: 'APIWebSocketRoute' object has no attribute 'methods'

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions