Invoke Fabric user data functions (experimental)
Source:vignettes/user-data-functions.Rmd
user-data-functions.RmdA Fabric user data function is reusable Python code that Fabric hosts and runs. It can accept inputs, perform a task, and return a result. With ‘fabricQueryR’, an R session can call the published function and receive its structured response.
Lifecycle
The package’s User Data Function discovery and invocation APIs are experimental. Their validation, request construction, and response handling are covered by offline tests, and lightweight Core item discovery is exercised against Fabric. However, the package cannot currently maintain repeatable end-to-end coverage for detailed User Data Function discovery and public function invocation.
The persistent sandbox is provisioned with a service principal. Microsoft’s User Data Function create, update-definition, detailed Get, and delete APIs currently support delegated users, but not service principals or managed identities. The sandbox therefore cannot provision, publish, fully inspect, and remove its own disposable public-function fixtures. Until repeatable end-to-end coverage is possible, treat these APIs and their returned service shapes as subject to change.
This guide prepares a function for external use, makes one small call, and then introduces structured parameters and safe retries. Start with a simple function whose output you can verify in the Fabric portal.
Prepare the function in Fabric
In the Fabric portal, publish the user data functions item, switch to Run only mode, open the function’s properties, enable Public access, and copy the Public URL. Each function has its own URL.
fabric_user_data_functions() and
workspace$user_data_functions() default to
detail = FALSE. This uses the Core item listing, which
supports delegated users, service principals, and managed identities,
and returns a read-only FabricItem R6 object.
$details() calls fabric_item() to refresh its
item record. To force the workload-specific Get API, use
$details(detail = TRUE) or rediscover with
detail = TRUE; Microsoft documents that API for delegated
users only, not service principals or managed identities. Neither
response includes enough information to derive each public function URL,
so pass the copied URL to fabric_function_invoke().
You could store the URL in an environment variable (rather than hardcoding it):
function_url <- Sys.getenv("FABRIC_FUNCTION_URL")The caller needs Execute permission on the item. A delegated sign-in
also needs one Power BI delegated permission. By default, ‘fabricQueryR’
requests the least-privilege UserDataFunction.Execute.All
scope. Microsoft also accepts the broader Item.Execute.All
scope, but it does not replace the caller’s item Execute permission. If
the app registration grants only that broader scope, select it
explicitly:
result <- fabric_function_invoke(
function_url,
parameters = list(customerName = "Ada", priority = 2L),
audience = paste0(
"https://analysis.windows.net/powerbi/api/",
"Item.Execute.All"
)
)If sign-in succeeds but the call is denied, ask the item owner or Fabric administrator to check item Execute access and the relevant tenant setting.
Make a first call
Parameter names must match the published Python function. For a
function with customerName and priority
inputs:
result <- fabric_function_invoke(
function_url,
parameters = list(
customerName = "Ada",
priority = 2L
)
)
result$status
result$outputSend structured parameters
The request body is one named JSON object. Its names must match the published function’s camelCase parameters:
structured_result <- fabric_function_invoke(
function_url,
parameters = list(
customerName = "Ada",
priority = 2L,
lineIds = I(c(101L, 102L)),
metadata = list(source = "R", approved = TRUE, note = NULL)
)
)One-element R values normally become JSON scalars. Wrap a one-element
value in I() when the Python signature expects a list.
Named atomic vectors and data frames are also accepted as top-level
parameter objects; a named list gives the clearest control over nested
JSON shapes.
The result is a list which can be inspected:
structured_result$function_name
structured_result$invocation_id
structured_result$status
structured_result$output
structured_result$errors
structured_result$http_statusThe response keeps the function status, output, and any structured errors together. Inspect these fields before using the output in a later step.
Retry only safe functions
A function can write data or call another service, so invocation POSTs are not retried by default. If a function is read-only or implements its own durable idempotency key, opt in explicitly:
result <- fabric_function_invoke(
function_url,
parameters = list(requestId = "stable-business-key"),
idempotent = TRUE
)Opted-in calls use bounded retries for transport failures, throttling, and transient HTTP responses.
Limits
Public function calls have request-size, execution-time, and response-size limits. Keep calls focused and pass large data through a Fabric data store instead of function parameters. See the service-limits link below for current values.
More information
See Microsoft’s external invocation tutorial, programming model, and service limits.