### Install FastAPI and Uvicorn
Source: https://docs.openbb.co/workspace/developers/data-integration
Install the necessary Python packages for creating a custom backend API. These are required before starting the integration.
```bash
pip install fastapi uvicorn
```
--------------------------------
### Install OpenBB AI SDK
Source: https://docs.openbb.co/workspace/developers/openbb-ai-sdk
Install the OpenBB AI SDK package in your agent backend using pip.
```bash
pip install openbb-ai
```
--------------------------------
### Basic Newsfeed Widget Example
Source: https://docs.openbb.co/workspace/developers/widget-types/newsfeed
A simple example demonstrating how to return sample news articles for the newsfeed widget.
```javascript
function getNews() {
return [
{
title: "OpenBB Workspace Launch",
date: "2023-10-27T10:00:00Z",
author: "OpenBB Team",
excerpt: "Announcing the latest features and improvements.",
body: "## OpenBB Workspace Launch\n\nWe are excited to announce the launch of OpenBB Workspace, featuring enhanced tools for financial analysis and data visualization."
},
{
title: "New Data Integrations",
date: "2023-10-26T14:30:00Z",
author: "Data Team",
excerpt: "Explore new sources for your analysis.",
body: "### New Data Sources Available\n\nOur platform now supports data from several new providers, expanding your analytical capabilities."
}
];
}
```
--------------------------------
### Skill Catalog Example
Source: https://docs.openbb.co/workspace/developers/ai-features/dynamic-skill-loading
An example of the skills_catalog array structure sent with each request, detailing available skills.
```json
{ "skills_catalog": [ { "slug": "financial-analysis", "description": "Analyze company financials and earnings", "updatedAt": "2026-03-22T12:00:00Z" } ]}
```
--------------------------------
### Example Backend Implementation for OpenBB Widget Forms
Source: https://docs.openbb.co/workspace/developers/widget-parameters/input-form
This Python code demonstrates how to set up POST and GET endpoints using FastAPI to handle form submissions and data retrieval for OpenBB widgets. It includes logic for validating input, adding new records, and updating existing ones, along with explanations of the widget's refresh mechanism.
```python
ALL_FORMS = []
# Submit form endpoint to handle the form submission
@app.post("/form_submit")
async def form_submit(params: dict) -> JSONResponse:
global ALL_FORMS
# Check if first name and last name are provided
if not params.get("client_first_name") or not params.get("client_last_name"):
# IMPORTANT: Even with a 400 status code, the error message is passed to the frontend
# and can be displayed to the user in the OpenBB widget
return JSONResponse(
status_code=400,
content={"error": "Client first name and last name are required"}
)
# Check if investment types and risk profile are provided
if not params.get("investment_types") or not params.get("risk_profile"):
return JSONResponse(
status_code=400,
content={"error": "Investment types and risk profile are required"}
)
# Check if add_record or update_record is provided
add_record = params.pop("add_record", None)
if add_record:
ALL_FORMS.append(
{k: ",".join(v) if isinstance(v, list) else v for k, v in params.items()}
)
update_record = params.pop("update_record", None)
if update_record:
for record in ALL_FORMS:
if record["client_first_name"] == params.get("client_first_name") and record[
"client_last_name"
] == params.get("client_last_name"):
record.update(params)
# IMPORTANT: The OpenBB Workspace only checks for a 200 status code from this endpoint
# The actual content returned doesn't matter for the widget refresh mechanism
# After a successful submission, Workspace will automatically refresh the widget
# by calling the GET endpoint defined in the widget configuration
return JSONResponse(content={"success": True})
# Get all forms
@app.get("/all_forms")
async def all_forms() -> list:
print(ALL_FORMS)
# IMPORTANT: This GET endpoint is called by the OpenBB widget after form submission
# The widget refresh mechanism works by:
# 1. User submits form (POST to /form_submit)
# 2. If POST returns 200, widget automatically refreshes
# 3. Widget refresh calls this GET endpoint to fetch updated data
# 4. This function must return ALL data needed to display the updated widget
return (
ALL_FORMS
if ALL_FORMS
else [
{"client_first_name": None, "client_last_name": None, "investment_types": None, "risk_profile": None}
]
)
```
--------------------------------
### Prompt Examples for Swap Data
Source: https://docs.openbb.co/workspace/developers/json-specs/apps-json-reference
Provides example natural language prompts for querying swap rate levels, trading volumes, trade distributions, and trade comparisons.
```text
"What are the latest OIS swap rate levels?",
"Show me the notional trading volumes for LIBOR vs OIS.",
"What is the distribution of trades for USD swaps?",
"Compare cleared vs. uncleared swap trades.",
"What's the 5-day moving average volume for swaps?"
```
--------------------------------
### Install Altair for Vega-Lite Helpers
Source: https://docs.openbb.co/workspace/developers/widget-types/vega-lite
To use helper functions for generating Vega-Lite specifications, install the Altair Python package. This is optional but recommended for easier spec creation.
```bash
pip install altair
```
--------------------------------
### FRED App Configuration Example
Source: https://docs.openbb.co/workspace/developers/json-specs/apps-json-reference
This JSON object defines the configuration for the FRED App, including its name, image URLs, description, customization settings, and layout for different tabs. It specifies how charts are rendered with various parameters like query, title, and start date.
```json
{
"name": "Your_FED",
"img": "https://ohiocapitaljournal.com/wp-content/uploads/2024/08/GettyImages-2164058797-scaled-1-2048x1366.jpg",
"img_dark": "https://ohiocapitaljournal.com/wp-content/uploads/2024/08/GettyImages-2164058797-scaled-1-2048x1366.jpg",
"img_light": "https://ohiocapitaljournal.com/wp-content/uploads/2024/08/GettyImages-2164058797-scaled-1-2048x1366.jpg",
"description": "Make The charts that mater to you always live",
"allowCustomization": true,
"tabs": {
"overview": {
"id": "overview",
"name": "Overview",
"layout": [
{
"i": "fred_chart",
"x": 0,
"y": 2,
"w": 20,
"h": 16,
"state": {
"params": {
"start": "1970-01-01"
}
}
},
{
"i": "fred_chart",
"x": 20,
"y": 2,
"w": 20,
"h": 16,
"state": {
"params": {
"query": "CPI 12-month@CPIAUCSL.p12.m100,CPI 6-month@CPIAUCSL.p6.pa2,CPI 3-month@CPIAUCSL.p3.pa4",
"title": "CPI Inflation Momentum",
"chart": "line"
}
}
},
{
"i": "fred_chart",
"x": 0,
"y": 18,
"w": 20,
"h": 16,
"state": {
"params": {
"query": "Core CPI YoY@CPILFESL.p12.m100,CPI YoY@CPIAUCSL.p12.m100",
"start": "2000-01-01"
}
}
},
{
"i": "fred_chart",
"x": 20,
"y": 18,
"w": 20,
"h": 16,
"state": {
"params": {
"query": "NFP@PAYEMS.d1.m1000",
"title": "NFP Changes "
}
}
},
{
"i": "fred_chart",
"x": 0,
"y": 34,
"w": 20,
"h": 16,
"state": {
"params": {
"query": "DGS2,DGS5,DGS10,DGS30"
}
}
}
]
}
},
"groups": [],
"prompts": [
"What is the latest CPI inflation momentum?",
"Show me the year-over-year Core CPI.",
"What was the last Non-Farm Payrolls (NFP) number?",
"Plot the 2-year and 10-year Treasury yields.",
"What is the current 30-year Treasury yield?"
]
}
```
--------------------------------
### OBB.WIDGET Example with Custom Backend
Source: https://docs.openbb.co/workspace/analysts/excel-addin/obb-widget
Example of using OBB.WIDGET to access data from a custom backend, specifying the backend name and the widget name for Portugal CPI.
```excel
=OBB.WIDGET("Custom Backend","Portugal CPI since 2000")
```
--------------------------------
### Comprehensive Widget Parameter Positioning Example
Source: https://docs.openbb.co/workspace/developers/widget-parameters/parameter-positioning
This example demonstrates advanced parameter positioning by using an empty first row to place all defined parameters onto the second row. It includes various parameter types like date pickers, text boxes, boolean selectors, and multi-select dropdowns.
```python
@register_widget({
"name": "Moving Parameters Example",
"description": "Show example of moving parameter positions",
"endpoint": "moving_parameters_example",
"gridData": {"w": 20, "h": 9},
"type": "table",
"params": [
[], # Empty first row - pushes all parameters to second row
[
# Second row with all parameters
{
"paramName": "datePicker1",
"value": "$currentDate-1d",
"label": "Param 1",
"description": "I'm a Date Picker!",
"type": "date"
},
{
"paramName": "textBox1",
"value": "Hello!",
"label": "Param 2",
"description": "I'm a text input box!",
"type": "text"
},
{
"paramName": "TrueFalse",
"value": True,
"label": "True/False",
"description": "I'm a True/False selector!",
"type": "boolean"
},
{
"paramName": "daysPicker1",
"value": "1",
"label": "Days",
"type": "text",
"multiSelect": True,
"description": "Number of days to look back",
"options": [
{"value": "1", "label": "1"},
{"value": "5", "label": "5"},
{"value": "10", "label": "10"},
{"value": "20", "label": "20"},
{"value": "30", "label": "30"}
]
}
]
]
})
@app.get("/moving_parameters_example")
def moving_parameters_example(
datePicker1: str = None,
textBox1: str = None,
daysPicker1: str = "1",
TrueFalse: bool = True):
"""Show example of how to move parameters - This will put them all on the second row of the widget"""
return {
"datePicker1": datePicker1,
"textBox1": textBox1,
"daysPicker1": daysPicker1.split(","),
"TrueFalse": TrueFalse
}
```
--------------------------------
### Example HTML Templates for Metric Cards
Source: https://docs.openbb.co/workspace/developers/ai-features/create-html-artifacts
Provides example HTML structures for creating metric cards, commonly used for displaying key performance indicators. Each card includes a metric name, value, and percentage change, styled with inline CSS.
```html
```
--------------------------------
### agents.json Example Configuration
Source: https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference
This is an example of the JSON structure returned by the /agents.json endpoint. It defines a custom AI agent named 'Financial Prompt Optimizer', including its description, image URL, API endpoints, and supported features like streaming.
```json
{
"financial_prompt_optimizer": {
"name": "Financial Prompt Optimizer",
"description": "Optimizes a user's prompt for finance: clearer, more specific, and actionable.",
"image": "https://github.com/OpenBB-finance/copilot-for-terminal-pro/assets/14093308/7da2a512-93b9-478d-90bc-b8c3dd0cabcf",
"endpoints": {"query": "http://localhost:7777/v1/query"},
"features": {
"streaming": true,
"widget-dashboard-select": false,
"widget-dashboard-search": false,
},
}
}
```
--------------------------------
### Run Uvicorn Server
Source: https://docs.openbb.co/workspace/developers/data-integration
Command to start the FastAPI application with hot-reloading and specified host and port.
```bash
uvicorn main:app --reload --host 0.0.0.0 --port 7779
```
--------------------------------
### OBB.WIDGET Example with Swap Trades
Source: https://docs.openbb.co/workspace/analysts/excel-addin/obb-widget
Example of using OBB.WIDGET to retrieve swap trades from the DTCC Trades backend. Parameters include currency, date, and clearing status.
```excel
=OBB.WIDGET("DTCC Trades","Swap Trades",{"currency","USD";"date","2025-04-15";"cleared_only","true";"include_starting","false"})
```
--------------------------------
### Basic Agent Configuration
Source: https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference
Configure a basic agent with essential details like name, description, image, and query endpoint. This example does not enable advanced features.
```json
{
"vanilla-agent": {
"name": "Vanilla Agent",
"description": "A basic agent that processes user queries",
"image": "https://api.example.com/static/agent-logo.png",
"endpoints": {
"query": "/query"
},
"features": {
"streaming": true,
"widget-dashboard-select": false,
"widget-dashboard-search": false
}
}
}
```
--------------------------------
### Example columnsDefs Configuration
Source: https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference
Defines column properties such as field name, header name, data type, alignment, and formatting.
```json
"columnsDefs": [
{
"field": "column1",
"headerName": "Column 1",
"chartDataType": "category",
"cellDataType": "text",
"align": "center",
"enableCellChangeWs": false,
"formatterFn": "int",
"decimalPlaces": 2,
"renderFn": "titleCase",
"renderFnParams": {
"actionType": "sendToAgent",
"sendToAgent": {
"markdown": "Analyze **{company}** data"
}
}
}
]
```
--------------------------------
### agents.json Configuration Example
Source: https://docs.openbb.co/workspace/developers/ai-features/dynamic-skill-loading
This snippet shows the configuration for a 'vanilla_agent_dynamic_skill' within the `agents.json` file. It defines the agent's name, description, API endpoint, and feature flags.
```json
{
"vanilla_agent_dynamic_skill": {
"name": "Vanilla Agent Dynamic Skill",
"description": (
"A minimal agent that dynamically loads one skill from the "
"client and then answers using those instructions."
),
"endpoints": {"query": "/v1/query"},
"features": {
"streaming": True,
"widget-dashboard-select": False,
"widget-dashboard-search": False,
},
}
}
```
--------------------------------
### Register a Basic Table Widget
Source: https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts
Registers a simple table widget that returns mock data. This serves as a basic example for creating table widgets.
```python
@register_widget({"name": "Table Widget", "description": "A table widget", "type": "table", "endpoint": "table_widget", "gridData": {"w": 12, "h": 4},})@app.get("/table_widget")def table_widget(): """Returns a mock table data for demonstration""" mock_data = [ { "name": "Ethereum", "tvl": 45000000000, "change_1d": 2.5, "change_7d": 5.2 }, { "name": "Bitcoin", "tvl": 35000000000, "change_1d": 1.2, "change_7d": 4.8 }, { "name": "Solana", "tvl": 8000000000, "change_1d": -0.5, "change_7d": 2.1 } ] return mock_data
```
--------------------------------
### Get Whitepaper Options by Category
Source: https://docs.openbb.co/workspace/developers/widget-types/file-viewer
Fetches a list of available whitepapers, optionally filtered by category. Used to populate dropdowns for file selection.
```python
from pydantic import BaseModelfrom typing import List, Unionfrom fastapi import Bodyclass FileOption(BaseModel):
label: str
value: strclass FileDataFormat(BaseModel):
data_type: str
filename: strclass DataContent(BaseModel):
content: str
data_format: FileDataFormatclass DataUrl(BaseModel):
url: str
data_format: FileDataFormatclass DataError(BaseModel):
error_type: str
content: str# Sample whitepaper data with categoriesWHITEPAPERS = [
{
"name": "Bitcoin",
"location": "bitcoin.pdf",
"url": "https://openbb-assets.s3.us-east-1.amazonaws.com/testing/bitcoin.pdf",
"category": "l1",
},
{
"name": "Ethereum",
"location": "ethereum.pdf",
"url": "https://openbb-assets.s3.us-east-1.amazonaws.com/testing/ethereum.pdf",
"category": "l1",
},
{
"name": "Chainlink",
"location": "chainlink.pdf",
"url": "https://openbb-assets.s3.us-east-1.amazonaws.com/testing/chainlink.pdf",
"category": "oracles",
},
{
"name": "Solana",
"location": "solana.pdf",
"url": "https://openbb-assets.s3.us-east-1.amazonaws.com/testing/solana.pdf",
"category": "l1",
},
]@app.get("/whitepapers/options")async def get_whitepaper_options(category: str = Query("all")) -> List[FileOption]:
"""Get list of available whitepapers filtered by category"""
if category == "all":
return [
FileOption(label=wp["name"], value=wp["name"])
for wp in WHITEPAPERS
]
return [
FileOption(label=wp["name"], value=wp["name"])
for wp in WHITEPAPERS
if wp["category"] == category
]
```
--------------------------------
### Basic Agent Query Handler
Source: https://docs.openbb.co/workspace/developers/openbb-ai-sdk
This is the main entry point for an agent. It demonstrates how to yield reasoning steps and stream responses from an LLM using the OpenBB AI SDK and OpenAI's async client.
```python
from openbb_ai.models import QueryRequest
from openbb_ai import message_chunk, reasoning_step
import openai
async def query(request: QueryRequest):
"""Main entry point for your agent."""
# Show the user what you're doing
yield reasoning_step(
event_type="INFO",
message="Processing your request..."
).model_dump()
# Access the user's latest message
last_message = request.messages[-1]
if last_message.role == "human":
user_query = last_message.content
# Stream a response from LLM
client = openai.AsyncOpenAI()
async for event in await client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": user_query}],
stream=True,
):
if chunk := event.choices[0].delta.content:
yield message_chunk(chunk).model_dump()
```
--------------------------------
### Example OBB.WIDGET Formula
Source: https://docs.openbb.co/workspace/analysts/excel-addin/excel-overview
This is an example of how to use the OBB.WIDGET function in Excel to retrieve data from a widget. It specifies the widget name and parameters.
```excel
=OBB.WIDGET("DTCC Trades","swap_rate_levels_custom_obb",{"currency","USD";"swap_type","OIS";"period","1y"})
```
--------------------------------
### Install Highcharts Core Package
Source: https://docs.openbb.co/workspace/developers/widget-types/highcharts
Install the `highcharts-core` Python package to enable Highcharts integration. This is a prerequisite for using Highcharts charts in the OpenBB Workspace.
```python
pip install highcharts-core
```
--------------------------------
### OpenBB AI SDK Core Logic Example
Source: https://docs.openbb.co/workspace/developers/ai-features/share-step-by-step-reasoning
Demonstrates the core logic for handling AI queries, including message conversion, emitting reasoning steps, and streaming LLM responses. This snippet is useful for understanding the flow of an AI request within the OpenBB ecosystem.
```python
from openbb_ai import reasoning_step, message_chunk
from openbb_ai.models import QueryRequest, LlmClientMessage
from openai.types.chat import ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam
async def query(request: QueryRequest) -> EventSourceResponse:
# Convert messages to OpenAI format
openai_messages = [
ChatCompletionSystemMessageParam(
role="system",
content="You are a helpful financial assistant."
)
]
for message in request.messages:
if message.role == "human":
openai_messages.append(
ChatCompletionUserMessageParam(role="user", content=message.content)
)
async def execution_loop():
# Pre-processing reasoning
yield reasoning_step(
event_type="INFO",
message="Processing your request...",
details={"total_messages": len(request.messages)}
).model_dump()
# Stream LLM response
yield reasoning_step(
event_type="INFO",
message="Generating response..."
).model_dump()
async for event in await client.chat.completions.create(
model="gpt-4o",
messages=openai_messages,
stream=True
):
if chunk := event.choices[0].delta.content:
yield message_chunk(chunk).model_dump()
# Completion reasoning
yield reasoning_step(
event_type="SUCCESS",
message="Response generated successfully!"
).model_dump()
return EventSourceResponse(execution_loop(), media_type="text/event-stream")
```
--------------------------------
### Run OpenBB API with SSL Certificates
Source: https://docs.openbb.co/workspace/getting-started/faqs
Launch the OpenBB API server using the generated SSL key and certificate files to enable HTTPS connections. This is a necessary step for local connections in browsers like Safari and Brave.
```bash
openbb-api --ssl_keyfile localhost.key --ssl_certfile localhost.crt
```
--------------------------------
### Basic YouTube Widget Configuration
Source: https://docs.openbb.co/workspace/developers/widget-types/youtube
Configure a widget to display a YouTube video. The 'type' is set to 'youtube', and an 'endpoint' provides the video URL. The 'params' define how the user selects a video.
```python
from fastapi import Query
from fastapi.responses import PlainTextResponse
from typing import List
from pydantic import BaseModel
class FileOption(BaseModel):
label: str
value: str
# Sample YouTube videos data
SAMPLE_VIDEOS = [
{
"name": "OpenBB Workspace Demo",
"url": "https://www.youtube.com/watch?v=uYyhswnZkSw",
},
{
"name": "Open Data Platform Demo",
"url": "https://www.youtube.com/watch?v=MSlhOFxEdxg",
}
]
# Options endpoint for video selection dropdown
@app.get("/get_video_options")
async def get_video_options() -> List[FileOption]:
"""Get list of available videos"""
return [
FileOption(label=video["name"], value=video["name"])
for video in SAMPLE_VIDEOS
]
# YouTube widget - video player only
@register_widget({
"name": "Video Library",
"description": "View YouTube videos",
"type": "youtube",
"endpoint": "/get_video",
"gridData": {"w": 20, "h": 12},
"params": [
{
"paramName": "video_name",
"description": "Video to display",
"type": "endpoint",
"label": "Video",
"optionsEndpoint": "/get_video_options",
"value": "OpenBB Workspace Demo",
}
]
})
@app.get("/get_video")
async def get_video(
video_name: str = Query("", description="Selected video"),
):
"""Get YouTube video URL"""
video = next((v for v in SAMPLE_VIDEOS if v["name"] == video_name), None)
if not video:
return PlainTextResponse(content="")
return PlainTextResponse(content=video["url"])
```
--------------------------------
### OBB.WIDGET Example with Economic PCE Data
Source: https://docs.openbb.co/workspace/analysts/excel-addin/obb-widget
Example of using OBB.WIDGET to fetch Personal Consumption Expenditures (PCE) data from the OpenBB Platform backend, specifying the category and provider.
```excel
=OBB.WIDGET("OpenBB Platform","economy_pce_fred_obb",{"category","personal_income";"provider","fred"})
```
--------------------------------
### SQL Widget Configuration
Source: https://docs.openbb.co/workspace/developers/widget-types/omni
Configure the SQL widget to execute SQL queries against mock stock data. The 'language: "sql"' parameter enables SQL syntax highlighting.
```json
{
"omni_sql_widget": {
"name": "SQL Query Widget",
"description": "Execute SQL queries against mock stock data. Use 'DATA' as the table name.",
"category": "General",
"type": "omni",
"endpoint": "omni-sql-widget",
"params": [
{
"paramName": "prompt",
"type": "text",
"description": "Enter a SQL query. Available columns: id, symbol, name, price, volume, sector",
"label": "SQL Query",
"value": "SELECT * FROM DATA LIMIT 5",
"show": false,
"language": "sql"
}
],
"gridData": {"w": 30, "h": 12}
}
}
```
--------------------------------
### HTML Alert Box Example
Source: https://docs.openbb.co/workspace/developers/ai-features/create-html-artifacts
An example of an HTML alert box with custom styling for displaying market alerts. It uses inline styles for cross-platform consistency and includes an exclamation mark icon.
```html
!
Market Alert
Unusual trading volume detected in AAPL. Volume is 3.2x higher than the 20-day average.
```
--------------------------------
### Example HTML Template for Dashboard Card
Source: https://docs.openbb.co/workspace/developers/ai-features/create-html-artifacts
An example of an HTML template designed for a portfolio summary dashboard card. It uses inline styles for formatting and includes sections for total value and today's change.
```html
```
--------------------------------
### Initial Request with Skill Catalog
Source: https://docs.openbb.co/workspace/developers/ai-features/dynamic-skill-loading
Send an initial request to the AI agent including a skill catalog. This allows the agent to identify relevant skills based on slugs and descriptions before any skill content is loaded.
```json
{
"messages": [
{
"role": "human",
"content": "Use the financial-analysis skill to review AAPL."
}
],
"skills_catalog": [
{
"slug": "financial-analysis",
"description": "Analyze company financials and earnings",
"updatedAt": "2026-03-22T12:00:00Z"
}
]
}
```
--------------------------------
### YouTube Widget with Transcript Support Configuration
Source: https://docs.openbb.co/workspace/developers/widget-types/youtube
Configure a widget to display YouTube videos and optionally provide transcripts for AI. Set `raw=True` in the widget configuration to enable transcript fetching.
```python
from fastapi import Query
from fastapi.responses import PlainTextResponse
from typing import List
from pydantic import BaseModel
class FileOption(BaseModel):
label: str
value: str
# Sample YouTube videos data with transcripts
SAMPLE_VIDEOS = [
{
"name": "OpenBB Workspace Demo",
"url": "https://www.youtube.com/watch?v=uYyhswnZkSw",
"transcript": "# OpenBB Workspace Demo\n\nThis video demonstrates the OpenBB Workspace features..."
},
{
"name": "Open Data Platform Demo",
"url": "https://www.youtube.com/watch?v=MSlhOFxEdxg",
"transcript": "# Open Data Platform Demo\n\nIn this video we explore the Open Data Platform..."
}
]
# Options endpoint for video selection dropdown
@app.get("/get_video_options")
async def get_video_options() -> List[FileOption]:
"""Get list of available videos"""
return [
FileOption(label=video["name"], value=video["name"])
for video in SAMPLE_VIDEOS
]
# YouTube widget with transcript support for AI
@register_widget({
"name": "Video Library with Transcript",
"description": "View YouTube videos with transcript support for AI",
"type": "youtube",
"endpoint": "/get_video_with_transcript",
"raw": True,
"gridData": {"w": 20, "h": 12},
"params": [
{
"paramName": "video_name",
"description": "Video to display",
"type": "endpoint",
"label": "Video",
"optionsEndpoint": "/get_video_options",
"value": "OpenBB Workspace Demo",
}
]
})
@app.get("/get_video_with_transcript")
async def get_video_with_transcript(
video_name: str = Query("", description="Selected video"),
raw: bool = Query(False, description="Return transcript instead of URL"),
):
"""Get YouTube video URL or transcript"""
video = next((v for v in SAMPLE_VIDEOS if v["name"] == video_name), None)
if not video:
return PlainTextResponse(content="*No video selected*" if raw else "")
if raw:
return PlainTextResponse(content=video["transcript"], media_type="text/markdown")
return PlainTextResponse(content=video["url"])
```
--------------------------------
### Complete Agent Implementation with Widget Data Flow
Source: https://docs.openbb.co/workspace/developers/openbb-ai-sdk
This Python function demonstrates a complete agent implementation that handles widget data flow, including fetching market data, analyzing it, streaming LLM responses, and displaying results in a table with citations. It manages different phases of interaction, from initial data requests to final analysis.
```python
from openbb_ai import WidgetRequest, message_chunk, reasoning_step, cite, citations, table, get_widget_data
from openbb_ai.models import QueryRequest, DataContent, ClientFunctionCallError
import json
import openai
async def query(request: QueryRequest):
"""Complete agent implementation with widget data flow."""
last_message = request.messages[-1]
# Check for orchestration requests
orchestration_requested = (
last_message.role == "ai" and last_message.agent_id == "openbb-copilot"
)
# Phase 1: Fetch widget data if needed
if ((last_message.role == "human" or orchestration_requested)
and request.widgets and request.widgets.primary):
widget_requests = [
WidgetRequest(
widget=widget,
input_arguments={
param.name: param.current_value for param in widget.params
}
)
for widget in request.widgets.primary
]
yield reasoning_step(
event_type="INFO",
message="Fetching market data..."
).model_dump()
yield get_widget_data(widget_requests).model_dump()
return # Exit and wait for callback
# Phase 2: Process widget data
if hasattr(last_message, 'data'):
yield reasoning_step(
event_type="INFO",
message="Analyzing data..."
).model_dump()
# Process the data
results = []
for item in last_message.data:
if isinstance(item, ClientFunctionCallError):
yield reasoning_step(
event_type="ERROR",
message=f"Failed: {item.content}"
).model_dump()
continue
if isinstance(item, DataContent):
for data_item in item.items:
data = json.loads(data_item.content)
results.append(data)
# Stream response from LLM
yield message_chunk("Based on the market data analysis:\n").model_dump()
# Continue with LLM streaming
client = openai.AsyncOpenAI()
async for event in await client.chat.completions.create(
model="gpt-4o",
messages=openai_messages,
stream=True,
):
if chunk := event.choices[0].delta.content:
yield message_chunk(chunk).model_dump()
# Show data table
if results:
yield table(
data=results[:5], # Show top 5
name="Market Summary",
description="Key metrics"
).model_dump()
# Add citations
citation_list = [
cite(widget=widget, input_arguments={
param.name: param.current_value for param in widget.params
})
for widget in request.widgets.primary
]
yield citations(citation_list).model_dump()
yield reasoning_step(
event_type="SUCCESS",
message="Analysis complete"
).model_dump()
# Phase 3: Handle regular chat without widgets
else:
yield message_chunk("Please add some widgets to analyze market data.").model_dump()
```
--------------------------------
### Example renderFnParams for GroupBy
Source: https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference
Configuration for cell click grouping, specifying the parameter name to update.
```json
"renderFnParams": {
"actionType": "groupBy",
"groupBy": {
"paramName": "symbol"
}
}
```
--------------------------------
### Example renderFnParams for Color Rules
Source: https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference
Defines rules for conditional coloring of cells based on specific criteria.
```json
"renderFnParams": {
"colorRules": [
{
"field": "Analyst",
"operator": "==",
"value": "John Doe",
"color": "#00FF00"
}
]
}
```
--------------------------------
### Example renderFnParams for Hover Card Data
Source: https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference
Specifies columns to be displayed in a hover card when interacting with a cell.
```json
"renderFnParams": {
"hoverCardData": ["column1", "column2"]
}
```
--------------------------------
### Create Bar Chart with OpenBB AI SDK
Source: https://docs.openbb.co/workspace/developers/openbb-ai-sdk
Generates a bar chart for comparative data. Requires specifying the chart type, data, x-axis key, y-axis keys, name, and description.
```python
from openbb_ai import chart
# Bar chart for comparisons
yield chart(
type="bar",
data=[
{"symbol": "AAPL", "volume": 50000000},
{"symbol": "GOOGL", "volume": 25000000},
{"symbol": "MSFT", "volume": 40000000}
],
x_key="symbol",
y_keys=["volume"],
name="Trading Volume",
description="Volume by symbol"
).model_dump()
```
--------------------------------
### GET /live_grid_data
Source: https://docs.openbb.co/workspace/developers/widget-types/live-grid
Initial data endpoint for the live grid. It fetches the current data for the specified symbols.
```APIDOC
## GET /live_grid_data
### Description
This endpoint provides the initial dataset for the live grid widget. It accepts a comma-separated string of stock symbols and returns their current market data.
### Method
GET
### Endpoint
`/live_grid_data`
### Parameters
#### Query Parameters
- **symbol** (string) - Required - The stock symbol(s) to retrieve data for. Can be a single symbol or a comma-separated list.
### Response
#### Success Response (200)
Returns a list of dictionaries, where each dictionary contains data for a specific stock symbol, including:
- **date** (string): The current date.
- **symbol** (string): The stock symbol.
- **price** (float): The current price of the stock.
- **change** (float): The change in price from the previous close.
- **change_percent** (float): The percentage change in price from the previous close.
- **volume** (integer): The trading volume.
- **market_cap** (integer): The market capitalization of the stock.
#### Response Example
```json
[
{
"date": "2023-10-27",
"symbol": "TSLA",
"price": 245.50,
"change": 5.50,
"change_percent": 0.022,
"volume": 1500000,
"market_cap": 1800000000
}
]
```
```
--------------------------------
### Get a Single Column by Name
Source: https://docs.openbb.co/workspace/analysts/excel-addin/obb-get
Retrieve all values from a specific column by providing its name. Column names are case-sensitive.
```excel
=OBB.GET(A1:D3, , "revenue")
```
--------------------------------
### Date Modifier Examples
Source: https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference
Demonstrates dynamic date settings for parameters like start_date and end_date. Supports relative date adjustments (e.g., -2y, +1d) and null values.
```json
[ { "paramName": "start_date", "value": "$currentDate-2y", "label": "Start Date", "type": "date", "description": "Current Date for the stock price" }, { "paramName": "end_date", "value": "$currentDate+1d", "label": "End Date", "type": "date", "description": "End Date for the stock price" }, { "paramName": "end_date", "value": null, "label": "End Date", "type": "date", "description": "End Date for the stock price" }, { "paramName": "interval", "value": "1d", "label": "Interval", "options": [ { "label": "Daily", "value": "1d" }, { "label": "Weekly", "value": "1w" }, { "label": "Monthly", "value": "1m" } ], "type": "text", "description": "Select the interval" }]
```
--------------------------------
### Example cellRangeCols Configuration
Source: https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference
Defines default column mappings for different chart types, specifying category and series columns.
```json
"cellRangeCols": {
"line": ["ticker", "weight", "weight2"],
"column": ["date", "price", "volume"]
}
```
--------------------------------
### Configure App Layout
Source: https://docs.openbb.co/workspace/developers/data-integration
Defines the app's layout, including widgets and their states, for integration into OpenBB.
```json
[
{
"name": "Hello World",
"img": "",
"img_dark": "",
"img_light": "",
"description": "Hello World template",
"allowCustomization": true,
"tabs": {
"": {
"id": "",
"name": "",
"layout": [
{
"i": "hello_world",
"x": 0,
"y": 0,
"w": 12,
"h": 4,
"state": {
"params": {
"name": ""
}
}
}
]
}
},
"groups": []
}
]
```