diff --git a/docs/en/docs/configurations/staticfiles.md b/docs/en/docs/configurations/staticfiles.md index 61fe3bfd..0b7f2477 100644 --- a/docs/en/docs/configurations/staticfiles.md +++ b/docs/en/docs/configurations/staticfiles.md @@ -41,3 +41,15 @@ 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 + +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: + +```python +{!> ../../../docs_src/configurations/staticfiles/example_multiple.py!} +``` + +!!! 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. diff --git a/docs/en/docs/release-notes.md b/docs/en/docs/release-notes.md index 64d591f8..983febb2 100644 --- a/docs/en/docs/release-notes.md +++ b/docs/en/docs/release-notes.md @@ -10,6 +10,7 @@ hide: ### Fixed - Fix cli detection of wrapped esmerald instances or different ASGI servers. +- Allow passing multiple `StaticFilesConfig` configurations in a tuple. ## 3.5.1 diff --git a/docs_src/configurations/staticfiles/example_multiple.py b/docs_src/configurations/staticfiles/example_multiple.py new file mode 100644 index 00000000..a282f199 --- /dev/null +++ b/docs_src/configurations/staticfiles/example_multiple.py @@ -0,0 +1,13 @@ +from pathlib import Path + +from esmerald import Esmerald, StaticFilesConfig + +static_files_config = StaticFilesConfig( + path="/static", packages=["mypackage"], directory=Path("static") +) + +static_files_node_modules_config = StaticFilesConfig( + path="/static/node_modules", directory=Path("node_modules") +) + +app = Esmerald(static_files_config=[static_files_node_modules_config, static_files_config]) diff --git a/esmerald/applications.py b/esmerald/applications.py index 81f640d3..eee2e11e 100644 --- a/esmerald/applications.py +++ b/esmerald/applications.py @@ -720,13 +720,18 @@ def is_valid(number: int) -> bool: ), ] = None, static_files_config: Annotated[ - Optional["StaticFilesConfig"], + Union[ + "StaticFilesConfig", + list["StaticFilesConfig"], + tuple["StaticFilesConfig", ...], + None, + ], Doc( """ An instance of [StaticFilesConfig](https://esmerald.dev/configurations/staticfiles/). This configuration is used to enable and serve static files via - Esmerald application. + Esmerald application. You can pass also multiple objects via a list or tuple. **Example** @@ -1683,7 +1688,7 @@ def _configure(self) -> None: if self.static_files_config: for config in ( self.static_files_config - if isinstance(self.static_files_config, list) + if isinstance(self.static_files_config, (list, tuple)) else [self.static_files_config] ): static_route = Include(path=config.path, app=config.to_app()) diff --git a/esmerald/conf/global_settings.py b/esmerald/conf/global_settings.py index 925430a6..01ebb3ee 100644 --- a/esmerald/conf/global_settings.py +++ b/esmerald/conf/global_settings.py @@ -875,7 +875,9 @@ def template_config(self) -> TemplateConfig: return None @property - def static_files_config(self) -> Optional[StaticFilesConfig]: + def static_files_config( + self, + ) -> Union[StaticFilesConfig, list[StaticFilesConfig], tuple[StaticFilesConfig, ...], None]: """ An instance of [StaticFilesConfig](https://esmerald.dev/configurations/staticfiles/). diff --git a/esmerald/config/static_files.py b/esmerald/config/static_files.py index 611c5211..acd1c509 100644 --- a/esmerald/config/static_files.py +++ b/esmerald/config/static_files.py @@ -26,6 +26,9 @@ class StaticFilesConfig(BaseModel): ) app = Esmerald(static_files_config=static_files_config) + # or multiple in descending priority + app = Esmerald(static_files_config=[static_files_config1, static_files_config2, ...]) + ``` """ diff --git a/esmerald/testclient.py b/esmerald/testclient.py index 437d7bb1..0f6295e8 100644 --- a/esmerald/testclient.py +++ b/esmerald/testclient.py @@ -129,7 +129,9 @@ def create_client( openapi_version: Optional[str] = "3.1.0", raise_server_exceptions: bool = True, root_path: str = "", - static_files_config: Optional["StaticFilesConfig"] = None, + static_files_config: Union[ + "StaticFilesConfig", list["StaticFilesConfig"], tuple["StaticFilesConfig", ...], None + ] = None, template_config: Optional["TemplateConfig"] = None, lifespan: Optional[Callable[["Esmerald"], "AsyncContextManager"]] = None, cookies: Optional[CookieTypes] = None,