Apps, Stubs, and entrypoints

Every object in Modal is attached to a Stub. This includes things like functions, secrets, and images. A Stub is a description of how to construct a Modal application. When you run or deploy a Stub, it creates an ephemeral or a deployed App, respectively.

You can view a list of all currently running Apps on the apps page.

Ephemeral apps

An ephemeral app is created when you use the modal run CLI command, or the stub.run method. This creates a temporary app that only exists for the duration of your script.

Ephemeral apps are stopped automatically when the calling program exits, or when the server detects that the client is no longer connected (use --detach in order to keep the app running even after the client exits).

Deployed apps

A deployed app is created using the modal deploy CLI command. The app is persisted indefinitely until you delete it from the web UI. Functions in a deployed app that have an attached schedule will be run on a schedule. Otherwise, you can invoke them manually using web endpoints or Python.

Deployed apps are named via the Stub constructor. Re-deploying an existing App (based on the name) will update it in place.

Entrypoints for ephemeral apps

The code that runs first when you modal run an app is called the entrypoint.

You can register a local entrypoint using the @stub.local_entrypoint() decorator. You can also use a regular Modal function as an entrypoint, in which case only the code in global scope is executed locally.

Argument parsing

If your entrypoint function take arguments with primitive types, modal run automatically parses them as CLI options. For example, the following function can be called with modal run script.py --foo 1 --bar "hello":

# script.py

@stub.local_entrypoint()
def main(foo: int, bar: str):
    some_modal_function.call(foo, bar)

Manually specifying an entrypoint

If there is only one local_entrypoint registered, modal run script.py will automatically use it. If you have no entrypoint specified, and just one decorated Modal function, that will be used as a remote entrypoint instead. Otherwise, you can direct modal run to use a specific entrypoint.

For example, if you have a function decorated with @stub.function() in your file:

# script.py

@stub.function()
def f():
    print("Hello world!")


@stub.function()
def g():
    print("Goodbye world!")


@stub.local_entrypoint()
def main():
    f.remote()

Running modal run script.py will execute the main function locally, which would call the f function remotely. However you can instead run modal run script.py::stub.f or modal run script.py::stub.g to execute f or g directly.