Repository: litestar-org/litestar

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


Discussion:
I agree. Do you want to submit a PR?

Resolving patch:
diff --git a/litestar/contrib/sqlalchemy/dto.py b/litestar/contrib/sqlalchemy/dto.py
--- a/litestar/contrib/sqlalchemy/dto.py
+++ b/litestar/contrib/sqlalchemy/dto.py
@@ -20,6 +20,7 @@
 from litestar.dto.factory.data_structures import FieldDefinition
 from litestar.dto.factory.field import DTO_FIELD_META_KEY, DTOField, Mark
 from litestar.dto.factory.utils import get_model_type_hints
+from litestar.exceptions import ImproperlyConfiguredException
 from litestar.types.empty import Empty
 from litestar.utils.helpers import get_fully_qualified_class_name
 from litestar.utils.signature import ParsedSignature
@@ -83,10 +84,15 @@ def _(
 
         default, default_factory = _detect_defaults(elem)
 
-        if (parsed_type := model_type_hints[key]).origin is Mapped:
-            (parsed_type,) = parsed_type.inner_types
-        else:
-            raise NotImplementedError(f"Expected 'Mapped' origin, got: '{parsed_type.origin}'")
+        try:
+            if (parsed_type := model_type_hints[key]).origin is Mapped:
+                (parsed_type,) = parsed_type.inner_types
+            else:
+                raise NotImplementedError(f"Expected 'Mapped' origin, got: '{parsed_type.origin}'")
+        except KeyError as e:
+            raise ImproperlyConfiguredException(
+                f"No type information found for '{orm_descriptor}'. Has a type annotation been added to the column?"
+            ) from e
 
         return [
             FieldDefinition(


Test patch:
diff --git a/tests/unit/test_contrib/test_sqlalchemy/test_dto.py b/tests/unit/test_contrib/test_sqlalchemy/test_dto.py
--- a/tests/unit/test_contrib/test_sqlalchemy/test_dto.py
+++ b/tests/unit/test_contrib/test_sqlalchemy/test_dto.py
@@ -6,6 +6,7 @@
 from uuid import UUID, uuid4
 
 import pytest
+import sqlalchemy
 from sqlalchemy import func
 from sqlalchemy.orm import DeclarativeBase, Mapped, MappedAsDataclass, declared_attr, mapped_column
 from typing_extensions import Annotated
@@ -15,6 +16,7 @@
 from litestar.dto.factory.field import DTO_FIELD_META_KEY
 from litestar.dto.interface import ConnectionContext, HandlerContext
 from litestar.dto.types import ForType
+from litestar.exceptions import ImproperlyConfiguredException
 from litestar.serialization import encode_json
 from litestar.typing import ParsedType
 
@@ -549,3 +551,12 @@ class A(Base):
     )
     assert vars(model)["a"] == {"b": 1}
     assert vars(model)["c"] == [1, 2, 3]
+
+
+async def test_no_type_hints(base: type[DeclarativeBase], connection_context: ConnectionContext) -> None:
+    class Model(base):
+        field = mapped_column(sqlalchemy.String)
+
+    dto_type = SQLAlchemyDTO[Annotated[Model, DTOConfig()]]
+    with pytest.raises(ImproperlyConfiguredException, match="No type information found for 'Model.field'"):
+        await get_model_from_dto(dto_type, Model, connection_context, b"")