Skip to content

Commit

Permalink
refactor!: Remove deprecated StaticFileConfig (#3357)
Browse files Browse the repository at this point in the history
* Remove deprecated StaticFiles and StaticFilesConfig
* remove special casing of static files app from handlers/router
* remove outdated docs sections
* Add what's new section
* Rename tests for consistency
  • Loading branch information
provinzkraut committed Aug 25, 2024
1 parent 5ecc7e4 commit 0bfc0ac
Show file tree
Hide file tree
Showing 40 changed files with 383 additions and 986 deletions.
8 changes: 0 additions & 8 deletions docs/examples/static_files/upgrade_from_static_1.py

This file was deleted.

8 changes: 0 additions & 8 deletions docs/examples/static_files/upgrade_from_static_2.py

This file was deleted.

6 changes: 3 additions & 3 deletions docs/release-notes/2.x-changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -423,15 +423,15 @@

Static file serving has been implemented with regular route handlers instead of
a specialised ASGI app. At the moment, this is complementary to the usage of
:class:`~litestar.static_files.StaticFilesConfig` to maintain backwards
`litestar.static_files.StaticFilesConfig`` to maintain backwards
compatibility.

This achieves a few things:

- Fixes https:/litestar-org/litestar/issues/2629
- Circumvents special casing needed in the routing logic for the static files app
- Removes the need for a ``static_files_config`` attribute on the app
- Removes the need for a special :meth:`~litestar.app.Litestar.url_for_static_asset`
- Removes the need for a special ``litestar.app.Litestar.url_for_static_asset``
method on the app since `route_reverse` can be used instead

Additionally:
Expand Down Expand Up @@ -1943,7 +1943,7 @@
:pr: 2154

Fixed a bug that would result in a ``404 - Not Found`` when requesting a static
file where the :attr:`~litestar.static_files.StaticFilesConfig.path` was also
file where the ``litestar.static_files.StaticFilesConfig.path`` was also
used by a route handler.

.. change:: HTMX: Missing default values for ``receive`` and ``send`` parameters of ``HTMXRequest``
Expand Down
2 changes: 1 addition & 1 deletion docs/release-notes/whats-new-2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Imports
+----------------------------------------------------+------------------------------------------------------------------------+
| ``starlite.OpenAPIConfig`` | :class:`.openapi.OpenAPIConfig` |
+----------------------------------------------------+------------------------------------------------------------------------+
| ``starlite.StaticFilesConfig`` | :class:`.static_files.config.StaticFilesConfig` |
| ``starlite.StaticFilesConfig`` | ``.static_files.config.StaticFilesConfig`` |
+----------------------------------------------------+------------------------------------------------------------------------+
| ``starlite.TemplateConfig`` | :class:`.template.TemplateConfig` |
+----------------------------------------------------+------------------------------------------------------------------------+
Expand Down
18 changes: 18 additions & 0 deletions docs/release-notes/whats-new-3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,24 @@ Imports
+----------------------------------------------------+------------------------------------------------------------------------+



Removal of ``StaticFileConfig``
-------------------------------

The ``StaticFilesConfig`` has been removed, alongside these related parameters and
functions:

- ``Litestar.static_files_config``
- ``Litestar.url_for_static_asset``
- ``Request.url_for_static_asset``

:func:`create_static_files_router` is a drop-in replacement for ``StaticFilesConfig``,
and can simply be added to the ``route_handlers`` like any other regular handler.

Usage of ``url_for_static_assets`` should be replaced with a ``url_for("static", ...)``
call.


Other Changes
-------------

Expand Down
17 changes: 0 additions & 17 deletions docs/usage/static-files.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,20 +94,3 @@ with support for popular cloud providers available via 3rd party implementations
.. literalinclude:: /examples/static_files/file_system.py
:caption: Using a custom file system with
:func:`create_static_files_router`

Upgrading from legacy StaticFilesConfig
---------------------------------------

.. deprecated:: v3.0
:class:`StaticFilesConfig` is deprecated and will be removed in Litestar 3.0

Existing code can be upgraded to :func:`create_static_files_router` by replacing
:class:`StaticFilesConfig` instances with this function call and passing the result to
``route_handlers`` instead of ``static_files_config``:

.. literalinclude:: /examples/static_files/upgrade_from_static_1.py
:caption: Using the deprecated :class:`~.static_files.config.StaticFilesConfig`

.. literalinclude:: /examples/static_files/upgrade_from_static_2.py
:caption: Upgrading from :class:`~.static_files.config.StaticFilesConfig` to
:func:`create_static_files_router`
7 changes: 4 additions & 3 deletions docs/usage/templating.rst
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,10 @@ Built-in callables
if you wish to insert the ``csrf_token`` into non-HTML based templates, or insert it into HTML templates not using a hidden input field but
by some other means, for example inside a special ``<meta>`` tag.

``url_for_static_asset``
URLs for static files can be created using the ``url_for_static_asset`` function. It's signature and behaviour are identical to
:meth:`app.url_for_static_asset <litestar.app.Litestar.url_for_static_asset>`.
``url_for`` for static files
For static file serving as provided by :func:`~litestar.static_files.create_static_files_router`,
``url_for`` can be used with the ``static`` handler name: ``url_for("static", file_name="style.css")``



Registering template callables
Expand Down
1 change: 0 additions & 1 deletion litestar/_asgi/routing_trie/mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ def add_mount_route(
current_node = current_node.children[component] # type: ignore[index]

current_node.is_mount = True
current_node.is_static = route.route_handler.is_static

if route.path != "/":
mount_routes[route.path] = root_node.children[route.path] = current_node
Expand Down
3 changes: 1 addition & 2 deletions litestar/_asgi/routing_trie/traversal.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,7 @@ def parse_path_to_route(
if not any(remaining_path.startswith(f"{sub_route}/") for sub_route in children):
asgi_app, handler = parse_node_handlers(node=mount_node, method=method)
remaining_path = remaining_path or "/"
if not mount_node.is_static:
remaining_path = remaining_path if remaining_path.endswith("/") else f"{remaining_path}/"
remaining_path = remaining_path if remaining_path.endswith("/") else f"{remaining_path}/"
return asgi_app, handler, remaining_path, {}, root_node.path_template

node, path_parameters, path = traverse_route_map(
Expand Down
4 changes: 0 additions & 4 deletions litestar/_asgi/routing_trie/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ class RouteTrieNode:
"children",
"is_asgi",
"is_mount",
"is_static",
"is_path_param_node",
"is_path_type",
"path_parameters",
Expand All @@ -57,8 +56,6 @@ class RouteTrieNode:
"""Designate the node as having an `asgi` type handler."""
is_mount: bool
"""Designate the node as being a mount route."""
is_static: bool
"""Designate the node as being a static mount route."""
path_parameters: dict[Method | Literal["websocket"] | Literal["asgi"], tuple[PathParameterDefinition, ...]]
"""A list of tuples containing path parameter definitions.
Expand All @@ -82,7 +79,6 @@ def create_node(path_template: str = "") -> RouteTrieNode:
is_path_param_node=False,
is_asgi=False,
is_mount=False,
is_static=False,
is_path_type=False,
path_parameters={},
path_template=path_template,
Expand Down
59 changes: 0 additions & 59 deletions litestar/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
from litestar.plugins.base import CLIPlugin
from litestar.router import Router
from litestar.routes import ASGIRoute, HTTPRoute, WebSocketRoute
from litestar.static_files.base import StaticFiles
from litestar.stores.registry import StoreRegistry
from litestar.types import Empty, TypeDecodersSequence
from litestar.types.internal_types import PathParameterDefinition, TemplateConfigType
Expand All @@ -68,13 +67,11 @@
from litestar.openapi.spec import SecurityRequirement
from litestar.openapi.spec.open_api import OpenAPI
from litestar.response import Response
from litestar.static_files.config import StaticFilesConfig
from litestar.stores.base import Store
from litestar.types import (
AfterExceptionHookHandler,
AfterRequestHookHandler,
AfterResponseHookHandler,
AnyCallable,
ASGIApp,
BeforeMessageSendHookHandler,
BeforeRequestHookHandler,
Expand Down Expand Up @@ -140,7 +137,6 @@ class Litestar(Router):
"_server_lifespan_managers",
"_debug",
"_openapi_schema",
"_static_files_config",
"plugins",
"after_exception",
"allowed_hosts",
Expand Down Expand Up @@ -211,7 +207,6 @@ def __init__(
signature_namespace: Mapping[str, Any] | None = None,
signature_types: Sequence[Any] | None = None,
state: State | None = None,
static_files_config: Sequence[StaticFilesConfig] | None = None,
stores: StoreRegistry | dict[str, Store] | None = None,
tags: Sequence[str] | None = None,
template_config: TemplateConfigType | None = None,
Expand Down Expand Up @@ -303,7 +298,6 @@ def __init__(
signature_types: A sequence of types for use in forward reference resolution during signature modeling.
These types will be added to the signature namespace using their ``__name__`` attribute.
state: An optional :class:`State <.datastructures.State>` for application state.
static_files_config: A sequence of :class:`StaticFilesConfig <.static_files.StaticFilesConfig>`
stores: Central registry of :class:`Store <.stores.base.Store>` that will be available throughout the
application. If this is a dictionary to it will be passed to a
:class:`StoreRegistry <.stores.registry.StoreRegistry>`. If it is a
Expand Down Expand Up @@ -371,7 +365,6 @@ def __init__(
signature_namespace=dict(signature_namespace or {}),
signature_types=list(signature_types or []),
state=state or State(),
static_files_config=list(static_files_config or []),
stores=stores,
tags=list(tags or []),
template_config=template_config,
Expand Down Expand Up @@ -431,7 +424,6 @@ def __init__(
self.request_class: type[Request] = config.request_class or Request
self.response_cache_config = config.response_cache_config
self.state = config.state
self._static_files_config = config.static_files_config
self.template_engine = config.template_config.engine_instance if config.template_config else None
self.websocket_class: type[WebSocket] = config.websocket_class or WebSocket
self.debug = config.debug
Expand Down Expand Up @@ -489,9 +481,6 @@ def __init__(
self.get_logger = self.logging_config.configure()
self.logger = self.get_logger("litestar")

for static_config in self._static_files_config:
self.register(static_config.to_static_files_app())

self.asgi_handler = self._create_asgi_handler()

@staticmethod
Expand All @@ -511,11 +500,6 @@ def _patch_opentelemetry_middleware(config: AppConfig) -> AppConfig:
pass
return config

@property
@deprecated(version="2.6.0", kind="property", info="Use create_static_files router instead")
def static_files_config(self) -> list[StaticFilesConfig]:
return self._static_files_config

@property
@deprecated(version="2.0", alternative="Litestar.plugins.cli", kind="property")
def cli_plugins(self) -> list[CLIPluginProtocol]:
Expand Down Expand Up @@ -799,49 +783,6 @@ def get_membership_details(group_id: int, user_id: int) -> None:

return join_paths(output)

@deprecated(
"2.6.0", info="Use create_static_files router instead of StaticFilesConfig, which works with route_reverse"
)
def url_for_static_asset(self, name: str, file_path: str) -> str:
"""Receives a static files handler name, an asset file path and returns resolved url path to the asset.
Examples:
.. code-block:: python
from litestar import Litestar
from litestar.static_files.config import StaticFilesConfig
app = Litestar(
static_files_config=[
StaticFilesConfig(directories=["css"], path="/static/css", name="css")
]
)
path = app.url_for_static_asset("css", "main.css")
# /static/css/main.css
Args:
name: A static handler unique name.
file_path: a string containing path to an asset.
Raises:
NoRouteMatchFoundException: If static files handler with ``name`` does not exist.
Returns:
A url path to the asset.
"""

handler_index = self.get_handler_index_by_name(name)
if handler_index is None:
raise NoRouteMatchFoundException(f"Static handler {name} can not be found")

handler_fn = cast("AnyCallable", handler_index["handler"].fn)
if not isinstance(handler_fn, StaticFiles):
raise NoRouteMatchFoundException(f"Handler with name {name} is not a static files handler")

return join_paths([handler_index["paths"][0], file_path])

@property
def route_handler_method_view(self) -> dict[str, list[str]]:
"""Map route handlers to paths.
Expand Down
9 changes: 0 additions & 9 deletions litestar/cli/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,15 +388,6 @@ def show_app_info(app: Litestar) -> None: # pragma: no cover
if app.template_engine:
table.add_row("Template engine", type(app.template_engine).__name__)

if app.static_files_config:
static_files_configs = app.static_files_config
static_files_info = [
f"path=[yellow]{static_files.path}[/] dirs=[yellow]{', '.join(map(str, static_files.directories))}[/] "
f"html_mode={_format_is_enabled(static_files.html_mode)}"
for static_files in static_files_configs
]
table.add_row("Static files", "\n".join(static_files_info))

middlewares = []
for middleware in app.middleware:
updated_middleware = middleware.middleware if isinstance(middleware, DefineMiddleware) else middleware
Expand Down
3 changes: 0 additions & 3 deletions litestar/config/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
from litestar.openapi.config import OpenAPIConfig
from litestar.openapi.spec import SecurityRequirement
from litestar.plugins import PluginProtocol
from litestar.static_files.config import StaticFilesConfig
from litestar.stores.base import Store
from litestar.stores.registry import StoreRegistry
from litestar.types import (
Expand Down Expand Up @@ -193,8 +192,6 @@ class AppConfig:
"""
state: State = field(default_factory=State)
"""A :class:`State` <.datastructures.State>` instance holding application state."""
static_files_config: list[StaticFilesConfig] = field(default_factory=list)
"""An instance or list of :class:`StaticFilesConfig <.static_files.StaticFilesConfig>`."""
stores: StoreRegistry | dict[str, Store] | None = None
"""Central registry of :class:`Store <.stores.base.Store>` to be made available and be used throughout the
application. Can be either a dictionary mapping strings to :class:`Store <.stores.base.Store>` instances, or an
Expand Down
18 changes: 0 additions & 18 deletions litestar/connection/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,21 +325,3 @@ def url_for(self, name: str, **path_parameters: Any) -> str:
url_path = litestar_instance.route_reverse(name, **path_parameters)

return make_absolute_url(url_path, self.base_url)

def url_for_static_asset(self, name: str, file_path: str) -> str:
"""Receives a static files handler name, an asset file path and returns resolved absolute url to the asset.
Args:
name: A static handler unique name.
file_path: a string containing path to an asset.
Raises:
NoRouteMatchFoundException: If static files handler with ``name`` does not exist.
Returns:
A string representing absolute url to the asset.
"""
litestar_instance = self.scope["app"]
url_path = litestar_instance.url_for_static_asset(name, file_path)

return make_absolute_url(url_path, self.base_url)
2 changes: 0 additions & 2 deletions litestar/contrib/jinja.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
TemplateEngineProtocol,
csrf_token,
url_for,
url_for_static_asset,
)

try:
Expand Down Expand Up @@ -52,7 +51,6 @@ def __init__(
self.engine = Environment(loader=loader, autoescape=True)
elif engine_instance:
self.engine = engine_instance
self.register_template_callable(key="url_for_static_asset", template_callable=url_for_static_asset)
self.register_template_callable(key="csrf_token", template_callable=csrf_token)
self.register_template_callable(key="url_for", template_callable=url_for)

Expand Down
2 changes: 0 additions & 2 deletions litestar/contrib/mako.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
TemplateProtocol,
csrf_token,
url_for,
url_for_static_asset,
)

try:
Expand Down Expand Up @@ -82,7 +81,6 @@ def __init__(self, directory: Path | list[Path] | None = None, engine_instance:
self.engine = engine_instance

self._template_callables: list[tuple[str, TemplateCallableType]] = []
self.register_template_callable(key="url_for_static_asset", template_callable=url_for_static_asset)
self.register_template_callable(key="csrf_token", template_callable=csrf_token)
self.register_template_callable(key="url_for", template_callable=url_for)

Expand Down
2 changes: 0 additions & 2 deletions litestar/contrib/minijinja.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
TemplateProtocol,
csrf_token,
url_for,
url_for_static_asset,
)
from litestar.utils.deprecation import warn_deprecation

Expand Down Expand Up @@ -141,7 +140,6 @@ def _loader(name: str) -> str:

self.register_template_callable("url_for", _transform_state(url_for))
self.register_template_callable("csrf_token", _transform_state(csrf_token))
self.register_template_callable("url_for_static_asset", _transform_state(url_for_static_asset))

def get_template(self, template_name: str) -> MiniJinjaTemplate:
"""Retrieve a template by matching its name (dotted path) with files in the directory or directories provided.
Expand Down
Loading

0 comments on commit 0bfc0ac

Please sign in to comment.