-
-
Notifications
You must be signed in to change notification settings - Fork 17
Version 3 refactoring #78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughRenames HTMLRenderer → RenderFunction; moves Jinja public symbols into Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant FastAPI
participant Decorator
participant RenderFunction
participant HTMLResponse
Client->>FastAPI: HTTP request
FastAPI->>Decorator: invoke route handler -> result
Decorator->>RenderFunction: pass result + context + request
RenderFunction-->>Decorator: return rendered HTML (str)
Decorator->>HTMLResponse: wrap HTML -> Response
HTMLResponse->>Client: HTTP response
sequenceDiagram
participant Client
participant FastAPI
participant JinjaDecorator
participant ComponentHeader
participant JinjaContextFactory
participant JinjaRenderer
Client->>FastAPI: HTTP request (may include header)
FastAPI->>JinjaDecorator: handler returns result
JinjaDecorator->>ComponentHeader: select component/template
JinjaDecorator->>JinjaContextFactory: build template context
JinjaDecorator->>JinjaRenderer: render selected component with context -> str
JinjaRenderer->>JinjaDecorator: return HTML string
JinjaDecorator->>FastAPI: wrap/return Response
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: ASSERTIVE Plan: Pro Knowledge base: Disabled due to 📒 Files selected for processing (2)
🔇 Additional comments (12)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Ruff (0.13.1)fasthx/htmy.py�[1;31mruff failed�[0m tests/test_htmy.py�[1;31mruff failed�[0m Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🔭 Outside diff range comments (1)
fasthx/jinja.py (1)
316-332: Update docstring to reflect the renamed return type.The return type annotation has been correctly updated to
RenderFunction[Any], but the docstring still references the oldHTMLRenderertype.def _make_render_function( self, template: ComponentSelector[str], *, make_context: JinjaContextFactory, prefix: str | None, error_renderer: bool = False, ) -> RenderFunction[Any]: """ - Creates an `HTMLRenderer` with the given configuration. + Creates a `RenderFunction` with the given configuration. Arguments: template: The template the renderer function should use. make_context: The Jinja rendering context factory to use. prefix: Optional template name prefix. error_renderer: Whether this is an error renderer creation. """
🧹 Nitpick comments (6)
docs/index.md (1)
46-46: Spelling: “Interally” → “Internally”
Minor typo right after the changed paragraph.-Interally, FastHX decorators always have access … +Internally, FastHX decorators always have access …docs/examples/custom-templating.md (2)
23-23: Loosened type hint may hide bugs
Switchingresultfrom a concretelist[dict[str, str]]toAnysacrifices static-type safety and defeats the explanatory comment on lines 21-22. Consider restoring the specific type or introducing aTypeVar/generic if flexibility is required.
14-14: Typo: “dependecy” → “dependency”-# Create a dependecy to see that its return value … +# Create a dependency to see that its return value …pyproject.toml (1)
3-3: Version bump to 3.0.0: remember CHANGELOG & breaking-change notice
Major version implies breaking changes; verifyCHANGELOG.mdor release notes are updated accordingly.examples/custom-rendering/custom_rendering_app.py (1)
34-35: Out-of-date comment
The explanatory comment about# type: ignoreis now misleading because the ignore directives were removed. Please update or delete the comment block.-# Note on the type ignore: it seems mypy generic resolution fails at -# fastapi==0.111.0, at least on the first mypy run when there's no cache. +# (comment removed – mypy ignore no longer necessary)docs/migrations/2-to-3.md (1)
17-21: Consider improving readability of the replacement instructions.While the migration steps are comprehensive and accurate, the repetitive "Replace" beginnings could be improved for better readability.
Consider using a more concise format:
-These are all typing-related changes and most likely not relevant to your project unless you have created custom render functions or integrations. - -- Replace `from fasthx import HTMLRenderer` with `from fasthx import RenderFunction`. -- Replace `from fasthx.typing import HTMLRenderer` with `from fasthx.typing import RenderFunction`. -- Replace `from fasthx.typing import SyncHTMLRenderer` with `from fasthx.typing import SyncRenderFunction`. -- Replace `from fasthx.typing import AsyncHTMLRenderer` with `from fasthx.typing import AsyncRenderFunction`. +These are all typing-related changes and most likely not relevant to your project unless you have created custom render functions or integrations. + +**Import changes:** +- `from fasthx import HTMLRenderer` → `from fasthx import RenderFunction` +- `from fasthx.typing import HTMLRenderer` → `from fasthx.typing import RenderFunction` +- `from fasthx.typing import SyncHTMLRenderer` → `from fasthx.typing import SyncRenderFunction` +- `from fasthx.typing import AsyncHTMLRenderer` → `from fasthx.typing import AsyncRenderFunction`
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (21)
README.md(2 hunks)docs/api/core-decorators.md(1 hunks)docs/api/dependencies.md(1 hunks)docs/api/jinja.md(1 hunks)docs/api/typing.md(1 hunks)docs/examples/custom-templating.md(1 hunks)docs/examples/htmy.md(6 hunks)docs/examples/jinja-templating.md(3 hunks)docs/index.md(1 hunks)docs/migrations/2-to-3.md(1 hunks)examples/custom-rendering/custom_rendering_app.py(2 hunks)examples/htmy-rendering/htmy_app.py(5 hunks)examples/jinja-rendering/jinja_app.py(1 hunks)fasthx/__init__.py(1 hunks)fasthx/core_decorators.py(2 hunks)fasthx/htmy.py(4 hunks)fasthx/jinja.py(3 hunks)fasthx/typing.py(4 hunks)mkdocs.yaml(1 hunks)pyproject.toml(2 hunks)tests/test_jinja.py(5 hunks)
🧬 Code Graph Analysis (4)
fasthx/htmy.py (2)
fasthx/typing.py (1)
RequestComponentSelector(53-84)fasthx/jinja.py (1)
_make_render_function(316-347)
tests/test_jinja.py (2)
fasthx/htmy.py (1)
ComponentHeader(24-30)fasthx/jinja.py (4)
ComponentHeader(218-224)Jinja(228-414)JinjaContext(49-215)JinjaPath(35-46)
fasthx/__init__.py (1)
fasthx/typing.py (1)
RequestComponentSelector(53-84)
examples/jinja-rendering/jinja_app.py (1)
fasthx/jinja.py (1)
Jinja(228-414)
🪛 LanguageTool
docs/examples/htmy.md
[grammar] ~105-~105: Ensure spelling is correct
Context: ...basic HTML document structure with some TailwindCSS styling and metadata. There is also a b...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
docs/migrations/2-to-3.md
[style] ~19-~19: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.typing import RenderFunction. - Replace from fasthx.typing import SyncHTMLRend...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~20-~20: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...hx.typing import SyncRenderFunction. - Replace from fasthx.typing import AsyncHTMLRen...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~28-~28: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...om fasthx.jinja import JinjaContext. - Replace from fasthx import JinjaPathwithfr...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~29-~29: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...from fasthx.jinja import JinjaPath. - Replace from fasthx import TemplateHeader wit...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~30-~30: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.jinja import ComponentHeader. - Replace from fasthx.jinja import TemplateHeade...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~31-~31: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.jinja import ComponentHeader. - Replace from fasthx import JinjaContextFactory...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~32-~32: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...hx.jinja import JinjaContextFactory. - Replace from fasthx.typing import JinjaContext...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🧰 Additional context used
🧬 Code Graph Analysis (4)
fasthx/htmy.py (2)
fasthx/typing.py (1)
RequestComponentSelector(53-84)fasthx/jinja.py (1)
_make_render_function(316-347)
tests/test_jinja.py (2)
fasthx/htmy.py (1)
ComponentHeader(24-30)fasthx/jinja.py (4)
ComponentHeader(218-224)Jinja(228-414)JinjaContext(49-215)JinjaPath(35-46)
fasthx/__init__.py (1)
fasthx/typing.py (1)
RequestComponentSelector(53-84)
examples/jinja-rendering/jinja_app.py (1)
fasthx/jinja.py (1)
Jinja(228-414)
🪛 LanguageTool
docs/examples/htmy.md
[grammar] ~105-~105: Ensure spelling is correct
Context: ...basic HTML document structure with some TailwindCSS styling and metadata. There is also a b...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
docs/migrations/2-to-3.md
[style] ~19-~19: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.typing import RenderFunction. - Replace from fasthx.typing import SyncHTMLRend...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~20-~20: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...hx.typing import SyncRenderFunction. - Replace from fasthx.typing import AsyncHTMLRen...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~28-~28: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...om fasthx.jinja import JinjaContext. - Replace from fasthx import JinjaPathwithfr...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~29-~29: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...from fasthx.jinja import JinjaPath. - Replace from fasthx import TemplateHeader wit...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~30-~30: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.jinja import ComponentHeader. - Replace from fasthx.jinja import TemplateHeade...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~31-~31: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.jinja import ComponentHeader. - Replace from fasthx import JinjaContextFactory...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~32-~32: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...hx.jinja import JinjaContextFactory. - Replace from fasthx.typing import JinjaContext...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🔇 Additional comments (35)
docs/index.md (1)
44-44: Grammar fix looks good
The sentence now reads fluently.pyproject.toml (1)
12-13: Runtime vs dev dependency drift
htmyis specified >=0.7.4 in runtime deps but still duplicated in[tool.poetry.group.dev.dependencies]. Duplication is fine, but ensure the spec stays identical to avoid confusion during upgrades.examples/jinja-rendering/jinja_app.py (1)
7-7: Import path update acknowledged
ImportingJinjafromfasthx.jinjamatches the new package structure.examples/custom-rendering/custom_rendering_app.py (1)
37-55: Good cleanup on removedtype: ignores
The code now type-checks without suppressions—nice!README.md (2)
44-44: Sentence is clear – no action requiredThe re-worded core-concept paragraph reads well and matches the new architecture.
100-106: Correct import path update looks goodSwitching to
fasthx.jinja.Jinjareflects the new package layout. No further changes needed here.docs/examples/jinja-templating.md (4)
5-5: Good update – matches the new public APIThe wording and import path (
fasthx.jinja.Jinja) align with the refactor.
10-10: Import line updated correctly
ComponentHeaderis now exposed fromfasthx.jinja; example compiles.
46-49: Nice addition explainingComponentHeaderClear explanation, consistent with the type rename.
58-66: Example code LGTMDecorator usage demonstrates the new selector API accurately.
tests/test_jinja.py (2)
10-10: LGTM: Import path updated correctly for Jinja refactoring.The import statement correctly reflects the relocation of Jinja-related code to the
fasthx.jinjapackage, which aligns with the PR's objective to modularize Jinja functionality.
53-53: LGTM: Consistent renaming of TemplateHeader to ComponentHeader.All instances of
TemplateHeaderhave been correctly updated toComponentHeaderthroughout the test decorators, maintaining consistency with the broader refactoring that renamed this class to better reflect its purpose in component selection.Also applies to: 69-69, 84-85, 103-104
mkdocs.yaml (2)
53-54: LGTM: Simplified navigation labels align with documentation restructuring.The simplification of navigation entries for
component_selectors.mdand the lowercase labeling ofhtmy.mdare consistent with the broader documentation consolidation approach mentioned in the AI summary.
59-59: LGTM: Essential migration guide added for v3 upgrade.The addition of
migrations/2-to-3.mdis crucial for users upgrading from v2 to v3, given the significant structural changes in this release including the Jinja module reorganization and type renaming.fasthx/__init__.py (1)
7-8: LGTM: Type imports updated to reflect v3 refactoring.The replacement of
HTMLRendererwithRenderFunctionand addition ofRequestComponentSelectorcorrectly align with the PR objectives to:
- Generalize rendering functions beyond HTML content
- Provide the protocol interface for component selection
- Remove deprecated type aliases while maintaining core functionality
The absence of Jinja-related imports is also appropriate, as they've been moved to the dedicated
fasthx.jinjapackage.docs/api/jinja.md (1)
1-4: LGTM: Documentation structure simplified to match module reorganization.The consolidation from multiple explicit sections to a single
fasthx.jinjadirective correctly reflects the new module structure where all Jinja-related functionality is grouped together. This approach is cleaner, more maintainable, and consistent with the broader documentation restructuring effort.fasthx/htmy.py (3)
12-12: LGTM: Import updated to use new RenderFunction type.The replacement of
HTMLRendererwithRenderFunctionin the import correctly aligns with the global type alias renaming to support more generalized rendering beyond HTML content.
26-26: LGTM: Comment updated to reference correct protocol.The comment correctly references
RequestComponentSelectorwhich is the appropriate protocol for component selection based on request headers.
200-200: LGTM: Return type annotations updated consistently.Both
_make_render_functionand_make_error_render_functionmethods have their return types correctly updated fromHTMLRenderertoRenderFunction, maintaining consistency with the global type alias renaming while preserving all functional behavior.Also applies to: 217-217
docs/examples/htmy.md (2)
26-36: LGTM! Function-based component factory is cleaner.The conversion from class-based
UserListItemto a simple function factoryuser_list_itemimproves code readability and reduces boilerplate. The function directly returns the HTML element without requiring instantiation.
108-132: LGTM! Page component refactoring is consistent.The
index_pagefunction factory follows the same pattern as the component refactoring, returning the HTML structure directly as a tuple. The route decorator correctly uses the function directly instead of wrapping it in a lambda.docs/migrations/2-to-3.md (1)
1-37: Comprehensive migration guide covers all major changes.The migration guide thoroughly documents all the breaking changes introduced in v3, providing clear upgrade paths for users. The organization into general, Jinja, and htmy sections makes it easy to follow.
fasthx/core_decorators.py (3)
10-10: LGTM! Type import updated consistently.The import change from
HTMLRenderertoRenderFunctionaligns with the v3 refactoring goals to support non-HTML rendering.
15-18: LGTM! Decorator signatures updated consistently.The type annotations in the
hxdecorator function signature correctly use the newRenderFunctiontype alias, maintaining the same functionality while supporting the broader rendering capabilities.
88-90: LGTM! Page decorator signature updated consistently.The
pagedecorator signature updates maintain consistency with thehxdecorator changes, usingRenderFunctioninstead ofHTMLRenderer.fasthx/typing.py (4)
11-11: LGTM! TypeAlias annotation added for clarity.Making
MaybeAsyncFuncexplicitly aTypeAliasimproves type clarity and follows best practices for type alias declarations.
14-27: LGTM! Protocol renamed and generalized appropriately.The rename from
SyncHTMLRenderertoSyncRenderFunctionwith updated docstring correctly reflects the broader scope of rendering beyond just HTML content.
48-49: LGTM! Union type alias updated consistently.The
RenderFunctiontype alias properly replacesHTMLRendererand maintains the same union of sync and async render functions while supporting the generalized naming convention.
87-88: LGTM! ComponentSelector docstring generalized.The updated docstring for
ComponentSelectorappropriately removes HTML-specific language to support broader component selection use cases.examples/htmy-rendering/htmy_app.py (3)
25-31: LGTM! Component factory function is cleaner.The conversion from
UserListItemclass touser_list_itemfunction factory eliminates unnecessary boilerplate and directly returns the HTML element. This aligns with the same refactoring pattern used in the documentation examples.
87-110: LGTM! Index page refactored consistently.The
index_pagefunction factory follows the same simplification pattern, returning the HTML structure directly as a tuple. The implementation maintains all original functionality while being more concise.
128-128: LGTM! Route decorator updated correctly.The route decorator now uses
index_pagedirectly instead of requiring a wrapper, which is cleaner and consistent with the function factory approach.fasthx/jinja.py (3)
1-12: Import changes align with the refactoring goals.The updated imports properly support the new architecture with the relocated
JinjaContextFactoryprotocol and renamed type annotations.
14-32: Well-structured protocol definition for Jinja context factories.The
JinjaContextFactoryprotocol is properly documented and its signature correctly matches the usage pattern throughout the codebase.
218-224: Clean implementation of the renamed component selector.The
ComponentHeaderclass properly inherits from the base_ComponentHeader[str]and maintains backward compatibility through clear documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (2)
README.md(5 hunks)docs/index.md(2 hunks)
🔇 Additional comments (1)
README.md (1)
106-112: Import path change looks correctMoving the import to
fasthx.jinjareflects the new package layout and removes the old top-level alias. No issues spotted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (1)
README.md (1)
153-160: Add missingRenderFunctionimport (repeat of earlier feedback)Example instructs readers to implement
RenderFunctionbut never shows where it comes from, which may confuse newcomers.-from fasthx import hx, page +from fasthx import hx, page +from fasthx.typing import RenderFunction # protocol used below
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (2)
README.md(5 hunks)docs/index.md(2 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md
[grammar] ~29-~29: There might be a mistake here.
Context: ... "Thank you for your work on htmy and fasthx, both have been very pleasant to use, an...
(QB_NEW_EN_OTHER)
[grammar] ~50-~50: Use correct spacing
Context: ...er using a declarative, decorator-based approach. Internally, FastHX decorators always hav...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~52-~52: Use correct spacing
Context: ...he rendering engine integration of your choice. The ComponentSelector abstraction make...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~106-~106: There might be a mistake here.
Context: ...you need to do is create an instance of fasthx.jinja.Jinja and use its hx() or page() methods...
(QB_NEW_EN_OTHER)
[grammar] ~106-~106: There might be a mistake here.
Context: ...ally renders HTML. See the example code below: python from fastapi import FastAPI from fastapi.templating import Jinja2Templates from fasthx.jinja import Jinja from pydantic import BaseModel # Pydantic model of the data the example API is using. class User(BaseModel): first_name: str last_name: str # Create the app. app = FastAPI() # Create a FastAPI Jinja2Templates instance and use it to create a # FastHX Jinja instance that will serve as your decorator. jinja = Jinja(Jinja2Templates("templates")) @app.get("/") @jinja.page("index.html") def index() -> None: ... @app.get("/user-list") @jinja.hx("user-list.html") async def htmx_or_data() -> list[User]: return [ User(first_name="John", last_name="Lennon"), User(first_name="Paul", last_name="McCartney"), User(first_name="George", last_name="Harrison"), User(first_name="Ringo", last_name="Starr"), ] @app.get("/admin-list") @jinja.hx("user-list.html", no_data=True) def htmx_only() -> list[User]: return [User(first_name="Billy", last_name="Shears")] ...
(QB_NEW_EN_OTHER)
[grammar] ~153-~153: Use correct spacing
Context: ...to do is implement the RenderFunction protocol. Similarly to the Jinja case, hx() only...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
🔇 Additional comments (2)
docs/index.md (1)
25-30: Consistent “Testimonials” heading looks goodThe rename from “Opinions” to “Testimonials” matches the docs style guide and keeps wording in sync with the README.
No further action needed.README.md (1)
106-112: Correct import path forJinja— LGTMSwitching the import to
from fasthx.jinja import Jinjaaccurately reflects the new package layout introduced in v3.
Example now compiles withoutImportError.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🔭 Outside diff range comments (2)
fasthx/htmy.py (2)
49-51: Typo in docstring“the there’s” → “there’s”.
- KeyError: If the there's no `Request` in the context. + KeyError: If there's no `Request` in the context.
200-215: Minor duplication: factor out component resolutionThe component resolution logic is duplicated in both render functions. Consider a small helper to DRY it up.
def _resolve_component( selector: HTMYComponentSelector[Any], request: Request, error: Exception | None, ) -> h.Component: chosen = selector.get_component(request, error) if isinstance(selector, RequestComponentSelector) else selector return chosenAnd then:
component = self._resolve_component(component_selector, request, None) # ... component = self._resolve_component(component_selector, request, result)Also applies to: 217-235
♻️ Duplicate comments (1)
README.md (1)
155-157: Clarify RenderFunction import in the “Custom templating” sectionThe text asks users to “implement the RenderFunction protocol,” but the example never shows where that comes from. Add an explicit import to prevent confusion.
Add after the other imports in the example:
from fasthx.typing import RenderFunction # for type checkersAlso, remove the double space after the period in “…protocol. Similarly…”.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (4)
README.md(5 hunks)docs/index.md(2 hunks)docs/migrations/2-to-3.md(1 hunks)fasthx/htmy.py(7 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
fasthx/htmy.py (2)
fasthx/typing.py (1)
RequestComponentSelector(53-84)fasthx/jinja.py (2)
render(334-345)_make_render_function(316-347)
🪛 LanguageTool
docs/migrations/2-to-3.md
[style] ~19-~19: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.typing import RenderFunction. - Replace from fasthx.typing import SyncHTMLRend...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~20-~20: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...hx.typing import SyncRenderFunction. - Replace from fasthx.typing import AsyncHTMLRen...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~28-~28: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...om fasthx.jinja import JinjaContext. - Replace from fasthx import JinjaPathwithfr...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~29-~29: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...from fasthx.jinja import JinjaPath. - Replace from fasthx import TemplateHeader wit...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~30-~30: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.jinja import ComponentHeader. - Replace from fasthx.jinja import TemplateHeade...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~31-~31: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.jinja import ComponentHeader. - Replace from fasthx import JinjaContextFactory...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~32-~32: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...hx.jinja import JinjaContextFactory. - Replace from fasthx.typing import JinjaContext...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
README.md
[grammar] ~31-~31: There might be a mistake here.
Context: ... "Thank you for your work on htmy and fasthx, both have been very pleasant to use, an...
(QB_NEW_EN_OTHER)
[grammar] ~52-~52: Use correct spacing
Context: ...er using a declarative, decorator-based approach. Internally, FastHX decorators always hav...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~54-~54: Use correct spacing
Context: ...he rendering engine integration of your choice. The ComponentSelector abstraction make...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~108-~108: There might be a mistake here.
Context: ...ally renders HTML. See the example code below: python from fastapi import FastAPI from fastapi.templating import Jinja2Templates from fasthx.jinja import Jinja from pydantic import BaseModel # Pydantic model of the data the example API is using. class User(BaseModel): first_name: str last_name: str # Create the app. app = FastAPI() # Create a FastAPI Jinja2Templates instance and use it to create a # FastHX Jinja instance that will serve as your decorator. jinja = Jinja(Jinja2Templates("templates")) @app.get("/") @jinja.page("index.html") def index() -> None: ... @app.get("/user-list") @jinja.hx("user-list.html") async def htmx_or_data() -> list[User]: return [ User(first_name="John", last_name="Lennon"), User(first_name="Paul", last_name="McCartney"), User(first_name="George", last_name="Harrison"), User(first_name="Ringo", last_name="Starr"), ] @app.get("/admin-list") @jinja.hx("user-list.html", no_data=True) def htmx_only() -> list[User]: return [User(first_name="Billy", last_name="Shears")] ...
(QB_NEW_EN_OTHER)
[grammar] ~155-~155: Use correct spacing
Context: ...to do is implement the RenderFunction protocol. Similarly to the Jinja case, hx() only...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
🔇 Additional comments (6)
docs/index.md (1)
25-32: Good rename to “Testimonials”This aligns with the docs tone elsewhere and addresses prior consistency feedback.
README.md (3)
25-32: Good addition of “Testimonials”Consistent with docs/index.md; improves social proof.
108-114: Jinja import path looks goodUsing “from fasthx.jinja import Jinja” reflects the new import location.
168-168: Nice touch on showing dependency values in render functionsGood example demonstrating that Depends results are available via the context.
fasthx/htmy.py (2)
115-116: Good: property rename torendererapplied consistentlyDocs, field, and call sites all updated (
self.renderer.render). Matches the v3 migration notes.Also applies to: 118-118, 198-199
200-215: No action needed:RequestComponentSelectoris runtime-checkable
Verified infasthx/typing.py(lines 52–53) thatRequestComponentSelectoris decorated with@runtime_checkable. Theisinstancecheck in_make_render_functionis safe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🔭 Outside diff range comments (2)
fasthx/htmy.py (2)
200-216: Variable naming nit:componentholds a factory, not a component.Renaming improves readability and avoids confusion between a component instance and its factory.
- async def render(result: T, *, context: dict[str, Any], request: Request) -> str: - component = ( + async def render(result: T, *, context: dict[str, Any], request: Request) -> str: + factory = ( component_selector.get_component(request, None) if isinstance(component_selector, RequestComponentSelector) else component_selector ) - return await self.renderer.render( - component(result), self._make_render_context(request, context) - ) + return await self.renderer.render( + factory(result), self._make_render_context(request, context) + )
219-235: Apply the same naming tweak in the error renderer.- async def render(result: Exception, *, context: dict[str, Any], request: Request) -> str: - component = ( + async def render(result: Exception, *, context: dict[str, Any], request: Request) -> str: + factory = ( component_selector.get_component(request, result) if isinstance(component_selector, RequestComponentSelector) else component_selector ) - return await self.renderer.render( - component(result), self._make_render_context(request, context) - ) + return await self.renderer.render( + factory(result), self._make_render_context(request, context) + )
♻️ Duplicate comments (3)
docs/migrations/2-to-3.md (3)
3-3: Fix minor grammar for clarity.Replace “among other, smaller improvements” with “among other smaller improvements”.
-`fasthx` was first developed with Jinja templating and HTML rendering in mind. The feature set of the project grew significantly since then, for example with error rendering support and `htmy` integration, among other, smaller improvements. +`fasthx` was first developed with Jinja templating and HTML rendering in mind. The feature set of the project grew significantly since then, for example with error rendering support and `htmy` integration, among other smaller improvements.
24-24: Correct modal verb usage (“only be imported”).-These are mostly import changes — all the Jinja-related utilities can now only imported from `fasthx.jinja` — and the renaming of `TemplateHeader` to `ComponentHeader`. +These are mostly import changes — all the Jinja-related utilities can now only be imported from `fasthx.jinja` — and the renaming of `TemplateHeader` to `ComponentHeader`.
33-33: Remove unnecessary comma for smoother reading.-- Instead of the `templates` argument of `TemplateHeader()`, you must use the `components` argument of `ComponentHeader`, if you passed `templates` as a keyword argument. +- Instead of the `templates` argument of `TemplateHeader()`, you must use the `components` argument of `ComponentHeader` if you passed `templates` as a keyword argument.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (2)
docs/migrations/2-to-3.md(1 hunks)fasthx/htmy.py(8 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
fasthx/htmy.py (2)
fasthx/typing.py (1)
RequestComponentSelector(53-84)fasthx/jinja.py (2)
render(334-345)_make_render_function(316-347)
🪛 LanguageTool
docs/migrations/2-to-3.md
[grammar] ~1-~1: Use correct spacing
Context: # From v2 to v3 fasthx was first developed with Jinja templati...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~3-~3: There might be a problem here.
Context: ...ndering in mind. The feature set of the project grew significantly since then, for example w...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~3-~3: Use correct spacing
Context: ...htmy` integration, among other, smaller improvements. More features and integrations are plann...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~5-~5: Use correct spacing
Context: ...is to prepare the project structure for them. Summary of major changes: - All Jinja-r...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~7-~7: There might be a mistake here.
Context: ...t structure for them. Summary of major changes: - All Jinja-related code now lives in `fa...
(QB_NEW_EN_OTHER)
[grammar] ~10-~10: Use correct spacing
Context: ...ted from that package. - *HTMLRenderer types have been renamed to *RenderFunction ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~11-~11: Use correct spacing
Context: ... Updated the required htmy version to >=0.7.4. ## Upgrade steps (general) These are all t...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~13-~13: Use correct spacing
Context: ...version to >=0.7.4. ## Upgrade steps (general) These are all typing-related changes and...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~15-~15: Use correct spacing
Context: ...have created custom render functions or integrations. - Replace `from fasthx import HTMLRenderer...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[style] ~19-~19: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.typing import RenderFunction. - Replace from fasthx.typing import SyncHTMLRend...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~20-~20: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...hx.typing import SyncRenderFunction. - Replace from fasthx.typing import AsyncHTMLRen...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[grammar] ~20-~20: Use correct spacing
Context: ...x.typing import AsyncHTMLRendererwithfrom fasthx.typing import AsyncRenderFunction`. ## Upgrade steps (Jinja) These are mostly ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~22-~22: Use correct spacing
Context: ...AsyncRenderFunction`. ## Upgrade steps (Jinja) These are mostly import changes — all th...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~24-~24: There might be a mistake here.
Context: ... steps (Jinja) These are mostly import changes — all the Jinja-related utilities can now ...
(QB_NEW_EN_OTHER)
[grammar] ~24-~24: Use modal and auxiliary verbs correctly
Context: ...all the Jinja-related utilities can now only imported from fasthx.jinja — and the ...
(QB_NEW_EN_OTHER_ERROR_IDS_24)
[grammar] ~24-~24: There might be a mistake here.
Context: ...ed utilities can now only imported from fasthx.jinja — and the renaming of TemplateHeader...
(QB_NEW_EN_OTHER)
[grammar] ~24-~24: Use correct spacing
Context: ...and the renaming of TemplateHeader to ComponentHeader. - Replace from fasthx import Jinja with ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[style] ~28-~28: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...om fasthx.jinja import JinjaContext. - Replace from fasthx import JinjaPathwithfr...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~29-~29: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...from fasthx.jinja import JinjaPath. - Replace from fasthx import TemplateHeader wit...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~30-~30: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.jinja import ComponentHeader. - Replace from fasthx.jinja import TemplateHeade...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~31-~31: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.jinja import ComponentHeader. - Replace from fasthx import JinjaContextFactory...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~32-~32: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...hx.jinja import JinjaContextFactory. - Replace from fasthx.typing import JinjaContext...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[grammar] ~33-~33: There might be a mistake here.
Context: ...u must use the components argument of ComponentHeader, if you passed templates as a keyword...
(QB_NEW_EN_OTHER)
[grammar] ~33-~33: Use correct spacing
Context: ... if you passed templates as a keyword argument. ## Upgrade steps (htmy) - Make sure you'...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~35-~35: Use correct spacing
Context: ...s a keyword argument. ## Upgrade steps (htmy) - Make sure you're using htmy version `>...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~38-~38: There might be a mistake here.
Context: ...HTMY instance no longer has an htmy property, it is replaced by the renderer proper...
(QB_NEW_EN_OTHER)
🔇 Additional comments (3)
fasthx/htmy.py (3)
12-12: Import/type updates align with v3 API (HTMLRenderer → RenderFunction).The switch to RenderFunction/MaybeAsyncFunc/P/T is consistent with the broader refactor.
198-199: Render delegation updated toself.renderer— good.Directly rendering with the injected/default renderer maintains behavior while matching the new API.
118-119: No stale.htmyproperty references remain — rename torendereris safe
I’ve searched for any.htmyattribute usage and only found module imports (from fasthx.htmy import …) and documentation mentions, which are expected. There are no remaining.htmyproperty references in code or docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🔭 Outside diff range comments (1)
pyproject.toml (1)
33-35: Build backend explicitly set to poetry-core — good.This improves build reproducibility. Optionally set a minimal version if you rely on newer features, e.g., requires = ["poetry-core>=1.8.0"].
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (1)
pyproject.toml(2 hunks)
🔇 Additional comments (3)
pyproject.toml (3)
3-3: SemVer major bump to 3.0.0 looks appropriate.Aligns with breaking API changes in v3 (Jinja relocation, type renames). No concerns.
23-31: Dev docs/tooling bumps: verify compatibility (mkdocs-material, mkdocstrings, ruff, mypy).These are sizable version jumps. mkdocstrings 0.30 introduced some changes around handlers/config; ruff config keys also evolved across 0.11→0.12 (you’ve already moved to lint.select which is correct). Suggest running a strict docs build and lint pass locally/CI.
Run locally:
- mkdocs build --strict
- poe static-checks
- poe test
If anything fails, I can help generate targeted config changes.
69-79: Ignore the Poe sequence configuration concern – it’s valid as isThe dotted assignments for
static-checks.sequenceandstatic-checks.ignore_fail = "return_non_zero"are both supported by TOML and PoeThePoet (v0.36.0). No changes needed here.Likely an incorrect or invalid review comment.
in the HTMY instance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🔭 Outside diff range comments (1)
fasthx/htmy.py (1)
64-66: Typo in docstring: getitem_ has an extra underscore.Minor doc fix to reference the correct dunder method.
- `__contains__`, `__getitem___()`, and `get()`. For more complex use-cases, you can rely on the + `__contains__`, `__getitem__()`, and `get()`. For more complex use-cases, you can rely on the
♻️ Duplicate comments (2)
docs/migrations/2-to-3.md (1)
3-3: Minor grammar and clarity nits in the migration guide.Applies small fixes for readability and consistency.
-`fasthx` was first developed with Jinja templating and HTML rendering in mind. The feature set of the project grew significantly since then, for example with error rendering support and `htmy` integration, among other, smaller improvements. +`fasthx` was first developed with Jinja templating and HTML rendering in mind. The feature set of the project grew significantly since then, for example with error rendering support and `htmy` integration, among other smaller improvements.-These are mostly import changes — all the Jinja-related utilities can now only imported from `fasthx.jinja` — and the renaming of `TemplateHeader` to `ComponentHeader`. +These are mostly import changes — all the Jinja-related utilities can now only be imported from `fasthx.jinja` — and the renaming of `TemplateHeader` to `ComponentHeader`.-- Instead of the `templates` argument of `TemplateHeader()`, you must use the `components` argument of `ComponentHeader`, if you passed `templates` as a keyword argument. +- Instead of the `templates` argument of `TemplateHeader()`, you must use the `components` argument of `ComponentHeader`, if you passed `templates` as a keyword argument.Also applies to: 24-24, 33-33
fasthx/htmy.py (1)
26-28: Docstring phrasing nit (make the sentence read naturally).Tighten the wording.
- `RequestComponentSelector` for HTMY components that selects the rendered component - based on a request header. + A `RequestComponentSelector` for HTMY components that selects the component to render + based on a request header.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (3)
docs/migrations/2-to-3.md(1 hunks)fasthx/htmy.py(8 hunks)pyproject.toml(2 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/migrations/2-to-3.md
[style] ~19-~19: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.typing import RenderFunction. - Replace from fasthx.typing import SyncHTMLRend...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~20-~20: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...hx.typing import SyncRenderFunction. - Replace from fasthx.typing import AsyncHTMLRen...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~28-~28: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...om fasthx.jinja import JinjaContext. - Replace from fasthx import JinjaPathwithfr...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~29-~29: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...from fasthx.jinja import JinjaPath. - Replace from fasthx import TemplateHeader wit...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~30-~30: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.jinja import ComponentHeader. - Replace from fasthx.jinja import TemplateHeade...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~31-~31: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.jinja import ComponentHeader. - Replace from fasthx import JinjaContextFactory...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~32-~32: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...hx.jinja import JinjaContextFactory. - Replace from fasthx.typing import JinjaContext...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🔇 Additional comments (3)
fasthx/htmy.py (3)
198-199: LGTM: Consistent switch to self.renderer for normal render path.Using self.renderer.render and returning a RenderFunction[T] aligns with the v3 refactor and the new typing.
Also applies to: 200-216
219-233: LGTM: Consistent switch to self.renderer for error render path.Error renderer now also uses self.renderer and the RenderFunction[Exception] return type. Looks correct.
115-116: RendererType annotation confirmed
htmy 0.8.1+ does export a public type aliasRendererTypefor its renderer call-signature. Usingrenderer: RendererType = field(default_factory=Renderer)in
fasthx/htmy.py(lines 115–116 and 118–119) is correct—just ensure you import it viafrom htmy import RendererTypeand no fallback to
Rendereras an annotation is needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🔭 Outside diff range comments (5)
fasthx/core_decorators.py (2)
101-101: Fix page() wrapper return annotationThe wrapper always returns a Response (either HTMLResponse or a Response returned by the route). The current annotation suggests it might return T, which it never does.
- ) -> T | Response: + ) -> Response:
119-130: Align page() with the str-only RenderFunction contractWith RenderFunction required to return str, the else branch returning “rendered” is dead code. Simplify and always wrap in HTMLResponse, like hx().
- return ( - HTMLResponse( - rendered, - # The default status code of the FastAPI Response dependency is None - # (not allowed by the typing but required for FastAPI). - status_code=getattr(response, "status_code", 200) or 200, - headers=getattr(response, "headers", None), - background=getattr(response, "background", None), - ) - if isinstance(rendered, str) - else rendered - ) + return HTMLResponse( + rendered, + # The default status code of the FastAPI Response dependency is None + # (not allowed by the typing but required for FastAPI). + status_code=getattr(response, "status_code", 200) or 200, + headers=getattr(response, "headers", None), + background=getattr(response, "background", None), + )fasthx/jinja.py (3)
78-81: Avoid treating str/bytes as generic Collections in unpack_object()str and bytes are Collections and will currently be wrapped as {"items": obj}, which is surprising. Exclude them from the “Collection” branch.
- # Covers lists, tuples, sets, etc.. - if isinstance(obj, Collection): + # Covers lists, tuples, sets, etc.; exclude str/bytes-like. + if isinstance(obj, Collection) and not isinstance(obj, (str, bytes, bytearray)): return {"items": obj}
88-96: Avoid shadowing cls; minor grammar fix
- Renaming the local cls variable prevents shadowing the classmethod parameter cls, improving readability.
- Typo: “with with slots”.
- cls = type(obj) - if hasattr(cls, "model_computed_fields"): # Pydantic computed fields support. + obj_cls = type(obj) + if hasattr(obj_cls, "model_computed_fields"): # Pydantic computed fields support. object_keys = [ *(() if object_keys is None else object_keys), - *cls.model_computed_fields, + *obj_cls.model_computed_fields, ] elif hasattr(obj, "__slots__"): - # Covers classes with with __slots__. + # Covers classes with __slots__. object_keys = obj.__slots__
194-194: Typo in docstring“whih” → “which”.
- context_key: The key by whih the `route_context` should be accessible in templates. + context_key: The key by which the `route_context` should be accessible in templates.
♻️ Duplicate comments (3)
docs/migrations/2-to-3.md (3)
3-3: Fix verb tense and comma usage in the intro“grew significantly since then” should be present perfect, and the comma before “smaller improvements” is unnecessary.
-`fasthx` was first developed with Jinja templating and HTML rendering in mind. The feature set of the project grew significantly since then, for example with error rendering support and `htmy` integration, among other, smaller improvements. +`fasthx` was first developed with Jinja templating and HTML rendering in mind. The project's feature set has grown significantly since then, for example with error rendering support and `htmy` integration, among other smaller improvements.
25-25: Grammar: missing “be”“…can now only imported…” → “…can now only be imported…”.
-These are mostly import changes — all the Jinja-related utilities can now only imported from `fasthx.jinja` — and the renaming of `TemplateHeader` to `ComponentHeader`. +These are mostly import changes — all the Jinja-related utilities can now only be imported from `fasthx.jinja` — and the renaming of `TemplateHeader` to `ComponentHeader`.
34-34: Minor clarity and commaAdd “of” after “argument” and drop the comma before the conditional clause.
-- Instead of the `templates` argument of `TemplateHeader()`, you must use the `components` argument of `ComponentHeader`, if you passed `templates` as a keyword argument. +- Instead of the `templates` argument of `TemplateHeader()`, you must use the `components` argument of `ComponentHeader` if you passed `templates` as a keyword argument.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (4)
docs/migrations/2-to-3.md(1 hunks)fasthx/core_decorators.py(3 hunks)fasthx/jinja.py(4 hunks)fasthx/typing.py(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
fasthx/jinja.py (4)
fasthx/htmy.py (5)
ComponentHeader(24-30)hx(135-156)page(158-178)render(205-213)render(224-232)fasthx/core_decorators.py (2)
hx(14-80)page(83-141)fasthx/typing.py (1)
RequestComponentSelector(51-82)tests/test_jinja.py (1)
error(93-98)
🪛 LanguageTool
docs/migrations/2-to-3.md
[grammar] ~1-~1: Use correct spacing
Context: # From v2 to v3 fasthx was first developed with Jinja templati...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~3-~3: Use the right verb tense
Context: ...in mind. The feature set of the project grew significantly since then, for example w...
(QB_NEW_EN_OTHER_ERROR_IDS_13)
[grammar] ~3-~3: Use correct spacing
Context: ...tion, among other, smaller improvements. More features and integrations are plann...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~5-~5: Use correct spacing
Context: ... prepare the project structure for them. Summary of major changes: - All Jinja-r...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~7-~7: Use correct spacing
Context: ...ure for them. Summary of major changes: - All Jinja-related code now lives in `fas...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~10-~10: Use correct spacing
Context: ...ted from that package. - *HTMLRenderer types have been renamed to `*RenderFunct...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~10-~10: There might be a mistake here.
Context: ... prepare for rendering non-HTML content. - The RenderFunction type has changed, `...
(QB_NEW_EN)
[grammar] ~11-~11: There might be a mistake here.
Context: ...ontent. - The RenderFunction type has changed, Response is no longer allowed as the ...
(QB_NEW_EN_OTHER)
[grammar] ~11-~11: There might be a mistake here.
Context: ...s no longer allowed as the return value. - Updated the required htmy version to `...
(QB_NEW_EN)
[grammar] ~12-~12: Use correct spacing
Context: ...he required htmy version to >=0.8.1. ## Upgrade steps (general) These are all t...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~14-~14: Use correct spacing
Context: ...o >=0.8.1. ## Upgrade steps (general) These are all typing-related changes and...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~16-~16: Use correct spacing
Context: ...custom render functions or integrations. - Replace `from fasthx import HTMLRenderer...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[style] ~20-~20: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.typing import RenderFunction. - Replace from fasthx.typing import SyncHTMLRend...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~21-~21: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...hx.typing import SyncRenderFunction. - Replace from fasthx.typing import AsyncHTMLRen...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[grammar] ~21-~21: Use correct spacing
Context: ...sthx.typing import AsyncRenderFunction`. ## Upgrade steps (Jinja) These are mostly ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~23-~23: Use correct spacing
Context: ...nderFunction`. ## Upgrade steps (Jinja) These are mostly import changes — all th...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~25-~25: There might be a mistake here.
Context: ... steps (Jinja) These are mostly import changes — all the Jinja-related utilities can now onl...
(QB_NEW_EN_OTHER)
[grammar] ~25-~25: Use modal and auxiliary verbs correctly
Context: ...all the Jinja-related utilities can now only imported from fasthx.jinja — and the ...
(QB_NEW_EN_OTHER_ERROR_IDS_24)
[grammar] ~25-~25: There might be a mistake here.
Context: ...ed utilities can now only imported from fasthx.jinja — and the renaming of TemplateHeader to `Co...
(QB_NEW_EN)
[grammar] ~25-~25: Use correct spacing
Context: ...f TemplateHeader to ComponentHeader. - Replace from fasthx import Jinja with ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[style] ~29-~29: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...om fasthx.jinja import JinjaContext. - Replace from fasthx import JinjaPathwithfr...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~30-~30: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...from fasthx.jinja import JinjaPath. - Replace from fasthx import TemplateHeader wit...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~31-~31: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.jinja import ComponentHeader. - Replace from fasthx.jinja import TemplateHeade...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~32-~32: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.jinja import ComponentHeader. - Replace from fasthx import JinjaContextFactory...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~33-~33: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...hx.jinja import JinjaContextFactory. - Replace from fasthx.typing import JinjaContext...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[grammar] ~34-~34: Use commas correctly
Context: ...omponentsargument ofComponentHeader, if you passed templates` as a keyword ...
(QB_NEW_EN_OTHER_ERROR_IDS_33)
[grammar] ~34-~34: There might be a problem here.
Context: ...assed templates as a keyword argument. - Jinja._make_response() has been removed to simplify the codebas...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~35-~35: Use correct spacing
Context: ...Jinja._make_render_function() instead. ## Upgrade steps (htmy) - Make sure you'...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~37-~37: Use correct spacing
Context: ...n() instead. ## Upgrade steps (htmy) - Make sure you're using htmyversion>...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~40-~40: Use correct spacing
Context: ...een replaced by the renderer property. ## Upgrade steps (custom rendering) - `Ren...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~43-~43: There might be a problem here.
Context: ...y. ## Upgrade steps (custom rendering) - RenderFunction must return a str, Response is no lo...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~45-~45: There might be a mistake here.
Context: ...ring) - RenderFunction must return a str, Response is no longer allowed.
(QB_NEW_EN_OTHER)
[grammar] ~45-~45: There might be a mistake here.
Context: ... str, Response is no longer allowed.
(QB_NEW_EN)
🪛 markdownlint-cli2 (0.17.2)
docs/migrations/2-to-3.md
42-42: Multiple consecutive blank lines
Expected: 1; Actual: 2
(MD012, no-multiple-blanks)
🔇 Additional comments (2)
fasthx/typing.py (1)
14-18: Rename to RenderFunction and str-only contracts look correctThe type and protocol renames are consistent with the v3 migration. Enforcing str return type for renderers aligns with the updated decorators.
Also applies to: 30-33, 46-47
fasthx/core_decorators.py (1)
62-69: Good: hx now consistently returns HTMLResponse for rendered stringsWrapping the rendered content in HTMLResponse ensures consistent response semantics and aligns with the new str-only renderer contract.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (3)
docs/migrations/2-to-3.md (3)
3-3: Fix tense and punctuation for readabilityUse present perfect with “since then” and remove the unnecessary comma.
-`fasthx` was first developed with Jinja templating and HTML rendering in mind. The feature set of the project grew significantly since then, for example with error rendering support and `htmy` integration, among other, smaller improvements. +`fasthx` was first developed with Jinja templating and HTML rendering in mind. The feature set has grown significantly since then—for example, with error rendering support and `htmy` integration—among other smaller improvements.
25-25: Grammar: insert missing auxiliary verb“can now only imported” → “can now only be imported.”
-These are mostly import changes — all the Jinja-related utilities can now only imported from `fasthx.jinja` — and the renaming of `TemplateHeader` to `ComponentHeader`. +These are mostly import changes — all the Jinja-related utilities can now only be imported from `fasthx.jinja` — and the renaming of `TemplateHeader` to `ComponentHeader`.
44-44: Avoid comma splice in list itemUse a semicolon for two independent clauses.
-`RenderFunction` must return a `str`, `Response` is no longer allowed. +`RenderFunction` must return a `str`; `Response` is no longer allowed.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (1)
docs/migrations/2-to-3.md(1 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/migrations/2-to-3.md
[grammar] ~1-~1: Use correct spacing
Context: # From v2 to v3 fasthx was first developed with Jinja templati...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~3-~3: Use the right verb tense
Context: ...in mind. The feature set of the project grew significantly since then, for example w...
(QB_NEW_EN_OTHER_ERROR_IDS_13)
[grammar] ~3-~3: Use correct spacing
Context: ...tion, among other, smaller improvements. More features and integrations are plann...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~5-~5: Use correct spacing
Context: ... prepare the project structure for them. Summary of major changes: - All Jinja-r...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~7-~7: Use correct spacing
Context: ...ure for them. Summary of major changes: - All Jinja-related code now lives in `fas...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~10-~10: Use correct spacing
Context: ...ted from that package. - *HTMLRenderer types have been renamed to `*RenderFunct...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~10-~10: There might be a mistake here.
Context: ... prepare for rendering non-HTML content. - The RenderFunction type has changed: `...
(QB_NEW_EN)
[grammar] ~12-~12: Use correct spacing
Context: ...he required htmy version to >=0.8.1. ## Upgrade steps (general) These are all t...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~14-~14: Use correct spacing
Context: ...o >=0.8.1. ## Upgrade steps (general) These are all typing-related changes and...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~16-~16: Use correct spacing
Context: ...custom render functions or integrations. - Replace `from fasthx import HTMLRenderer...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[style] ~20-~20: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.typing import RenderFunction. - Replace from fasthx.typing import SyncHTMLRend...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~21-~21: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...hx.typing import SyncRenderFunction. - Replace from fasthx.typing import AsyncHTMLRen...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[grammar] ~21-~21: Use correct spacing
Context: ...sthx.typing import AsyncRenderFunction`. ## Upgrade steps (Jinja) These are mostly ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~23-~23: Use correct spacing
Context: ...nderFunction`. ## Upgrade steps (Jinja) These are mostly import changes — all th...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~25-~25: There might be a mistake here.
Context: ... steps (Jinja) These are mostly import changes — all the Jinja-related utilities can now onl...
(QB_NEW_EN_OTHER)
[grammar] ~25-~25: Use modal and auxiliary verbs correctly
Context: ...all the Jinja-related utilities can now only imported from fasthx.jinja — and the ...
(QB_NEW_EN_OTHER_ERROR_IDS_24)
[grammar] ~25-~25: There might be a mistake here.
Context: ...ed utilities can now only imported from fasthx.jinja — and the renaming of TemplateHeader to `Co...
(QB_NEW_EN)
[grammar] ~25-~25: Use correct spacing
Context: ...f TemplateHeader to ComponentHeader. - Replace from fasthx import Jinja with ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[style] ~29-~29: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...om fasthx.jinja import JinjaContext. - Replace from fasthx import JinjaPathwithfr...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~30-~30: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...from fasthx.jinja import JinjaPath. - Replace from fasthx import TemplateHeader wit...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~31-~31: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.jinja import ComponentHeader. - Replace from fasthx.jinja import TemplateHeade...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~32-~32: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...fasthx.jinja import ComponentHeader. - Replace from fasthx import JinjaContextFactory...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~33-~33: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...hx.jinja import JinjaContextFactory. - Replace from fasthx.typing import JinjaContext...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[grammar] ~34-~34: Use commas correctly
Context: ...omponentsargument ofComponentHeader, if you passed templates` as a keyword ...
(QB_NEW_EN_OTHER_ERROR_IDS_33)
[grammar] ~34-~34: There might be a problem here.
Context: ...assed templates as a keyword argument. - Jinja._make_response() has been removed to simplify the codebas...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~35-~35: Use correct spacing
Context: ...Jinja._make_render_function() instead. ## Upgrade steps (htmy) - Make sure you'...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~37-~37: Use correct spacing
Context: ...n() instead. ## Upgrade steps (htmy) - Make sure you're using htmyversion>...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~40-~40: Use correct spacing
Context: ...een replaced by the renderer property. ## Upgrade steps (custom rendering) - `Ren...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~42-~42: There might be a problem here.
Context: ...ty. ## Upgrade steps (custom rendering) - RenderFunction must return a str, Response is no lo...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~44-~44: There might be a mistake here.
Context: ...ring) - RenderFunction must return a str, Response is no longer allowed.
(QB_NEW_EN_OTHER)
[grammar] ~44-~44: There might be a mistake here.
Context: ... str, Response is no longer allowed.
(QB_NEW_EN)
🔇 Additional comments (3)
docs/migrations/2-to-3.md (3)
11-12: LGTM on summary bulletsComma splice has been resolved with a colon, and the
htmyversion aligns with the project pin (>=0.8.1).
39-40: LGTM on htmy migration notesThe version requirement and the property rename are clear and consistent; the semicolon avoids a comma splice.
18-33: No leftover v2 references found — no action requiredRan the provided ripgrep checks (excluding docs/migrations/2-to-3.md). There were no matches for HTMLRenderer / SyncHTMLRenderer / AsyncHTMLRenderer, Jinja root imports (Jinja, JinjaContext, JinjaPath, TemplateHeader), JinjaContextFactory outside fasthx.jinja, Jinja._make_response, or .htmy. Migration doc is accurate and no code changes are needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (1)
fasthx/core_decorators.py(5 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
fasthx/core_decorators.py (3)
fasthx/utils.py (3)
append_to_signature(12-32)execute_maybe_sync_func(35-48)get_response(51-62)fasthx/jinja.py (2)
hx(248-282)render(334-346)fasthx/htmy.py (3)
hx(135-156)render(205-213)render(224-232)
🔇 Additional comments (4)
fasthx/core_decorators.py (4)
15-19: hx() signature change to RenderFunction is correct and consistent.
Generic param usage and the render_error shape look good. No concerns with the public API surface here.
84-86: page() signature change to RenderFunction is correct and consistent.
Matches the v3 rename and the usage pattern elsewhere. Looks good.
101-101: Return annotation to Response is appropriate.
Matches the new unconditional HTMLResponse wrapping behavior.
10-10: No leftover HTMLRenderer usages in code; only migration docs reference it.Repo-wide search found only:
- docs/migrations/2-to-3.md — lines 10 and 18–21 mention
HTMLRenderer(migration notes).No code files or imports reference
HTMLRenderer, so no changes required in the codebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting
📒 Files selected for processing (5)
docs/migrations/1-to-2.md(1 hunks)docs/migrations/2-to-3.md(1 hunks)fasthx/htmy.py(12 hunks)fasthx/jinja.py(5 hunks)tests/test_htmy.py(2 hunks)
🧰 Additional context used
🪛 GitHub Actions: Linters
tests/test_htmy.py
[error] 80-80: Mypy: Argument 1 has incompatible type "Callable[[], HelloWorld]"; expected "Callable[[], Never] | Callable[[], Coroutine[Any, Any, Never]]".
[error] 85-85: Mypy: Argument 1 has incompatible type "Callable[[], HelloWorld]"; expected "Callable[[], Never] | Callable[[], Coroutine[Any, Any, Never]]".
🔇 Additional comments (10)
docs/migrations/1-to-2.md (1)
1-1: Heading tweak aligns with migration doc namingThe revised title matches the action-oriented style you’re adopting for the migration guides. 👍
docs/migrations/2-to-3.md (3)
3-3: Remove the extra comma in the intro sentenceDrop the comma after “other” to keep the flow natural.
-`fasthx` was first developed with Jinja templating and HTML rendering in mind. The feature set of the project grew significantly since then, for example with error rendering support and `htmy` integration, among other, smaller improvements. +`fasthx` was first developed with Jinja templating and HTML rendering in mind. The feature set of the project grew significantly since then, for example with error rendering support and `htmy` integration, among other smaller improvements.
25-25: Fix the missing verb in the import sentenceAdd “be” so the sentence reads correctly.
-These are mostly import changes — all the Jinja-related utilities can now only imported from `fasthx.jinja` — and the renaming of `TemplateHeader` to `ComponentHeader`. +These are mostly import changes — all the Jinja-related utilities can now only be imported from `fasthx.jinja` — and the renaming of `TemplateHeader` to `ComponentHeader`.
34-34: Tighten the TemplateHeader/ComponentHeader instructionUse “argument to” and drop the extra comma to smooth out the sentence.
-Instead of the `templates` argument of `TemplateHeader()`, you must use the `components` argument of `ComponentHeader`, if you passed `templates` as a keyword argument. +Instead of the `templates` argument to `TemplateHeader()`, use the `components` argument to `ComponentHeader` if you passed `templates` as a keyword argument.fasthx/jinja.py (1)
341-347: LGTM! Previous TemplateResponse API concern has been resolved.The code correctly passes
requestas a keyword argument toTemplateResponse, which is the proper API usage for FastAPI's Jinja2Templates.tests/test_htmy.py (1)
197-198: Test coverage looks good for the new no-selector endpoints.The test cases properly validate that both
/hx-no-selectorand/page-no-selectorendpoints return the expected "Hello World!" response for HTMX requests.fasthx/htmy.py (4)
118-119: Good API rename fromhtmytorenderer.The rename from
htmyfield torendereris more descriptive and aligns well with the broader refactoring to support non-HTML rendering in the future.
137-147: Excellent addition of optional component_selector parameter.Making
component_selectoroptional with a sensible default (_default_component_selector) provides a cleaner API for simple use cases where routes directly return components.
266-274: Clear documentation for the default component selector.The
_default_component_selectorfunction is well-documented with clear assumptions about its usage. The identity function pattern is appropriate for this use case.
206-241: Consistent renderer usage throughout the codebase.All references to
self.htmy.renderhave been properly updated toself.renderer.render, maintaining consistency with the API rename.
Summary of changes:
fasthx.jinjaand can only be imported from that package, and not directly fromfasthx. See V3 plan #45 for details*HTMLRenderertypes to*RenderFunctionto prepare for non-HTML rendering. See Support non-HTML responses #44htmyversion (if used withhtmy).Summary by CodeRabbit
New Features
Refactor
Bug Fixes
Chores
Documentation
Tests