FortifyRoot Ocelle SDK for LLM observability
Project description
FortifyRoot Ocelle
FortifyRoot Ocelle is the Python SDK for FortifyRoot LLM observability and runtime safety. Add one initialization call to your application and Ocelle will instrument supported LLM providers and frameworks, emit OpenTelemetry traces/metrics/logs to FortifyRoot, and apply configured prompt/completion safety rules before sensitive content leaves or enters your application flow.
Ocelle is built on a FortifyRoot-maintained OpenLLMetry fork, vendored into this repository for dependency isolation, safety extensions, and stable FortifyRoot packaging.
What Ocelle Captures
- LLM request/response traces with provider, model, span hierarchy, token usage, latency, retry-attempt, and streaming timing metadata.
- Framework spans for workflows, tasks, agents, and tools through decorators and supported framework integrations.
- Optional prompt and completion content when content tracing is enabled.
- Safety findings for prompt and completion content, including masking decisions and rule metadata.
- OTLP traces, metrics, and correlated logs for FortifyRoot ingestion.
Installation
Ocelle supports Python 3.10 and newer.
pip install fortifyroot-ocelle
Install only the provider/framework extras your application uses:
pip install "fortifyroot-ocelle[openai]"
pip install "fortifyroot-ocelle[openai,anthropic,langchain]"
pip install "fortifyroot-ocelle[bedrock,litellm,llamaindex]"
Quick Start
import fortifyroot.ocelle as ocelle
ocelle.init(
app_name="my-llm-app",
api_key="fr_sk_...",
resource_attributes={"environment": "prod"},
)
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Hello!"}],
)
The canonical SDK import is:
import fortifyroot.ocelle as ocelle
The package also exposes a convenience alias:
import ocelle
Supported Providers And Frameworks
This table lists the launch-supported instrumentation exposed through fortifyroot.ocelle.Instruments and SDK extras. Package ranges are the ranges declared by this SDK; they are not a claim about the latest upstream release.
| Library / framework | Instrument | Extra | Declared package range | Sync | Async | Streaming | Safety |
|---|---|---|---|---|---|---|---|
| OpenAI | Instruments.OPENAI |
openai |
openai >=1.31.1,<3 |
Yes | Yes | Yes | Prompt + completion, including streaming paths |
| Anthropic | Instruments.ANTHROPIC |
anthropic |
anthropic >=0.49,<1.0.0 |
Yes | Yes | Yes | Prompt + completion, including streaming paths |
| Google GenAI / Gemini | Instruments.GOOGLE_GENERATIVEAI |
google-generativeai |
google-genai >=1.0.0,<2 |
Yes | Yes | Yes | Prompt + completion, including streaming paths |
| AWS Bedrock Runtime | Instruments.BEDROCK |
bedrock |
boto3 >=1.34.120,<2 |
Yes | No native async client path | Yes | Prompt + completion for invoke/converse paths, including stream wrappers |
| LiteLLM | Instruments.LITELLM |
litellm |
litellm >=1.71.2,<2,!=1.82.7,!=1.82.8 |
Yes | Yes | Yes | Prompt + completion, including streaming paths |
| LangChain | Instruments.LANGCHAIN |
langchain |
langchain >=0.2.5,<2.0.0, langchain-openai >=0.1.15,<2.0.0 |
Yes | Yes | Provider-dependent | Prompt + completion for supported chat/LLM paths |
| LangGraph | via Instruments.LANGCHAIN |
install with app | Covered through LangChain/OpenAI launch path | Yes | Yes | Provider-dependent | Same supported path as LangChain |
| LlamaIndex | Instruments.LLAMA_INDEX |
llamaindex |
llama-index >=0.14.12,<0.15.0 |
Yes | Yes | Yes | Prompt + completion, including streaming paths |
For provider-role behavior, routed providers such as OpenRouter, LiteLLM, Bedrock, Azure OpenAI, and planned/mapper-supported providers, see Provider Support. That document is the source of truth for what is launch-certified versus planned.
Runtime Safety
Ocelle can poll a FortifyRoot SDK config profile and apply configured safety rules locally in the SDK. Rules can inspect prompt and completion text and currently resolve to ALLOW or MASK.
Supported safety categories are:
PII, PCI, PHI, API_KEY, SECRET, PROMPT_INJECTION, PROFANITY, TOXICITY, VIOLENCE, SELF_HARM, CONFIDENTIAL, and CUSTOM.
Rules can be backed by regex matchers, string-list matchers, or approved user-defined detectors. Masking is applied before the instrumented provider/framework returns the text to application code where the integration can safely mutate the response object or stream chunk.
Because Ocelle is open source, the SDK's enforcement flow is visible by design. Organization-specific safety policy is fetched at runtime from your FortifyRoot SDK config profile, so public code review exposes the engine and built-in defaults, not customer-specific rules.
Configuration
Environment Variables
| Environment variable | Description | Default |
|---|---|---|
FORTIFYROOT_API_KEY |
FortifyRoot API key | None |
FORTIFYROOT_BASE_URL |
FortifyRoot API endpoint | https://api.fortifyroot.com |
FORTIFYROOT_TRACE_CONTENT |
Capture prompt/response content | true |
FORTIFYROOT_TRACING_ENABLED |
Enable trace export | true |
FORTIFYROOT_METRICS_ENABLED |
Enable metric export | true |
FORTIFYROOT_LOGGING_ENABLED |
Enable OTLP log export and synthetic span-end logs | false |
When FORTIFYROOT_LOGGING_ENABLED=true, Python logging records emitted inside active spans are exported with trace/span correlation. print(...), stdout, and stderr capture are not included; use Python logging for application logs.
Programmatic Configuration
import fortifyroot.ocelle as ocelle
from fortifyroot.ocelle import Instruments
ocelle.init(
app_name="my-llm-app",
api_key="fr_sk_...",
api_endpoint="https://api.fortifyroot.com",
trace_content=True,
instruments={Instruments.OPENAI, Instruments.LANGCHAIN},
)
Fluent API
import fortifyroot.ocelle as ocelle
from opentelemetry.sdk.trace.sampling import TraceIdRatioBased
ocelle.configure() \
.app_name("my-llm-app") \
.api_key("fr_sk_...") \
.trace_content(False) \
.sampler(TraceIdRatioBased(0.1)) \
.init()
Decorators
Use decorators to add trace structure around your own application logic:
from fortifyroot.ocelle import agent, task, tool, workflow
@workflow(name="document_qa")
def answer_question(document: str, question: str):
chunks = split_document(document)
relevant = find_relevant_chunks(chunks, question)
return generate_answer(relevant, question)
@task(name="split_document")
def split_document(document: str):
return chunks
@task(name="find_relevant")
def find_relevant_chunks(chunks, question):
return relevant_chunks
@task(name="generate_answer")
def generate_answer(context, question):
return answer
Association Properties
Attach properties to traces for filtering and correlation:
import fortifyroot.ocelle as ocelle
ocelle.init(app_name="my-app", api_key="fr_sk_...")
ocelle.set_association_properties({
"user_id": "user_12345",
"session_id": "sess_abc",
"conversation_id": "conv_xyz",
})
Network Requirements
If your app runs in a private subnet, VPC, Kubernetes cluster, or locked-down runtime, allow outbound HTTPS egress on TCP 443 to api.fortifyroot.com.
Ocelle exports telemetry over OTLP/HTTP to:
https://api.fortifyroot.com/v1/traceshttps://api.fortifyroot.com/v1/metricshttps://api.fortifyroot.com/v1/logs
If safety enforcement is enabled with config_profile_id, the SDK also polls:
https://api.fortifyroot.com/v1/sdk/config/{config_profile_id}
No inbound firewall rule is required. Hosted FortifyRoot usage does not require opening OTLP ports 4317 or 4318. Your workload still needs separate egress to whichever LLM providers it calls.
Privacy And Content Tracing
Disable prompt and response content capture with:
export FORTIFYROOT_TRACE_CONTENT=false
or programmatically:
import fortifyroot.ocelle as ocelle
ocelle.init(
app_name="my-app",
api_key="fr_sk_...",
trace_content=False,
)
Safety rules can still run when configured; content tracing controls what is exported as telemetry content.
License And Attribution
Apache License, Version 2.0.
FortifyRoot Ocelle includes code derived from OpenLLMetry and traceloop-sdk by Traceloop, licensed under the Apache License, Version 2.0. The license text and attribution are retained in LICENSE.
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 fortifyroot_ocelle-1.0.1.tar.gz.
File metadata
- Download URL: fortifyroot_ocelle-1.0.1.tar.gz
- Upload date:
- Size: 282.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
906def8cbc82d47fc823cbdb88530ab158ad3b22b6a4bde253c2630fa0ddf97f
|
|
| MD5 |
922eececa31f21030dc51aa8fbbe873e
|
|
| BLAKE2b-256 |
cceaf6d09e47f8418ef9ce954c11e1138d3a63fc84d64462ab10194dd4f6775b
|
Provenance
The following attestation bundles were made for fortifyroot_ocelle-1.0.1.tar.gz:
Publisher:
publish-release.yml on FortifyRoot/ocelle-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fortifyroot_ocelle-1.0.1.tar.gz -
Subject digest:
906def8cbc82d47fc823cbdb88530ab158ad3b22b6a4bde253c2630fa0ddf97f - Sigstore transparency entry: 2101532263
- Sigstore integration time:
-
Permalink:
FortifyRoot/ocelle-py@d705a39bcb8955ad8e396f1ccc6ea7d960b11465 -
Branch / Tag:
refs/heads/release/1.0.1 - Owner: https://github.com/FortifyRoot
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-release.yml@d705a39bcb8955ad8e396f1ccc6ea7d960b11465 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file fortifyroot_ocelle-1.0.1-py3-none-any.whl.
File metadata
- Download URL: fortifyroot_ocelle-1.0.1-py3-none-any.whl
- Upload date:
- Size: 373.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a3157eeb1082f0fe3ca1707e6fcab2ba1c2e70f206532f01c0369b750f28a70c
|
|
| MD5 |
ca9f1cf04f8d0e0323d2d2df8f0b8932
|
|
| BLAKE2b-256 |
2c2797de6ecd398451843b0ea01c5a45e035d72193c4a635d1cc74b22163a567
|
Provenance
The following attestation bundles were made for fortifyroot_ocelle-1.0.1-py3-none-any.whl:
Publisher:
publish-release.yml on FortifyRoot/ocelle-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fortifyroot_ocelle-1.0.1-py3-none-any.whl -
Subject digest:
a3157eeb1082f0fe3ca1707e6fcab2ba1c2e70f206532f01c0369b750f28a70c - Sigstore transparency entry: 2101532751
- Sigstore integration time:
-
Permalink:
FortifyRoot/ocelle-py@d705a39bcb8955ad8e396f1ccc6ea7d960b11465 -
Branch / Tag:
refs/heads/release/1.0.1 - Owner: https://github.com/FortifyRoot
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-release.yml@d705a39bcb8955ad8e396f1ccc6ea7d960b11465 -
Trigger Event:
workflow_dispatch
-
Statement type: