1010from fastapi import FastAPI , HTTPException , Request
1111from fastapi .responses import FileResponse
1212from pydantic import BaseModel
13- from labthings_fastapi .outputs .blob import blob_to_link
1413
14+ from labthings_fastapi .utilities import model_to_dict
1515from labthings_fastapi .utilities .introspection import EmptyInput
1616from ..thing_description .model import LinkElement
1717from ..file_manager import FileManager
2121 InvocationCancelledError ,
2222 invocation_logger ,
2323)
24+ from ..outputs .blob import BlobIOContextDep
2425
2526if TYPE_CHECKING :
2627 # We only need these imports for type hints, so this avoids circular imports.
@@ -158,32 +159,32 @@ def response(self, request: Optional[Request] = None):
158159 timeCompleted = self ._end_time ,
159160 timeRequested = self ._request_time ,
160161 input = self .input ,
161- output = blob_to_link ( self .output , href + "/output" ) ,
162+ output = self .output ,
162163 links = links ,
163164 log = self .log ,
164165 )
165166
166167 def run (self ):
167168 """Overrides default threading.Thread run() method"""
168- self .action .emit_changed_event (self .thing , self ._status )
169+ try :
170+ self .action .emit_changed_event (self .thing , self ._status )
169171
170- # Capture just this thread's log messages
171- handler = DequeLogHandler (dest = self ._log )
172- logger = invocation_logger (self .id )
173- logger .addHandler (handler )
172+ # Capture just this thread's log messages
173+ handler = DequeLogHandler (dest = self ._log )
174+ logger = invocation_logger (self .id )
175+ logger .addHandler (handler )
174176
175- action = self .action
176- thing = self .thing
177- kwargs = self .input . model_dump () or {}
178- assert action is not None
179- assert thing is not None
177+ action = self .action
178+ thing = self .thing
179+ kwargs = model_to_dict ( self .input )
180+ assert action is not None
181+ assert thing is not None
180182
181- with self ._status_lock :
182- self ._status = InvocationStatus .RUNNING
183- self ._start_time = datetime .datetime .now ()
184- self .action .emit_changed_event (self .thing , self ._status )
183+ with self ._status_lock :
184+ self ._status = InvocationStatus .RUNNING
185+ self ._start_time = datetime .datetime .now ()
186+ self .action .emit_changed_event (self .thing , self ._status )
185187
186- try :
187188 # The next line actually runs the action.
188189 ret = action .__get__ (thing )(** kwargs , ** self .dependencies )
189190
@@ -283,6 +284,11 @@ def invoke_action(
283284 thread .start ()
284285 return thread
285286
287+ def get_invocation (self , id : uuid .UUID ) -> Invocation :
288+ """Retrieve an invocation by ID"""
289+ with self ._invocations_lock :
290+ return self ._invocations [id ]
291+
286292 def list_invocations (
287293 self ,
288294 action : Optional [ActionDescriptor ] = None ,
@@ -314,15 +320,17 @@ def attach_to_app(self, app: FastAPI):
314320 """Add /action_invocations and /action_invocation/{id} endpoints to FastAPI"""
315321
316322 @app .get (ACTION_INVOCATIONS_PATH , response_model = list [InvocationModel ])
317- def list_all_invocations (request : Request ):
323+ def list_all_invocations (request : Request , _blob_manager : BlobIOContextDep ):
318324 return self .list_invocations (as_responses = True , request = request )
319325
320326 @app .get (
321327 ACTION_INVOCATIONS_PATH + "/{id}" ,
322328 response_model = InvocationModel ,
323329 responses = {404 : {"description" : "Invocation ID not found" }},
324330 )
325- def action_invocation (id : uuid .UUID , request : Request ):
331+ def action_invocation (
332+ id : uuid .UUID , request : Request , _blob_manager : BlobIOContextDep
333+ ):
326334 try :
327335 with self ._invocations_lock :
328336 return self ._invocations [id ].response (request = request )
@@ -346,7 +354,7 @@ def action_invocation(id: uuid.UUID, request: Request):
346354 503 : {"description" : "No result is available for this invocation" },
347355 },
348356 )
349- def action_invocation_output (id : uuid .UUID ):
357+ def action_invocation_output (id : uuid .UUID , _blob_manager : BlobIOContextDep ):
350358 """Get the output of an action invocation
351359
352360 This returns just the "output" component of the action invocation. If the
0 commit comments