requirements for installable Python projects, app_files for local files and directories, local_python_modules for Python modules that should be serialized alongside your app, and clone_repository for pulling external Git repos at startup.
These mechanisms work with the fal Runtime (pip requirements). If your app uses a custom Docker container, package or copy your code in the Dockerfile instead.
Choosing the Right Mechanism
fal provides several ways to bring code into the remote environment, each suited to a different situation. Use local-pathrequirements when your local code is an installable Python project with a pyproject.toml. This is the best choice for projects with dependencies or optional extras such as .[extra] or projects/foo[extra]. fal builds an sdist locally and uses it in the remote environment.
Use app_files when you have a multi-file project that is not packaged as an installable Python project, or when you need to include non-Python assets alongside your app. Files are uploaded and placed at the same relative paths, so imports and file reads work identically to local development.
Use local_python_modules when you have a simple Python module that your app imports at the top level. The module is serialized (pickled) alongside your app class and made available on the remote Python path. This is lighter-weight than app_files but only works for importable Python packages.
Use clone_repository when you need to pull code from an external Git repository at runner startup. The clone happens inside setup(), so the code is available before your first request.
Local Project Requirements
Use local-path entries inrequirements when your app code or shared library is packaged as a Python project. For entries such as ., .[extra], and projects/foo[extra], fal builds an sdist locally and uses it in the remote environment.
pyproject.toml with [project].name. Optional extras are preserved, so .[extra] becomes an install of your package with that extra on the runner.
For monorepos, either point the requirement at the package directory:
requirements_context_dir and use . relative to that directory:
fal.function, pass the same option to the decorator:
pyproject.toml app configuration, set the same fields on the app entry:
requirements are resolved from requirements_context_dir. When no context directory is set, class-based apps resolve from the app file directory, while pyproject.toml app entries resolve from the directory containing pyproject.toml. Relative requirements_context_dir values in pyproject.toml are also resolved from the directory containing pyproject.toml.
Package Entry Points
By default, aref such as apps/image_generator/app.py::ImageGenerator loads your app file locally and serializes the fal.App class into the deployment payload. Use python_entry_point when your app or function is part of an installable Python package and you want the runner to import it by module path instead.
Package entry points are useful when your app is already structured as a package, when you want top-level package code to run in the remote environment, or when your app definition references objects that should be imported normally rather than pickled from your local process.
my_image_app/server.py:
pyproject.toml with python_entry_point:
python_entry_point must use <module>:<symbol> format. The symbol can be a fal.App subclass or a @fal.function, and python_entry_point is mutually exclusive with ref.
When you use python_entry_point, put runtime and deployment settings in the [tool.fal.apps.<app-name>] entry. fal uses the options from pyproject.toml, such as machine_type, requirements, auth, scaling settings, and image configuration, instead of reading those settings from the imported app class or function decorator.
When you use the fal Runtime, include the package through local-path requirements such as ., .[serverless], or projects/foo[serverless]. For monorepos, use requirements_context_dir the same way as with local project requirements:
requirements. The entry point can still point at the installed package:
App Files
Theapp_files attribute includes local files and directories in the remote environment, mirroring your local file layout exactly. Imports and file paths work the same way they do on your machine.
from utils.helper import process_data and from models.classifier import MyModel work exactly as they do locally. Files are placed relative to your app file location.
Context Directory
By default, all file paths are resolved relative to the directory containing your fal app file. You can change this base directory withapp_files_context_dir, which is useful for monorepos or when you need to include files from a parent directory:
../../outside) are rejected. Included files are read-only on the runner.
Ignoring Files
Useapp_files_ignore to exclude files using regex patterns. fal excludes .pyc, __pycache__/, .git/, and .DS_Store by default.
Local Python Modules
Thelocal_python_modules attribute ships a Python module alongside your app by serializing it into the deployment payload. This is a simpler mechanism than app_files - it adds the specified modules to the remote Python path so they can be imported directly. Use it when you have a small utility module that your app imports at the top level.
app_files is the better choice because it preserves the full directory structure and supports ignore patterns.
Git Repositories
Useclone_repository to pull code from a Git repository at runner startup. The clone happens inside setup(), so the repository is available before any requests are processed. Pin to a specific commit hash for reproducibility.
include_to_path=True adds the cloned directory to PYTHONPATH, so you can import modules from the repository directly.
For a private repository, build the URL from a
secret. Do not write the
token in your code. clone_repository runs in setup(), which is runtime, so
fal supplies the secret as a normal environment variable.
A private package in
requirements works differently. That install runs at
build time, before a runner exists. fal puts the secret in the requirement
string and does not set an environment variable. Write ${GITHUB_TOKEN} in the
string, and do not call os.environ.Use this rule. Code in setup() or in an endpoint is runtime, so use
os.environ. Entries in requirements are build time, so use ${...}. Refer
to Private Packages.