Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with SessionAutoloadMiddleware #57

Closed
sasha-id opened this issue Oct 1, 2022 · 5 comments
Closed

Issue with SessionAutoloadMiddleware #57

sasha-id opened this issue Oct 1, 2022 · 5 comments

Comments

@sasha-id
Copy link

sasha-id commented Oct 1, 2022

Hi Alex,

Trying to use starsessions with SessionAutoloadMiddleware and getting this erorr:

INFO:     127.0.0.1:51099 - "GET / HTTP/1.1" 500 Internal Server Error
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/Users/sash/Library/Caches/pypoetry/virtualenvs/core-W7t3oa5Y-py3.10/lib/python3.10/site-packages/uvicorn/protocols/http/h11_impl.py", line 404, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
  File "/Users/sash/Library/Caches/pypoetry/virtualenvs/core-W7t3oa5Y-py3.10/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
    return await self.app(scope, receive, send)
  File "/Users/sash/Library/Caches/pypoetry/virtualenvs/core-W7t3oa5Y-py3.10/lib/python3.10/site-packages/uvicorn/middleware/debug.py", line 106, in __call__
    raise exc from None
  File "/Users/sash/Library/Caches/pypoetry/virtualenvs/core-W7t3oa5Y-py3.10/lib/python3.10/site-packages/uvicorn/middleware/debug.py", line 103, in __call__
    await self.app(scope, receive, inner_send)
  File "/Users/sash/Library/Caches/pypoetry/virtualenvs/core-W7t3oa5Y-py3.10/lib/python3.10/site-packages/starlette/applications.py", line 124, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/Users/sash/Library/Caches/pypoetry/virtualenvs/core-W7t3oa5Y-py3.10/lib/python3.10/site-packages/starlette/middleware/errors.py", line 184, in __call__
    raise exc
  File "/Users/sash/Library/Caches/pypoetry/virtualenvs/core-W7t3oa5Y-py3.10/lib/python3.10/site-packages/starlette/middleware/errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "/Users/sash/Library/Caches/pypoetry/virtualenvs/core-W7t3oa5Y-py3.10/lib/python3.10/site-packages/starlette/middleware/cors.py", line 84, in __call__
    await self.app(scope, receive, send)
  File "/Users/sash/Library/Caches/pypoetry/virtualenvs/core-W7t3oa5Y-py3.10/lib/python3.10/site-packages/starception/middleware.py", line 54, in __call__
    raise exc
  File "/Users/sash/Library/Caches/pypoetry/virtualenvs/core-W7t3oa5Y-py3.10/lib/python3.10/site-packages/starception/middleware.py", line 38, in __call__
    await self.app(scope, receive, _send)
  File "/Users/sash/Library/Caches/pypoetry/virtualenvs/core-W7t3oa5Y-py3.10/lib/python3.10/site-packages/starsessions/middleware.py", line 159, in __call__
    await load_session(connection)
  File "/Users/sash/Library/Caches/pypoetry/virtualenvs/core-W7t3oa5Y-py3.10/lib/python3.10/site-packages/starsessions/session.py", line 49, in load_session
    await get_session_handler(connection).load()
  File "/Users/sash/Library/Caches/pypoetry/virtualenvs/core-W7t3oa5Y-py3.10/lib/python3.10/site-packages/starsessions/session.py", line 39, in get_session_handler
    return typing.cast(SessionHandler, connection.scope["session_handler"])
KeyError: 'session_handler'

Here's my starlette setup:

def main():
    return Server(
        db_url=Config.POSTGRES_URL,
        debug=DEBUG,
        controllers=[PagesController],
    )


if __name__ == "__main__":
    uvicorn.run(
        f"{__name__}:main",
        debug=DEBUG,
        factory=True,
        reload=DEBUG,
        # log_config=log_config,
        host='0.0.0.0',
        port=int(listen_port),
        log_level="debug" if DEBUG else "info",
    )
from sqlalchemy.exc import DatabaseError
from starlette.applications import Starlette
from starlette.middleware.cors import CORSMiddleware
from starlette.staticfiles import StaticFiles
from starlette.routing import Mount
from starception import StarceptionMiddleware
from starsessions import CookieStore, SessionAutoloadMiddleware, SessionMiddleware
from imia import AuthenticationMiddleware, SessionAuthenticator

from core_utils.config import Config
from app.auth.user_provider import AuthUserProvider
from app.database import DatabaseManager
from app.exceptions import RequestError
from app.errors import on_error
from app.protocol import HttpMethod
from app.config.settings import STATIC_DIR


class Server(Starlette):
    def __init__(self, db_url, controllers, *args, debug=False, **kwargs):
        # TODO: Implement proper logging
        # logging.basicConfig(level=logging.DEBUG if debug else logging.INFO, stream=sys.stderr)
        # logging.config.dictConfig(yaml.load(open("app/config/logging.yml").read(), Loader=yaml.FullLoader))
        # self.log = logging.getLogger(__name__)
        super(Server, self).__init__(*args, **kwargs)
        self.debug = debug

        # Initialize database
        self.db = DatabaseManager(db_url, debug)

        # Session store
        session_store = CookieStore(secret_key=Config.SECRET)

        # Middlewares
        self.add_middleware(SessionMiddleware, store=session_store, cookie_name="s", lifetime=300, rolling=True)
        self.add_middleware(SessionAutoloadMiddleware)
        # ^^^^^^^^ Problem somewhere here ^^^^^^^^
        # self.add_middleware(AuthenticationMiddleware, authenticators=[SessionAuthenticator(user_provider=AuthUserProvider)])
        self.add_middleware(StarceptionMiddleware)
        self.add_middleware(CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"])  # CORS

        # Static route
        self.routes.append(Mount("/static", StaticFiles(directory=STATIC_DIR), name="static"))

        # Register controllers with app
        for ctrl_cls in controllers:
            self._controller_register(ctrl_cls)

        # Event handlers
        self.add_event_handler("startup", self.on_app_start)
        self.add_event_handler("shutdown", self.on_app_stop)

        # Error handlers
        self.add_exception_handler(RequestError, on_error)
        self.add_exception_handler(DatabaseError, on_error)
        self.add_exception_handler(Exception, on_error)
        

       # Etc.

Looks like the problem is here:

if scope["type"] not in ("http", "websocket"): # pragma: no cover

Because of scope["type"] == "lifespan" the rest of the code is ignored. Am I missing something? Can you point me in the right direction?

@alex-oleshkevich
Copy link
Owner

add_middleware adds middleware in reverse order.
So in your case you have to use this order:

  1. SessionAutoloadMiddleware
  2. SessionMiddleware

@alex-oleshkevich
Copy link
Owner

Also, add_middleware is deprecated and it's no longer a recommended way to attach a middleware.

@sasha-id
Copy link
Author

sasha-id commented Oct 1, 2022

Thank you!
it's working in reverse order. What's the recommended way to add middleware from the inside of inherited(Starlette) class?

@alex-oleshkevich
Copy link
Owner

call super.__init__(middleware=[...])

@sasha-id
Copy link
Author

sasha-id commented Oct 1, 2022

Perfect, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants