Skip to content

Commit 8904774

Browse files
author
Maarten Breddels AI
committed
fix: use lifespan instead of on_startup/on_shutdown for Starlette 1.0 compatibility
Starlette 1.0 removed the on_startup and on_shutdown parameters in favor of the lifespan context manager. This change migrates to using lifespan, which has been supported since Starlette 0.13.5. Fixes #1143
1 parent 954c5eb commit 8904774

2 files changed

Lines changed: 33 additions & 1 deletion

File tree

solara/server/starlette.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import asyncio
2+
from contextlib import asynccontextmanager
23
import json
34
import logging
45
import math
@@ -633,6 +634,14 @@ def on_shutdown():
633634
telemetry.server_stop()
634635

635636

637+
@asynccontextmanager
638+
async def lifespan(app):
639+
"""Lifespan context manager for Starlette (replaces on_startup/on_shutdown)."""
640+
on_startup()
641+
yield
642+
on_shutdown()
643+
644+
636645
def readyz(request: Request):
637646
json, status = server.readyz()
638647
return JSONResponse(json, status_code=status)
@@ -767,7 +776,7 @@ def expand(named_tuple):
767776
Route("/{fullpath:path}", endpoint=root),
768777
]
769778

770-
app = Starlette(routes=routes, on_startup=[on_startup], on_shutdown=[on_shutdown], middleware=middleware)
779+
app = Starlette(routes=routes, lifespan=lifespan, middleware=middleware)
771780

772781
# Uncomment the lines below to test solara mouted under a subpath
773782
# def myroot(request: Request):
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""Tests for Starlette lifespan context manager."""
2+
3+
import asyncio
4+
from unittest import mock
5+
6+
7+
def test_lifespan_context_manager():
8+
"""Test that the lifespan context manager calls on_startup and on_shutdown."""
9+
from solara.server.starlette import lifespan
10+
11+
startup_called = []
12+
shutdown_called = []
13+
14+
with mock.patch("solara.server.starlette.on_startup", lambda: startup_called.append(True)):
15+
with mock.patch("solara.server.starlette.on_shutdown", lambda: shutdown_called.append(True)):
16+
17+
async def test_lifespan():
18+
async with lifespan(None):
19+
assert startup_called == [True], "on_startup should be called before yield"
20+
assert shutdown_called == [], "on_shutdown should not be called before yield"
21+
assert shutdown_called == [True], "on_shutdown should be called after yield"
22+
23+
asyncio.run(test_lifespan())

0 commit comments

Comments
 (0)