We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
StaticFilesConfig and virtual directories
I'm trying to write a ``FileSystemProtocol`` to load files from the package data using [importlib_resources](https://importlib-resources.readthedocs.io/en/latest/using.html#). But because ``directories`` is defined as ``DirectoryPath``, pydantic checks if the given directories exist in the local filesystem. 

This is not generally true, especially in any kind of virtual filesystem (e.g. a zipped package). I think this condition should be relaxed to support virtual filesystems.

https://github.com/starlite-api/starlite/blob/9bb6dcd57c10a591377cf8e3a537e9292566d5b9/starlite/config/static_files.py#L32

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `starlite/contrib/sqlalchemy/init_plugin/config/common.py`
Content:
```
1 from __future__ import annotations
2 
3 from dataclasses import dataclass, field
4 from typing import TYPE_CHECKING, Callable, Generic, TypeVar, cast
5 
6 from starlite.constants import HTTP_DISCONNECT, HTTP_RESPONSE_START, WEBSOCKET_CLOSE, WEBSOCKET_DISCONNECT
7 from starlite.exceptions import ImproperlyConfiguredException
8 from starlite.types import Empty
9 from starlite.utils import get_starlite_scope_state, set_starlite_scope_state
10 from starlite.utils.dataclass import simple_asdict
11 
12 from .engine import EngineConfig
13 
14 if TYPE_CHECKING:
15     from typing import Any
16 
17     from sqlalchemy import Connection, Engine
18     from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine, AsyncSession, async_sessionmaker
19     from sqlalchemy.orm import Mapper, Query, Session, sessionmaker
20     from sqlalchemy.orm.session import JoinTransactionMode
21     from sqlalchemy.sql import TableClause
22 
23     from starlite.datastructures.state import State
24     from starlite.types import BeforeMessageSendHookHandler, EmptyType, Scope
25 
26 __all__ = (
27     "SESSION_SCOPE_KEY",
28     "SESSION_TERMINUS_ASGI_EVENTS",
29     "GenericSQLAlchemyConfig",
30     "GenericSessionConfig",
31 )
32 
33 SESSION_SCOPE_KEY = "_sqlalchemy_db_session"
34 SESSION_TERMINUS_ASGI_EVENTS = {HTTP_RESPONSE_START, HTTP_DISCONNECT, WEBSOCKET_DISCONNECT, WEBSOCKET_CLOSE}
35 
36 ConnectionT = TypeVar("ConnectionT", bound="Connection | AsyncConnection")
37 EngineT = TypeVar("EngineT", bound="Engine | AsyncEngine")
38 SessionT = TypeVar("SessionT", bound="Session | AsyncSession")
39 SessionMakerT = TypeVar("SessionMakerT", bound="sessionmaker | async_sessionmaker")
40 
41 
42 @dataclass
43 class GenericSessionConfig(Generic[ConnectionT, EngineT, SessionT]):
44     """SQLAlchemy async session config."""
45 
46     autobegin: bool | EmptyType = Empty
47     """Automatically start transactions when database access is requested by an operation."""
48     autoflush: bool | EmptyType = Empty
49     """When ``True``, all query operations will issue a flush call to this :class:`Session <sqlalchemy.orm.Session>`
50     before proceeding"""
51     bind: EngineT | ConnectionT | None | EmptyType = Empty
52     """The :class:`Engine <sqlalchemy.engine.Engine>` or :class:`Connection <sqlalchemy.engine.Connection>` that new
53     :class:`Session <sqlalchemy.orm.Session>` objects will be bound to."""
54     binds: dict[type[Any] | Mapper[Any] | TableClause | str, EngineT | ConnectionT] | None | EmptyType = Empty
55     """A dictionary which may specify any number of :class:`Engine <sqlalchemy.engine.Engine>` or :class:`Connection
56     <sqlalchemy.engine.Connection>` objects as the source of connectivity for SQL operations on a per-entity basis. The
57     keys of the dictionary consist of any series of mapped classes, arbitrary Python classes that are bases for mapped
58     classes, :class:`Table <sqlalchemy.schema.Table>` objects and :class:`Mapper <sqlalchemy.orm.Mapper>` objects. The
59     values of the dictionary are then instances of :class:`Engine <sqlalchemy.engine.Engine>` or less commonly
60     :class:`Connection <sqlalchemy.engine.Connection>` objects."""
61     class_: type[SessionT] | EmptyType = Empty
62     """Class to use in order to create new :class:`Session <sqlalchemy.orm.Session>` objects."""
63     expire_on_commit: bool | EmptyType = Empty
64     """If ``True``, all instances will be expired after each commit."""
65     info: dict[str, Any] | None | EmptyType = Empty
66     """Optional dictionary of information that will be available via the
67     :attr:`Session.info <sqlalchemy.orm.Session.info>`"""
68     join_transaction_mode: JoinTransactionMode | EmptyType = Empty
69     """Describes the transactional behavior to take when a given bind is a Connection that has already begun a
70     transaction outside the scope of this Session; in other words the
71     :attr:`Connection.in_transaction() <sqlalchemy.Connection.in_transaction>` method returns True."""
72     query_cls: type[Query] | None | EmptyType = Empty
73     """Class which should be used to create new Query objects, as returned by the
74     :attr:`Session.query() <sqlalchemy.orm.Session.query>` method."""
75     twophase: bool | EmptyType = Empty
76     """When ``True``, all transactions will be started as a “two phase” transaction, i.e. using the “two phase”
77     semantics of the database in use along with an XID. During a :attr:`commit() <sqlalchemy.orm.Session.commit>`, after
78     :attr:`flush() <sqlalchemy.orm.Session.flush>` has been issued for all attached databases, the
79     :attr:`TwoPhaseTransaction.prepare() <sqlalchemy.engine.TwoPhaseTransaction.prepare>` method on each database`s
80     :class:`TwoPhaseTransaction <sqlalchemy.engine.TwoPhaseTransaction>` will be called. This allows each database to
81     roll back the entire transaction, before each transaction is committed."""
82 
83 
84 @dataclass
85 class GenericSQLAlchemyConfig(Generic[EngineT, SessionT, SessionMakerT]):
86     """Common SQLAlchemy Configuration."""
87 
88     create_engine_callable: Callable[[str], EngineT]
89     """Callable that creates an :class:`AsyncEngine <sqlalchemy.ext.asyncio.AsyncEngine>` instance or instance of its
90     subclass.
91     """
92     session_config: GenericSessionConfig
93     """Configuration options for either the :class:`async_sessionmaker <sqlalchemy.ext.asyncio.async_sessionmaker>`
94     or :class:`sessionmaker <sqlalchemy.orm.sessionmaker>`.
95     """
96     session_maker_class: type[sessionmaker] | type[async_sessionmaker]
97     """Sessionmaker class to use."""
98     before_send_handler: BeforeMessageSendHookHandler
99     """Handler to call before the ASGI message is sent.
100 
101     The handler should handle closing the session stored in the ASGI scope, if its still open, and committing and
102     uncommitted data.
103     """
104     connection_string: str | None = field(default=None)
105     """Database connection string in one of the formats supported by SQLAlchemy.
106 
107     Notes:
108         - For async connections, the connection string must include the correct async prefix.
109           e.g. ``'postgresql+asyncpg://...'`` instead of ``'postgresql://'``, and for sync connections its the opposite.
110 
111     """
112     engine_dependency_key: str = "db_engine"
113     """Key to use for the dependency injection of database engines."""
114     session_dependency_key: str = "db_session"
115     """Key to use for the dependency injection of database sessions."""
116     engine_app_state_key: str = "db_engine"
117     """Key under which to store the SQLAlchemy engine in the application :class:`State <.datastructures.State>`
118     instance.
119     """
120     engine_config: EngineConfig = field(default_factory=EngineConfig)
121     """Configuration for the SQLAlchemy engine.
122 
123     The configuration options are documented in the SQLAlchemy documentation.
124     """
125     session_maker_app_state_key: str = "session_maker_class"
126     """Key under which to store the SQLAlchemy :class:`sessionmaker <sqlalchemy.orm.sessionmaker>` in the application
127     :class:`State <.datastructures.State>` instance.
128     """
129     session_maker: Callable[[], SessionT] | None = None
130     """Callable that returns a session.
131 
132     If provided, the plugin will use this rather than instantiate a sessionmaker.
133     """
134     engine_instance: EngineT | None = None
135     """Optional engine to use.
136 
137     If set, the plugin will use the provided instance rather than instantiate an engine.
138     """
139 
140     def __post_init__(self) -> None:
141         if self.connection_string is not None and self.engine_instance is not None:
142             raise ImproperlyConfiguredException("Only one of 'connection_string' or 'engine_instance' can be provided.")
143 
144     @property
145     def engine_config_dict(self) -> dict[str, Any]:
146         """Return the engine configuration as a dict.
147 
148         Returns:
149             A string keyed dict of config kwargs for the SQLAlchemy :func:`create_engine <sqlalchemy.create_engine>`
150             function.
151         """
152         return simple_asdict(self.engine_config, exclude_empty=True)
153 
154     @property
155     def session_config_dict(self) -> dict[str, Any]:
156         """Return the session configuration as a dict.
157 
158         Returns:
159             A string keyed dict of config kwargs for the SQLAlchemy :class:`sessionmaker <sqlalchemy.orm.sessionmaker>`
160             class.
161         """
162         return simple_asdict(self.session_config, exclude_empty=True)
163 
164     @property
165     def signature_namespace(self) -> dict[str, Any]:
166         """Return the plugin's signature namespace.
167 
168         Returns:
169             A string keyed dict of names to be added to the namespace for signature forward reference resolution.
170         """
171         return {}  # pragma: no cover
172 
173     def create_engine(self) -> EngineT:
174         """Return an engine. If none exists yet, create one.
175 
176         Returns:
177             Getter that returns the engine instance used by the plugin.
178         """
179         if self.engine_instance:
180             return self.engine_instance
181 
182         if self.connection_string is None:
183             raise ImproperlyConfiguredException("One of 'connection_string' or 'engine_instance' must be provided.")
184 
185         engine_config = self.engine_config_dict
186         try:
187             return self.create_engine_callable(self.connection_string, **engine_config)
188         except ValueError:
189             # likely due to a dialect that doesn't support json type
190             del engine_config["json_deserializer"]
191             del engine_config["json_serializer"]
192             return self.create_engine_callable(self.connection_string, **engine_config)
193 
194     def create_session_maker(self) -> Callable[[], SessionT]:
195         """Get a session maker. If none exists yet, create one.
196 
197         Returns:
198             Session factory used by the plugin.
199         """
200         if self.session_maker:
201             return self.session_maker
202 
203         session_kws = self.session_config_dict
204         if session_kws.get("bind") is None:
205             session_kws["bind"] = self.create_engine()
206         return self.session_maker_class(**session_kws)
207 
208     def provide_engine(self, state: State) -> EngineT:
209         """Create an engine instance.
210 
211         Args:
212             state: The ``Starlite.state`` instance.
213 
214         Returns:
215             An engine instance.
216         """
217         return cast("EngineT", state.get(self.engine_app_state_key))
218 
219     def provide_session(self, state: State, scope: Scope) -> SessionT:
220         """Create a session instance.
221 
222         Args:
223             state: The ``Starlite.state`` instance.
224             scope: The current connection's scope.
225 
226         Returns:
227             A session instance.
228         """
229         session = cast("SessionT | None", get_starlite_scope_state(scope, SESSION_SCOPE_KEY))
230         if session is None:
231             session_maker = cast("Callable[[], SessionT]", state[self.session_maker_app_state_key])
232             session = session_maker()
233             set_starlite_scope_state(scope, SESSION_SCOPE_KEY, session)
234         return session
235 
236     def create_app_state_items(self) -> dict[str, Any]:
237         """Key/value pairs to be stored in application state."""
238         return {
239             self.engine_app_state_key: self.create_engine(),
240             self.session_maker_app_state_key: self.create_session_maker(),
241         }
242
```

Path: `starlite/contrib/sqlalchemy/init_plugin/plugin.py`
Content:
```
1 from __future__ import annotations
2 
3 from typing import TYPE_CHECKING
4 
5 from starlite.di import Provide
6 from starlite.plugins import InitPluginProtocol
7 
8 if TYPE_CHECKING:
9     from starlite.config.app import AppConfig
10 
11     from .config import SQLAlchemyAsyncConfig, SQLAlchemySyncConfig
12 
13 __all__ = ("SQLAlchemyInitPlugin",)
14 
15 
16 class SQLAlchemyInitPlugin(InitPluginProtocol):
17     """SQLAlchemy application lifecycle configuration."""
18 
19     __slots__ = ("_config",)
20 
21     def __init__(self, config: SQLAlchemyAsyncConfig | SQLAlchemySyncConfig) -> None:
22         """Initialize ``SQLAlchemyPlugin``.
23 
24         Args:
25             config: configure DB connection and hook handlers and dependencies.
26         """
27         self._config = config
28 
29     def on_app_init(self, app_config: AppConfig) -> AppConfig:
30         """Configure application for use with SQLAlchemy.
31 
32         Args:
33             app_config: The :class:`AppConfig <.config.app.AppConfig>` instance.
34         """
35         app_config.dependencies.update(
36             {
37                 self._config.engine_dependency_key: Provide(self._config.provide_engine),
38                 self._config.session_dependency_key: Provide(self._config.provide_session),
39             }
40         )
41         app_config.before_send.append(self._config.before_send_handler)
42         app_config.on_shutdown.append(self._config.on_shutdown)
43         app_config.state.update(self._config.create_app_state_items())
44         app_config.signature_namespace.update(self._config.signature_namespace)
45         return app_config
46
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/starlite/contrib/sqlalchemy/init_plugin/config/common.py b/starlite/contrib/sqlalchemy/init_plugin/config/common.py
--- a/starlite/contrib/sqlalchemy/init_plugin/config/common.py
+++ b/starlite/contrib/sqlalchemy/init_plugin/config/common.py
@@ -239,3 +239,11 @@
             self.engine_app_state_key: self.create_engine(),
             self.session_maker_app_state_key: self.create_session_maker(),
         }
+
+    def update_app_state(self, state: State) -> None:
+        """Set the app state with engine and session.
+
+        Args:
+            state: The ``Starlite.state`` instance.
+        """
+        state.update(self.create_app_state_items())
diff --git a/starlite/contrib/sqlalchemy/init_plugin/plugin.py b/starlite/contrib/sqlalchemy/init_plugin/plugin.py
--- a/starlite/contrib/sqlalchemy/init_plugin/plugin.py
+++ b/starlite/contrib/sqlalchemy/init_plugin/plugin.py
@@ -39,7 +39,7 @@
             }
         )
         app_config.before_send.append(self._config.before_send_handler)
+        app_config.on_startup.append(self._config.update_app_state)
         app_config.on_shutdown.append(self._config.on_shutdown)
-        app_config.state.update(self._config.create_app_state_items())
         app_config.signature_namespace.update(self._config.signature_namespace)
         return app_config

{"golden_diff": "diff --git a/starlite/contrib/sqlalchemy/init_plugin/config/common.py b/starlite/contrib/sqlalchemy/init_plugin/config/common.py\n--- a/starlite/contrib/sqlalchemy/init_plugin/config/common.py\n+++ b/starlite/contrib/sqlalchemy/init_plugin/config/common.py\n@@ -239,3 +239,11 @@\n             self.engine_app_state_key: self.create_engine(),\n             self.session_maker_app_state_key: self.create_session_maker(),\n         }\n+\n+    def update_app_state(self, state: State) -> None:\n+        \"\"\"Set the app state with engine and session.\n+\n+        Args:\n+            state: The ``Starlite.state`` instance.\n+        \"\"\"\n+        state.update(self.create_app_state_items())\ndiff --git a/starlite/contrib/sqlalchemy/init_plugin/plugin.py b/starlite/contrib/sqlalchemy/init_plugin/plugin.py\n--- a/starlite/contrib/sqlalchemy/init_plugin/plugin.py\n+++ b/starlite/contrib/sqlalchemy/init_plugin/plugin.py\n@@ -39,7 +39,7 @@\n             }\n         )\n         app_config.before_send.append(self._config.before_send_handler)\n+        app_config.on_startup.append(self._config.update_app_state)\n         app_config.on_shutdown.append(self._config.on_shutdown)\n-        app_config.state.update(self._config.create_app_state_items())\n         app_config.signature_namespace.update(self._config.signature_namespace)\n         return app_config\n", "issue": "StaticFilesConfig and virtual directories\nI'm trying to write a ``FileSystemProtocol`` to load files from the package data using [importlib_resources](https://importlib-resources.readthedocs.io/en/latest/using.html#). But because ``directories`` is defined as ``DirectoryPath``, pydantic checks if the given directories exist in the local filesystem. \r\n\r\nThis is not generally true, especially in any kind of virtual filesystem (e.g. a zipped package). I think this condition should be relaxed to support virtual filesystems.\r\n\r\nhttps://github.com/starlite-api/starlite/blob/9bb6dcd57c10a591377cf8e3a537e9292566d5b9/starlite/config/static_files.py#L32\n", "before_files": [{"content": "from __future__ import annotations\n\nfrom dataclasses import dataclass, field\nfrom typing import TYPE_CHECKING, Callable, Generic, TypeVar, cast\n\nfrom starlite.constants import HTTP_DISCONNECT, HTTP_RESPONSE_START, WEBSOCKET_CLOSE, WEBSOCKET_DISCONNECT\nfrom starlite.exceptions import ImproperlyConfiguredException\nfrom starlite.types import Empty\nfrom starlite.utils import get_starlite_scope_state, set_starlite_scope_state\nfrom starlite.utils.dataclass import simple_asdict\n\nfrom .engine import EngineConfig\n\nif TYPE_CHECKING:\n    from typing import Any\n\n    from sqlalchemy import Connection, Engine\n    from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine, AsyncSession, async_sessionmaker\n    from sqlalchemy.orm import Mapper, Query, Session, sessionmaker\n    from sqlalchemy.orm.session import JoinTransactionMode\n    from sqlalchemy.sql import TableClause\n\n    from starlite.datastructures.state import State\n    from starlite.types import BeforeMessageSendHookHandler, EmptyType, Scope\n\n__all__ = (\n    \"SESSION_SCOPE_KEY\",\n    \"SESSION_TERMINUS_ASGI_EVENTS\",\n    \"GenericSQLAlchemyConfig\",\n    \"GenericSessionConfig\",\n)\n\nSESSION_SCOPE_KEY = \"_sqlalchemy_db_session\"\nSESSION_TERMINUS_ASGI_EVENTS = {HTTP_RESPONSE_START, HTTP_DISCONNECT, WEBSOCKET_DISCONNECT, WEBSOCKET_CLOSE}\n\nConnectionT = TypeVar(\"ConnectionT\", bound=\"Connection | AsyncConnection\")\nEngineT = TypeVar(\"EngineT\", bound=\"Engine | AsyncEngine\")\nSessionT = TypeVar(\"SessionT\", bound=\"Session | AsyncSession\")\nSessionMakerT = TypeVar(\"SessionMakerT\", bound=\"sessionmaker | async_sessionmaker\")\n\n\n@dataclass\nclass GenericSessionConfig(Generic[ConnectionT, EngineT, SessionT]):\n    \"\"\"SQLAlchemy async session config.\"\"\"\n\n    autobegin: bool | EmptyType = Empty\n    \"\"\"Automatically start transactions when database access is requested by an operation.\"\"\"\n    autoflush: bool | EmptyType = Empty\n    \"\"\"When ``True``, all query operations will issue a flush call to this :class:`Session <sqlalchemy.orm.Session>`\n    before proceeding\"\"\"\n    bind: EngineT | ConnectionT | None | EmptyType = Empty\n    \"\"\"The :class:`Engine <sqlalchemy.engine.Engine>` or :class:`Connection <sqlalchemy.engine.Connection>` that new\n    :class:`Session <sqlalchemy.orm.Session>` objects will be bound to.\"\"\"\n    binds: dict[type[Any] | Mapper[Any] | TableClause | str, EngineT | ConnectionT] | None | EmptyType = Empty\n    \"\"\"A dictionary which may specify any number of :class:`Engine <sqlalchemy.engine.Engine>` or :class:`Connection\n    <sqlalchemy.engine.Connection>` objects as the source of connectivity for SQL operations on a per-entity basis. The\n    keys of the dictionary consist of any series of mapped classes, arbitrary Python classes that are bases for mapped\n    classes, :class:`Table <sqlalchemy.schema.Table>` objects and :class:`Mapper <sqlalchemy.orm.Mapper>` objects. The\n    values of the dictionary are then instances of :class:`Engine <sqlalchemy.engine.Engine>` or less commonly\n    :class:`Connection <sqlalchemy.engine.Connection>` objects.\"\"\"\n    class_: type[SessionT] | EmptyType = Empty\n    \"\"\"Class to use in order to create new :class:`Session <sqlalchemy.orm.Session>` objects.\"\"\"\n    expire_on_commit: bool | EmptyType = Empty\n    \"\"\"If ``True``, all instances will be expired after each commit.\"\"\"\n    info: dict[str, Any] | None | EmptyType = Empty\n    \"\"\"Optional dictionary of information that will be available via the\n    :attr:`Session.info <sqlalchemy.orm.Session.info>`\"\"\"\n    join_transaction_mode: JoinTransactionMode | EmptyType = Empty\n    \"\"\"Describes the transactional behavior to take when a given bind is a Connection that has already begun a\n    transaction outside the scope of this Session; in other words the\n    :attr:`Connection.in_transaction() <sqlalchemy.Connection.in_transaction>` method returns True.\"\"\"\n    query_cls: type[Query] | None | EmptyType = Empty\n    \"\"\"Class which should be used to create new Query objects, as returned by the\n    :attr:`Session.query() <sqlalchemy.orm.Session.query>` method.\"\"\"\n    twophase: bool | EmptyType = Empty\n    \"\"\"When ``True``, all transactions will be started as a \u201ctwo phase\u201d transaction, i.e. using the \u201ctwo phase\u201d\n    semantics of the database in use along with an XID. During a :attr:`commit() <sqlalchemy.orm.Session.commit>`, after\n    :attr:`flush() <sqlalchemy.orm.Session.flush>` has been issued for all attached databases, the\n    :attr:`TwoPhaseTransaction.prepare() <sqlalchemy.engine.TwoPhaseTransaction.prepare>` method on each database`s\n    :class:`TwoPhaseTransaction <sqlalchemy.engine.TwoPhaseTransaction>` will be called. This allows each database to\n    roll back the entire transaction, before each transaction is committed.\"\"\"\n\n\n@dataclass\nclass GenericSQLAlchemyConfig(Generic[EngineT, SessionT, SessionMakerT]):\n    \"\"\"Common SQLAlchemy Configuration.\"\"\"\n\n    create_engine_callable: Callable[[str], EngineT]\n    \"\"\"Callable that creates an :class:`AsyncEngine <sqlalchemy.ext.asyncio.AsyncEngine>` instance or instance of its\n    subclass.\n    \"\"\"\n    session_config: GenericSessionConfig\n    \"\"\"Configuration options for either the :class:`async_sessionmaker <sqlalchemy.ext.asyncio.async_sessionmaker>`\n    or :class:`sessionmaker <sqlalchemy.orm.sessionmaker>`.\n    \"\"\"\n    session_maker_class: type[sessionmaker] | type[async_sessionmaker]\n    \"\"\"Sessionmaker class to use.\"\"\"\n    before_send_handler: BeforeMessageSendHookHandler\n    \"\"\"Handler to call before the ASGI message is sent.\n\n    The handler should handle closing the session stored in the ASGI scope, if its still open, and committing and\n    uncommitted data.\n    \"\"\"\n    connection_string: str | None = field(default=None)\n    \"\"\"Database connection string in one of the formats supported by SQLAlchemy.\n\n    Notes:\n        - For async connections, the connection string must include the correct async prefix.\n          e.g. ``'postgresql+asyncpg://...'`` instead of ``'postgresql://'``, and for sync connections its the opposite.\n\n    \"\"\"\n    engine_dependency_key: str = \"db_engine\"\n    \"\"\"Key to use for the dependency injection of database engines.\"\"\"\n    session_dependency_key: str = \"db_session\"\n    \"\"\"Key to use for the dependency injection of database sessions.\"\"\"\n    engine_app_state_key: str = \"db_engine\"\n    \"\"\"Key under which to store the SQLAlchemy engine in the application :class:`State <.datastructures.State>`\n    instance.\n    \"\"\"\n    engine_config: EngineConfig = field(default_factory=EngineConfig)\n    \"\"\"Configuration for the SQLAlchemy engine.\n\n    The configuration options are documented in the SQLAlchemy documentation.\n    \"\"\"\n    session_maker_app_state_key: str = \"session_maker_class\"\n    \"\"\"Key under which to store the SQLAlchemy :class:`sessionmaker <sqlalchemy.orm.sessionmaker>` in the application\n    :class:`State <.datastructures.State>` instance.\n    \"\"\"\n    session_maker: Callable[[], SessionT] | None = None\n    \"\"\"Callable that returns a session.\n\n    If provided, the plugin will use this rather than instantiate a sessionmaker.\n    \"\"\"\n    engine_instance: EngineT | None = None\n    \"\"\"Optional engine to use.\n\n    If set, the plugin will use the provided instance rather than instantiate an engine.\n    \"\"\"\n\n    def __post_init__(self) -> None:\n        if self.connection_string is not None and self.engine_instance is not None:\n            raise ImproperlyConfiguredException(\"Only one of 'connection_string' or 'engine_instance' can be provided.\")\n\n    @property\n    def engine_config_dict(self) -> dict[str, Any]:\n        \"\"\"Return the engine configuration as a dict.\n\n        Returns:\n            A string keyed dict of config kwargs for the SQLAlchemy :func:`create_engine <sqlalchemy.create_engine>`\n            function.\n        \"\"\"\n        return simple_asdict(self.engine_config, exclude_empty=True)\n\n    @property\n    def session_config_dict(self) -> dict[str, Any]:\n        \"\"\"Return the session configuration as a dict.\n\n        Returns:\n            A string keyed dict of config kwargs for the SQLAlchemy :class:`sessionmaker <sqlalchemy.orm.sessionmaker>`\n            class.\n        \"\"\"\n        return simple_asdict(self.session_config, exclude_empty=True)\n\n    @property\n    def signature_namespace(self) -> dict[str, Any]:\n        \"\"\"Return the plugin's signature namespace.\n\n        Returns:\n            A string keyed dict of names to be added to the namespace for signature forward reference resolution.\n        \"\"\"\n        return {}  # pragma: no cover\n\n    def create_engine(self) -> EngineT:\n        \"\"\"Return an engine. If none exists yet, create one.\n\n        Returns:\n            Getter that returns the engine instance used by the plugin.\n        \"\"\"\n        if self.engine_instance:\n            return self.engine_instance\n\n        if self.connection_string is None:\n            raise ImproperlyConfiguredException(\"One of 'connection_string' or 'engine_instance' must be provided.\")\n\n        engine_config = self.engine_config_dict\n        try:\n            return self.create_engine_callable(self.connection_string, **engine_config)\n        except ValueError:\n            # likely due to a dialect that doesn't support json type\n            del engine_config[\"json_deserializer\"]\n            del engine_config[\"json_serializer\"]\n            return self.create_engine_callable(self.connection_string, **engine_config)\n\n    def create_session_maker(self) -> Callable[[], SessionT]:\n        \"\"\"Get a session maker. If none exists yet, create one.\n\n        Returns:\n            Session factory used by the plugin.\n        \"\"\"\n        if self.session_maker:\n            return self.session_maker\n\n        session_kws = self.session_config_dict\n        if session_kws.get(\"bind\") is None:\n            session_kws[\"bind\"] = self.create_engine()\n        return self.session_maker_class(**session_kws)\n\n    def provide_engine(self, state: State) -> EngineT:\n        \"\"\"Create an engine instance.\n\n        Args:\n            state: The ``Starlite.state`` instance.\n\n        Returns:\n            An engine instance.\n        \"\"\"\n        return cast(\"EngineT\", state.get(self.engine_app_state_key))\n\n    def provide_session(self, state: State, scope: Scope) -> SessionT:\n        \"\"\"Create a session instance.\n\n        Args:\n            state: The ``Starlite.state`` instance.\n            scope: The current connection's scope.\n\n        Returns:\n            A session instance.\n        \"\"\"\n        session = cast(\"SessionT | None\", get_starlite_scope_state(scope, SESSION_SCOPE_KEY))\n        if session is None:\n            session_maker = cast(\"Callable[[], SessionT]\", state[self.session_maker_app_state_key])\n            session = session_maker()\n            set_starlite_scope_state(scope, SESSION_SCOPE_KEY, session)\n        return session\n\n    def create_app_state_items(self) -> dict[str, Any]:\n        \"\"\"Key/value pairs to be stored in application state.\"\"\"\n        return {\n            self.engine_app_state_key: self.create_engine(),\n            self.session_maker_app_state_key: self.create_session_maker(),\n        }\n", "path": "starlite/contrib/sqlalchemy/init_plugin/config/common.py"}, {"content": "from __future__ import annotations\n\nfrom typing import TYPE_CHECKING\n\nfrom starlite.di import Provide\nfrom starlite.plugins import InitPluginProtocol\n\nif TYPE_CHECKING:\n    from starlite.config.app import AppConfig\n\n    from .config import SQLAlchemyAsyncConfig, SQLAlchemySyncConfig\n\n__all__ = (\"SQLAlchemyInitPlugin\",)\n\n\nclass SQLAlchemyInitPlugin(InitPluginProtocol):\n    \"\"\"SQLAlchemy application lifecycle configuration.\"\"\"\n\n    __slots__ = (\"_config\",)\n\n    def __init__(self, config: SQLAlchemyAsyncConfig | SQLAlchemySyncConfig) -> None:\n        \"\"\"Initialize ``SQLAlchemyPlugin``.\n\n        Args:\n            config: configure DB connection and hook handlers and dependencies.\n        \"\"\"\n        self._config = config\n\n    def on_app_init(self, app_config: AppConfig) -> AppConfig:\n        \"\"\"Configure application for use with SQLAlchemy.\n\n        Args:\n            app_config: The :class:`AppConfig <.config.app.AppConfig>` instance.\n        \"\"\"\n        app_config.dependencies.update(\n            {\n                self._config.engine_dependency_key: Provide(self._config.provide_engine),\n                self._config.session_dependency_key: Provide(self._config.provide_session),\n            }\n        )\n        app_config.before_send.append(self._config.before_send_handler)\n        app_config.on_shutdown.append(self._config.on_shutdown)\n        app_config.state.update(self._config.create_app_state_items())\n        app_config.signature_namespace.update(self._config.signature_namespace)\n        return app_config\n", "path": "starlite/contrib/sqlalchemy/init_plugin/plugin.py"}], "after_files": [{"content": "from __future__ import annotations\n\nfrom dataclasses import dataclass, field\nfrom typing import TYPE_CHECKING, Callable, Generic, TypeVar, cast\n\nfrom starlite.constants import HTTP_DISCONNECT, HTTP_RESPONSE_START, WEBSOCKET_CLOSE, WEBSOCKET_DISCONNECT\nfrom starlite.exceptions import ImproperlyConfiguredException\nfrom starlite.types import Empty\nfrom starlite.utils import get_starlite_scope_state, set_starlite_scope_state\nfrom starlite.utils.dataclass import simple_asdict\n\nfrom .engine import EngineConfig\n\nif TYPE_CHECKING:\n    from typing import Any\n\n    from sqlalchemy import Connection, Engine\n    from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine, AsyncSession, async_sessionmaker\n    from sqlalchemy.orm import Mapper, Query, Session, sessionmaker\n    from sqlalchemy.orm.session import JoinTransactionMode\n    from sqlalchemy.sql import TableClause\n\n    from starlite.datastructures.state import State\n    from starlite.types import BeforeMessageSendHookHandler, EmptyType, Scope\n\n__all__ = (\n    \"SESSION_SCOPE_KEY\",\n    \"SESSION_TERMINUS_ASGI_EVENTS\",\n    \"GenericSQLAlchemyConfig\",\n    \"GenericSessionConfig\",\n)\n\nSESSION_SCOPE_KEY = \"_sqlalchemy_db_session\"\nSESSION_TERMINUS_ASGI_EVENTS = {HTTP_RESPONSE_START, HTTP_DISCONNECT, WEBSOCKET_DISCONNECT, WEBSOCKET_CLOSE}\n\nConnectionT = TypeVar(\"ConnectionT\", bound=\"Connection | AsyncConnection\")\nEngineT = TypeVar(\"EngineT\", bound=\"Engine | AsyncEngine\")\nSessionT = TypeVar(\"SessionT\", bound=\"Session | AsyncSession\")\nSessionMakerT = TypeVar(\"SessionMakerT\", bound=\"sessionmaker | async_sessionmaker\")\n\n\n@dataclass\nclass GenericSessionConfig(Generic[ConnectionT, EngineT, SessionT]):\n    \"\"\"SQLAlchemy async session config.\"\"\"\n\n    autobegin: bool | EmptyType = Empty\n    \"\"\"Automatically start transactions when database access is requested by an operation.\"\"\"\n    autoflush: bool | EmptyType = Empty\n    \"\"\"When ``True``, all query operations will issue a flush call to this :class:`Session <sqlalchemy.orm.Session>`\n    before proceeding\"\"\"\n    bind: EngineT | ConnectionT | None | EmptyType = Empty\n    \"\"\"The :class:`Engine <sqlalchemy.engine.Engine>` or :class:`Connection <sqlalchemy.engine.Connection>` that new\n    :class:`Session <sqlalchemy.orm.Session>` objects will be bound to.\"\"\"\n    binds: dict[type[Any] | Mapper[Any] | TableClause | str, EngineT | ConnectionT] | None | EmptyType = Empty\n    \"\"\"A dictionary which may specify any number of :class:`Engine <sqlalchemy.engine.Engine>` or :class:`Connection\n    <sqlalchemy.engine.Connection>` objects as the source of connectivity for SQL operations on a per-entity basis. The\n    keys of the dictionary consist of any series of mapped classes, arbitrary Python classes that are bases for mapped\n    classes, :class:`Table <sqlalchemy.schema.Table>` objects and :class:`Mapper <sqlalchemy.orm.Mapper>` objects. The\n    values of the dictionary are then instances of :class:`Engine <sqlalchemy.engine.Engine>` or less commonly\n    :class:`Connection <sqlalchemy.engine.Connection>` objects.\"\"\"\n    class_: type[SessionT] | EmptyType = Empty\n    \"\"\"Class to use in order to create new :class:`Session <sqlalchemy.orm.Session>` objects.\"\"\"\n    expire_on_commit: bool | EmptyType = Empty\n    \"\"\"If ``True``, all instances will be expired after each commit.\"\"\"\n    info: dict[str, Any] | None | EmptyType = Empty\n    \"\"\"Optional dictionary of information that will be available via the\n    :attr:`Session.info <sqlalchemy.orm.Session.info>`\"\"\"\n    join_transaction_mode: JoinTransactionMode | EmptyType = Empty\n    \"\"\"Describes the transactional behavior to take when a given bind is a Connection that has already begun a\n    transaction outside the scope of this Session; in other words the\n    :attr:`Connection.in_transaction() <sqlalchemy.Connection.in_transaction>` method returns True.\"\"\"\n    query_cls: type[Query] | None | EmptyType = Empty\n    \"\"\"Class which should be used to create new Query objects, as returned by the\n    :attr:`Session.query() <sqlalchemy.orm.Session.query>` method.\"\"\"\n    twophase: bool | EmptyType = Empty\n    \"\"\"When ``True``, all transactions will be started as a \u201ctwo phase\u201d transaction, i.e. using the \u201ctwo phase\u201d\n    semantics of the database in use along with an XID. During a :attr:`commit() <sqlalchemy.orm.Session.commit>`, after\n    :attr:`flush() <sqlalchemy.orm.Session.flush>` has been issued for all attached databases, the\n    :attr:`TwoPhaseTransaction.prepare() <sqlalchemy.engine.TwoPhaseTransaction.prepare>` method on each database`s\n    :class:`TwoPhaseTransaction <sqlalchemy.engine.TwoPhaseTransaction>` will be called. This allows each database to\n    roll back the entire transaction, before each transaction is committed.\"\"\"\n\n\n@dataclass\nclass GenericSQLAlchemyConfig(Generic[EngineT, SessionT, SessionMakerT]):\n    \"\"\"Common SQLAlchemy Configuration.\"\"\"\n\n    create_engine_callable: Callable[[str], EngineT]\n    \"\"\"Callable that creates an :class:`AsyncEngine <sqlalchemy.ext.asyncio.AsyncEngine>` instance or instance of its\n    subclass.\n    \"\"\"\n    session_config: GenericSessionConfig\n    \"\"\"Configuration options for either the :class:`async_sessionmaker <sqlalchemy.ext.asyncio.async_sessionmaker>`\n    or :class:`sessionmaker <sqlalchemy.orm.sessionmaker>`.\n    \"\"\"\n    session_maker_class: type[sessionmaker] | type[async_sessionmaker]\n    \"\"\"Sessionmaker class to use.\"\"\"\n    before_send_handler: BeforeMessageSendHookHandler\n    \"\"\"Handler to call before the ASGI message is sent.\n\n    The handler should handle closing the session stored in the ASGI scope, if its still open, and committing and\n    uncommitted data.\n    \"\"\"\n    connection_string: str | None = field(default=None)\n    \"\"\"Database connection string in one of the formats supported by SQLAlchemy.\n\n    Notes:\n        - For async connections, the connection string must include the correct async prefix.\n          e.g. ``'postgresql+asyncpg://...'`` instead of ``'postgresql://'``, and for sync connections its the opposite.\n\n    \"\"\"\n    engine_dependency_key: str = \"db_engine\"\n    \"\"\"Key to use for the dependency injection of database engines.\"\"\"\n    session_dependency_key: str = \"db_session\"\n    \"\"\"Key to use for the dependency injection of database sessions.\"\"\"\n    engine_app_state_key: str = \"db_engine\"\n    \"\"\"Key under which to store the SQLAlchemy engine in the application :class:`State <.datastructures.State>`\n    instance.\n    \"\"\"\n    engine_config: EngineConfig = field(default_factory=EngineConfig)\n    \"\"\"Configuration for the SQLAlchemy engine.\n\n    The configuration options are documented in the SQLAlchemy documentation.\n    \"\"\"\n    session_maker_app_state_key: str = \"session_maker_class\"\n    \"\"\"Key under which to store the SQLAlchemy :class:`sessionmaker <sqlalchemy.orm.sessionmaker>` in the application\n    :class:`State <.datastructures.State>` instance.\n    \"\"\"\n    session_maker: Callable[[], SessionT] | None = None\n    \"\"\"Callable that returns a session.\n\n    If provided, the plugin will use this rather than instantiate a sessionmaker.\n    \"\"\"\n    engine_instance: EngineT | None = None\n    \"\"\"Optional engine to use.\n\n    If set, the plugin will use the provided instance rather than instantiate an engine.\n    \"\"\"\n\n    def __post_init__(self) -> None:\n        if self.connection_string is not None and self.engine_instance is not None:\n            raise ImproperlyConfiguredException(\"Only one of 'connection_string' or 'engine_instance' can be provided.\")\n\n    @property\n    def engine_config_dict(self) -> dict[str, Any]:\n        \"\"\"Return the engine configuration as a dict.\n\n        Returns:\n            A string keyed dict of config kwargs for the SQLAlchemy :func:`create_engine <sqlalchemy.create_engine>`\n            function.\n        \"\"\"\n        return simple_asdict(self.engine_config, exclude_empty=True)\n\n    @property\n    def session_config_dict(self) -> dict[str, Any]:\n        \"\"\"Return the session configuration as a dict.\n\n        Returns:\n            A string keyed dict of config kwargs for the SQLAlchemy :class:`sessionmaker <sqlalchemy.orm.sessionmaker>`\n            class.\n        \"\"\"\n        return simple_asdict(self.session_config, exclude_empty=True)\n\n    @property\n    def signature_namespace(self) -> dict[str, Any]:\n        \"\"\"Return the plugin's signature namespace.\n\n        Returns:\n            A string keyed dict of names to be added to the namespace for signature forward reference resolution.\n        \"\"\"\n        return {}  # pragma: no cover\n\n    def create_engine(self) -> EngineT:\n        \"\"\"Return an engine. If none exists yet, create one.\n\n        Returns:\n            Getter that returns the engine instance used by the plugin.\n        \"\"\"\n        if self.engine_instance:\n            return self.engine_instance\n\n        if self.connection_string is None:\n            raise ImproperlyConfiguredException(\"One of 'connection_string' or 'engine_instance' must be provided.\")\n\n        engine_config = self.engine_config_dict\n        try:\n            return self.create_engine_callable(self.connection_string, **engine_config)\n        except ValueError:\n            # likely due to a dialect that doesn't support json type\n            del engine_config[\"json_deserializer\"]\n            del engine_config[\"json_serializer\"]\n            return self.create_engine_callable(self.connection_string, **engine_config)\n\n    def create_session_maker(self) -> Callable[[], SessionT]:\n        \"\"\"Get a session maker. If none exists yet, create one.\n\n        Returns:\n            Session factory used by the plugin.\n        \"\"\"\n        if self.session_maker:\n            return self.session_maker\n\n        session_kws = self.session_config_dict\n        if session_kws.get(\"bind\") is None:\n            session_kws[\"bind\"] = self.create_engine()\n        return self.session_maker_class(**session_kws)\n\n    def provide_engine(self, state: State) -> EngineT:\n        \"\"\"Create an engine instance.\n\n        Args:\n            state: The ``Starlite.state`` instance.\n\n        Returns:\n            An engine instance.\n        \"\"\"\n        return cast(\"EngineT\", state.get(self.engine_app_state_key))\n\n    def provide_session(self, state: State, scope: Scope) -> SessionT:\n        \"\"\"Create a session instance.\n\n        Args:\n            state: The ``Starlite.state`` instance.\n            scope: The current connection's scope.\n\n        Returns:\n            A session instance.\n        \"\"\"\n        session = cast(\"SessionT | None\", get_starlite_scope_state(scope, SESSION_SCOPE_KEY))\n        if session is None:\n            session_maker = cast(\"Callable[[], SessionT]\", state[self.session_maker_app_state_key])\n            session = session_maker()\n            set_starlite_scope_state(scope, SESSION_SCOPE_KEY, session)\n        return session\n\n    def create_app_state_items(self) -> dict[str, Any]:\n        \"\"\"Key/value pairs to be stored in application state.\"\"\"\n        return {\n            self.engine_app_state_key: self.create_engine(),\n            self.session_maker_app_state_key: self.create_session_maker(),\n        }\n\n    def update_app_state(self, state: State) -> None:\n        \"\"\"Set the app state with engine and session.\n\n        Args:\n            state: The ``Starlite.state`` instance.\n        \"\"\"\n        state.update(self.create_app_state_items())\n", "path": "starlite/contrib/sqlalchemy/init_plugin/config/common.py"}, {"content": "from __future__ import annotations\n\nfrom typing import TYPE_CHECKING\n\nfrom starlite.di import Provide\nfrom starlite.plugins import InitPluginProtocol\n\nif TYPE_CHECKING:\n    from starlite.config.app import AppConfig\n\n    from .config import SQLAlchemyAsyncConfig, SQLAlchemySyncConfig\n\n__all__ = (\"SQLAlchemyInitPlugin\",)\n\n\nclass SQLAlchemyInitPlugin(InitPluginProtocol):\n    \"\"\"SQLAlchemy application lifecycle configuration.\"\"\"\n\n    __slots__ = (\"_config\",)\n\n    def __init__(self, config: SQLAlchemyAsyncConfig | SQLAlchemySyncConfig) -> None:\n        \"\"\"Initialize ``SQLAlchemyPlugin``.\n\n        Args:\n            config: configure DB connection and hook handlers and dependencies.\n        \"\"\"\n        self._config = config\n\n    def on_app_init(self, app_config: AppConfig) -> AppConfig:\n        \"\"\"Configure application for use with SQLAlchemy.\n\n        Args:\n            app_config: The :class:`AppConfig <.config.app.AppConfig>` instance.\n        \"\"\"\n        app_config.dependencies.update(\n            {\n                self._config.engine_dependency_key: Provide(self._config.provide_engine),\n                self._config.session_dependency_key: Provide(self._config.provide_session),\n            }\n        )\n        app_config.before_send.append(self._config.before_send_handler)\n        app_config.on_startup.append(self._config.update_app_state)\n        app_config.on_shutdown.append(self._config.on_shutdown)\n        app_config.signature_namespace.update(self._config.signature_namespace)\n        return app_config\n", "path": "starlite/contrib/sqlalchemy/init_plugin/plugin.py"}]}