File and project structure
Apps spanning multiple files
If you have a project spanning multiple files, you can either use a single Modal
App
to create Modal resources across all of them or
compose multiple apps using
app.include(other_app)
into a single
app at deploy time.
In this guide we’ll show you how to use composition of multiple smaller files with their own “apps” in order to cleanly separate different parts of your app into multiple files. You can see a realistic instance of a single app use in our LLM + TTS example.
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
# pkg/a.py
a_app = modal.App("a")
image_1 = modal.Image.debian_slim().pip_install("some_package")
@a_app.function(image=image_1)
def f():
...
# pkg/b.py
b_app = modal.App("b")
image_2 = modal.Image.debian_slim().pip_install("other_package")
@b_app.function(image=image_2)
def g():
...
To deploy these resources together, make a
single deployment file, perhaps deploy.py
(the name itself doesn’t matter),
that imports the apps from each of the sub-modules and includes them in a
common parent app that represents your entire app:
# pkg/deploy.py
from .a import a_app
from .b import b_app
app = modal.App("multi-file-app")
app.include(a_app)
app.include(b_app)
Now you can deploy your app by running modal deploy pkg.deploy
from above the
pkg
directory. Your deployed Modal app will have both the f
and g
functions.
The final file structure now looks like this:
pkg/
├── __init__.py
├── a.py
├── b.py
└── deploy.py
One advantage of splitting up apps this way is that you can opt to run only part
of your larger app during development. For example, running modal run a.py
to
test some functionality in that part without having to process any changes to
the rest of the app.
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
.
Note: Since the multi-file app still has a single namespace for all functions, it’s important to name your Modal functions uniquely across the project even when splitting it up across files - otherwise you risk some functions “shadowing” others with the same name.