1818 Optional ,
1919 Tuple ,
2020 TypeVar ,
21+ Union ,
2122 overload ,
2223)
2324from urllib .parse import urlparse
@@ -111,7 +112,7 @@ def _build_primitive_call(
111112 )
112113
113114
114- class Function (PrimitiveFunction , Generic [P , T ]):
115+ class AsyncFunction (PrimitiveFunction , Generic [P , T ]):
115116 """Callable wrapper around a function meant to be used throughout the
116117 Dispatch Python SDK.
117118 """
@@ -157,7 +158,7 @@ def __call__(self, *args: P.args, **kwargs: P.kwargs) -> Coroutine[Any, Any, T]:
157158 else :
158159 return self ._call_dispatch (* args , ** kwargs )
159160
160- def dispatch (self , * args : P .args , ** kwargs : P .kwargs ) -> DispatchID :
161+ async def dispatch (self , * args : P .args , ** kwargs : P .kwargs ) -> DispatchID :
161162 """Dispatch an asynchronous call to the function without
162163 waiting for a result.
163164
@@ -171,7 +172,7 @@ def dispatch(self, *args: P.args, **kwargs: P.kwargs) -> DispatchID:
171172 Returns:
172173 DispatchID: ID of the dispatched call.
173174 """
174- return asyncio . run ( self ._primitive_dispatch (Arguments (args , kwargs ) ))
175+ return await self ._primitive_dispatch (Arguments (args , kwargs ))
175176
176177 def build_call (self , * args : P .args , ** kwargs : P .kwargs ) -> Call :
177178 """Create a Call for this function with the provided input. Useful to
@@ -187,11 +188,38 @@ def build_call(self, *args: P.args, **kwargs: P.kwargs) -> Call:
187188 return self ._build_primitive_call (Arguments (args , kwargs ))
188189
189190
191+ class BlockingFunction (Generic [P , T ]):
192+ """BlockingFunction is like Function but exposes a blocking API instead of
193+ functions that use asyncio.
194+
195+ Applications typically don't create instances of BlockingFunction directly,
196+ and instead use decorators from packages that provide integrations with
197+ Python frameworks.
198+ """
199+
200+ def __init__ (self , func : AsyncFunction [P , T ]):
201+ self ._func = func
202+
203+ def __call__ (self , * args : P .args , ** kwargs : P .kwargs ) -> T :
204+ return asyncio .run (self ._func (* args , ** kwargs ))
205+
206+ def dispatch (self , * args : P .args , ** kwargs : P .kwargs ) -> DispatchID :
207+ return asyncio .run (self ._func .dispatch (* args , ** kwargs ))
208+
209+ def build_call (self , * args : P .args , ** kwargs : P .kwargs ) -> Call :
210+ return self ._func .build_call (* args , ** kwargs )
211+
212+
190213class Reset (TailCall ):
191214 """The current coroutine is aborted and scheduling reset to be replaced with
192215 the call embedded in this exception."""
193216
194- def __init__ (self , func : Function [P , T ], * args : P .args , ** kwargs : P .kwargs ):
217+ def __init__ (
218+ self ,
219+ func : Union [AsyncFunction [P , T ], BlockingFunction [P , T ]],
220+ * args : P .args ,
221+ ** kwargs : P .kwargs ,
222+ ):
195223 super ().__init__ (call = func .build_call (* args , ** kwargs ))
196224
197225
@@ -267,10 +295,12 @@ def endpoint(self, value: str):
267295 self ._endpoint = value
268296
269297 @overload
270- def function (self , func : Callable [P , Coroutine [Any , Any , T ]]) -> Function [P , T ]: ...
298+ def function (
299+ self , func : Callable [P , Coroutine [Any , Any , T ]]
300+ ) -> AsyncFunction [P , T ]: ...
271301
272302 @overload
273- def function (self , func : Callable [P , T ]) -> Function [P , T ]: ...
303+ def function (self , func : Callable [P , T ]) -> AsyncFunction [P , T ]: ...
274304
275305 def function (self , func ):
276306 """Decorator that registers functions."""
@@ -283,7 +313,9 @@ def function(self, func):
283313 logger .info ("registering coroutine: %s" , name )
284314 return self ._register_coroutine (name , func )
285315
286- def _register_function (self , name : str , func : Callable [P , T ]) -> Function [P , T ]:
316+ def _register_function (
317+ self , name : str , func : Callable [P , T ]
318+ ) -> AsyncFunction [P , T ]:
287319 func = durable (func )
288320
289321 @wraps (func )
@@ -296,7 +328,7 @@ async def asyncio_wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
296328
297329 def _register_coroutine (
298330 self , name : str , func : Callable [P , Coroutine [Any , Any , T ]]
299- ) -> Function [P , T ]:
331+ ) -> AsyncFunction [P , T ]:
300332 logger .info ("registering coroutine: %s" , name )
301333 func = durable (func )
302334
@@ -307,7 +339,7 @@ async def primitive_func(input: Input) -> Output:
307339 primitive_func .__qualname__ = f"{ name } _primitive"
308340 durable_primitive_func = durable (primitive_func )
309341
310- wrapped_func = Function [P , T ](
342+ wrapped_func = AsyncFunction [P , T ](
311343 self ,
312344 name ,
313345 durable_primitive_func ,
@@ -555,7 +587,9 @@ def __init__(self, client: Client):
555587 self .client = client
556588 self .calls = []
557589
558- def add (self , func : Function [P , T ], * args : P .args , ** kwargs : P .kwargs ) -> Batch :
590+ def add (
591+ self , func : AsyncFunction [P , T ], * args : P .args , ** kwargs : P .kwargs
592+ ) -> Batch :
559593 """Add a call to the specified function to the batch."""
560594 return self .add_call (func .build_call (* args , ** kwargs ))
561595
0 commit comments