Skip to main content
Modal provides several decorator functions for modifying function and method behavior.

@modal.method

@modal.method(
    *,
    is_generator: Optional[bool] = None,
)
Decorator for methods within a @app.cls() class. Marks a method as a Modal method that can be called remotely.
is_generator
bool
Explicitly mark whether the method is a generator. Auto-detected if not specified.
Example:
@app.cls()
class MyModel:
    @modal.method()
    def predict(self, x):
        return x * 2

result = MyModel().predict.remote(21)  # Returns 42

@modal.enter

@modal.enter(
    *,
    snap: bool = False,
)
Decorator for lifecycle methods that run when a container starts. Can be used with both classes and functions.
snap
bool
default:"False"
If True, method runs before snapshotting (requires enable_memory_snapshot=True).
Example:
@app.cls()
class MyService:
    @modal.enter()
    def startup(self):
        print("Container starting up")
        self.model = load_model()
    
    @modal.method()
    def predict(self, x):
        return self.model.predict(x)

@modal.exit

@modal.exit()
Decorator for lifecycle methods that run when a container shuts down. Example:
@app.cls()
class MyService:
    @modal.exit()
    def shutdown(self):
        print("Container shutting down")
        self.cleanup()

@modal.build

@modal.build()
Decorator for methods that run during image build time. Useful for downloading models or other build-time setup. Example:
@app.cls()
class MyModel:
    @modal.build()
    def download_model(self):
        # This runs during image build
        download_weights()

@modal.web_endpoint

@modal.web_endpoint(
    method: str = "GET",
    label: Optional[str] = None,
    docs: bool = False,
)
Decorator to create a web endpoint from a function.
method
str
default:"GET"
HTTP method (GET, POST, PUT, DELETE, etc.).
label
str
Custom label for the endpoint URL.
docs
bool
default:"False"
Enable automatic API documentation.
Example:
@app.function()
@modal.web_endpoint(method="POST")
def my_endpoint(data: dict):
    return {"result": process(data)}

@modal.asgi_app

@modal.asgi_app()
Decorator to serve an ASGI application (e.g., FastAPI, Starlette). Example:
from fastapi import FastAPI

web_app = FastAPI()

@web_app.get("/hello")
def hello():
    return {"message": "Hello World"}

@app.function()
@modal.asgi_app()
def fastapi_app():
    return web_app

@modal.wsgi_app

@modal.wsgi_app()
Decorator to serve a WSGI application (e.g., Flask, Django). Example:
from flask import Flask

web_app = Flask(__name__)

@web_app.route("/")
def home():
    return "Hello World"

@app.function()
@modal.wsgi_app()
def flask_app():
    return web_app

@modal.concurrent

@modal.concurrent(
    *,
    max_inputs: int,
    target_inputs: Optional[int] = None,
)
Decorator to enable concurrent input processing for a function or class.
max_inputs
int
required
Maximum number of concurrent inputs per container.
target_inputs
int
Target number of concurrent inputs for autoscaling.
Example:
@app.function()
@modal.concurrent(max_inputs=100)
async def process(item):
    await async_work(item)

@modal.batched

@modal.batched(
    max_batch_size: int,
    wait_ms: int,
)
Decorator to enable automatic batching of inputs.
max_batch_size
int
required
Maximum batch size.
wait_ms
int
required
Maximum time to wait for a batch in milliseconds.
Example:
@app.function()
@modal.batched(max_batch_size=32, wait_ms=100)
def predict_batch(items: list):
    # items is a list of inputs
    return model.predict(items)

Build docs developers (and LLMs) love