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.
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.
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.
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)
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.
-
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 directlyNot 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.