Simple Application with Dependencies

Here's a an example of an application that include a local module and package, and also depend on third-party PiPy libraries.

A dstack application may contain its own packages and modules as well have dependencies to third-party libraries.

In order to push such an application, one must provide the information on these packages, modules, and libraries within the call of the dstack.app() function.

Imagine, we have a folder with the following structure:

utils
__init__.py
fake_utils.py
app.py
requirements.txt
handlers.py

Here's app.py:

import dstack as ds
from handlers import fake_handler
# Create an instance of an application an pass over
# dependencies to local modules "handlers" and "utils" and third-party packages
app = ds.app(depends=["handlers", "utils"], requirements="requirements.txt")
# The line above is equal to the line below
# app = ds.app(depends=["numpy", "pandas", "faker==5.5.0", "handlers", "utils"])
# An output with a handler from one of the modules the application depends on
app.output(handler=fake_handler)
# Deploy the application with the name "faker" and print its URL
url = app.deploy("faker")
print(url)

As you see, we use depends and requirements arguments to specify what modules, packages, and libraries our application depends on. In this case, the application depends on the module `handlers`, the package utils, and on all libraries specified in the requirements.txt.

The depends argument may list either local modules and packages or PiPy packages. An alternative equivalent of the line above would be the following:

app = ds.app(depends=["numpy", "pandas", "faker==5.5.0", "handlers", "utils"])

Note, it's important that when you run app.py the root directory is deps_app where handlers and utils are located. If the directory is different, dstack may not find them.

Here's handlers.py:

import pandas as pd
from utils.fake_utils import random_names, random_genders, random_dates
def fake_handler(self):
size = 100
df = pd.DataFrame(columns=['First', 'Last', 'Gender', 'Birthdate'])
df['First'] = random_names('first_names', size)
df['Last'] = random_names('last_names', size)
df['Gender'] = random_genders(size)
df['Birthdate'] = random_dates(start=pd.to_datetime('1940-01-01'), end=pd.to_datetime('2008-01-01'), size=size)
self.data = df

Here's utils/fake_utils.py:

import numpy as np
import pandas as pd
from faker.providers.person.en import Provider
def random_names(name_type, size):
names = getattr(Provider, name_type)
return np.random.choice(names, size=size)
def random_genders(size, p=None):
if not p:
p = (0.49, 0.49, 0.01, 0.01)
gender = ("M", "F", "O", "")
return np.random.choice(gender, size=size, p=p)
def random_dates(start, end, size):
divide_by = 24 * 60 * 60 * 10 ** 9
start_u = start.value // divide_by
end_u = end.value // divide_by
return pd.to_datetime(np.random.randint(start_u, end_u, size), unit="D")

Here's requirements.txt:

pandas
numpy
faker==5.5.0

Now if you run app.py and click the URL, you'll see a very simple application that on every run generates a new list of fake personal data.

When you run the application the first time, dstack makes sure all dependencies are installed.