22
33import copy
44import importlib
5- import json
65import logging
76import uuid
87from collections .abc import (
1817import httpx
1918import jsonschema .exceptions
2019import jsonschema .validators
21- from prefect import flow
2220from prefect .blocks .core import Block
2321from prefect .client .schemas import FlowRun
2422from prefect .deployments import run_deployment
25- from prefect .exceptions import MissingResult
2623from prefect .results import (
2724 ResultRecord ,
2825 ResultStore ,
@@ -102,6 +99,7 @@ class PrefectManager:
10299 _processor_configurations : dict [ProcessId , dict [str , Any ]]
103100
104101 is_async : bool = True
102+ use_vanilla_processor_deployments : bool
105103 supports_subscribing : bool
106104 prefect_state_map = {
107105 StateType .SCHEDULED : JobStatus .accepted ,
@@ -120,6 +118,9 @@ class PrefectManager:
120118 sync_job_execution_timeout_seconds : int
121119
122120 def __init__ (self , manager_def : dict [str , Any ]):
121+ self .use_vanilla_processor_deployments = manager_def .get (
122+ "use_vanilla_processor_deployments" , True )
123+ # self.use_vanilla_processor_deployments = False
123124 self .name = "." .join (
124125 (self .__class__ .__module__ , self .__class__ .__qualname__ )
125126 )
@@ -322,6 +323,15 @@ def execute_process(
322323 if execution_mode == RequestedProcessExecutionMode .respond_async :
323324 chosen_mode = ProcessExecutionMode .async_execute
324325 response_headers ["Preference-Applied" ] = RequestedProcessExecutionMode .respond_async .value
326+ if isinstance (requested_outputs , Sequence ) and not isinstance (requested_outputs , str ):
327+ outs = {out_name : ExecutionOutput () for out_name in requested_outputs }
328+ elif isinstance (requested_outputs , Mapping ):
329+ outs = {
330+ out_name : ExecutionOutput (** out_info )
331+ for out_name , out_info in requested_outputs .items ()
332+ }
333+ else :
334+ outs = None
325335
326336 match processor := self .get_processor (process_id ):
327337 case BasePrefectProcessor ():
@@ -334,15 +344,7 @@ def execute_process(
334344 )
335345 case _:
336346 raise ProcessError (f"Unknown processor type { type (processor )!r} " )
337- if isinstance (requested_outputs , Sequence ) and not isinstance (requested_outputs , str ):
338- outs = {out_name : ExecutionOutput () for out_name in requested_outputs }
339- elif isinstance (requested_outputs , Mapping ):
340- outs = {
341- out_name : ExecutionOutput (** out_info )
342- for out_name , out_info in requested_outputs .items ()
343- }
344- else :
345- outs = None
347+
346348 execution_request = ExecuteRequest (
347349 deployment_info = deployment_info ,
348350 inputs = data_ ,
@@ -351,8 +353,15 @@ def execute_process(
351353 subscriber = subscriber ,
352354 )
353355 if chosen_mode == ProcessExecutionMode .sync_execute :
354- media_type , generated_output = self ._execute_job_sync (
355- job_id , processor , execution_request )
356+ if isinstance (processor , BaseProcessor ) and not self .use_vanilla_processor_deployments :
357+ print (f"Executing processor { processor .metadata ['id' ]!r} in-process..." )
358+ media_type , generated_output = _execute_job_sync_without_deployment (
359+ job_id , processor , execution_request
360+ )
361+ else :
362+ print (f"Executing processor { processor .metadata ['id' ]!r} via Prefect deployment..." )
363+ media_type , generated_output = self ._execute_job_sync (
364+ job_id , processor , execution_request )
356365 print (f"{ media_type = } " )
357366 print (f"{ generated_output = } " )
358367 return job_id , media_type , generated_output , JobStatus .successful , response_headers
@@ -464,3 +473,29 @@ def _retrieve_result_from_prefect(
464473 media_type = MediaType (result_record .result [0 ])
465474 generated_output = result_record .result [1 ]
466475 return media_type , generated_output
476+
477+
478+ def _execute_job_sync_without_deployment (
479+ job_id : PygeoapiPrefectJobId ,
480+ processor : BaseProcessor ,
481+ execution_request : ExecuteRequest ,
482+ ) -> tuple [MediaType , Any ]:
483+ """Execute a job in sync mode by calling a flow directly
484+
485+ This execution mode is only suitable for:
486+
487+ - flows that wrap vanilla pygeoapi processors
488+ - flows whose source code is reachable in the same process
489+ as this one
490+ """
491+ configured_flow = vanilla_flow .get_processor_as_flow (processor )
492+ configured_flow (
493+ processor .metadata ["id" ],
494+ job_id ,
495+ execution_request .inputs ,
496+ execution_request .outputs
497+ )
498+ return _retrieve_result_from_prefect (
499+ result_storage_block = execution_request .deployment_info .result_storage_block ,
500+ result_storage_key_template = execution_request .deployment_info .result_storage_key_template
501+ )
0 commit comments