Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/Litestar/App/__main__.py.jinja
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
"""Application entry point."""

{% if litestar_granian %}
from granian import Granian
from granian.constants import Interfaces
{% else %}
import uvicorn
{% endif %}

from config import settings


def main() -> None:
"""Run the application."""
{% if litestar_granian %}
Granian(
"app:app",
address=settings.HOST,
port=settings.PORT,
interface=Interfaces.ASGI,
reload=settings.DEBUG,
).serve()
{% else %}
uvicorn.run(
"app:app",
host=settings.HOST,
port=settings.PORT,
reload=settings.DEBUG,
)
{% endif %}


if __name__ == "__main__":
Expand Down
6 changes: 6 additions & 0 deletions src/Litestar/App/app.py.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ from .config import redis_store
{% if litestar_saq %}
from .config import saq
{% endif %}
{% if litestar_granian %}
from litestar_granian import GranianPlugin
{% endif %}

@get("/health")
async def health() -> dict[str, str]:
Expand Down Expand Up @@ -64,6 +67,9 @@ app = Litestar(
{% endif %}
{% if litestar_saq %}
saq,
{% endif %}
{% if litestar_granian %}
GranianPlugin(),
{% endif %}
],
)
3 changes: 3 additions & 0 deletions src/Litestar/Config/pyproject.toml.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ dependencies = [
{% if litestar_saq %}
"litestar-saq>=0.7.0",
{% endif %}
{% if litestar_granian %}
"litestar-granian>=0.14.2",
{% endif %}
]

[tool.ruff]
Expand Down
27 changes: 27 additions & 0 deletions src/Litestar/Plugins/LitestarGranian/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Litestar Granian plugin."""

from src.plugin import BasePlugin


class LitestarGranianPlugin(BasePlugin):
"""Granian ASGI server integration for Litestar."""

@property
def name(self) -> str:
"""Get the plugin name.

Returns:
The plugin name.

"""
return "Litestar Granian (Server)"

@property
def description(self) -> str:
"""Get the plugin description.

Returns:
The plugin description.

"""
return "Granian ASGI server integration for Litestar"
55 changes: 55 additions & 0 deletions tests/test_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,58 @@ def test_litestar_generator_saq_rendering(tmp_path: Path) -> None:
# Verify SAQ dependency in pyproject.toml
pyproject_content = (tmp_path / "pyproject.toml").read_text()
assert "litestar-saq>=0.7.0" in pyproject_content


def test_litestar_generator_granian_context(tmp_path: Path) -> None:
"""Verify Litestar generator template context values with Granian plugin enabled."""
config = ProjectConfig(
name="Granian Test",
framework=Framework.LITESTAR,
database=Database.NONE,
memory_store=MemoryStore.NONE,
plugins=["litestar_granian"],
docker=False,
docker_infra=False,
)

generator = LitestarGenerator(config, tmp_path)
context = generator._get_template_context()

assert context["litestar_granian"] is True


def test_litestar_generator_granian_rendering(tmp_path: Path) -> None:
"""Verify that Granian plugin templates are correctly rendered into the output directory."""
config = ProjectConfig(
name="Granian Plugin Test",
framework=Framework.LITESTAR,
database=Database.NONE,
memory_store=MemoryStore.NONE,
plugins=["litestar_granian"],
docker=False,
docker_infra=False,
)

generator = LitestarGenerator(config, tmp_path)
generator.generate()

# Verify base files
assert (tmp_path / "pyproject.toml").exists()
assert (tmp_path / "src" / "backend" / "app.py").exists()
assert (tmp_path / "src" / "backend" / "__main__.py").exists()

# Verify Granian plugin in app.py
app_content = (tmp_path / "src" / "backend" / "app.py").read_text()
assert "from litestar_granian import GranianPlugin" in app_content
assert "GranianPlugin()," in app_content

# Verify Granian in __main__.py (not uvicorn)
main_content = (tmp_path / "src" / "backend" / "__main__.py").read_text()
assert "from granian import Granian" in main_content
assert "from granian.constants import Interfaces" in main_content
assert "Granian(" in main_content
assert "uvicorn" not in main_content

# Verify Granian dependency in pyproject.toml
pyproject_content = (tmp_path / "pyproject.toml").read_text()
assert "litestar-granian>=0.14.2" in pyproject_content
3 changes: 2 additions & 1 deletion tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from src.plugin import Plugin, discover_plugins

MIN_PLUGIN_COUNT = 3
MIN_PLUGIN_COUNT = 4


def test_discover_litestar_plugins() -> None:
Expand All @@ -14,6 +14,7 @@ def test_discover_litestar_plugins() -> None:
assert "advanced_alchemy" in ids
assert "litestar_saq" in ids
assert "litestar_vite" in ids
assert "litestar_granian" in ids

for plugin in plugins:
assert isinstance(plugin, Plugin)
Expand Down