App

class App(object)

A Modal App is a group of functions and classes that are deployed together.

The app serves at least three purposes:

  • A unit of deployment for functions and classes.
  • Syncing of identities of (primarily) functions and classes across processes (your local Python interpreter and every Modal container active in your application).
  • Manage log collection for everything that happens inside your code.

Registering functions with an app

The most common way to explicitly register an Object with an app is through the @app.function() decorator. It both registers the annotated function itself and other passed objects, like schedules and secrets, with the app:

import modal

app = modal.App()

@app.function(
    secrets=[modal.Secret.from_name("some_secret")],
    schedule=modal.Period(days=1),
)
def foo():
    pass

In this example, the secret and schedule are registered with the app.

__init__(self, name=None, *, tags=None, image=None, secrets=[], volumes={},
    include_source=True)

Construct a new app, optionally with default image, mounts, secrets, or volumes.

Parameters

namestr | None
Optional app name used for registration and lookup.
tagsdict[str, str] | None
Additional metadata to set on the App.
image_Image | None
Default image for the App (otherwise defaults to modal.Image.debian_slim()).
secretsSequence[_Secret]
Secrets to add for all Functions in the App. (Default is [])
volumesdict[str | PurePosixPath, _Volume]
Volume mounts to use for all Functions. (Default is {})
include_sourcebool
Default for whether Function source files are added to the Modal container (per-function override possible). (Default is True)

Usage

image = modal.Image.debian_slim().pip_install(...)
secret = modal.Secret.from_name("my-secret")
volume = modal.Volume.from_name("my-data")
app = modal.App(image=image, secrets=[secret], volumes={"/mnt/data": volume})

name

name(self)

The user-provided name of the App.

Returns

The configured app name, if any.

app_id

app_id(self)

Return the app_id of a running or stopped app.

Returns

The app ID when the app has been deployed or run, otherwise None.

description

description(self)

The App's name, if available, or a fallback descriptive identifier.

Returns

Human-readable description string for the app.

lookup

lookup(name, *, client=None, environment_name=None, create_if_missing=False)

Look up an App with a given name, creating a new App if necessary.

Note that Apps created through this method will be in a deployed state, but they will not have any associated Functions or Classes. This method is mainly useful for creating an App to associate with a Sandbox.

Parameters

namestr
App name to resolve or create.
client_Client | None
Modal client to use; defaults to Client.from_env() when omitted.
environment_namestr | None
Optional environment name; defaults to the configured environment.
create_if_missingbool
If True, create the app when it does not already exist. (Default is False)

Returns

An App handle tied to the deployed app record.

Usage

app = modal.App.lookup("my-app", create_if_missing=True)
modal.Sandbox.create("echo", "hi", app=app)

get_dashboard_url

get_dashboard_url(self)

Get the dashboard URL for the App.

Returns

The dashboard URL for the App.

Usage

app = modal.App.lookup("my-app")
print(app.get_dashboard_url())

run

run(self, *, name=None, client=None, detach=False, interactive=False,
    environment_name=None)

Context manager that runs an ephemeral app on Modal.

Use this as the main entry point for your Modal application. All calls to Modal Functions should be made within the scope of this context manager, and they will correspond to the current App.

Note that you should not invoke this in global scope of a file where you have Modal Functions or Classes defined, since that would run the block when the Function or Cls is imported in your containers as well. If you want to run it as your entrypoint, consider protecting it with if __name__ == "__main__".

Parameters

client_Client | None
Modal client to use for the run session.
detachbool
Whether to detach after starting the app. (Default is False)
interactivebool
Whether to run in interactive mode. (Default is False)
environment_namestr | None
Optional environment name; defaults to the configured environment.

Returns

Async context manager yielding this App while it is running.

Usage

with app.run():
    some_modal_function.remote()

To enable output printing (i.e., to see App logs), use modal.enable_output():

with modal.enable_output():
    with app.run():
        some_modal_function.remote()

Note that you should not invoke this in global scope of a file where you have Modal Functions or Classes defined, since that would run the block when the Function or Cls is imported in your containers as well. If you want to run it as your entrypoint, consider protecting it:

if __name__ == "__main__":
    with app.run():
        some_modal_function.remote()

You can then run your script with:

python app_module.py

deploy

deploy(self, *, name=None, environment_name=None, tag="", client=None,
    strategy="rolling")

Deploy the App so that it is available persistently.

Deployed Apps will be available for lookup or web-based invocations until they are stopped. Unlike with App.run, this method will return as soon as the deployment completes.

This method is a programmatic alternative to the modal deploy CLI command.

Unlike with App.run, Function logs will not stream back to the local client after the App is deployed.

Note that you should not invoke this method in global scope, as that would redeploy the App every time the file is imported. If you want to write a programmatic deployment script, protect this call so that it only runs when the file is executed directly.

Parameters

namestr | None
Name for the deployment, overriding any set on the App.
environment_namestr | None
Environment to deploy the App in.
tagstr
Optional metadata that is specific to this deployment. (Default is "")
client_Client | None
Alternate client to use for communication with the server.
strategystr
Deployment strategy. rolling (default) shifts traffic gradually to new containers while old ones drain. recreate terminates all running containers as part of the deployment before new work starts. (Default is "rolling")

Returns

This app instance after deployment completes.

Usage

app = App("my-app")
app.deploy()

To enable output printing (i.e., to see build logs), use modal.enable_output():

app = App("my-app")
with modal.enable_output():
    app.deploy()

Unlike with App.run, Function logs will not stream back to the local client after the App is deployed.

Note that you should not invoke this method in global scope, as that would redeploy the App every time the file is imported. If you want to write a programmatic deployment script, protect this call so that it only runs when the file is executed directly. You can then run your script with:

if __name__ == "__main__":
    with modal.enable_output():
        app.deploy()

Then you can deploy your app with:

python app_module.py

local_entrypoint

local_entrypoint(self, _warn_parentheses_missing=None, *, name=None)

Decorate a function to be used as a CLI entrypoint for a Modal App.

These functions can be used to define code that runs locally to set up the app, and act as an entrypoint to start Modal functions from. Note that regular Modal functions can also be used as CLI entrypoints, but unlike local_entrypoint, those functions are executed remotely directly.

Note that an explicit app.run() is not needed, as an app is automatically created for you.

Parameters

namestr | None
Optional name for the entrypoint; defaults to the function's qualified name.

Returns

A decorator that registers the wrapped callable as a local CLI entrypoint.

Usage

@app.local_entrypoint()
def main():
    some_modal_function.remote()

You can call the function using modal run directly from the CLI:

modal run app_module.py

Note that an explicit app.run() is not needed, as an app is automatically created for you.

Multiple entrypoints

If you have multiple local_entrypoint functions, qualify the name:

modal run app_module.py::app.some_other_function

Parsing arguments

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 app_module.py --foo 1 --bar "hello":

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

Currently, str, int, float, bool, and datetime.datetime are supported. Use modal run app_module.py --help for more information on usage.

function

function(self, *, image=None, schedule=None, env=None, secrets=None, gpu=None,
    serialized=False, network_file_systems={}, volumes={}, cpu=None,
    memory=None, ephemeral_disk=None, min_containers=None, max_containers=None,
    buffer_containers=None, scaledown_window=None, proxy=None, retries=None,
    timeout=300, startup_timeout=None, name=None, is_generator=None, cloud=None,
    region=None, routing_region=None, nonpreemptible=False,
    enable_memory_snapshot=False, block_network=False,
    restrict_modal_access=False, single_use_containers=False, i6pn=None,
    include_source=None, experimental_options=None,
    _experimental_restrict_output=False, max_inputs=None)

Decorator to register a new Modal Function with this App.

Parameters

image_Image | None
The image to run as the container for the function.
scheduleSchedule | None
An optional Modal Schedule for the function.
envdict[str, str | None] | None
Environment variables to set in the container.
secretsCollection[_Secret] | None
Secrets to inject into the container as environment variables.
gpustr | list[str] | None
GPU request; either a single GPU type or a list of types.
serializedbool
Whether to send the function over using cloudpickle. (Default is False)
network_file_systemsdict[str | PurePosixPath, _NetworkFileSystem]
Mountpoints for Modal NetworkFileSystems. (Default is {})
volumesdict[str | PurePosixPath, _Volume | _CloudBucketMount]
Mount points for Modal Volumes & CloudBucketMounts. (Default is {})
cpufloat | tuple[float, float] | None
Specify, in fractional CPU cores, how many CPU cores to request. Or, pass (request, limit) to additionally specify a hard limit in fractional CPU cores. CPU throttling will prevent a container from exceeding its specified limit.
memoryint | tuple[int, int] | None
Specify, in MiB, a memory request which is the minimum memory required. Or, pass (request, limit) to additionally specify a hard limit in MiB.
ephemeral_diskint | None
Specify, in MiB, the ephemeral disk size for the Function.
min_containersint | None
Minimum number of containers to keep warm, even when Function is idle.
max_containersint | None
Limit on the number of containers that can be concurrently running.
buffer_containersint | None
Number of additional idle containers to maintain under active load.
scaledown_windowint | None
Max time (in seconds) a container can remain idle while scaling down.
proxy_Proxy | None
Reference to a Modal Proxy to use in front of this function.
retriesint | Retries | None
Number of times to retry each input in case of failure.
timeoutint
Maximum execution time for inputs and startup time in seconds. (Default is 300)
startup_timeoutint | None
Maximum startup time in seconds with higher precedence than timeout.
namestr | None
Sets the Modal name of the function within the app.
is_generatorNone | bool
Set this to True if it's a non-generator function returning a sync or async generator object.
cloudstr | None
Cloud provider to run the function on. Possible values are aws, gcp, oci, auto.
regionstr | Sequence[str] | None
Region or regions to run the function on.
routing_regionstr | None
Region to route inputs to the function through.
nonpreemptiblebool
Whether to run the function on a nonpreemptible instance. (Default is False)
enable_memory_snapshotbool
Enable memory checkpointing for faster cold starts. (Default is False)
block_networkbool
Whether to block network access. (Default is False)
restrict_modal_accessbool
Whether to allow this function access to other Modal resources. (Default is False)
single_use_containersbool
When True, containers will shut down after handling a single input. (Default is False)
i6pnbool | None
Whether to enable IPv6 container networking within the region.
include_sourcebool | None
Whether the file or directory containing the Function's source should automatically be included in the container. When unset, falls back to the App-level configuration, or is otherwise True by default.
experimental_optionsdict[str, Any] | None
Experimental options for the function.
_experimental_restrict_outputbool
Experimental; do not use pickle for return values. (Default is False)
max_inputsint | None
Deprecated; replaced with single_use_containers.

Returns

A decorator that registers the wrapped callable or partial as a Modal Function.

cls

cls(self, *, image=None, env=None, secrets=None, gpu=None, serialized=False,
    network_file_systems={}, volumes={}, cpu=None, memory=None,
    ephemeral_disk=None, min_containers=None, max_containers=None,
    buffer_containers=None, scaledown_window=None, proxy=None, retries=None,
    timeout=300, startup_timeout=None, cloud=None, region=None,
    routing_region=None, nonpreemptible=False, enable_memory_snapshot=False,
    block_network=False, restrict_modal_access=False,
    single_use_containers=False, i6pn=None, include_source=None,
    experimental_options=None, _experimental_restrict_output=False,
    max_inputs=None)

Decorator to register a new Modal Cls with this App.

Parameters

image_Image | None
The image to run as the container for the class service.
envdict[str, str | None] | None
Environment variables to set in the container.
secretsCollection[_Secret] | None
Secrets to inject into the container as environment variables.
gpustr | list[str] | None
GPU request; either a single GPU type or a list of types.
serializedbool
Whether to send the class over using cloudpickle. (Default is False)
network_file_systemsdict[str | PurePosixPath, _NetworkFileSystem]
Mountpoints for Modal NetworkFileSystems. (Default is {})
volumesdict[str | PurePosixPath, _Volume | _CloudBucketMount]
Mount points for Modal Volumes & CloudBucketMounts. (Default is {})
cpufloat | tuple[float, float] | None
Specify, in fractional CPU cores, how many CPU cores to request. Or, pass (request, limit) to additionally specify a hard limit in fractional CPU cores. CPU throttling will prevent a container from exceeding its specified limit.
memoryint | tuple[int, int] | None
Specify, in MiB, a memory request which is the minimum memory required. Or, pass (request, limit) to additionally specify a hard limit in MiB.
ephemeral_diskint | None
Specify, in MiB, the ephemeral disk size for the Function.
min_containersint | None
Minimum number of containers to keep warm, even when Function is idle.
max_containersint | None
Limit on the number of containers that can be concurrently running.
buffer_containersint | None
Number of additional idle containers to maintain under active load.
scaledown_windowint | None
Max time (in seconds) a container can remain idle while scaling down.
proxy_Proxy | None
Reference to a Modal Proxy to use in front of this function.
retriesint | Retries | None
Number of times to retry each input in case of failure.
timeoutint
Maximum execution time for inputs and startup time in seconds. (Default is 300)
startup_timeoutint | None
Maximum startup time in seconds with higher precedence than timeout.
cloudstr | None
Cloud provider to run the function on. Possible values are aws, gcp, oci, auto.
regionstr | Sequence[str] | None
Region or regions to run the function on.
routing_regionstr | None
Region to route inputs to the function through.
nonpreemptiblebool
Whether to run the function on a non-preemptible instance. (Default is False)
enable_memory_snapshotbool
Enable memory checkpointing for faster cold starts. (Default is False)
block_networkbool
Whether to block network access. (Default is False)
restrict_modal_accessbool
Whether to allow this class access to other Modal resources. (Default is False)
single_use_containersbool
When True, containers will shut down after handling a single input. (Default is False)
i6pnbool | None
Whether to enable IPv6 container networking within the region.
include_sourcebool | None
When False, don't automatically add the App source to the container.
experimental_optionsdict[str, Any] | None
Experimental options for the class service.
_experimental_restrict_outputbool
Experimental; do not use pickle for return values. (Default is False)
max_inputsint | None
Deprecated; replaced with single_use_containers.

Returns

A decorator that registers the wrapped class or partial as a Modal Cls.

server

server(self, *, image=None, env=None, secrets=None, gpu=None, serialized=False,
    volumes={}, cpu=None, memory=None, ephemeral_disk=None,
    target_concurrency=None, min_containers=None, max_containers=None,
    buffer_containers=None, scaleup_window=None, scaledown_window=None,
    startup_timeout=30, name=None, port=8000, unauthenticated=False,
    h2_enabled=False, exit_grace_period=0, routing_region="us-east",
    compute_region=None, cloud=None, nonpreemptible=False, proxy=None,
    i6pn=None, enable_memory_snapshot=False, include_source=None,
    experimental_options=None)

Decorator to register a new Modal Server with this App.

Servers run HTTP servers that are started in a @modal.enter() method. Unlike @app.cls(), servers only expose HTTP endpoints and do not support .remote() method calls.

See the guide for more information.

Parameters

image_Image | None
The image to run as the container for the server.
envdict[str, str | None] | None
Environment variables to set in the container.
secretsCollection[_Secret] | None
Secrets to inject into the container as environment variables.
gpustr | list[str] | None
GPU request; either a single GPU type or a list of types.
serializedbool
Whether to send the server class over using cloudpickle. (Default is False)
volumesdict[ str | PurePosixPath, _Volume | _CloudBucketMount ]
Mount points for Modal Volumes & CloudBucketMounts. (Default is {})
cpufloat | tuple[float, float] | None
Specify, in fractional CPU cores, how many CPU cores to request. Or, pass (request, limit) to additionally specify a hard limit in fractional CPU cores. CPU throttling will prevent a container from exceeding its specified limit.
memoryint | tuple[int, int] | None
Specify, in MiB, a memory request which is the minimum memory required. Or, pass (request, limit) to additionally specify a hard limit in MiB.
ephemeral_diskint | None
Specify, in MiB, the ephemeral disk size for the server.
target_concurrencyfloat | None
Target number of concurrent requests per container; 0 disables autoscaling. May be fractional, e.g. 1.5 to target three concurrent requests per two containers.
min_containersint | None
Minimum number of containers to keep running regardless of demand.
max_containersint | None
Limit on the number of containers that can be concurrently running.
buffer_containersint | None
Extra containers to scale up beyond current demand.
scaleup_windowint | None
Seconds of sustained demand required before scaling up new containers.
scaledown_windowint | None
Maximum duration (in seconds) idle containers wait before scaling down.
startup_timeoutint
Maximum container startup time in seconds. (Default is 30)
namestr | None
Sets the Modal name of the function within the app, defaults to class name.
portint
Port the HTTP server listens on. (Default is 8000)
unauthenticatedbool
Whether the endpoint requires proxy authentication; required by default. (Default is False)
h2_enabledbool
Enable HTTP/2. (Default is False)
exit_grace_periodint
Grace period for in-flight requests on shutdown. (Default is 0)
routing_regionstr
Region to route Server requests through. (Default is "us-east")
compute_regionstr | Sequence[str] | None
Region(s) where containers can be scheduled.
cloudstr | None
Cloud provider (aws, gcp, oci, auto).
nonpreemptiblebool
Whether to use non-preemptible instances. (Default is False)
proxy_Proxy | None
Modal Proxy to use in front of this server.
i6pnbool | None
Enable IPv6 container networking.
enable_memory_snapshotbool
Enable memory checkpointing. (Default is False)
include_sourcebool | None
Whether to add source to container.
experimental_optionsdict[str, Any] | None
Experimental options.

Usage

@app.server(port=8000, routing_region="us-east")
class MyServer:
    @modal.enter()
    def start(self):
        self.proc = subprocess.Popen(["python3", "-m", "http.server", "8000"])

    @modal.exit()
    def stop(self):
        self.proc.terminate()

include

include(self, /, other_app, inherit_tags=True)

Include another App's objects in this one.

Useful for splitting up Modal Apps across different self-contained files.

When inherit_tags=True any tags set on the other App will be inherited by this App (with this App's tags taking precedence in the case of conflicts).

Parameters

other_app"_App"
App whose registered functions and classes are merged into this app.
inherit_tagsbool
If True, merge tags from other_app into this app (this app wins on conflicts). (Default is True)

Returns

This app instance for chaining.

Usage

app_a = modal.App("a")
@app_a.function()
def foo():
    ...

app_b = modal.App("b")
@app_b.function()
def bar():
    ...

app_a.include(app_b)

@app_a.local_entrypoint()
def main():
    # use function declared on the included app
    bar.remote()

set_tags

set_tags(self, tags, *, client=None)

Attach key-value metadata to the App.

Tag metadata can be used to add organization-specific context to the App and can be included in billing reports and other informational APIs. Tags can also be set in the App constructor.

Any tags set on the App before calling this method will be removed if they are not included in the argument (i.e., this method does not have .update() semantics).

Parameters

tagsMapping[str, str]
Complete tag set to store on the app (replaces previous tags).
client_Client | None
Modal client to use for the RPC.

get_tags

get_tags(self, *, client=None)

Get the tags that are currently attached to the App.

Parameters

client_Client | None
Modal client to use for the RPC.

Returns

Tags as a map from key to value.

logs

logs: AppLogsManager

Access logs for an App.

Use fetch() to read logs from a UTC time range, tail() to read the most recent logs, and stream() to follow new logs as they arrive.

See Also

logs.fetch

fetch(self, *, since, until=None, source=None, search_text="")

Fetch App logs corresponding to the date range and filters.

Parameters

sincedatetime
Start date to fetch logs from. Must be in UTC or timezone-naive, which is interpreted as local time.
untildatetime | None
Defaults to current date if None. Must be in UTC or timezone-naive, which is interpreted as local time.
sourceLogSource | None
Filter by source: 'stdout', 'stderr', or 'system'.
search_textstr
Filter by search text. (Default is "")

Yields

LogEntry objects in chronological order.

Usage

app = modal.App.lookup("my-app")

for entry in app.logs.fetch(
    since=datetime.now() - timedelta(hours=4),
    source="stdout",
):
    print(entry.message, end="")

logs.tail

tail(self, entries=100, *, source=None)

Fetch the most recent App logs.

Parameters

entriesint
The number of log entries to return. (Default is 100)
sourceLogSource | None
Filter by source: 'stdout', 'stderr', or 'system'.

Yields

LogEntry objects in chronological order.

Usage

app = modal.App.lookup("my-app")

for entry in app.logs.tail(20):
    print(entry.message, end="")

logs.stream

stream(self, timeout=None)

Stream new App logs until the timeout is reached.

Parameters

timeoutfloat | None
Number of seconds to wait between log entries before terminating the stream. By default, this will block until it is interrupted.

Yields

LogEntry objects as they arrive.

Usage

app = modal.App.lookup("my-app")

for entry in app.logs.stream(timeout=60):
    print(entry.message, end="")