Package Creation Quickstart

Perhaps you want to tweak an existing protocol, build off other protocols, or create something entirely new. Whatever the reason, it's time to learn how to create a package for yourself. This guide will walk you through the process of writing a protocol to run on Strateos, from start to finish.


First off, you'll need to understand a little about Autoprotocol. Autoprotocol instructions are the basic building blocks of protocols at Strateos. Autoprotocol is a specification for a JSON-formatted, biologically precise description of actions to be taken to perform a protocol. Please read the spec at to see what different instructions look like expressed as Autoprotocol. For this guide, it isn't necessary to know all the details, but you'll definitely want to refer to the Autoprotocol specification while writing your protocol.

There are no decisions made in the course of executing a run. The instructions will be executed from start to finish, as quickly as possible, and it is up to you to submit another run, if further action is desired.

Generating Autoprotocol

A protocol isn't always the exact same set of steps. Depending on the inputs, you may want to pipette different volumes, or heat at a different temperature. To respond to these varying conditions, we encode the decision making process in a programming language (in this case, Python). Your script will take in a set of parameters, and convert them into explicit, precise actions to be taken.

You'll also want to refer to the About Autoprotocol and Related Tools section of this documentation, but we'll do a brief overview here.

To the code!

Without further ado, let's jump into the code. We're going to build a simple protocol that transfers an amount of dye you specify to a corresponding well you specify. We'll use the autoprotocol-python library for convenience.

from autoprotocol.unit import Unit

def sample_protocol(protocol, params):
    dest_plate = params["destination_plate"]
    wells_to_measure = []

    for location in params["dye_locations"]:
        if location["volume"] != Unit(100, "microliter"):
                              Unit(100,"microliter") - location["volume"],
                              mix_after = True)

    protocol.absorbance(dest_plate, wells_to_measure, "475:nanometer", "test")

if __name__ == '__main__':
    from autoprotocol.harness import run
    run(sample_protocol, "SampleProtocol")

This file defines a function, sample_protocol(), which takes two arguments. The first, protocol, is an instance of the Protocol class. It starts empty, and it's the job of the sample_protocol function to add instructions and refs to it.

The second argument, params, is a dictionary containing all of the parameters used within the protocol, entered by the user. The form of those inputs, as well as other metadata about the protocol, is defined in the manifest.json file:

  "format": "python",
  "license": "MIT",
  "protocols": [
      "name": "SampleProtocol",
      "version": "1.0.0",
      "description": "Measure absorbance of various dilutions of OrangeG dye.",
      "command_string": "python",
      "inputs": {
          "dye": "aliquot",
          "water": "aliquot",
          "destination_plate": "container",
            "type": "group+",
            "description": "Each group represents a volume of dye to be placed in the specified well",
            "inputs": {
              "volume": {
                "type": "volume",
                "description": "Enter a volume up to 100 microliters"
              "well_index": {
                "type": "string",
                "description": "Enter a numerical well index (between 0 and 95)"
      "preview": {/* see code snippet below */}

The manifest defines metadata that is package-wide (the "format" and "license" fields), as well as a list of protocols contained in the package and metadata about each protocol. Read more about the manifest file here.

The "inputs" dictionary in a protocol's metadata defines what data a user must supply through the UI before executing the protocol. Each key in the dictionary is the name of an input, and the value is the type of input. See Input types for details of the various input types available. Each input is turned into its respective field type in the UI.

The "preview" section (omitted in the above example and optional in general) contains an example input set from which the transcriptic preview command will generate a preview of your protocol formatted in autoprotocol on the command-line. This should be representative of the expected input. We'll use this as our preview input set:

"preview": {
   "refs": {
       "type": "micro-1.5",
       "store": "cold_4"
     "Water": {
       "type": "micro-1.5",
       "store": "cold_4"
     "Test plate": {
       "type": "96-flat",
       "discard": true
     "dye": "OrangeG/0",
     "water": "Water/0",
     "destination_plate": "Test plate",
     "dye_locations": [
       {"volume": "10:microliter", "well_index": 0},
       {"volume": "20:microliter", "well_index": 1},
       {"volume": "30:microliter", "well_index": 2},
       {"volume": "40:microliter", "well_index": 3},
       {"volume": "100:microliter", "well_index": 4}

The last thing we need before we can run this protocol is a requirements.txt file to import the autoprotocol-python library. You can specify either the latest release, or if your script uses unreleased changes to the library, you can specify the latest commit's SHA from the repo:

# requirements.txt using the latest autoprotocol release 
# requirements.txt using a specific commit from a git repo
-e git://[email protected]<commit SHA>#egg=autoprotocol

To try it out before we upload it, save the manifest.json, requirements.txt and files to a directory called Install and login to the transcriptic runner if you haven't already, then open your terminal and run:

$ pip install -r requirements.txt
$ transcriptic preview SampleProtocol
# ... autoprotocol! ...

This will give you the autoprotocol output of your script using the parameters in the "preview" section of your manifest.json file (if applicable).

Packaging and uploading

The last step is to package all files into a file and upload it to Strateos.

Zip up your requirements.txt, manifest.json and files from the command line:

$ zip requirements.txt manifest.json

or compress them as in the video below:


requirements.txt, manifest.json and any code you're including in your package must exist at the top level of a zip, do NOT zip or compress a folder

Navigate to where it says your organization's name in the upper right corner, then click on "Manage." On the next screen click on the "Packages" tab and then click "Create A New Package." Enter a name and description for your package and upload your zipped archive. Finally, click on "publish" next to your release to make it available for all members of your organization.

If you have updated or added a script as part of a package, you may upload a new release by clicking the "upload new" button in the upper right corner of the screen when viewing a package. Ensure that the "version" number for each protocol your manifest.json file is at least one patch version larger than any previous uploads.

Congratulations! You just created your first package!

Clicking the "Launch a Run" button from any project will bring up the Protocol Browser, and protocols you've uploaded yourself will appear under the "Organization" link