| name | uipath-functions |
| description | UiPath Coded Functions — deterministic Python units built via `uip functions` (new/init/run/pack/publish); the `functions` map in `uipath.json`, `entry-points.json`, Pydantic Input/Output. Rule-based logic, data transforms, ERP/Integration Service connector calls — no LLM reasoning or agent loop. For LLM/agentic projects (LangGraph, LlamaIndex, OpenAI Agents, `agent.json`)→uipath-agents. |
| allowed-tools | Bash, Read, Write, Edit, Glob, Grep, AskUserQuestion |
UiPath Python Coded Functions
What Python Coded Functions Are
Python Coded Functions are atomic, bespoke units of business logic — deterministic Python code packaged as a first-class UiPath artifact. Use them when generic activities don't cover the required logic: calling a third-party API with custom auth, processing documents with domain-specific rules, querying ERP systems via Integration Service connections, or transforming data in ways that no out-of-the-box activity handles.
A Coded Function is not an agent. It does not reason, route, or call LLMs. It takes typed input, executes deterministic code, and returns typed output.
Invocation surfaces
A Python Coded Function can be invoked from any UiPath surface:
| Surface | How |
|---|
| Maestro BPMN | Service Task node |
| Maestro Flow | Coded Agent node or Service Task |
| Coded Agents (LangGraph / LlamaIndex / OpenAI Agents) | Called as a tool or step |
| Other Coded Functions | Direct Python call or Orchestrator job |
| Orchestrator API | POST /Jobs/StartJobs |
| CLI | uip functions pack → uip functions publish |
Python Functions vs JS Functions
| Python Coded Function | JS/TS Function |
|---|
| Job semantics | Yes — Orchestrator job ID, audit trail, retry, scheduling | No — inline HTTP only, no job lifecycle |
| Invocation | Maestro, Flow, Agents, Orchestrator API | HTTP endpoint (BFF for Coded Apps) |
| Runtime | Serverless or Local Unattended Robot | Serverless HTTP shared tier |
| SDK access | Full UiPath Python SDK (assets, buckets, queues, connections) | Workload token forwarding only |
| Scaffold | uip functions new <name> --language py | uip functions new <name> --language ts (default) |
| Init | uip functions init (generates entry-points.json) | Not needed |
| Local dev | uip functions run | uip functions serve + uip functions run |
| Best for | Agentic process steps, ERP integration, document AI, data pipelines | Backend-for-Frontend for Coded Apps |
Use Python when the logic needs job semantics, platform SDK access, or is invoked from Maestro/agents. Use JS when the caller is a Coded App frontend and low HTTP latency matters.
CLI Reference
All Python Coded Function lifecycle commands use uip functions:
uip functions new <name> -l py
uip functions init
uip functions pack
uip functions publish
uip functions push
uip functions run works for both Python and JS/TS. uip functions serve is JS/TS only — it starts the local HTTP server that run invokes against.
Workflow
Step 1: Scaffold
uip functions new <name> --language py
uip functions new <name> --language ts
uip functions new <name> --language js
--language py is required for Python. The default language is TypeScript — omitting --language scaffolds a JS/TS project. Always pass -l py or --language py when building a Python Coded Function.
--empty skips the hello-world function (JS/TS only).
Step 2: Define Function Schema
Use typed I/O. The SDK accepts pydantic BaseModel, pydantic.dataclasses.dataclass, a stdlib @dataclass, or a thin class with typed annotations. The shipped samples favor pydantic (BaseModel in csv-processor, pydantic.dataclasses.dataclass in calculator/greeter):
from pydantic import BaseModel
class Input(BaseModel):
document_id: str = ""
class Output(BaseModel):
vendor_name: str = ""
total_amount: float = 0.0
error_type: str = ""
error_message: str = ""
Step 3: Implement Business Logic
Do NOT make LLM calls inside a Coded Function. LLM calls introduce non-determinism and latency that break the function contract. If the step requires LLM reasoning or multi-step AI decisions, use a framework-based agent (LangGraph, LlamaIndex, OpenAI Agents) instead.
Minimal template
from __future__ import annotations
from pydantic import BaseModel
from uipath.tracing import traced
from uipath.platform import UiPath
class Input(BaseModel):
document_id: str = ""
class Output(BaseModel):
result: str = ""
error_type: str = ""
error_message: str = ""
_sdk: UiPath | None = None
def sdk() -> UiPath:
global _sdk
if _sdk is None:
_sdk = UiPath()
return _sdk
@traced(name="my_function", run_type="uipath")
def my_function(input: Input) -> Output:
out = Output()
try:
asset = sdk().assets.retrieve("MY_ASSET", folder_path="Shared")
out.result = str(asset.value)
except Exception as exc:
out.error_type = "FAILED"
out.error_message = str(exc)
return out
Key rules:
- Typed I/O — pydantic
BaseModel, pydantic.dataclasses.dataclass, stdlib @dataclass, or a thin class with typed annotations; samples favor pydantic
def or async def — both supported (csv-processor uses async def main); the function name is arbitrary
- Lazy SDK init — instantiate
UiPath() inside a getter, never at module level
- Errors returned, not raised — populate
error_type/error_message output fields and return; never let exceptions bubble out of the entrypoint
@traced(name=..., run_type="uipath") — apply to the entrypoint and any sub-functions you want visible in LLM Ops Traces
Step 4: Register in uipath.json
{
"runtimeOptions": { "isConversational": false },
"functions": {
"main": "main.py:my_function"
}
}
The key is the entrypoint name — it can be any string and marks this as the callable entrypoint. The value is "<file>:<function_name>". Both the key and the function name are arbitrary.
This functions map is what identifies the project as a Coded Function — the runtime's determine_project_type() reads the entrypoint type from uipath.json.
Step 5: Declare dependencies in pyproject.toml
[project]
name = "my-function"
version = "0.1.0"
description = "..."
requires-python = ">=3.11"
dependencies = [
"uipath",
"httpx>=0.28",
"pydantic-settings>=2",
]
No [build-system] section. The project is identified as a Coded Function by the functions map in uipath.json (Step 4).
Step 6: Generate Entry Points
uip functions init
Python only. Discovers entrypoints and generates entry-points.json, bindings.json, and project.uiproj. Must run before pack or push. Re-run whenever Input/Output schemas or the entrypoint registration in uipath.json changes.
Step 7: SDK Capabilities
Full SDK reference: https://uipath.github.io/uipath-python/
Access UiPath platform resources via sdk():
from uipath.platform import UiPath
from uipath.platform.connections.connections import ActivityMetadata, ActivityParameterLocationInfo
asset = sdk().assets.retrieve("ASSET_NAME", folder_path="Shared")
value = asset.string_value
sdk().buckets.download(
name="BucketName",
blob_file_path="relative/path/file.pdf",
destination_path="/tmp/local.pdf",
folder_path="Shared",
)
result = sdk().connections.invoke_activity(
activity_metadata=ActivityMetadata(
object_path="/executeSuiteQL",
method_name="POST",
content_type="application/json",
parameter_location_info=ActivityParameterLocationInfo(body_fields=["q"]),
),
connection_id="<connection-uuid>",
activity_input={"q": "SELECT id FROM vendor WHERE ..."},
)
File attachment inputs
To accept a runtime file, type an Input field as Attachment (pydantic model, not a dataclass):
from pydantic import BaseModel
from uipath.platform.attachments import Attachment
class Input(BaseModel):
attachment: Attachment
uip functions init recognizes the Attachment type and emits x-uipath-resource-kind: JobAttachment in entry-points.json — the schema Studio Web and Orchestrator read to render a file picker for that field. Access fields snake_case: attachment.full_name, attachment.content.
Step 8: Pack and Publish
uip functions pack
uip functions publish
uip functions publish --feed-id <FEED_ID>
To sync to Studio Web instead of publishing to Orchestrator:
uip functions push
Important Notes
UiPath() must never be instantiated at module level — always inside a function body
- The
functions map in uipath.json marks the project as a Coded Function (determine_project_type() reads the entrypoint type from uipath.json)
uip functions init must run before pack or push — it generates entry-points.json
- Python Functions have full job semantics: Orchestrator job ID, audit trail, retry, scheduling
- JS Functions have no job semantics and cannot be started as Orchestrator jobs — use Python when the caller is Maestro, a Flow, or an agent
uip functions run works for both Python and JS/TS local execution; uip functions serve is JS/TS only (starts the local HTTP server that run invokes against)
- If cloud-backed work requires authentication, run
uip login --organization "<ORG>" --tenant "<TENANT>" --output json.