diff options
Diffstat (limited to 'venv/lib/python3.11/site-packages/litestar/static_files')
-rw-r--r-- | venv/lib/python3.11/site-packages/litestar/static_files/__init__.py | 4 | ||||
-rw-r--r-- | venv/lib/python3.11/site-packages/litestar/static_files/__pycache__/__init__.cpython-311.pyc | bin | 443 -> 0 bytes | |||
-rw-r--r-- | venv/lib/python3.11/site-packages/litestar/static_files/__pycache__/base.cpython-311.pyc | bin | 7052 -> 0 bytes | |||
-rw-r--r-- | venv/lib/python3.11/site-packages/litestar/static_files/__pycache__/config.cpython-311.pyc | bin | 10192 -> 0 bytes | |||
-rw-r--r-- | venv/lib/python3.11/site-packages/litestar/static_files/base.py | 141 | ||||
-rw-r--r-- | venv/lib/python3.11/site-packages/litestar/static_files/config.py | 224 |
6 files changed, 0 insertions, 369 deletions
diff --git a/venv/lib/python3.11/site-packages/litestar/static_files/__init__.py b/venv/lib/python3.11/site-packages/litestar/static_files/__init__.py deleted file mode 100644 index 3cd4594..0000000 --- a/venv/lib/python3.11/site-packages/litestar/static_files/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from litestar.static_files.base import StaticFiles -from litestar.static_files.config import StaticFilesConfig, create_static_files_router - -__all__ = ("StaticFiles", "StaticFilesConfig", "create_static_files_router") diff --git a/venv/lib/python3.11/site-packages/litestar/static_files/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/static_files/__pycache__/__init__.cpython-311.pyc Binary files differdeleted file mode 100644 index 1cc4497..0000000 --- a/venv/lib/python3.11/site-packages/litestar/static_files/__pycache__/__init__.cpython-311.pyc +++ /dev/null diff --git a/venv/lib/python3.11/site-packages/litestar/static_files/__pycache__/base.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/static_files/__pycache__/base.cpython-311.pyc Binary files differdeleted file mode 100644 index 0ca9dae..0000000 --- a/venv/lib/python3.11/site-packages/litestar/static_files/__pycache__/base.cpython-311.pyc +++ /dev/null diff --git a/venv/lib/python3.11/site-packages/litestar/static_files/__pycache__/config.cpython-311.pyc b/venv/lib/python3.11/site-packages/litestar/static_files/__pycache__/config.cpython-311.pyc Binary files differdeleted file mode 100644 index fd93af6..0000000 --- a/venv/lib/python3.11/site-packages/litestar/static_files/__pycache__/config.cpython-311.pyc +++ /dev/null diff --git a/venv/lib/python3.11/site-packages/litestar/static_files/base.py b/venv/lib/python3.11/site-packages/litestar/static_files/base.py deleted file mode 100644 index 9827697..0000000 --- a/venv/lib/python3.11/site-packages/litestar/static_files/base.py +++ /dev/null @@ -1,141 +0,0 @@ -from __future__ import annotations - -from os.path import commonpath -from pathlib import Path -from typing import TYPE_CHECKING, Literal, Sequence - -from litestar.enums import ScopeType -from litestar.exceptions import MethodNotAllowedException, NotFoundException -from litestar.file_system import FileSystemAdapter -from litestar.response.file import ASGIFileResponse -from litestar.status_codes import HTTP_404_NOT_FOUND - -__all__ = ("StaticFiles",) - - -if TYPE_CHECKING: - from litestar.types import Receive, Scope, Send - from litestar.types.composite_types import PathType - from litestar.types.file_types import FileInfo, FileSystemProtocol - - -class StaticFiles: - """ASGI App that handles file sending.""" - - __slots__ = ("is_html_mode", "directories", "adapter", "send_as_attachment", "headers") - - def __init__( - self, - is_html_mode: bool, - directories: Sequence[PathType], - file_system: FileSystemProtocol, - send_as_attachment: bool = False, - resolve_symlinks: bool = True, - headers: dict[str, str] | None = None, - ) -> None: - """Initialize the Application. - - Args: - is_html_mode: Flag dictating whether serving html. If true, the default file will be ``index.html``. - directories: A list of directories to serve files from. - file_system: The file_system spec to use for serving files. - send_as_attachment: Whether to send the file with a ``content-disposition`` header of - ``attachment`` or ``inline`` - resolve_symlinks: Resolve symlinks to the directories - headers: Headers that will be sent with every response. - """ - self.adapter = FileSystemAdapter(file_system) - self.directories = tuple(Path(p).resolve() if resolve_symlinks else Path(p) for p in directories) - self.is_html_mode = is_html_mode - self.send_as_attachment = send_as_attachment - self.headers = headers - - async def get_fs_info( - self, directories: Sequence[PathType], file_path: PathType - ) -> tuple[Path, FileInfo] | tuple[None, None]: - """Return the resolved path and a :class:`stat_result <os.stat_result>`. - - Args: - directories: A list of directory paths. - file_path: A file path to resolve - - Returns: - A tuple with an optional resolved :class:`Path <anyio.Path>` instance and an optional - :class:`stat_result <os.stat_result>`. - """ - for directory in directories: - try: - joined_path = Path(directory, file_path) - file_info = await self.adapter.info(joined_path) - if file_info and commonpath([str(directory), file_info["name"], joined_path]) == str(directory): - return joined_path, file_info - except FileNotFoundError: - continue - return None, None - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - """ASGI callable. - - Args: - scope: ASGI scope - receive: ASGI ``receive`` callable - send: ASGI ``send`` callable - - Returns: - None - """ - if scope["type"] != ScopeType.HTTP or scope["method"] not in {"GET", "HEAD"}: - raise MethodNotAllowedException() - - res = await self.handle(path=scope["path"], is_head_response=scope["method"] == "HEAD") - await res(scope=scope, receive=receive, send=send) - - async def handle(self, path: str, is_head_response: bool) -> ASGIFileResponse: - split_path = path.split("/") - filename = split_path[-1] - joined_path = Path(*split_path) - resolved_path, fs_info = await self.get_fs_info(directories=self.directories, file_path=joined_path) - content_disposition_type: Literal["inline", "attachment"] = ( - "attachment" if self.send_as_attachment else "inline" - ) - - if self.is_html_mode and fs_info and fs_info["type"] == "directory": - filename = "index.html" - resolved_path, fs_info = await self.get_fs_info( - directories=self.directories, - file_path=Path(resolved_path or joined_path) / filename, - ) - - if fs_info and fs_info["type"] == "file": - return ASGIFileResponse( - file_path=resolved_path or joined_path, - file_info=fs_info, - file_system=self.adapter.file_system, - filename=filename, - content_disposition_type=content_disposition_type, - is_head_response=is_head_response, - headers=self.headers, - ) - - if self.is_html_mode: - # for some reason coverage doesn't catch these two lines - filename = "404.html" # pragma: no cover - resolved_path, fs_info = await self.get_fs_info( # pragma: no cover - directories=self.directories, file_path=filename - ) - - if fs_info and fs_info["type"] == "file": - return ASGIFileResponse( - file_path=resolved_path or joined_path, - file_info=fs_info, - file_system=self.adapter.file_system, - filename=filename, - status_code=HTTP_404_NOT_FOUND, - content_disposition_type=content_disposition_type, - is_head_response=is_head_response, - headers=self.headers, - ) - - raise NotFoundException( - f"no file or directory match the path {resolved_path or joined_path} was found" - ) # pragma: no cover diff --git a/venv/lib/python3.11/site-packages/litestar/static_files/config.py b/venv/lib/python3.11/site-packages/litestar/static_files/config.py deleted file mode 100644 index 22b6620..0000000 --- a/venv/lib/python3.11/site-packages/litestar/static_files/config.py +++ /dev/null @@ -1,224 +0,0 @@ -from __future__ import annotations - -from dataclasses import dataclass -from pathlib import PurePath # noqa: TCH003 -from typing import TYPE_CHECKING, Any, Sequence - -from litestar.exceptions import ImproperlyConfiguredException -from litestar.file_system import BaseLocalFileSystem -from litestar.handlers import asgi, get, head -from litestar.response.file import ASGIFileResponse # noqa: TCH001 -from litestar.router import Router -from litestar.static_files.base import StaticFiles -from litestar.types import Empty -from litestar.utils import normalize_path, warn_deprecation - -__all__ = ("StaticFilesConfig",) - -if TYPE_CHECKING: - from litestar.datastructures import CacheControlHeader - from litestar.handlers.asgi_handlers import ASGIRouteHandler - from litestar.openapi.spec import SecurityRequirement - from litestar.types import ( - AfterRequestHookHandler, - AfterResponseHookHandler, - BeforeRequestHookHandler, - EmptyType, - ExceptionHandlersMap, - Guard, - Middleware, - PathType, - ) - - -@dataclass -class StaticFilesConfig: - """Configuration for static file service. - - To enable static files, pass an instance of this class to the :class:`Litestar <litestar.app.Litestar>` constructor using - the 'static_files_config' key. - """ - - path: str - """Path to serve static files from. - - Note that the path cannot contain path parameters. - """ - directories: list[PathType] - """A list of directories to serve files from.""" - html_mode: bool = False - """Flag dictating whether serving html. - - If true, the default file will be 'index.html'. - """ - name: str | None = None - """An optional string identifying the static files handler.""" - file_system: Any = BaseLocalFileSystem() # noqa: RUF009 - """The file_system spec to use for serving files. - - Notes: - - A file_system is a class that adheres to the - :class:`FileSystemProtocol <litestar.types.FileSystemProtocol>`. - - You can use any of the file systems exported from the - [fsspec](https://filesystem-spec.readthedocs.io/en/latest/) library for this purpose. - """ - opt: dict[str, Any] | None = None - """A string key dictionary of arbitrary values that will be added to the static files handler.""" - guards: list[Guard] | None = None - """A list of :class:`Guard <litestar.types.Guard>` callables.""" - exception_handlers: ExceptionHandlersMap | None = None - """A dictionary that maps handler functions to status codes and/or exception types.""" - send_as_attachment: bool = False - """Whether to send the file as an attachment.""" - - def __post_init__(self) -> None: - _validate_config(path=self.path, directories=self.directories, file_system=self.file_system) - self.path = normalize_path(self.path) - warn_deprecation( - "2.6.0", - kind="class", - deprecated_name="StaticFilesConfig", - removal_in="3.0", - alternative="create_static_files_router", - info='Replace static_files_config=[StaticFilesConfig(path="/static", directories=["assets"])] with ' - 'route_handlers=[..., create_static_files_router(path="/static", directories=["assets"])]', - ) - - def to_static_files_app(self) -> ASGIRouteHandler: - """Return an ASGI app serving static files based on the config. - - Returns: - :class:`StaticFiles <litestar.static_files.StaticFiles>` - """ - static_files = StaticFiles( - is_html_mode=self.html_mode, - directories=self.directories, - file_system=self.file_system, - send_as_attachment=self.send_as_attachment, - ) - return asgi( - path=self.path, - name=self.name, - is_static=True, - opt=self.opt, - guards=self.guards, - exception_handlers=self.exception_handlers, - )(static_files) - - -def create_static_files_router( - path: str, - directories: list[PathType], - file_system: Any = None, - send_as_attachment: bool = False, - html_mode: bool = False, - name: str = "static", - after_request: AfterRequestHookHandler | None = None, - after_response: AfterResponseHookHandler | None = None, - before_request: BeforeRequestHookHandler | None = None, - cache_control: CacheControlHeader | None = None, - exception_handlers: ExceptionHandlersMap | None = None, - guards: list[Guard] | None = None, - include_in_schema: bool | EmptyType = Empty, - middleware: Sequence[Middleware] | None = None, - opt: dict[str, Any] | None = None, - security: Sequence[SecurityRequirement] | None = None, - tags: Sequence[str] | None = None, - router_class: type[Router] = Router, - resolve_symlinks: bool = True, -) -> Router: - """Create a router with handlers to serve static files. - - Args: - path: Path to serve static files under - directories: Directories to serve static files from - file_system: A *file system* implementing - :class:`~litestar.types.FileSystemProtocol`. - `fsspec <https://filesystem-spec.readthedocs.io/en/latest/>`_ can be passed - here as well - send_as_attachment: Whether to send the file as an attachment - html_mode: When in HTML: - - Serve an ``index.html`` file from ``/`` - - Serve ``404.html`` when a file could not be found - name: Name to pass to the generated handlers - after_request: ``after_request`` handlers passed to the router - after_response: ``after_response`` handlers passed to the router - before_request: ``before_request`` handlers passed to the router - cache_control: ``cache_control`` passed to the router - exception_handlers: Exception handlers passed to the router - guards: Guards passed to the router - include_in_schema: Include the routes / router in the OpenAPI schema - middleware: Middlewares passed to the router - opt: Opts passed to the router - security: Security options passed to the router - tags: ``tags`` passed to the router - router_class: The class used to construct a router from - resolve_symlinks: Resolve symlinks of ``directories`` - """ - - if file_system is None: - file_system = BaseLocalFileSystem() - - _validate_config(path=path, directories=directories, file_system=file_system) - path = normalize_path(path) - - headers = None - if cache_control: - headers = {cache_control.HEADER_NAME: cache_control.to_header()} - - static_files = StaticFiles( - is_html_mode=html_mode, - directories=directories, - file_system=file_system, - send_as_attachment=send_as_attachment, - resolve_symlinks=resolve_symlinks, - headers=headers, - ) - - @get("{file_path:path}", name=name) - async def get_handler(file_path: PurePath) -> ASGIFileResponse: - return await static_files.handle(path=file_path.as_posix(), is_head_response=False) - - @head("/{file_path:path}", name=f"{name}/head") - async def head_handler(file_path: PurePath) -> ASGIFileResponse: - return await static_files.handle(path=file_path.as_posix(), is_head_response=True) - - handlers = [get_handler, head_handler] - - if html_mode: - - @get("/", name=f"{name}/index") - async def index_handler() -> ASGIFileResponse: - return await static_files.handle(path="/", is_head_response=False) - - handlers.append(index_handler) - - return router_class( - after_request=after_request, - after_response=after_response, - before_request=before_request, - cache_control=cache_control, - exception_handlers=exception_handlers, - guards=guards, - include_in_schema=include_in_schema, - middleware=middleware, - opt=opt, - path=path, - route_handlers=handlers, - security=security, - tags=tags, - ) - - -def _validate_config(path: str, directories: list[PathType], file_system: Any) -> None: - if not path: - raise ImproperlyConfiguredException("path must be a non-zero length string,") - - if not directories or not any(bool(d) for d in directories): - raise ImproperlyConfiguredException("directories must include at least one path.") - - if "{" in path: - raise ImproperlyConfiguredException("path parameters are not supported for static files") - - if not (callable(getattr(file_system, "info", None)) and callable(getattr(file_system, "open", None))): - raise ImproperlyConfiguredException("file_system must adhere to the FileSystemProtocol type") |