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.