Skip to content

Commit

Permalink
Merge pull request #24 from volfpeter/wrap_as-JinjaContextFactory
Browse files Browse the repository at this point in the history
Add JinjaContext.wrap_as() utility and tests
  • Loading branch information
volfpeter authored Jul 31, 2024
2 parents 1dd33f6 + 063e054 commit 593d75a
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
36 changes: 36 additions & 0 deletions fasthx/jinja.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from collections.abc import Callable, Collection, Iterable
from dataclasses import dataclass, field
from functools import lru_cache
from typing import Any, Coroutine

from fastapi import Request, Response
Expand Down Expand Up @@ -89,6 +90,41 @@ def unpack_result_with_route_context(
route_context.update(result)
return route_context

@classmethod
@lru_cache
def wrap_as(cls, result_key: str, context_key: str | None = None) -> JinjaContextFactory:
"""
Creates a `JinjaContextFactory` that wraps the route's result and optionally the route
context under user-specified keys.
`result_key` and `context_key` must be different.
Arguments:
result_key: The key by which the `route_result` should be accessible in templates.
See `JinjaContextFactory` for `route_result` details.
context_key: The key by whih the `route_context` should be accessible in templates.
If `None` (the default), then the `route_context` will not be accessible.
See `JinjaContextFactory` for `route_context` details.
Returns:
The created `JinjaContextFactory`.
Raises:
ValueError: If `result_key` and `context_key` are equal.
"""

if result_key == context_key:
raise ValueError("The two keys must be different, merging is not supported.")

def wrap(*, route_result: Any, route_context: dict[str, Any]) -> dict[str, Any]:
result = {result_key: route_result}
if context_key is not None:
result[context_key] = route_context

return result

return wrap


@dataclass(frozen=True, slots=True)
class TemplateHeader:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "fasthx"
version = "1.0.0"
version = "1.1.0"
description = "FastAPI data APIs with HTMX support."
authors = ["Peter Volf <[email protected]>"]
readme = "README.md"
Expand Down
16 changes: 16 additions & 0 deletions tests/test_jinja.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,22 @@ def test_unpack_methods(self, route_result: Any, route_converted: dict[str, Any]
)
assert result == {**route_context, **route_converted}

def test_wrap_as(self) -> None:
result_only = JinjaContext.wrap_as("item")
assert result_only is JinjaContext.wrap_as("item")

result_and_context = JinjaContext.wrap_as("item", "route")
route_result, route_context = 22, {"4": 4}

assert {"item": route_result} == result_only(route_result=route_result, route_context=route_context)
assert {"item": route_result, "route": route_context} == result_and_context(
route_result=route_result, route_context=route_context
)

def test_wrap_as_name_conflict(self) -> None:
with pytest.raises(ValueError):
JinjaContext.wrap_as("foo", "foo")

def test_unpack_result_with_route_context_conflict(self) -> None:
with pytest.raises(ValueError):
JinjaContext.unpack_result_with_route_context(
Expand Down

0 comments on commit 593d75a

Please sign in to comment.