modal.functions

modal.functions.Function

class Function(modal.object.Object)

Functions are the basic units of serverless execution on Modal.

Generally, you will not construct a Function directly. Instead, use the @stub.function() decorator on the Stub object for your application.

def __init__(self, *args, **kwargs):

from_name

@classmethod
def from_name(
    cls: Type["_Function"],
    app_name: str,
    tag: Optional[str] = None,
    namespace=api_pb2.DEPLOYMENT_NAMESPACE_WORKSPACE,
    environment_name: Optional[str] = None,
) -> "_Function":

Retrieve a function with a given name and tag.

other_function = modal.Function.from_name("other-app", "function")

lookup

@staticmethod
def lookup(
    app_name: str,
    tag: Optional[str] = None,
    namespace=api_pb2.DEPLOYMENT_NAMESPACE_WORKSPACE,
    client: Optional[_Client] = None,
    environment_name: Optional[str] = None,
) -> "_Function":

Lookup a function with a given name and tag.

other_function = modal.Function.lookup("other-app", "function")

web_url

@property
def web_url(self) -> str:

URL of a Function running as a web endpoint.

map

@warn_if_generator_is_not_consumed
@live_method_gen
@synchronizer.no_input_translation
def map(
    self,
    *input_iterators,  # one input iterator per argument in the mapped-over function/generator
    kwargs={},  # any extra keyword arguments for the function
    order_outputs: bool = True,  # return outputs in order
    return_exceptions: bool = False,  # propogate exceptions (False) or aggregate them in the results list (True)
) -> AsyncGenerator[Any, None]:

Parallel map over a set of inputs.

Takes one iterator argument per argument in the function being mapped over.

Example:

@stub.function()
def my_func(a):
    return a ** 2


@stub.local_entrypoint()
def main():
    assert list(my_func.map([1, 2, 3, 4])) == [1, 4, 9, 16]

If applied to a stub.function, map() returns one result per input and the output order is guaranteed to be the same as the input order. Set order_outputs=False to return results in the order that they are completed instead.

return_exceptions can be used to treat exceptions as successful results:

@stub.function()
def my_func(a):
    if a == 2:
        raise Exception("ohno")
    return a ** 2


@stub.local_entrypoint()
def main():
    # [0, 1, UserCodeException(Exception('ohno'))]
    print(list(my_func.map(range(3), return_exceptions=True)))

for_each

@synchronizer.no_input_translation
def for_each(self, *input_iterators, kwargs={}, ignore_exceptions: bool = False):

Execute function for all inputs, ignoring outputs.

Convenient alias for .map() in cases where the function just needs to be called. as the caller doesn’t have to consume the generator to process the inputs.

starmap

@warn_if_generator_is_not_consumed
@live_method_gen
@synchronizer.no_input_translation
def starmap(
    self, input_iterator, kwargs={}, order_outputs: bool = True, return_exceptions: bool = False
) -> AsyncGenerator[Any, None]:

Like map, but spreads arguments over multiple function arguments.

Assumes every input is a sequence (e.g. a tuple).

Example:

@stub.function()
def my_func(a, b):
    return a + b


@stub.local_entrypoint()
def main():
    assert list(my_func.starmap([(1, 2), (3, 4)])) == [3, 7]

remote

@synchronizer.no_io_translation
@live_method
def remote(self, *args, **kwargs) -> Any:

Calls the function remotely, executing it with the given arguments and returning the execution’s result.

remote_gen

@synchronizer.no_io_translation
@live_method_gen
def remote_gen(self, *args, **kwargs) -> AsyncGenerator[Any, None]:

Calls the generator remotely, executing it with the given arguments and returning the execution’s result.

call

def call(self, *args, **kwargs) -> None:

Deprecated. Use f.remote or f.remote_gen instead.

shell

@synchronizer.no_io_translation
@live_method
def shell(self, *args, **kwargs) -> None:

local

@synchronizer.nowrap
def local(self, *args, **kwargs) -> Any:

Calls the function locally, executing it with the given arguments and returning the execution’s result. This method allows a caller to execute the standard Python function wrapped by Modal.

spawn

@synchronizer.no_input_translation
@live_method
def spawn(self, *args, **kwargs) -> Optional["_FunctionCall"]:

Calls the function with the given arguments, without waiting for the results.

Returns a modal.functions.FunctionCall object, that can later be polled or waited for using .get(timeout=...). Conceptually similar to multiprocessing.pool.apply_async, or a Future/Promise in other contexts.

Note: .spawn() on a modal generator function does call and execute the generator, but does not currently return a function handle for polling the result.

get_raw_f

def get_raw_f(self) -> Callable[..., Any]:

Return the inner Python object wrapped by this Modal Function.

get_current_stats

@live_method
def get_current_stats(self) -> FunctionStats:

Return a FunctionStats object describing the current function’s queue and runner counts.

modal.functions.FunctionCall

class FunctionCall(modal.object.Object)

A reference to an executed function call.

Constructed using .spawn(...) on a Modal function with the same arguments that a function normally takes. Acts as a reference to an ongoing function call that can be passed around and used to poll or fetch function results at some later time.

Conceptually similar to a Future/Promise/AsyncResult in other contexts and languages.

def __init__(self, *args, **kwargs):

get

def get(self, timeout: Optional[float] = None):

Get the result of the function call.

This function waits indefinitely by default. It takes an optional timeout argument that specifies the maximum number of seconds to wait, which can be set to 0 to poll for an output immediately.

The returned coroutine is not cancellation-safe.

get_call_graph

def get_call_graph(self) -> List[InputInfo]:

Returns a structure representing the call graph from a given root call ID, along with the status of execution for each node.

See modal.call_graph reference page for documentation on the structure of the returned InputInfo items.

cancel

def cancel(self):

Cancels the function call, which will stop its execution and mark its inputs as TERMINATED.

from_id

@staticmethod
def from_id(function_call_id: str, client: Optional[_Client] = None) -> "_FunctionCall":

modal.functions.FunctionEnv

class FunctionEnv(object)

Stores information about the function environment. This is used for modal shell to support running shells in the same environment as a user-defined function.

def __init__(self, image: Optional[modal.image._Image], mounts: Sequence[modal.mount._Mount], secrets: Sequence[modal.secret._Secret], network_file_systems: Dict[Union[str, pathlib.PurePosixPath], modal.network_file_system._NetworkFileSystem], volumes: Dict[Union[str, pathlib.PurePosixPath], Union[modal.volume._Volume, modal.s3mount._S3Mount]], gpu: Union[NoneType, bool, str, modal.gpu._GPUConfig], cloud: Optional[str], cpu: Optional[float], memory: Optional[int]) -> None

modal.functions.FunctionStats

class FunctionStats(object)

Simple data structure storing stats for a running function.

def __init__(self, backlog: int, num_active_runners: int, num_total_runners: int) -> None

modal.functions.current_function_call_id

def current_function_call_id() -> Optional[str]:

Returns the function call ID for the current input.

Can only be called from Modal function (i.e. in a container context).

from modal import current_function_call_id

@stub.function()
def process_stuff():
    print(f"Starting to process input from {current_function_call_id()}")

modal.functions.current_input_id

def current_input_id() -> Optional[str]:

Returns the input ID for the current input.

Can only be called from Modal function (i.e. in a container context).

from modal import current_input_id

@stub.function()
def process_stuff():
    print(f"Starting to process {current_input_id()}")

modal.functions.gather

async def gather(*function_calls: _FunctionCall):

Wait until all Modal function calls have results before returning

Accepts a variable number of FunctionCall objects as returned by Function.spawn().

Returns a list of results from each function call, or raises an exception of the first failing function call.

E.g.

function_call_1 = slow_func_1.spawn()
function_call_2 = slow_func_2.spawn()

result_1, result_2 = gather(function_call_1, function_call_2)