Skip to main content

Getting Started

So you installed arkitekt and now you want to start using it. This guide will help you get started. This tutorial assumes you have a basic (really basic) understanding of the command line and have arkitekt installed on your computer.

Lets check things are setup correctly

Before we start, lets make sure that arkitekt is installed correctly. To do this, we will run the following command.

Hallo

If you dont see the following output, then you need to go back and install arkitekt. If you are still not greeted by the CLI, try to install arkitekt in a new virtual environment (conda or venv) and try again.

Creating a new app

Now that things are setup correctly, lets create a new app. To do this, we will run the following command.

Create a new folder for your app, which we will call demo and then navigate into it.

mkdir demo
cd demo

Inside the folder, we will run the following command to create a new arkitekt app.

arkitekt init

This will launch the arkitekt CLI and ask you a few questions about your app. Don't worry, you can always change these settings later. For now, lets just use what the CLI suggests.

Hallo

What just happened?

Arkitekt jsut initialized a new app for you. If you inspect the folder you will see that a new file called app.py has been created as well as a new folder called .arkitekt. Lets briefly go over what these files are and what they are used for.

The .arkitekt folder

The .arkitekt folder is a folder that contains information about your app. Most Importantly, it contains the manifest for your app, which is a file that contains information about your app, such as its name, version, and entrypoint, but also information about which rights your app needs to run, and how it should be built and deployed. This manifest is a crucial part of your app, and you should not delete it. You can read more about the manifest in the manifest section.

Lets look at the manifest that was created for us, if you chose the filter template:

author: jhnnsrs
entrypoint: app
identifier: demo
requirements: []
scopes:
- read
version: 0.0.1

This is a very simple manifest. It contains information about the author of the app, the entrypoint, the name of the app, So far we have only very basic access rights (we can read data from the platform, but not write to it), but we will change this later. Also note that we have not defined any requirements for our app. Requirements let us define hardware and software requirements for our app, when it is being deployed as an PluginApp. We will also change this later.

You will also note that the ".arktiekt" folder containts some additional files such as ".gitignore" and ".dockerignore". These files are used to prevent git and docker from including cached secrests (such as accesstokens) in your git repository or docker image. You should not delete these files, as they are crucial for the security of your app.

I dont see the .arkitekt folder

By default, the .arkitekt uses the "." prefix, to hide it from the file explorer on your computer. This is a common practice for folders that are used to store configuration files, such as the .git folder. If you are using a file explorer that does not show hidden files, you might not see the .arkitekt folder. Dont' worry though, most IDEs will show hidden files by default, and you can always use the terminal to navigate into the folder.

The app.py file

The app.py file is the entrypoint for your app. When you run your app, this is the file that will be executed. Arkitekt will import this file and register all of the functions that are defined (and decorated) with your arkitekt instance, enabling them as nodes. You can imaging the app.py file as the "main" file of your app, for all things "arkitekt" related.

Lets take a look at the app.py file that was created for us, if you chose the filter template:

from arkitekt import register
from mikro.api.schema import RepresentationFragment, from_xarray


@register
def max_intensity_projection(image: RepresentationFragment) -> RepresentationFragment:
"""Z-Project the Maximum Intensity

This function projects the maximum intensity of the input image
along the z-axis

Parameters
----------
image : RepresentationFragment
The input image

Returns
-------
RepresentationFragment
The projected image

"""
image = image.data.max(dim="z")
return from_xarray(
image, name="Max Intensity Projection" + image.name, origins=[image]
)

This is the hello world of arkitekt apps. A simple function that takes an image as input and returns a new image as output. Lets break it down.

from arkitekt import register
from mikro.api.schema import RepresentationFragment, from_xarray

First we import the register decorator from the arkitekt package. This is the decorator that we will use to register our functions with the arkitekt instance. We also import the RepresentationFragment and from_xarray functions from the mikro package (which will help us interact with the Mikro service on the connected instance). Calling from_xarray will create a new representation/image from any xarray or numpy object.

@register
def max_intensity_projection(image: RepresentationFragment) -> RepresentationFragment:
"""Z-Project the Maximum Intensity

This function projects the maximum intensity of the input image
along the z-axis

Parameters
----------
image : RepresentationFragment
The input image

Returns
-------
RepresentationFragment
The projected image

"""
...

And this is our function. It takes a single argument, which is an image, and returns a new image. The function is decorated with the @register decorator, which will register the function with the arkitekt instance when the app is run. A lot of the information that is needed to register the function is extracted from the function signature. For example, the name of the function is extracted from the function name, the description is extracted from the docstring, and the input and output types are extracted from the function signature. The @register decorator also takes a few optional arguments, which can be used to customize the registration process. You can read more about the @register decorator in the decorators section.

image = image.data.max(dim="z")
return from_xarray(
image, name="Max Intensity Projection" + image.name, origins=[image]
)

And this is the body of our function. When calling our function, the arkitekt instance will pass in a RepresentationFragment object, which contains the input data. We can access the data by calling image.data. The data is stored as an xarray object, which we can use to perform our calculations. In this case, we are calculating the maximum intensity projection of the image along the z-axis. We then create a new Image on the platform from the calculated data and return it, through the from_xarray function. (Note that we are also adding a prefix to the name of the image, to make it easier to distinguish between the input and output images)

Why Representation Fragment?

If you are wondering why our image is called a RepresentationFragment and not just an image, please read the mikro and graphql sections of the docs. But in short, a RepresentationFragment is a representation of an image that is stored on a mikro instance. It contains information about the image, such as its name, description, and data. Besides the data, it also contains a "fragment" of metadata from all of the metadata that is associated with the image. The nomenclature is a bit confusing, and we will definetly change it in the future, but for now, just think of it as an image.

A few things to note
  • The app.py file should NOT contain any code that is being executed when the file is imported. It should rather contain a collection of function that are being registered with the arkitekt instance. If you have code that is being executed when the file is imported, it will be executed every time a user runs your app (or you run and change your file in dev mode

    Ok:

    if __name__ == "__main__":
    print("Hello World") # will only be executed when the file is run directly

    Not ok:

    print("Hello World") # will be executed every time the file is imported
  • The app.py should NOT contain an app instance (e.g. when calling easy("app", "version")), as this will be created by the arkitekt CLI when you run your app.

Running Demo

Now that we have created our app, lets run it. Lets start by running it in dev mode. Follow on to the next section.