Blocks
Blocks are the units of work that comprise a worklet.
Blocks are the units of work that comprise a worklet. To create a block, click "Add block" in a worklet graph and select the type of block that you want to add.
Baseten allows you to write your own Python code as part of your worklet. Simply add a Code block to your worklet and select the desired function from a file.

Code blocks require a function with the following signature, selected from the appropriate file.
def func(block_input, env, context):
The three arguments are all optional, but they are positional, so you can't have
env
without block_input
or context
without both block_input
and env
. Because the arguments are positional, you can call them whatever you want, but we recommend sticking with the standard parameter names. Valid function signatures:def func():
def func(block_input):
def func(block_input, env):
def func(block_input, env, context):
def func(predictions, env, context): # Meaningful name for block_input
def func(apples, oranges, grapefruit): # Valid, but not recommended
Let's examine the arguments individually.
This is the input to the block. If this block is the first in the worklet, then
block_input
is what the worklet was called with. Otherwise block_input
is the return value of the previous block in the worklet.Exclusively relying on block input/output for the execution of the worklet would cause headaches. What if the final block needs to access the first block's input? Would you have to ensure that the input is passed along all the way to the end? No.
That's where
env
comes in. It's an empty dictionary to which you can add key/value pairs (again, JSON-serializable values only). env
is persisted through the worklet execution, which means that after a block modifies it, all subsequent blocks have access to that data.While
block_input
is limited in scope to a single block and env
is limited to a single worklet, context
infuses your function with every available data source. context
provides contextual information as well as variety of ways of invoking many Baseten functionalities:- 1.
- 2.
- 3.
- 4.Access to user information like user ID and username
Visit those pages to learn how to use the
context
parameter for specific use cases.It's worth repeating that Code blocks must explicitly return a JSON-serializable value to use as input for the next block, unless the Code block in question is the last block in a worklet. Even in this case, we recommend returning JSON in case the worklet is ever called from another worklet.
If your function is only called for its side effects, simply end with
return block_input
to pass along the block's input to the next block in the worklet.A Model block is the heart of any ML-powered worklet. This block invokes a selected model and returns its output.

While the model doesn't have access to
env
or context
, the output of the previous block becomes the model's input. As such, make sure to pass along an input of the correct type. For example, if the model expects a list or numpy array, the previous block should return this type.In your model blocks, you can set a model's version. Like all changes to worklets, changing a model version is environment-specific for users in workspaces with the draft environment feature. Setting the model version to primary will keep your worklet up-to-date as you publish new model versions, but specifying a version lets you roll out new model versions in sync with application changes that support the new version.

The query block, like all other blocks, takes a JSON dictionary as input. For queries that do not require input, this can be an empty dictionary. But in some cases, we need to pass inputs into a query. For example:
SELECT
id,
image_url,
Round(friendly_score, 2) AS "Friendly score",
Round(dangerous_score, 2) AS "Dangerous score",
Round(not_feline_score, 2) AS "Not feline score"
FROM
classified_feline
WHERE
friendly_score < {{upper_limit}}
AND friendly_score > {{lower_limit}}
AND friendly_score != 1
AND dangerous_score != 1
OR (
not_feline_score > friendly_score
AND not_feline_score > dangerous_score
)
In this case, invoking the query block would require passing in:
{
"upper_limit": 0.6,
"lower_limit": 0.4
}
The query block outputs a dictionary with the key
results
and a list of query results. For example, a query that returns the following tabular output:question | answer
"What is 1 + 1" | 2
"What is 7 - 2" | 5
Would return the following JSON when run as a worklet block:
{
"results": [
{
"question": "what is 1 + 1",
"answer": 2
},
{
"question": "what is 7 - 2",
"answer": 5
}
]
}
Decision blocks are very similar to Code blocks in that you write custom Python code with access to the same
block_input, env, context
args. However, Decision blocks' output must be a boolean, which will determine which of its two child blocks should be called next.

If the decision block returns
True
(or a truthy value), the "then" path will be executed. If it returns False
(or equivalent), the "else" path will be executed.Since a block's output becomes the subsequent block's input, you can imagine that the boolean result of the Decision block will become the input to its subsequent block. That would be somewhat useless, so we made an exception: The input to the Decision block becomes the input to the subsequent block.
While
block_input
and env
are available arguments for a Decision block's function, they are considered read-only. Decision blocks should solely return a boolean value, not have any side effects. Any changes made to the input or environment will not be available in subsequent blocks.Worklets, like functions, are composable. With a worklet block, you can call another worklet from your current worklet. This does not result in a new API request or worklet invocation, and
env
persists in the called worklet. This block returns the result of the called worklet, so be sure to format it as a valid input for the next block.

If you don't enjoy recursion, you can skip this paragraph and still be a fully capable Baseten user. A worklet can call itself, opening the possibility of recursive worklets. Also, worklet A can call worklet B, which in turn calls worklet A. Such complexities are rarely the best way to solve problems, but we have left the capability in the platform to maximize developer freedom and flexibility. The runtime will error out at an unsustainable recursion depth (think hundreds of recursive calls), so don't go too wild.
To send a Slack message from a worklet:
- 1.
- 2.Paste the webhook into the appropriate field.
- 3.Write your message! To include the value of
block_input
in your message, use a single empty pair of curly braces{}
.
When you run the worklet, the Slack message will be sent!
The output of the Slack block will be
{'message_sent': 'Your message here'}
, so if you have any blocks set to run after the Slack block make sure that any necessary variables are stored in env
.

Slack is our first of many planned integrations. If there is an API that you would like a similar integration for, please let us know.
Last modified 7mo ago