Skip to content

Commit 7c125dc

Browse files
authored
Merge pull request #50 from volfpeter/fix/multiple-actions-with-same-path-diff-method
Fix: allow multiple actions with same path but different method
2 parents f9fc45b + 7cb1579 commit 7c125dc

File tree

13 files changed

+107
-59
lines changed

13 files changed

+107
-59
lines changed

.github/workflows/build-docs.yml

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,28 @@
11
name: Build documentation
2-
32
on:
43
push:
54
branches:
65
- main
7-
86
permissions:
9-
contents: write
10-
7+
contents: read
8+
pages: write
9+
id-token: write
1110
jobs:
1211
deploy:
12+
environment:
13+
name: github-pages
14+
url: ${{ steps.deployment.outputs.page_url }}
1315
runs-on: ubuntu-latest
1416
steps:
15-
- name: Checkout repository
16-
uses: actions/checkout@v5
17-
18-
- name: Setup Python
19-
uses: actions/setup-python@v6
17+
- uses: actions/checkout@v5
18+
- uses: actions/configure-pages@v5
19+
- uses: actions/setup-python@v5
2020
with:
21-
python-version-file: pyproject.toml
22-
23-
- run: pip install mkdocs-material mkdocstrings[python]
24-
25-
- uses: actions/cache@v4
21+
python-version: 3.x
22+
- run: pip install zensical mkdocstrings[python]
23+
- run: zensical build --clean
24+
- uses: actions/upload-pages-artifact@v4
2625
with:
27-
key: ${{ github.ref }}
28-
path: .cache
29-
30-
- run: mkdocs gh-deploy --force
26+
path: site
27+
- uses: actions/deploy-pages@v4
28+
id: deployment

.github/workflows/linters.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ jobs:
1717
uses: actions/checkout@v5
1818

1919
- name: Install the latest version of uv
20-
uses: astral-sh/setup-uv@v6
20+
uses: astral-sh/setup-uv@v7
2121
with:
22-
enable-cache: true
22+
enable-cache: true
2323

2424
- name: Setup Python
2525
uses: actions/setup-python@v6

.github/workflows/publish.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ jobs:
1717
uses: actions/checkout@v5
1818

1919
- name: Install the latest version of uv
20-
uses: astral-sh/setup-uv@v6
20+
uses: astral-sh/setup-uv@v7
2121
with:
22-
enable-cache: true
22+
enable-cache: true
2323

2424
- name: Setup Python
2525
uses: actions/setup-python@v6

.github/workflows/tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ jobs:
1717
uses: actions/checkout@v5
1818

1919
- name: Install the latest version of uv
20-
uses: astral-sh/setup-uv@v6
20+
uses: astral-sh/setup-uv@v7
2121
with:
22-
enable-cache: true
22+
enable-cache: true
2323

2424
- name: Setup Python
2525
uses: actions/setup-python@v6

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,10 @@ uv.lock
2222

2323
dist/
2424

25+
# Docs
26+
27+
site/
28+
29+
# Place for local dev stuff
30+
2531
dev/

holm/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "0.8.0"
1+
__version__ = "0.8.1"
22

33
from .app import App as App
44
from .fastapi import FastAPIDependency as FastAPIDependency

holm/app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def _build_api(
135135

136136
# -- Register actions from every action owner.
137137
for actions in (a for a in (get_actions(page_module), get_actions(actions_module)) if a):
138-
for action_path, desc in actions.items():
138+
for action_key, desc in actions.items():
139139
if desc.use_layout or (desc.metadata is not None):
140140
# Use _make_page_path_operation() if the action requires the layout or has
141141
# metadata. If one is missing, the overhead is minimal, but the code is
@@ -150,7 +150,7 @@ def _build_api(
150150
# No layout or metadata. Use the most efficient route registration.
151151
route = htmy.page()(desc.action)
152152

153-
api.api_route(action_path, **desc.route_args)(route)
153+
api.api_route(action_key[0], **desc.route_args)(route)
154154

155155
for sub_url, child_node in node.subtree.items():
156156
api.include_router(

holm/module_options/_actions.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import sys
2-
from collections.abc import Callable, Collection, Sequence
2+
from collections.abc import Callable, Sequence
33
from dataclasses import dataclass
44
from enum import Enum
55
from typing import Any, Literal, TypeAlias, TypeGuard
@@ -41,16 +41,17 @@ class ActionDescriptor:
4141
"""
4242

4343

44-
ActionDescriptors: TypeAlias = dict[str, ActionDescriptor]
44+
HTTPMethod: TypeAlias = Literal["GET", "POST", "PUT", "PATCH", "DELETE"]
45+
46+
47+
ActionDescriptors: TypeAlias = dict[tuple[str, HTTPMethod], ActionDescriptor]
4548
"""
4649
Typing for the value of `_actions_variable`.
4750
48-
Dictionary that maps action paths to action descriptors. This allows
51+
Dictionary that maps action path-method pairs to action descriptors. This allows
4952
decorator stacking (registering the same action with multiple paths).
5053
"""
5154

52-
HTTPMethod: TypeAlias = Literal["GET", "POST", "PUT", "PATCH", "DELETE"]
53-
5455

5556
_actions_variable = "_holm_action_descriptors"
5657
"""The name of the variable that stores action descriptors in modules."""
@@ -89,7 +90,7 @@ def __call__(
8990
*,
9091
use_layout: bool = False,
9192
metadata: MetadataMappingOrDependency | None = None,
92-
methods: Collection[HTTPMethod] | None = None,
93+
methods: Sequence[HTTPMethod] | None = None,
9394
dependencies: Sequence[DependsParam] | None = None,
9495
deprecated: bool | None = None,
9596
tags: list[str | Enum] | None = None,
@@ -329,6 +330,7 @@ def _register_action(
329330
action: ActionDependency,
330331
*,
331332
use_layout: bool,
333+
methods: Sequence[HTTPMethod] | None,
332334
metadata: MetadataMappingOrDependency | None,
333335
path: str | None,
334336
tags: list[str | Enum] | None,
@@ -362,9 +364,10 @@ def _register_action(
362364
route_args["response_model"] = None # Don't generate a response schema.
363365

364366
# Register the action.
365-
module_actions[path] = ActionDescriptor(
366-
action=action,
367-
route_args=route_args,
368-
use_layout=use_layout,
369-
metadata=metadata,
370-
)
367+
for method in ("GET",) if not methods else methods:
368+
module_actions[(path, method)] = ActionDescriptor(
369+
action=action,
370+
route_args={**route_args, "methods": (method,)},
371+
use_layout=use_layout,
372+
metadata=metadata,
373+
)

holm/modules/_layout.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import inspect
2-
from asyncio import iscoroutinefunction
32
from collections.abc import Awaitable, Callable, Coroutine
43
from dataclasses import dataclass
54
from typing import Any, Protocol, TypeAlias, TypeGuard
@@ -142,7 +141,7 @@ def layout_to_dependency(layout: Layout) -> FastAPIDependency[LayoutFactory]:
142141
raise ValueError("Layout factory must at least one argument.")
143142

144143
result: FastAPIDependency[LayoutFactory]
145-
if iscoroutinefunction(layout):
144+
if inspect.iscoroutinefunction(layout):
146145

147146
async def async_layout_factory_dep(**kwargs: Any) -> LayoutFactory:
148147
async def layout_factory(props: Any) -> Any:

mkdocs.yml

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,26 @@ repo_name: volfpeter/holm
33
repo_url: https://github.com/volfpeter/holm
44

55
theme:
6-
name: material
6+
name: modern
77
palette:
8+
# Palette toggle for automatic mode
9+
- media: "(prefers-color-scheme)"
10+
scheme: slate
11+
toggle:
12+
icon: lucide/sun-moon
13+
name: Switch to light mode
814
# Palette toggle for light mode
915
- media: "(prefers-color-scheme: light)"
1016
scheme: default
1117
toggle:
12-
icon: material/brightness-7
18+
icon: lucide/sun
1319
name: Switch to dark mode
1420
# Palette toggle for dark mode
1521
- media: "(prefers-color-scheme: dark)"
1622
scheme: slate
1723
toggle:
18-
icon: material/brightness-4
19-
name: Switch to light mode
24+
icon: lucide/moon
25+
name: Switch to system preference
2026
features:
2127
- navigation.indexes
2228
- navigation.instant
@@ -49,11 +55,11 @@ nav:
4955
- utilities.md
5056
- security.md
5157
- Guides:
52-
- guides/quick-start-guide.md
53-
- guides/path-parameters.md
54-
- guides/actions-with-htmx.md
55-
- guides/forms.md
56-
- guides/rendering-apis-with-htmx.md
57-
- guides/custom-applications.md
58-
- guides/error-handling.md
58+
- guides/quick-start-guide.md
59+
- guides/path-parameters.md
60+
- guides/actions-with-htmx.md
61+
- guides/forms.md
62+
- guides/rendering-apis-with-htmx.md
63+
- guides/custom-applications.md
64+
- guides/error-handling.md
5965
- API Reference: api.md

0 commit comments

Comments
 (0)