FastAPI-style framework for building composable Function Apps for Cognite Functions with automatic OpenAPI schema generation and MCP integration
Project description
Function Apps
A framework for building structured, self-describing APIs on Cognite Functions — with type-safe routing, automatic validation, and native AI agent support.
Why Function Apps?
1. Classic functions are black boxes
A standard Cognite Function exposes a single handle(client, data) endpoint with no machine-readable description of what operations it supports, what inputs they accept, or what they return. You have to read the source to understand it — and AI agents simply can't call it without custom tooling.
Function Apps are self-describing. Built-in /schema, /routes, and /health endpoints let any caller — human or AI agent — discover what a function provides and how to invoke it. This is the foundation for native MCP support and the interactive local dev server.
2. The 100-function limit
CDF projects start with a limit of 100 Cognite Functions (extendable to 250 on request). Many customers have collections of 3–10 tightly related functions that logically belong together. Function Apps lets you package those into a single deployable unit with proper internal routing, so you stop burning one slot per operation.
3. Dynamic workflow orchestration
Complex use cases — like equipment monitoring — require functions that coordinate and chain operations dynamically. The composable app architecture makes this tractable.
4. Observability and better habits
Customers hitting runtime limits often can't tell whether they're CPU-bound or I/O-bound. Built-in tracing and enforced type annotations make it possible to actually diagnose that, and nudge toward code that's easier to maintain and hand off.
The boilerplate problem is also real. Standard Cognite Functions require a bare handle(client, data) function that becomes unwieldy for complex APIs:
def handle(client, data):
try:
asset_no = int(data["assetNo"]) # Manual validation
include_tax = data.get("includeTax", "false").lower() == "true" # Manual parsing
# Handle routing manually based on data
if data.get("action") == "get_item":
# Implementation here
elif data.get("action") == "create_item":
# Different implementation
except Exception as e:
return {"error": str(e)} # Basic error handling
With Function Apps:
@app.get("/items/{item_id}")
def get_item(client: CogniteClient, item_id: int, include_tax: bool = False) -> ItemResponse:
"""Retrieve an item by ID."""
item = Item(name=f"Item {item_id}", price=100.0, tax=10.0 if include_tax else None)
return ItemResponse(id=item_id, item=item, total_price=item.price + (item.tax or 0))
Key Features
- Type-safe routing - Decorator-based syntax with automatic validation
- Async/await support - Write both sync and async handlers
- Error handling - Comprehensive error handling with structured responses
- Logging - Enterprise logging with dependency injection
- Distributed tracing - OpenTelemetry-based tracing
- Dependency injection - Inject custom dependencies
- Introspection - Built-in schema, routes, health endpoints
- Model Context Protocol - Native AI tool exposure
- Local development server - Test locally with interactive API docs
- Function client - Notebook-first client for exploring functions
Installation
Requirements:
- Python 3.10 or higher
- uv (recommended) or pip
# Install the package
pip install cognite-function-apps
# Optional: Install with CLI support for dev server
pip install cognite-function-apps[cli]
# Optional: Install with tracing support
pip install cognite-function-apps[tracing]
Quick Start
from cognite.client import CogniteClient
from pydantic import BaseModel
from cognite_function_apps import FunctionApp, create_function_service
# Create your app
app = FunctionApp(title="My API", version="1.0.0")
# Define your models
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
class ItemResponse(BaseModel):
id: int
item: Item
total_price: float
# Define your endpoints
@app.get("/items/{item_id}")
def get_item(
client: CogniteClient,
item_id: int,
include_tax: bool = False
) -> ItemResponse:
"""Retrieve an item by ID"""
item = Item(
name=f"Item {item_id}",
price=100.0,
tax=10.0 if include_tax else None
)
total = item.price + (item.tax or 0)
return ItemResponse(id=item_id, item=item, total_price=total)
@app.post("/items/")
def create_item(client: CogniteClient, item: Item) -> ItemResponse:
"""Create a new item"""
new_id = 12345 # Your creation logic here
total = item.price + (item.tax or 0)
return ItemResponse(id=new_id, item=item, total_price=total)
# Wraps the app in the handle(client, data) interface expected by Cognite Functions
handle = create_function_service(app)
Test Locally
Install with CLI support and run the development server:
pip install cognite-function-apps[cli]
fun serve examples/
Visit http://localhost:8000/docs for interactive API documentation.
Examples
The framework includes a complete example in examples/handler.py demonstrating:
- Type-safe routing with decorator syntax
- MCP integration for AI tool exposure
- Built-in introspection endpoints
- Async handler support
- Composable app architecture
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Acknowledgments
- Built specifically for Cognite Data Fusion Functions platform
- Decorator routing syntax inspired by FastAPI
- Data validation powered by Pydantic
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cognite_function_apps-0.13.0.tar.gz.
File metadata
- Download URL: cognite_function_apps-0.13.0.tar.gz
- Upload date:
- Size: 426.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7e61c876cdf89c4312d0eb48718235f6960c8df1664e563e364d10946108e7b
|
|
| MD5 |
07250c9c5dc9cae2f365c6b99c92848a
|
|
| BLAKE2b-256 |
e6a460d8ee3ea0bb8ec78257af19e260133bccee10cc65f3fb11dcd9924a4f72
|
File details
Details for the file cognite_function_apps-0.13.0-py3-none-any.whl.
File metadata
- Download URL: cognite_function_apps-0.13.0-py3-none-any.whl
- Upload date:
- Size: 111.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aa9f0e1f1d62384648c638352fe0dde09439d592bb5250f8048609597c494fbf
|
|
| MD5 |
b77cfdde892a8eebfd66c58ba65cdb2a
|
|
| BLAKE2b-256 |
3931afc5ee1cc374da82679d04cf5aa27e25f3a3ab323df98cf5351e77a4fb50
|