Spice Functions

Spice Functions (beta)
Spice Functions is in beta and initially available for Design Partners. Get in touch for more info.
Spice Functions is a hosted compute experience that enables developers to write code in their preferred language and run it on the Spice platform, co-located with Spice data.
Spice Functions enables new use-cases for developers building intelligent applications with time-series and blockchain data, including flexible data transformation and aggregations, AI/ML data preparation, alerting, filtering, and integrations with other services.
Functions can be implemented in Python or Go, with support for Node.js and Rust coming.
See the Spice Functions Roadmap for upcoming features.

Creating an output dataset

Spice Functions currently requires a designated dataset to store function output.
Follow the Datasets and Views guide to create a new dataset. In addition, add a migration to define the dataset schema and create the table.
Example output dataset
# .spice/datasets/hello_world.yml
name: hello_world
type: append
- name: create_table
sql: |
block_number BIGINT PRIMARY KEY,
greeting TEXT
Optionally specifying a primary key will help enforce data integrity and enables the dataset rows to be updatable.
Datasets defined in a Spice app will be available and queryable from all apps in the organization.
Once you've created the YAML and committed to your repository, follow the same steps outlined in Datasets and Views to sync from GitHub and deploy the dataset to the Spice platform.

Creating a function

A Spice Function is defined by creating a directory in the Spice app's connected GitHub repository and adding a function.yaml file.
In the function.yaml , code execution runtime and invocation handler is defined.
Example function.yaml for a Python function
# hello_world/function.yaml
output_dataset: hello_world
# This will trigger the function to execute on every new Ethereum block.
- path: eth
# This selects the runtime that will execute your code.
runtime: python3.11
# For Python, handler is [script_name].[method]
# The below will invoke a method `process` in a file ``.
handler: spice_function.process
See Spice Functions YAML Specification for the full YAML schema.

Function Handlers

A Python invocation handler method has the following signature:
def process(context: dict,
duckdb: duckdb.DuckDBPyConnection,
spice_client: spicepy.Client):
  • context: A dictionary with context variables, E.g. block_number and block_hash
  • duckdb: A connection to the Spice Function's DuckDB instance.
  • spice_client: A spicepy client that is pre-initialized with the Spice app's API Key.
The handler method will be called on each triggered event.
See Golang for defining a Go function handler.
Each Spice Function is provisioned with a private, dedicated, and persisted DuckDB instance accessed by the duckdb parameter. The DuckDB instance can be used to query, persist, process, and analyze data across function invocations.
To load and persist data into the output dataset, first create a staging table in the DuckDB instance, in the output namespace with the same schema used in the dataset creation. E.g.
# Create output dataset staging table in DuckDB
duckdb.sql("""CREATE TABLE IF NOT EXISTS output.hello_world (
block_number BIGINT,
greeting TEXT
Data inserted into the staging output.{output_dataset} table will be loaded and merged into the output dataset. For example:
duckdb.sql(f"INSERT INTO output.hello_world VALUES ({context['block_number']}, 'Hello!')")
The staging output.{output_dataset} table is reset upon each function invocation and thus will be empty on each function invocation.
Rows inserted into the duckdb output.{output_dataset} table with an existing primary key value will be updated in-place.
See Python and Go for full example code.

Sync with GitHub

Once your function is committed to the GitHub repository, navigate to the Functions section of the Hub, and click Sync with GitHub. The newly defined function will appear in the functions list.
List of synced Functions

Deploy the Function

Click the function Deploy button. It may take a few moments as the code is packaged and deployed for use within the platform.
Deployed function hello_world is now running.

View Function details

Clicking the function name will show its details along with it's deployments.
Function details page

View Function executions

Clicking the Executions tab in the Function details page will show the recent function executions.
Function executions page

View Function execution logs

Click on the UUID of a function execution to view the logs from a function execution, including its standard output, standard error and exit code.
Logs from a function execution

Query the Function output dataset

If data was inserted into the output dataset, upon successful function execution, it will be available for query in the datasets."{your_org_name}".{your_dataset_name} path.
Querying for hello_world's output