Creating Functions
Write and deploy browser automation Functions
Writing a Function#
Functions are Python scripts with a run() function that serves as the entry point.
Basic Function#
def run():
"""A simple function that returns a greeting."""
return "Hello from Notte Functions!"Function with Parameters#
def run(name: str, greeting: str = "Hello"):
"""
Greet someone by name.
"""
return f"{greeting}, {name}!"Browser Automation Function#
from notte_sdk import NotteClient
def run(url: str, selector: str):
"""
Scrape data from a website.
"""
client = NotteClient()
with client.Session() as session:
session.execute(type="goto", url=url)
data = session.scrape(instructions=f"Extract content from {selector}")
return {"url": url, "data": data}Deploying Functions#
from notte_sdk import NotteClient
client = NotteClient()
function = client.Function(
path="my_function.py",
name="My Function", # Display name
description="What this function does",
shared=False, # Private by default
)Parameters: workflow_path (str, required) — path to your Python file. name (str, optional) — display name. description (str, optional). shared (bool, default=False) — whether function is publicly accessible.
Function Requirements#
The Handler#
Must have a run() function (any other name is not picked up).
Dependencies#
Available packages: notte-sdk, requests, pydantic, the standard library, and most common packages.
Return Values#
Return JSON-serializable data only — strings, numbers, dicts, lists, None. Types like datetime or functions are not serializable directly.
Parameter Types#
def run(
text: str,
number: int,
decimal: float,
flag: bool,
items: list,
data: dict,
optional: str | None = None,
with_default: int = 10,
):
passUse Pydantic models for structured, validated parameters:
from pydantic import BaseModel
class SearchParams(BaseModel):
url: str
query: str
max_results: int = 10
def run(params: SearchParams):
client = NotteClient()
# Use params.url, params.query, etc.Environment Variables#
import os
from notte_sdk import NotteClient
def run():
api_key = os.getenv("MY_API_KEY")
if not api_key:
return {"error": "API key not configured"}
client = NotteClient(api_key=api_key)Set environment variables in the Console or locally for testing.
Error Handling#
def run(url: str):
try:
client = NotteClient()
with client.Session() as session:
session.execute(type="goto", url=url)
data = session.scrape()
return {"success": True, "data": data}
except Exception as e:
return {"success": False, "error": str(e), "error_type": type(e).__name__}Let Functions fail explicitly when the caller passes bad input:
def run(url: str):
if not url.startswith("https://"):
raise ValueError("URL must use HTTPS")Testing Locally#
def run(url: str, selector: str) -> dict:
return {"url": url, "selector": selector}
result = run(url="https://example.com", selector=".content")
print(result)Best Practices#
1. Document Parameters#
Use clear docstrings describing every argument and the return shape.
2. Return Structured Data#
Use consistent return formats across every Function, including a success flag and a timestamp.
3. Add Logging#
Log key steps (session start, navigation complete, item count extracted) for debugging.
4. Set Timeouts#
with client.Session(idle_timeout_minutes=5) as session:
session.execute(type="goto", url=url)5. Validate Inputs#
def run(url: str, count: int):
if not url.startswith("http"):
return {"error": "Invalid URL format"}
if count < 1 or count > 100:
return {"error": "Count must be between 1 and 100"}Examples#
Form Submission#
from notte_sdk import NotteClient
def run(form_url: str, name: str, email: str, message: str):
"""Submit a contact form."""
client = NotteClient()
with client.Session() as session:
session.execute(type="goto", url=form_url)
session.execute(type="fill", id="name", value=name)
session.execute(type="fill", id="email", value=email)
session.execute(type="fill", id="message", value=message)
session.execute(type="click", selector="button[type='submit']")
return {"status": "submitted"}Data Extraction#
from notte_sdk import NotteClient
from pydantic import BaseModel
class Product(BaseModel):
name: str
price: float
in_stock: bool
def run(product_url: str):
"""Extract structured product data."""
client = NotteClient()
with client.Session() as session:
session.execute(type="goto", url=product_url)
product = session.scrape(response_format=Product, instructions="Extract product details")
return product.model_dump()Next Steps#
-
Invocations — Learn how to call your Functions
-
Schedules — Schedule Functions to run automatically
-
Management — Update and manage Functions
-
Functions Concept — Back to Functions overview