Write a function
Write the Python that an app-mode function runs, save it as a new version, and move between the versions you have saved.
Prerequisites#
- An app-mode function to edit. To create one, follow Create, run, and delete a function.
- An organization owner or admin account, or another cloud user with access to the site.
- An API key or JWT for that account.
Write the entry point#
Define a function called main that takes exactly three parameters:
def main(params, user_data, sdk_client):
return {"ok": True}
| Parameter | Carries |
|---|---|
params | The caller's input, plus keys the platform adds |
user_data | The authenticated caller |
sdk_client | A TaruviBase SDK client that acts as that caller |
Return a JSON-serializable value. It becomes the data field of a synchronous
response, and the stored result of an asynchronous one. A falsy return value
(None, {}, [], 0, False, or "") comes back as the whole execution
record, {result, stdout, stderr, logs, success}, instead. Return a non-empty
object, such as {"items": []}.
Three checks decide whether code is accepted when you save it:
- The literal text
def main(params, user_data, sdk_client):must appear, so annotations, renamed parameters, and different spacing are rejected. - Imports must come from the permitted list; any other import is rejected.
- A security scan rejects dynamic-execution builtins such as
eval,exec,compile,open, and__import__, attribute names that start with_, and direct database connections. The response is400withFunction code failed the security scanand the findings undererrors.code.getattr,setattr, anddelattraren't available when the code runs.
See the function signature and sandbox imports for both in full.
Reach the rest of the platform#
Use sdk_client to call TaruviBase from inside the function:
def main(params, user_data, sdk_client):
invoice = sdk_client.database.get("invoices", params["invoice_id"])
return {"status": invoice["status"]}
The client acts as the caller, or as the function's creator for scheduled runs
and anonymous calls to a public function. It uses a system token, so it can
also read sensitive secrets the caller couldn't read directly. Don't return
secret values to callers.
Handle failures explicitly#
An uncaught exception fails the execution and returns a 400 carrying the exception type and message. That is often the right outcome. Where a caller needs to distinguish failure modes, return them instead:
def main(params, user_data, sdk_client):
invoice_id = params.get("invoice_id")
if not invoice_id:
return {"ok": False, "error": "invoice_id is required"}
try:
invoice = sdk_client.database.get("invoices", invoice_id)
except Exception as exc:
log("Lookup failed", level="error", data={"error": str(exc)})
return {"ok": False, "error": "invoice not found"}
return {"ok": True, "status": invoice["status"]}
Validate params before use. On a public function it is untrusted input from
anyone on the internet.
The log helper above writes a structured entry onto the run's record. See
Read logs and invocations.
Save a change#
Saving code creates a new version whenever the code actually changes.
- REST API
- TaruviBase Console
/api/apps/$TARUVI_APP_SLUG/functions/$FUNCTION_SLUG/Headers
AuthorizationApi-Key $TARUVI_API_KEYContent-Typeapplication/json
Request body
{
"code": "def main(params, user_data, sdk_client):\n invoice_id = params.get(\"invoice_id\")\n if not invoice_id:\n return {\"ok\": False, \"error\": \"invoice_id is required\"}\n log(\"Syncing invoice\", level=\"info\", data={\"invoice_id\": invoice_id})\n return {\"ok\": True, \"invoice_id\": invoice_id}\n"
}
View cURL
curl -X PATCH "$TARUVI_SITE_URL/api/apps/$TARUVI_APP_SLUG/functions/$FUNCTION_SLUG/" \
-H "Authorization: Api-Key $TARUVI_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'JSON'
{
"code": "def main(params, user_data, sdk_client):\n invoice_id = params.get(\"invoice_id\")\n if not invoice_id:\n return {\"ok\": False, \"error\": \"invoice_id is required\"}\n log(\"Syncing invoice\", level=\"info\", data={\"invoice_id\": invoice_id})\n return {\"ok\": True, \"invoice_id\": invoice_id}\n"
}
JSON
200Returns the updated function. A request that changes no versioned field also returns 200, with status set to error.
- Open the function and select the Editor tab.
- Edit the code and save.
- The Version History tab records the new version.
Saving without changing anything records no version, and the response reports
No changes detected, version unchanged rather than an error status.
Find a function you saved#
List the functions in an app when you need a slug:
- Python SDK
- REST API
- TaruviBase Console
client.functions.list()
/api/apps/$TARUVI_APP_SLUG/functions/Headers
AuthorizationApi-Key $TARUVI_API_KEY
View cURL
curl "$TARUVI_SITE_URL/api/apps/$TARUVI_APP_SLUG/functions/" \
-H "Authorization: Api-Key $TARUVI_API_KEY"
200Returns a paginated list.
- Open the app and select Functions.
- Filter by Mode, Status, or tag.
Read one function to see its current code and version:
- Python SDK
- REST API
- TaruviBase Console
client.functions.get("FUNCTION_SLUG")
/api/apps/$TARUVI_APP_SLUG/functions/$FUNCTION_SLUG/Headers
AuthorizationApi-Key $TARUVI_API_KEY
View cURL
curl "$TARUVI_SITE_URL/api/apps/$TARUVI_APP_SLUG/functions/$FUNCTION_SLUG/" \
-H "Authorization: Api-Key $TARUVI_API_KEY"
200Returns the function object, including its current code and version.
- Open the function and select the Editor tab.
Review versions and restore one#
Read the history to see what changed and when. Each entry carries a
history_id, which is what revert takes.
- REST API
- TaruviBase Console
/api/apps/$TARUVI_APP_SLUG/functions/$FUNCTION_SLUG/history/Headers
AuthorizationApi-Key $TARUVI_API_KEY
View cURL
curl "$TARUVI_SITE_URL/api/apps/$TARUVI_APP_SLUG/functions/$FUNCTION_SLUG/history/" \
-H "Authorization: Api-Key $TARUVI_API_KEY"
200Returns history records newest first, each with a history_id used by revert.
- Open the function and select the Version History tab.
Other versioned fields — including webhook_url, headers, and config — keep
their current values, so reverting a function whose configuration changed since
that version produces a combination that never existed. Read the history for
changes to those fields first. See
Versioning.
- REST API
- TaruviBase Console
/api/apps/$TARUVI_APP_SLUG/functions/$FUNCTION_SLUG/revert/Headers
AuthorizationApi-Key $TARUVI_API_KEYContent-Typeapplication/json
Request body
{
"history_id": 12
}
View cURL
curl -X POST "$TARUVI_SITE_URL/api/apps/$TARUVI_APP_SLUG/functions/$FUNCTION_SLUG/revert/" \
-H "Authorization: Api-Key $TARUVI_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'JSON'
{
"history_id": 12
}
JSON
200Restores code and filter_conditions only, and creates a new version rather than rewinding the counter.
- Open the function and select the Version History tab.
- Choose the version, then select Restore.
Reverting creates a new version rather than rewinding the counter, so the history stays append-only.
Verify#
Execute the function once and confirm it returns what you expect. See Execute a function.
If the save is rejected, the message names the cause — most often the signature check or a compilation error. See Troubleshooting.