summaryrefslogtreecommitdiff
path: root/venv/lib/python3.11/site-packages/litestar/middleware/session/base.py
diff options
context:
space:
mode:
Diffstat (limited to 'venv/lib/python3.11/site-packages/litestar/middleware/session/base.py')
-rw-r--r--venv/lib/python3.11/site-packages/litestar/middleware/session/base.py256
1 files changed, 0 insertions, 256 deletions
diff --git a/venv/lib/python3.11/site-packages/litestar/middleware/session/base.py b/venv/lib/python3.11/site-packages/litestar/middleware/session/base.py
deleted file mode 100644
index a823848..0000000
--- a/venv/lib/python3.11/site-packages/litestar/middleware/session/base.py
+++ /dev/null
@@ -1,256 +0,0 @@
-from __future__ import annotations
-
-from abc import ABC, abstractmethod
-from typing import (
- TYPE_CHECKING,
- Any,
- Awaitable,
- Callable,
- Generic,
- Literal,
- TypeVar,
- cast,
-)
-
-from litestar.connection import ASGIConnection
-from litestar.enums import ScopeType
-from litestar.middleware.base import AbstractMiddleware, DefineMiddleware
-from litestar.serialization import decode_json, encode_json
-from litestar.utils import get_serializer_from_scope
-
-__all__ = ("BaseBackendConfig", "BaseSessionBackend", "SessionMiddleware")
-
-
-if TYPE_CHECKING:
- from litestar.types import ASGIApp, Message, Receive, Scope, Scopes, ScopeSession, Send
-
-ONE_DAY_IN_SECONDS = 60 * 60 * 24
-
-ConfigT = TypeVar("ConfigT", bound="BaseBackendConfig")
-BaseSessionBackendT = TypeVar("BaseSessionBackendT", bound="BaseSessionBackend")
-
-
-class BaseBackendConfig(ABC, Generic[BaseSessionBackendT]): # pyright: ignore
- """Configuration for Session middleware backends."""
-
- _backend_class: type[BaseSessionBackendT] # pyright: ignore
-
- key: str
- """Key to use for the cookie inside the header, e.g. ``session=<data>`` where ``session`` is the cookie key and
- ``<data>`` is the session data.
-
- Notes:
- - If a session cookie exceeds 4KB in size it is split. In this case the key will be of the format
- ``session-{segment number}``.
-
- """
- max_age: int
- """Maximal age of the cookie before its invalidated."""
- scopes: Scopes = {ScopeType.HTTP, ScopeType.WEBSOCKET}
- """Scopes for the middleware - options are ``http`` and ``websocket`` with the default being both"""
- path: str
- """Path fragment that must exist in the request url for the cookie to be valid.
-
- Defaults to ``'/'``.
- """
- domain: str | None
- """Domain for which the cookie is valid."""
- secure: bool
- """Https is required for the cookie."""
- httponly: bool
- """Forbids javascript to access the cookie via 'Document.cookie'."""
- samesite: Literal["lax", "strict", "none"]
- """Controls whether or not a cookie is sent with cross-site requests.
-
- Defaults to ``lax``.
- """
- exclude: str | list[str] | None
- """A pattern or list of patterns to skip in the session middleware."""
- exclude_opt_key: str
- """An identifier to use on routes to disable the session middleware for a particular route."""
-
- @property
- def middleware(self) -> DefineMiddleware:
- """Use this property to insert the config into a middleware list on one of the application layers.
-
- Examples:
- .. code-block:: python
-
- from os import urandom
-
- from litestar import Litestar, Request, get
- from litestar.middleware.sessions.cookie_backend import CookieBackendConfig
-
- session_config = CookieBackendConfig(secret=urandom(16))
-
-
- @get("/")
- def my_handler(request: Request) -> None: ...
-
-
- app = Litestar(route_handlers=[my_handler], middleware=[session_config.middleware])
-
-
- Returns:
- An instance of DefineMiddleware including ``self`` as the config kwarg value.
- """
- return DefineMiddleware(SessionMiddleware, backend=self._backend_class(config=self))
-
-
-class BaseSessionBackend(ABC, Generic[ConfigT]):
- """Abstract session backend defining the interface between a storage mechanism and the application
- :class:`SessionMiddleware`.
-
- This serves as the base class for all client- and server-side backends
- """
-
- __slots__ = ("config",)
-
- def __init__(self, config: ConfigT) -> None:
- """Initialize ``BaseSessionBackend``
-
- Args:
- config: A instance of a subclass of ``BaseBackendConfig``
- """
- self.config = config
-
- @staticmethod
- def serialize_data(data: ScopeSession, scope: Scope | None = None) -> bytes:
- """Serialize data into bytes for storage in the backend.
-
- Args:
- data: Session data of the current scope.
- scope: A scope, if applicable, from which to extract a serializer.
-
- Notes:
- - The serializer will be extracted from ``scope`` or fall back to
- :func:`default_serializer <.serialization.default_serializer>`
-
- Returns:
- ``data`` serialized as bytes.
- """
- serializer = get_serializer_from_scope(scope) if scope else None
- return encode_json(data, serializer)
-
- @staticmethod
- def deserialize_data(data: Any) -> dict[str, Any]:
- """Deserialize data into a dictionary for use in the application scope.
-
- Args:
- data: Data to be deserialized
-
- Returns:
- Deserialized data as a dictionary
- """
- return cast("dict[str, Any]", decode_json(value=data))
-
- @abstractmethod
- def get_session_id(self, connection: ASGIConnection) -> str | None:
- """Try to fetch session id from connection ScopeState. If one does not exist, generate one.
-
- Args:
- connection: Originating ASGIConnection containing the scope
-
- Returns:
- Session id str or None if the concept of a session id does not apply.
- """
-
- @abstractmethod
- async def store_in_message(self, scope_session: ScopeSession, message: Message, connection: ASGIConnection) -> None:
- """Store the necessary information in the outgoing ``Message``
-
- Args:
- scope_session: Current session to store
- message: Outgoing send-message
- connection: Originating ASGIConnection containing the scope
-
- Returns:
- None
- """
-
- @abstractmethod
- async def load_from_connection(self, connection: ASGIConnection) -> dict[str, Any]:
- """Load session data from a connection and return it as a dictionary to be used in the current application
- scope.
-
- Args:
- connection: An ASGIConnection instance
-
- Returns:
- The session data
-
- Notes:
- - This should not modify the connection's scope. The data returned by this
- method will be stored in the application scope by the middleware
-
- """
-
-
-class SessionMiddleware(AbstractMiddleware, Generic[BaseSessionBackendT]):
- """Litestar session middleware for storing session data."""
-
- def __init__(self, app: ASGIApp, backend: BaseSessionBackendT) -> None:
- """Initialize ``SessionMiddleware``
-
- Args:
- app: An ASGI application
- backend: A :class:`BaseSessionBackend` instance used to store and retrieve session data
- """
-
- super().__init__(
- app=app,
- exclude=backend.config.exclude,
- exclude_opt_key=backend.config.exclude_opt_key,
- scopes=backend.config.scopes,
- )
- self.backend = backend
-
- def create_send_wrapper(self, connection: ASGIConnection) -> Callable[[Message], Awaitable[None]]:
- """Create a wrapper for the ASGI send function, which handles setting the cookies on the outgoing response.
-
- Args:
- connection: ASGIConnection
-
- Returns:
- None
- """
-
- async def wrapped_send(message: Message) -> None:
- """Wrap the ``send`` function.
-
- Declared in local scope to make use of closure values.
-
- Args:
- message: An ASGI message.
-
- Returns:
- None
- """
- if message["type"] != "http.response.start":
- await connection.send(message)
- return
-
- scope_session = connection.scope.get("session")
-
- await self.backend.store_in_message(scope_session, message, connection)
- await connection.send(message)
-
- return wrapped_send
-
- async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
- """ASGI-callable.
-
- Args:
- scope: The ASGI connection scope.
- receive: The ASGI receive function.
- send: The ASGI send function.
-
- Returns:
- None
- """
-
- connection = ASGIConnection[Any, Any, Any, Any](scope, receive=receive, send=send)
- scope["session"] = await self.backend.load_from_connection(connection)
- connection._connection_state.session_id = self.backend.get_session_id(connection) # pyright: ignore [reportGeneralTypeIssues]
-
- await self.app(scope, receive, self.create_send_wrapper(connection))