Skip to content

Commit 323031e

Browse files
committed
feat(plugin): add granian
1 parent 56d8def commit 323031e

6 files changed

Lines changed: 108 additions & 1 deletion

File tree

src/Litestar/App/__main__.py.jinja

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,33 @@
11
"""Application entry point."""
22

3+
{% if litestar_granian %}
4+
from granian import Granian
5+
from granian.constants import Interfaces
6+
{% else %}
37
import uvicorn
8+
{% endif %}
49

510
from config import settings
611

712

813
def main() -> None:
914
"""Run the application."""
15+
{% if litestar_granian %}
16+
Granian(
17+
"app:app",
18+
address=settings.HOST,
19+
port=settings.PORT,
20+
interface=Interfaces.ASGI,
21+
reload=settings.DEBUG,
22+
).serve()
23+
{% else %}
1024
uvicorn.run(
1125
"app:app",
1226
host=settings.HOST,
1327
port=settings.PORT,
1428
reload=settings.DEBUG,
1529
)
30+
{% endif %}
1631

1732

1833
if __name__ == "__main__":

src/Litestar/App/app.py.jinja

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ from .config import redis_store
2020
{% if litestar_saq %}
2121
from .config import saq
2222
{% endif %}
23+
{% if litestar_granian %}
24+
from litestar_granian import GranianPlugin
25+
{% endif %}
2326

2427
@get("/health")
2528
async def health() -> dict[str, str]:
@@ -64,6 +67,9 @@ app = Litestar(
6467
{% endif %}
6568
{% if litestar_saq %}
6669
saq,
70+
{% endif %}
71+
{% if litestar_granian %}
72+
GranianPlugin(),
6773
{% endif %}
6874
],
6975
)

src/Litestar/Config/pyproject.toml.jinja

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ dependencies = [
2626
{% if litestar_saq %}
2727
"litestar-saq>=0.7.0",
2828
{% endif %}
29+
{% if litestar_granian %}
30+
"litestar-granian>=0.14.2",
31+
{% endif %}
2932
]
3033

3134
[tool.ruff]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""Litestar Granian plugin."""
2+
3+
from src.plugin import BasePlugin
4+
5+
6+
class LitestarGranianPlugin(BasePlugin):
7+
"""Granian ASGI server integration for Litestar."""
8+
9+
@property
10+
def name(self) -> str:
11+
"""Get the plugin name.
12+
13+
Returns:
14+
The plugin name.
15+
16+
"""
17+
return "Litestar Granian (Server)"
18+
19+
@property
20+
def description(self) -> str:
21+
"""Get the plugin description.
22+
23+
Returns:
24+
The plugin description.
25+
26+
"""
27+
return "Granian ASGI server integration for Litestar"

tests/test_generator.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,58 @@ def test_litestar_generator_saq_rendering(tmp_path: Path) -> None:
183183
# Verify SAQ dependency in pyproject.toml
184184
pyproject_content = (tmp_path / "pyproject.toml").read_text()
185185
assert "litestar-saq>=0.7.0" in pyproject_content
186+
187+
188+
def test_litestar_generator_granian_context(tmp_path: Path) -> None:
189+
"""Verify Litestar generator template context values with Granian plugin enabled."""
190+
config = ProjectConfig(
191+
name="Granian Test",
192+
framework=Framework.LITESTAR,
193+
database=Database.NONE,
194+
memory_store=MemoryStore.NONE,
195+
plugins=["litestar_granian"],
196+
docker=False,
197+
docker_infra=False,
198+
)
199+
200+
generator = LitestarGenerator(config, tmp_path)
201+
context = generator._get_template_context()
202+
203+
assert context["litestar_granian"] is True
204+
205+
206+
def test_litestar_generator_granian_rendering(tmp_path: Path) -> None:
207+
"""Verify that Granian plugin templates are correctly rendered into the output directory."""
208+
config = ProjectConfig(
209+
name="Granian Plugin Test",
210+
framework=Framework.LITESTAR,
211+
database=Database.NONE,
212+
memory_store=MemoryStore.NONE,
213+
plugins=["litestar_granian"],
214+
docker=False,
215+
docker_infra=False,
216+
)
217+
218+
generator = LitestarGenerator(config, tmp_path)
219+
generator.generate()
220+
221+
# Verify base files
222+
assert (tmp_path / "pyproject.toml").exists()
223+
assert (tmp_path / "src" / "backend" / "app.py").exists()
224+
assert (tmp_path / "src" / "backend" / "__main__.py").exists()
225+
226+
# Verify Granian plugin in app.py
227+
app_content = (tmp_path / "src" / "backend" / "app.py").read_text()
228+
assert "from litestar_granian import GranianPlugin" in app_content
229+
assert "GranianPlugin()," in app_content
230+
231+
# Verify Granian in __main__.py (not uvicorn)
232+
main_content = (tmp_path / "src" / "backend" / "__main__.py").read_text()
233+
assert "from granian import Granian" in main_content
234+
assert "from granian.constants import Interfaces" in main_content
235+
assert "Granian(" in main_content
236+
assert "uvicorn" not in main_content
237+
238+
# Verify Granian dependency in pyproject.toml
239+
pyproject_content = (tmp_path / "pyproject.toml").read_text()
240+
assert "litestar-granian>=0.14.2" in pyproject_content

tests/test_plugin.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from src.plugin import Plugin, discover_plugins
44

5-
MIN_PLUGIN_COUNT = 3
5+
MIN_PLUGIN_COUNT = 4
66

77

88
def test_discover_litestar_plugins() -> None:
@@ -14,6 +14,7 @@ def test_discover_litestar_plugins() -> None:
1414
assert "advanced_alchemy" in ids
1515
assert "litestar_saq" in ids
1616
assert "litestar_vite" in ids
17+
assert "litestar_granian" in ids
1718

1819
for plugin in plugins:
1920
assert isinstance(plugin, Plugin)

0 commit comments

Comments
 (0)