encode / starlette

The little ASGI framework that shines. 🌟

Home Page:https://www.starlette.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Relax typing of lifespan state from Dict[str, Any] to Dict[Any, Any]

HansBrende opened this issue · comments

Relevant conversation: django/asgiref#354 (comment)

Key points:

  • a Starlette application shouldn't impose a typing restriction on what types of keys are passed into its state via the lifespan function, as the contents of particular namespace is supposed to be left up to the application programmer. Quote from the asgiref docs:

Applications can store arbitrary data in this namespace.

  • string keys are fine, but object keys (functioning similar to a Symbol key in Javascript) also make a lot of sense and can simplify application code (see example use-case below).
  • The asgiref documentation states:

applications should be cooperative by properly naming their keys such that they
will not collide with other frameworks or middleware.

yet the most foulproof and simplest way to ensure no collisions would be to not use string keys at all, but object references (in the manner of Javascript's Symbol)!

Here's an example use-case of non-string keys using fastapi's dependency injection system:

# (roughly)
HTTP_CLIENT: ClientSession = fastapi.Depends(lambda request: request.scope['state'][HTTP_CLIENT])
DB_POOL: Pool = fastapi.Depends(lambda request: request.scope['state'][DB_POOL])

@asynccontextmanager
async def app_lifespan(app: FastAPI) -> AsyncIterator[Dict[Any, Any]]:
    async with make_http_client() as client:
        async with make_database_connection_pool() as db_pool:
            yield {HTTP_CLIENT: client, DB_POOL: db_pool}

It is worth noting that this use-case already works just fine! It is just annoying that the typing hints prohibit it. Since the state dictionary should be agnostic to its contents (only requiring it to be a dict for the purposes of copying it and updating it), I don't see any reason to enforce that keys must be strings in this dictionary... that should be left up to the application programmer!

I think you should open this as an issue in asgiref since it's part of the spec

@adriangb will do!