Movatterモバイル変換


[0]ホーム

URL:


Skip to content
❤️ Support Starlette viasponsors! 📚 Do you like the new docs?Let us know!

Lifespan

Starlette applications can register a lifespan handler for dealing withcode that needs to run before the application starts up, or when the applicationis shutting down.

importcontextlibfromstarlette.applicationsimportStarlette@contextlib.asynccontextmanagerasyncdeflifespan(app):asyncwithsome_async_resource():print("Run at startup!")yieldprint("Run on shutdown!")routes=[...]app=Starlette(routes=routes,lifespan=lifespan)

Starlette will not start serving any incoming requests until the lifespan has been run.

The lifespan teardown will run once all connections have been closed, andany in-process background tasks have completed.

Consider usinganyio.create_task_group()for managing asynchronous tasks.

Lifespan State

The lifespan has the concept ofstate, which is a dictionary thatcan be used to share the objects between the lifespan, and the requests.

importcontextlibfromtypingimportAsyncIterator,TypedDictimporthttpxfromstarlette.applicationsimportStarlettefromstarlette.requestsimportRequestfromstarlette.responsesimportPlainTextResponsefromstarlette.routingimportRouteclassState(TypedDict):http_client:httpx.AsyncClient@contextlib.asynccontextmanagerasyncdeflifespan(app:Starlette)->AsyncIterator[State]:asyncwithhttpx.AsyncClient()asclient:yield{"http_client":client}asyncdefhomepage(request:Request)->PlainTextResponse:client=request.state.http_clientresponse=awaitclient.get("https://www.example.com")returnPlainTextResponse(response.text)app=Starlette(lifespan=lifespan,routes=[Route("/",homepage)])

Thestate received on the requests is ashallow copy of the state received on thelifespan handler.

Accessing State

The state can be accessed using either attribute-style or dictionary-style syntax.

The dictionary-style syntax was introduced in Starlette 0.52.0 (January 2026), with the idea ofimproving type safety when using the lifespan state, given thatRequest became a generic overthe state type.

fromcollections.abcimportAsyncIteratorfromcontextlibimportasynccontextmanagerfromtypingimportTypedDictimporthttpxfromstarlette.applicationsimportStarlettefromstarlette.requestsimportRequestfromstarlette.responsesimportPlainTextResponsefromstarlette.routingimportRouteclassState(TypedDict):http_client:httpx.AsyncClient@asynccontextmanagerasyncdeflifespan(app:Starlette)->AsyncIterator[State]:asyncwithhttpx.AsyncClient()asclient:yield{"http_client":client}asyncdefhomepage(request:Request[State])->PlainTextResponse:client=request.state["http_client"]reveal_type(client)# Revealed type is 'httpx.AsyncClient'response=awaitclient.get("https://www.example.com")returnPlainTextResponse(response.text)app=Starlette(lifespan=lifespan,routes=[Route("/",homepage)])

Note

There were many attempts to make this work with attribute-style access instead ofdictionary-style access, but none were satisfactory, given they would have beenbreaking changes, or there were typing limitations.

For more details, see:

Running lifespan in tests

You should useTestClient as a context manager, to ensure that the lifespan is called.

fromexampleimportappfromstarlette.testclientimportTestClientdeftest_homepage():withTestClient(app)asclient:# Application's lifespan is called on entering the block.response=client.get("/")assertresponse.status_code==200# And the lifespan's teardown is run when exiting the block.

[8]ページ先頭

©2009-2026 Movatter.jp