1- """
2- Context Var access to the Action Manager
1+ """Context Var access to the Action Manager.
32
43This module provides a context var to access the Action Manager instance.
54While LabThings tries pretty hard to conform to FastAPI's excellent convention
65that everything should be passed as a parameter, there are some cases where
76that's hard. In particular, generating URLs when responses are serialised is
8- difficult, because `pydantic` doesn't have a way to pass in extra context.
7+ difficult, because `pydantic` doesn't have a way to access the `fastapi.Request`
8+ object and use `fastapi.Request.url_for`.
9+
10+ If an endpoint uses the `.ActionManagerDep` dependency, then the `.ActionManager`
11+ is supplied as an argument. More usefully, when the output is serialised the
12+ `.ActionManager` is available using `.ActionManagerContext.get()`.
913
10- If an endpoint uses the `ActionManagerDep` dependency, then the Action Manager
11- is available using `ActionManagerContext.get()` .
14+ This is currently only used by `.Blob` objects, as "serialising" a `.Blob`
15+ involves adding it to the `.ActionManager` and generating a download URL .
1216"""
1317
1418from __future__ import annotations
1519
1620from contextvars import ContextVar
1721
18- from typing import Annotated
22+ from typing import Annotated , AsyncGenerator
1923from typing_extensions import TypeAlias
2024from fastapi import Depends , Request
2125from ..dependencies .thing_server import find_thing_server
2226from ..actions import ActionManager
2327
2428
2529def action_manager_from_thing_server (request : Request ) -> ActionManager :
26- """Retrieve the Action Manager from the Thing Server
30+ """Retrieve the Action Manager from the Thing Server.
31+
32+ This is for use as a FastAPI dependency. We use the ``request`` to
33+ access the `.ThingServer` and thus access the `.ActionManager`.
2734
28- This is for use as a FastAPI dependency, so the thing server is
29- retrieved from the request object.
35+ :param request: the FastAPI request object. This will be supplied by
36+ FastAPI when this function is used as a dependency.
37+
38+ :return: the `.ActionManager` object associated with our `.ThingServer`.
3039 """
3140 action_manager = find_thing_server (request .app ).action_manager
32- if action_manager is None :
33- raise RuntimeError ("Could not get the blocking portal from the server." )
41+ assert action_manager is not None
3442 return action_manager
3543
3644
@@ -43,10 +51,19 @@ def action_manager_from_thing_server(request: Request) -> ActionManager:
4351ActionManagerContext = ContextVar [ActionManager ]("ActionManagerContext" )
4452
4553
46- async def make_action_manager_context_available (action_manager : ActionManagerDep ):
47- """Make the Action Manager available in the context
54+ async def make_action_manager_context_available (
55+ action_manager : ActionManagerDep ,
56+ ) -> AsyncGenerator [ActionManager ]:
57+ """Make the Action Manager available in the context variable.
58+
59+ The action manager may be accessed using `ActionManagerContext.get()` within
60+ this context manager.
61+
62+ :param action_manager: The `.ActionManager` object. Note that this is an
63+ annotated type so it will be supplied automatically when used as a FastAPI
64+ dependency.
4865
49- The action manager may be accessed using `ActionManagerContext.get()` .
66+ :yield: the `.ActionManager` object .
5067 """
5168 ActionManagerContext .set (action_manager )
5269 yield action_manager
0 commit comments