diff --git a/docs/en/docs/configurations/staticfiles.md b/docs/en/docs/configurations/staticfiles.md index 0b7f2477..942cdff6 100644 --- a/docs/en/docs/configurations/staticfiles.md +++ b/docs/en/docs/configurations/staticfiles.md @@ -42,7 +42,7 @@ but also via settings. This will make sure you keep the settings clean, separated and without a bloated **Esmerald** instance. -## Multiple directories and multiple pathes +## Multiple directories and multiple pathes (without fallthrough) Imagine, for example, you have multiple directories you would like to access including a `node_modules/` one. This is possible do do it by passing multiple `StaticFilesConfig` configurations and shown below: @@ -50,6 +50,19 @@ This is possible do do it by passing multiple `StaticFilesConfig` configurations ```python {!> ../../../docs_src/configurations/staticfiles/example_multiple.py!} ``` +The advantage is a fine granular configuration. Different options and packages can be set. !!! Note The first path match is used and there is currently no fallthrough in case no file is found, so the order is very important. + + +## Multiple directories with fallthrough + +Designers may want to provide overwrites to static files or have fallbacks. In the [former example](#multiple-directories-and-multiple-pathes-without-fallthrough) this wasn't possible. +For **newer** lilya versions it is possible to provide multiple directories to lilya and get such a behavior + +```python +{!> ../../../docs_src/configurations/staticfiles/example_multiple_fallthrough.py!} +``` + +Both styles can diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 983febb2..fe47173d 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -11,6 +11,8 @@ hide: - Fix cli detection of wrapped esmerald instances or different ASGI servers. - Allow passing multiple `StaticFilesConfig` configurations in a tuple. +- Allow passing multiple directories to `StaticFiles` by removing the stringification in `StaticFilesConfig` so a fallthrough behavior can be etablished. + Note: this requires a newer lilya version. ## 3.5.1 diff --git a/docs_src/configurations/staticfiles/example_multiple_fallthrough.py b/docs_src/configurations/staticfiles/example_multiple_fallthrough.py new file mode 100644 index 00000000..fb5581b2 --- /dev/null +++ b/docs_src/configurations/staticfiles/example_multiple_fallthrough.py @@ -0,0 +1,9 @@ +from pathlib import Path + +from esmerald import Esmerald, StaticFilesConfig + +static_files_config = StaticFilesConfig( + path="/static", directory=["static/overwrites", "static", "static/defaults", "node_modules"] +) + +app = Esmerald(static_files_config=static_files_config) diff --git a/esmerald/config/static_files.py b/esmerald/config/static_files.py index acd1c509..532c8eb0 100644 --- a/esmerald/config/static_files.py +++ b/esmerald/config/static_files.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Any, Dict, List, Optional, Tuple, Union +from typing import Any, List, Optional, Tuple, Union from lilya._internal._path import clean_path from lilya.staticfiles import StaticFiles @@ -7,6 +7,8 @@ from pydantic import BaseModel, DirectoryPath, constr, field_validator from typing_extensions import Annotated, Doc +DirectoryType = Union[DirectoryPath, str, Path, Any] + class StaticFilesConfig(BaseModel): """ @@ -41,7 +43,7 @@ class StaticFilesConfig(BaseModel): ), ] directory: Annotated[ - Optional[Union[DirectoryPath, str, Path, Any]], + Optional[Union[DirectoryType, list[DirectoryType], tuple[DirectoryType, ...]]], Doc( """ The directory for the statics in the format of a path like. @@ -81,22 +83,9 @@ def validate_path(cls, value: str) -> str: raise ValueError("path parameters are not supported for static files") return clean_path(value) - def _build_kwargs( - self, - ) -> Dict[str, Union[bool, int, DirectoryPath, List[Union[str, Tuple[str, str]]]]]: - """ - Builds the necessary kwargs to create an StaticFiles object. - """ - kwargs = {"html": self.html, "check_dir": self.check_dir} - if self.packages: - kwargs.update({"packages": self.packages}) # type: ignore - if self.directory: - kwargs.update({"directory": str(self.directory)}) # type: ignore - return kwargs # type: ignore - def to_app(self) -> ASGIApp: """ It can be three scenarios """ - return StaticFiles(**self._build_kwargs()) # type: ignore + return StaticFiles(**self.model_dump(exclude_none=True, exclude=["path"])) # type: ignore