File and project structure

Apps spanning multiple files

If you have a project spanning multiple files, you can still use a single Modal Stub to create Modal resources across all of them.

Assume we have a package named pkg with files a.py and b.py that contain functions we want to deploy:

pkg/
├── __init__.py
├── a.py
└── b.py

First create a separate file with your shared Modal resources, such as your stub definition and images:

# pkg/common.py
stub = modal.Stub()

image_1 = modal.Image.debian_slim().pip_install(...)
image_2 = modal.Image.debian_slim().pip_install(...)

Then, import these definitions from each of your existing project files and decorate any functions you need to deploy:

# pkg/a.py
from .common import stub, image_1

@stub.fuction(image=image_1)
def f():
    ...
# pkg/b.py
from .common import stub, image_2

@stub.fuction(image=image_2)
def g():
    ...

Finally, to deploy all of these resources together, make a single deployment file that imports all of the app resources that should be created in one place:

# pkg/deploy.py
from .a import f
from .b import g

Now you can deploy your app by running modal deploy pkg.deploy from above the pkg directory. Your deployed Modal app will have both f and g.

The final file structure now looks like this:

pkg/
├── __init__.py
├── common.py
├── a.py
├── b.py
└── deploy.py

Tip: you can also make __init__.py your deployment file, which makes deploying a package slightly more convenient. With this, you can deploy your entire project using just modal deploy pkg.