Sharing functions

Modal lets you take a function created in an app and call it from other contexts. Some use cases:

  • You want to call Modal code from outside Modal. For instance if you have an existing web server in Python and you want to call some function running in Modal.
  • You have a large code base of Modal code and you want to break it up into units that are deployed independently.

Calling code from outside Modal.

Let’s say you have a script my_shared_app.py and this script defines a Modal app with a function that computes the square of a number:

import modal

stub = modal.Stub("my-shared-app")

@stub.function
def square(x):
    return x ** 2

Now, you can deploy this app to create a persistent deployment:

% modal app deploy shared_app.py
✓ Initialized.
✓ Created objects.
├── 🔨 Created square.
├── 🔨 Mounted /Users/erikbern/modal/shared_app.py.
✓ App deployed! 🎉

View Deployment: https://modal.com/deployments/my-shared-app

Let’s try to run this function from a different context. For instance, let’s fire up the Python interactive interpreter:

% python
Python 3.9.1 (v3.9.1:1e5d33e9b9, Dec  7 2020, 12:44:01)
[Clang 12.0.0 (clang-1200.0.32.27)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import modal
>>> f = modal.lookup("my-shared-app", "square")
>>> f(42)
1764
>>>

Importing a Modal function between apps.

You can also import one function defined in an app from another app:

import modal

stub = modal.Stub("another-app")
stub.square = modal.ref("my-shared-app", "square")

@stub.function
def cube(x):
    return x * stub.square(x)

if __name__ == "__main__":
    with stub.run():
        assert cube(42) == 74088

Difference from using ephemeral apps

If you have a non-Modal web server and want to run Modal code from it, you could of course run it using stub.run. What’s the benefit of deploying a function and looking it up from a different context?

  • You will be able to call this function much faster, since it doesn’t have to be created each time. Since Modal knows that it’s the same function, it will in fact keep containers “warm” for a short period in between function calls. This means subsequent function calls will be even faster.
  • You can separate the code bases. The caller doesn’t have to know anything about the implementation of the function.
  • The code bases can be deployed independently. For instance the function might be a machine learning prediction function that gets deployed by a different team or a different pipeline.
  • Ephemeral apps are typically meant for interactive development. They will show up in the web UI and clutter the interface if there are many.

Difference from webhooks

You can also use webhooks to share functions. Some differences:

  • Webhooks are public to the entire internet, whereas shared functions are only visible to you (and your org).
  • You can work with shared functions as if they are normal Python functions, which might be more convenient.