### 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
Revenue
$2.4M
↑ 14.2%
Users
48.2K
↑ 8.1%
``` -------------------------------- ### 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

Portfolio Summary

$124.5K
Total Value
+12.3%
Today's Change
``` -------------------------------- ### 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": [] } ] ```