Function Types
The Forra SDK provides three types of function decorators, each designed for different use cases. Understanding when to use each type will help you build more effective and responsive assistants.
Overview
Forra supports three function types:
@forra.function- Synchronous functions that return results immediately@forra.async_function- Long-running functions that execute in the background@forra.webhook- HTTP endpoints that respond to external events
Context and Variables
Functions have access to assistant configuration, secrets, and conversation context through forra.context.
Available Context Variables
When running in Forra, the following variables are automatically available:
from forrasdk import forra
forra.context["FORRA_API_URL"] # The URL of the calling Forra instance
forra.context["FORRA_API_ACCESS_TOKEN"] # A scoped access token for Forra API calls
forra.context["FORRA_ASSISTANT_ID"] # The assistant ID
forra.context["FORRA_CONVERSATION_ID"] # The current conversation ID (optional)
# Custom variables from assistant configuration
forra.context["YOUR_ASSISTANT_VAR"] # A variable declared in the assistant
forra.context["YOUR_ASSISTANT_SECRET"] # A secret variable
Local Development Context
When developing locally, create a forra_context.json file in your project directory:
{
"FORRA_API_URL": "https://your-forra-instance.com",
"FORRA_API_ACCESS_TOKEN": "your-test-token",
"FORRA_CONVERSATION_ID": "test-conversation-id",
"FORRA_ASSISTANT_ID": "test-assistant-id",
"YOUR_ASSISTANT_VAR": "test-value",
"YOUR_ASSISTANT_SECRET": "test-secret"
}
The Forra SDK automatically loads this file when running locally, allowing you to test your functions with realistic context.
1. Synchronous Functions (@forra.function)
Use @forra.function for operations that complete quickly and return results immediately. The assistant waits for the function to complete before responding to the user.
Best for: Data retrieval, calculations, API calls with quick responses, formatting operations.
Example: Basic Function
from pydantic import Field
from forrasdk import forra
@forra.function(description="Say hello world with the name of the user")
def hello_world_function(
first_name: str = Field(description="The name of the person we want to write a hello world for")
):
return f"Hello {first_name} World!"
if __name__ == "__main__":
print(hello_world_function("Mart"))
Deployment Steps
- Save your function in a Python file (e.g.,
hello_skill.py) - Drag and drop the file in the Skills section of your assistant
- Wait for processing to complete
- Test by asking your assistant to use the function
Calling Functions Programmatically
- REST API:
POST https://forra.domain.com/api/assistants/{assistant_id}/functions/{function_name} - Body: JSON with function parameters (e.g.,
{"first_name": "Mart"}) - Python SDK:
ForraAPI().call_assistant_function(assistant_id, "hello_world_function", {"first_name": "Mart"})
2. Asynchronous Functions (@forra.async_function)
Use @forra.async_function for long-running operations that take significant time to complete. The assistant acknowledges the function has started and allows the user to continue the conversation while the function runs in the background.
Best for: File processing, large data analysis, external integrations, batch operations, machine learning tasks.
Key behaviors: - The assistant responds immediately that the task has started - An url is returned that can be polled until the return value is in it. - Function runs independently in the background - Use Forra API calls within the function to communicate results
Example: Long-Running Task
from pydantic import Field
from forrasdk import forra, ForraAPI
import time
@forra.async_function(description="Process a large dataset in the background")
def process_large_dataset(
dataset_url: str = Field(description="URL of the dataset to process")
):
# Simulate long-running work
time.sleep(10) # In real scenarios, this could be minutes or hours
return "Hello 10 seconds later"
if __name__ == "__main__":
# Local testing
process_large_dataset("https://example.com/data.csv")
3. Webhooks (@forra.webhook)
Use @forra.webhook to create HTTP endpoints that external services can call to trigger actions in your assistant. Webhooks enable your assistant to react to external events in real-time.
Best for: External service integrations, automated notifications, real-time data updates, third-party system events.
Key features:
- Creates an HTTP endpoint at https://your.forra.instance/api/assistants/{assistant_id}/webhooks/{path}
- Includes signature verification for security
- Processes incoming HTTP requests and payloads
Security Configuration
Webhooks require two security parameters:
verification_signature_header_key: Header name containing the SHA256 signature of secret + payloadassistant_secret_variable_key: Assistant variable name containing the signing secret
Example: GitHub Webhook
from forrasdk import forra, ForraAPI
import json
@forra.webhook(
path="/github-events",
verification_signature_header_key="X-Hub-Signature-256",
assistant_secret_variable_key="github_webhook_secret"
)
def github_webhook_handler(headers: dict, payload: str):
"""Handle GitHub webhook events"""
# Parse the payload
event_data = json.loads(payload)
event_type = headers.get('X-GitHub-Event', 'unknown')
# Get Forra API instance
api = ForraAPI()
# Process different event types
if event_type == 'push':
repo_name = event_data['repository']['name']
commit_message = event_data['head_commit']['message']
# Notify relevant conversation or create new one
message = f"New push to {repo_name}: {commit_message}"
api.create_conversation(
assistant_id=forra.context["FORRA_ASSISTANT_ID"],
title=f"GitHub Update: {repo_name}",
payload=[{"role": "system", "content": message}]
)
Webhook URL Format
The webhook creates an endpoint at:
To package an entire Python project, including all its dependencies, making it fully compatible with the assistant, see Deployment Guide.