Global variables
There are cases where you might want objects or data available in global scope. For example:
- You need to use the data in a scheduled function (scheduled functions don’t accept arguments)
- You need to construct objects (e.g. Secrets) in global scope to use as function annotations
- You don’t want to clutter many function signatures with some common arguments they all use, and pass the same arguments through many layers of function calls.
For these cases, you can use the
modal.is_local
function, which
returns True
if the app is running locally (initializing) or False
if the
app is executing in the cloud.
For instance, you can use a modal.Dict
object to
store one or multiple objects by key (similar to a Python dict) for later access
in Modal functions:
import json
import random
if modal.is_local():
with open("list.json", "r") as f:
foo_list = json.load(f) # reads from local disk on the development machine
stub.data_dict = modal.Dict({"foo": foo_list})
@stub.function(schedule=modal.Period(days=1))
def daily_random_entry():
print(random.choice(stub.app.data_dict["foo"]))
Similarly, to create a modal.Secret
that you can pass
to your function decorators to create environment variables, you can run:
import os
if modal.is_local():
stub["password"] = modal.Secret.from_dict({"PGPASS": os.environ["MY_LOCAL_PASSWORD"]})
@stub.function(secret=stub["password"])
def get_secret_data():
connection = psycopg2.connect(password=os.environ["PGPASS"])
...
Warning about regular module globals
If you try to construct a global in module scope using some local data without
using something like
modal.is_local
, it might have
unexpected effects since your Python modules will be not only be loaded on your
local machine, but also on the remote worker.
E.g., this will typically not work:
# blob.json doesn't exist on the remote worker, so this will cause an error there
data_blob = open("blob.json", "r").read()
@stub.function()
def foo():
print(data_blob)