# Table of Contents - [Page Not Found | OpenBB Docs](#page-not-found-openbb-docs) - [OpenBB Workspace Docs](#openbb-workspace-docs) - [Progressive Web App (PWA) | OpenBB Workspace Docs](#progressive-web-app-pwa-openbb-workspace-docs) - [Enterprise | OpenBB Workspace Docs](#enterprise-openbb-workspace-docs) - [Open source platform integration | OpenBB Workspace Docs](#open-source-platform-integration-openbb-workspace-docs) - [FAQs | OpenBB Workspace Docs](#faqs-openbb-workspace-docs) - [Dashboards - OpenBB Workspace Docs](#dashboards-openbb-workspace-docs) - [Agent Skills | OpenBB Workspace Docs](#agent-skills-openbb-workspace-docs) - [Apps | OpenBB Workspace Docs](#apps-openbb-workspace-docs) - [Data Integration | OpenBB Workspace Docs](#data-integration-openbb-workspace-docs) - [Apps | OpenBB Workspace Docs](#apps-openbb-workspace-docs) - [Support & Services | OpenBB Workspace Docs](#support-services-openbb-workspace-docs) - [Sandbox Widgets | OpenBB Workspace Docs](#sandbox-widgets-openbb-workspace-docs) - [Widgets Overview | OpenBB Workspace Docs](#widgets-overview-openbb-workspace-docs) - [Widgets.json | OpenBB Workspace Docs](#widgets-json-openbb-workspace-docs) - [Python Interface - Quick Start | OpenBB Docs](#python-interface-quick-start-openbb-docs) - [Core Widgets | OpenBB Workspace Docs](#core-widgets-openbb-workspace-docs) - [Troubleshooting | OpenBB Add-in for Excel Docs](#troubleshooting-openbb-add-in-for-excel-docs) - [Interacting With Data | OpenBB Workspace Docs](#interacting-with-data-openbb-workspace-docs) - [Static Files | OpenBB Workspace Docs](#static-files-openbb-workspace-docs) - [AI-generated Widgets | OpenBB Workspace Docs](#ai-generated-widgets-openbb-workspace-docs) - [Matching widget to MCP tool | OpenBB Workspace Docs](#matching-widget-to-mcp-tool-openbb-workspace-docs) - [Settings - ODP Python | OpenBB Docs](#settings-odp-python-openbb-docs) - [Markdown | OpenBB Workspace Docs](#markdown-openbb-workspace-docs) - [Copilot Basics | OpenBB Workspace Docs](#copilot-basics-openbb-workspace-docs) - [Agents Integration | OpenBB Workspace Docs](#agents-integration-openbb-workspace-docs) - [Data Control & Security | OpenBB Workspace Docs](#data-control-security-openbb-workspace-docs) - [Administration | OpenBB Workspace Docs](#administration-openbb-workspace-docs) - [Team Collaboration | OpenBB Workspace Docs](#team-collaboration-openbb-workspace-docs) - [OpenBB AI SDK | OpenBB Workspace Docs](#openbb-ai-sdk-openbb-workspace-docs) - [Page Not Found | OpenBB Docs](#page-not-found-openbb-docs) - [Search the documentation | OpenBB Docs](#search-the-documentation-openbb-docs) - [Markdown page example | OpenBB Docs](#markdown-page-example-openbb-docs) - [OpenBB Docs](#openbb-docs) - [Apps.json Reference | OpenBB Workspace Docs](#apps-json-reference-openbb-workspace-docs) - [Getting Started | OpenBB Add-in for Excel Docs](#getting-started-openbb-add-in-for-excel-docs) - [OBB.WIDGET | OpenBB Add-in for Excel Docs](#obb-widget-openbb-add-in-for-excel-docs) - [OpenBB Add-in for Excel Docs](#openbb-add-in-for-excel-docs) - [OBB.GET | OpenBB Add-in for Excel Docs](#obb-get-openbb-add-in-for-excel-docs) - [agents.json Reference | OpenBB Workspace Docs](#agents-json-reference-openbb-workspace-docs) - [Categories and Subcategories | OpenBB Workspace Docs](#categories-and-subcategories-openbb-workspace-docs) - [Error Handling | OpenBB Workspace Docs](#error-handling-openbb-workspace-docs) - [Grid Size | OpenBB Workspace Docs](#grid-size-openbb-workspace-docs) - [Run Button | OpenBB Workspace Docs](#run-button-openbb-workspace-docs) - [Stale Time | OpenBB Workspace Docs](#stale-time-openbb-workspace-docs) - [Render Functions | OpenBB Workspace Docs](#render-functions-openbb-workspace-docs) - [Metric | OpenBB Workspace Docs](#metric-openbb-workspace-docs) - [Refetch Interval | OpenBB Workspace Docs](#refetch-interval-openbb-workspace-docs) - [SSRM Mode | OpenBB Workspace Docs](#ssrm-mode-openbb-workspace-docs) - [HTML | OpenBB Workspace Docs](#html-openbb-workspace-docs) - [Context Management | OpenBB Workspace Docs](#context-management-openbb-workspace-docs) - [Data Handling | OpenBB Workspace Docs](#data-handling-openbb-workspace-docs) - [Step-by-Step Reasoning | OpenBB Workspace Docs](#step-by-step-reasoning-openbb-workspace-docs) - [MCP Tools | OpenBB Workspace Docs](#mcp-tools-openbb-workspace-docs) - [YouTube | OpenBB Workspace Docs](#youtube-openbb-workspace-docs) - [Environment Variables - ODP Python | OpenBB Docs](#environment-variables-odp-python-openbb-docs) - [Highcharts Chart | OpenBB Workspace Docs](#highcharts-chart-openbb-workspace-docs) - [OpenBB Snowflake Native App - Quick Start](#openbb-snowflake-native-app-quick-start) - [Live Grid | OpenBB Workspace Docs](#live-grid-openbb-workspace-docs) - [Output Formats | OpenBB Workspace Docs](#output-formats-openbb-workspace-docs) - [Open Data Platform by OpenBB | ODP Docs](#open-data-platform-by-openbb-odp-docs) - [TradingView Charts | OpenBB Workspace Docs](#tradingview-charts-openbb-workspace-docs) - [Commands And Arguments | ODP CLI Docs](#commands-and-arguments-odp-cli-docs) - [AI Features — Interact with dashboard | OpenBB Workspace Docs](#ai-features-interact-with-dashboard-openbb-workspace-docs) - [OpenBBUserData Folder | ODP CLI Docs](#openbbuserdata-folder-odp-cli-docs) - [Installation | ODP CLI Docs](#installation-odp-cli-docs) - [Interactive Charts - | ODP CLI Docs](#interactive-charts-odp-cli-docs) - [Data Sources | ODP CLI Docs](#data-sources-odp-cli-docs) - [Newsfeed | OpenBB Workspace Docs](#newsfeed-openbb-workspace-docs) - [API Keys & Credentials - ODP Python | OpenBB Docs](#api-keys-credentials-odp-python-openbb-docs) - [Generative UI (Beta) | OpenBB Workspace Docs](#generative-ui-beta-openbb-workspace-docs) - [Interactive Tables - | ODP CLI Docs](#interactive-tables-odp-cli-docs) - [User Settings - ODP Python | OpenBB Docs](#user-settings-odp-python-openbb-docs) - [Configuration & Settings - | ODP CLI Docs](#configuration-settings-odp-cli-docs) - [Structure and Navigation | ODP CLI Docs](#structure-and-navigation-odp-cli-docs) - [Uninstall | ODP Desktop App Docs](#uninstall-odp-desktop-app-docs) - [File Viewer | OpenBB Workspace Docs](#file-viewer-openbb-workspace-docs) - [ODP CLI Docs](#odp-cli-docs) - [Omni, SQL, Python | OpenBB Workspace Docs](#omni-sql-python-openbb-workspace-docs) - [AI Features — Create tables | OpenBB Workspace Docs](#ai-features-create-tables-openbb-workspace-docs) - [AI Features — Highlight widget citations | OpenBB Workspace Docs](#ai-features-highlight-widget-citations-openbb-workspace-docs) - [AI Features — Share step-by-step reasoning | OpenBB Workspace Docs](#ai-features-share-step-by-step-reasoning-openbb-workspace-docs) - [Installation | ODP Desktop App Docs](#installation-odp-desktop-app-docs) - [AI Features — Create charts | OpenBB Workspace Docs](#ai-features-create-charts-openbb-workspace-docs) - [Troubleshooting | ODP Desktop App Docs](#troubleshooting-odp-desktop-app-docs) - [AgGrid Table Charts | OpenBB Workspace Docs](#aggrid-table-charts-openbb-workspace-docs) - [Orchestrator Mode | OpenBB Workspace Docs](#orchestrator-mode-openbb-workspace-docs) - [AI Features — Parse widget data | OpenBB Workspace Docs](#ai-features-parse-widget-data-openbb-workspace-docs) - [Environments | ODP Desktop App Docs](#environments-odp-desktop-app-docs) - [Quick Start - Usage | ODP CLI Docs](#quick-start-usage-odp-cli-docs) - [AI Features — Parse PDF context | OpenBB Workspace Docs](#ai-features-parse-pdf-context-openbb-workspace-docs) - [AI Features — Custom agent features | OpenBB Workspace Docs](#ai-features-custom-agent-features-openbb-workspace-docs) - [AI Features — Citations for documents | OpenBB Workspace Docs](#ai-features-citations-for-documents-openbb-workspace-docs) - [MCP Settings - ODP Python | OpenBB Docs](#mcp-settings-odp-python-openbb-docs) - [Routines - | ODP CLI Docs](#routines-odp-cli-docs) - [Backends | ODP Desktop App Docs](#backends-odp-desktop-app-docs) - [Routine Macro Recorder - Routines - Usage | ODP CLI Docs](#routine-macro-recorder-routines-usage-odp-cli-docs) - [AI Features — MCP Tools Integration | OpenBB Workspace Docs](#ai-features-mcp-tools-integration-openbb-workspace-docs) - [Introduction | ODP Desktop App Docs](#introduction-odp-desktop-app-docs) - [AI Features — Create HTML artifacts | OpenBB Workspace Docs](#ai-features-create-html-artifacts-openbb-workspace-docs) - [OpenBB Docs](#openbb-docs) - [Introduction to Routines - Routines | ODP CLI Docs](#introduction-to-routines-routines-odp-cli-docs) - [Advanced Routines - Routines | ODP CLI Docs](#advanced-routines-routines-odp-cli-docs) - [Importing - ODP Python | OpenBB Docs](#importing-odp-python-openbb-docs) - [Plotly Charts | OpenBB Workspace Docs](#plotly-charts-openbb-workspace-docs) - [API Keys | ODP Desktop App Docs](#api-keys-odp-desktop-app-docs) - [System Settings - ODP Python | OpenBB Docs](#system-settings-odp-python-openbb-docs) - [Input Query Params - ODP Python | OpenBB Docs](#input-query-params-odp-python-openbb-docs) - [Python Outputs - Basic Usage | OpenBB Docs](#python-outputs-basic-usage-openbb-docs) - [Options | OpenBB Docs](#options-openbb-docs) - [Price | OpenBB Docs](#price-openbb-docs) - [Installation | OpenBB Docs](#installation-openbb-docs) - [Price | OpenBB Docs](#price-openbb-docs) - [Price | OpenBB Docs](#price-openbb-docs) - [Futures | OpenBB Docs](#futures-openbb-docs) - [Shipping | OpenBB Docs](#shipping-openbb-docs) - [Survey | OpenBB Docs](#survey-openbb-docs) - [How-To Guides - Development | OpenBB Docs](#how-to-guides-development-openbb-docs) - [Compare | OpenBB Docs](#compare-openbb-docs) - [Darkpool | OpenBB Docs](#darkpool-openbb-docs) - [Discovery | OpenBB Docs](#discovery-openbb-docs) - [Gdp | OpenBB Docs](#gdp-openbb-docs) - [Estimates | OpenBB Docs](#estimates-openbb-docs) - [Boolean Toggle | OpenBB Workspace Docs](#boolean-toggle-openbb-workspace-docs) - [Licensing FAQ | OpenBB Docs](#licensing-faq-openbb-docs) - [Derivatives | OpenBB Docs](#derivatives-openbb-docs) - [Crypto | OpenBB Docs](#crypto-openbb-docs) - [Fundamental | OpenBB Docs](#fundamental-openbb-docs) - [Date Picker | OpenBB Workspace Docs](#date-picker-openbb-workspace-docs) - [Calendar | OpenBB Docs](#calendar-openbb-docs) - [OpenBB Charting | OpenBB Docs](#openbb-charting-openbb-docs) - [Advanced Dropdown | OpenBB Workspace Docs](#advanced-dropdown-openbb-workspace-docs) - [Dropdown | OpenBB Workspace Docs](#dropdown-openbb-workspace-docs) - [Development Overview | OpenBB Docs](#development-overview-openbb-docs) - [Providers | OpenBB Docs](#providers-openbb-docs) - [Number Input | OpenBB Workspace Docs](#number-input-openbb-workspace-docs) - [Rate | OpenBB Docs](#rate-openbb-docs) - [Government | OpenBB Docs](#government-openbb-docs) - [Dependent Dropdown | OpenBB Workspace Docs](#dependent-dropdown-openbb-workspace-docs) - [OpenBB Core | OpenBB Docs](#openbb-core-openbb-docs) - [MCP Server - Quick Start | OpenBB Docs](#mcp-server-quick-start-openbb-docs) - [Text Input | OpenBB Workspace Docs](#text-input-openbb-workspace-docs) - [Currency | OpenBB Docs](#currency-openbb-docs) - [Technical Indicators - OpenBB Charting | OpenBB Docs](#technical-indicators-openbb-charting-openbb-docs) - [Corporate | OpenBB Docs](#corporate-openbb-docs) - [Rolling | OpenBB Docs](#rolling-openbb-docs) - [Cell Click Grouping | OpenBB Workspace Docs](#cell-click-grouping-openbb-workspace-docs) - [OpenBB Quantitative - Python Packages & Extensions | OpenBB Docs](#openbb-quantitative-python-packages-extensions-openbb-docs) - [Input Form | OpenBB Workspace Docs](#input-form-openbb-workspace-docs) - [Commodity | OpenBB Docs](#commodity-openbb-docs) - [OpenBB Technical - Python Packages & Extensions | OpenBB Docs](#openbb-technical-python-packages-extensions-openbb-docs) - [Extension Types | OpenBB Docs](#extension-types-openbb-docs) - [OpenBB Econometrics - Python Packages & Extensions | OpenBB Docs](#openbb-econometrics-python-packages-extensions-openbb-docs) - [Performance | OpenBB Docs](#performance-openbb-docs) - [Standardization - Developer | OpenBB Docs](#standardization-developer-openbb-docs) - [Parameter Positioning | OpenBB Workspace Docs](#parameter-positioning-openbb-workspace-docs) - [Data Providers FAQ - FAQs | OpenBB Docs](#data-providers-faq-faqs-openbb-docs) - [Quickstart - Workspace Custom Backend | OpenBB Docs](#quickstart-workspace-custom-backend-openbb-docs) - [Tabs | OpenBB Workspace Docs](#tabs-openbb-workspace-docs) - [REST API - Quick Start | OpenBB Docs](#rest-api-quick-start-openbb-docs) - [News | OpenBB Docs](#news-openbb-docs) - [Errors FAQ - FAQs | OpenBB Docs](#errors-faq-faqs-openbb-docs) - [Python Packages & Extensions | OpenBB Docs](#python-packages-extensions-openbb-docs) - [Parameter Grouping | OpenBB Workspace Docs](#parameter-grouping-openbb-workspace-docs) - [Uscongress | OpenBB Docs](#uscongress-openbb-docs) - [Deprecating Endpoints - How-To | OpenBB Docs](#deprecating-endpoints-how-to-openbb-docs) - [Fixedincome | OpenBB Docs](#fixedincome-openbb-docs) - [openbb-mcp | OpenBB Docs](#openbb-mcp-openbb-docs) - [Converting FastAPI Apps - Developer | OpenBB Docs](#converting-fastapi-apps-developer-openbb-docs) - [Build OBBject Extensions - Developer | OpenBB Docs](#build-obbject-extensions-developer-openbb-docs) - [Validators - Developer | OpenBB Docs](#validators-developer-openbb-docs) - [Dynamic Command Execution - Developer | OpenBB Docs](#dynamic-command-execution-developer-openbb-docs) - [Architecture Overview - Developer | OpenBB Docs](#architecture-overview-developer-openbb-docs) - [Disabling Output Validation - Developer Guides | OpenBB Docs](#disabling-output-validation-developer-guides-openbb-docs) - [Build OBBject Plugin Extensions - Developer | OpenBB Docs](#build-obbject-plugin-extensions-developer-openbb-docs) - [Docstring Examples - Developer | OpenBB Docs](#docstring-examples-developer-openbb-docs) - [Build Provider Extensions - Developer | OpenBB Docs](#build-provider-extensions-developer-openbb-docs) - [Annotated Results & Metadata - Developer | OpenBB Docs](#annotated-results-metadata-developer-openbb-docs) - [Quantitative | OpenBB Docs](#quantitative-openbb-docs) - [Econometrics | OpenBB Docs](#econometrics-openbb-docs) - [HTTP Requests - Contributor Guidelines - Development | OpenBB Docs](#http-requests-contributor-guidelines-development-openbb-docs) - [Preferences - ODP Python | OpenBB Docs](#preferences-odp-python-openbb-docs) - [Defaults - ODP Python | OpenBB Docs](#defaults-odp-python-openbb-docs) - [Tests - Contributor Guidelines - Development | OpenBB Docs](#tests-contributor-guidelines-development-openbb-docs) - [Charting Extensions - Developer | OpenBB Docs](#charting-extensions-developer-openbb-docs) - [Build Router Extensions - Developer | OpenBB Docs](#build-router-extensions-developer-openbb-docs) - [Equity | OpenBB Docs](#equity-openbb-docs) - [Reference | OpenBB Docs](#reference-openbb-docs) - [crypto/search - Reference | OpenBB Docs](#crypto-search-reference-openbb-docs) - [crypto/price/historical - Reference | OpenBB Docs](#crypto-price-historical-reference-openbb-docs) - [derivatives/futures/curve - Reference | OpenBB Docs](#derivatives-futures-curve-reference-openbb-docs) - [derivatives/futures/info - Reference | OpenBB Docs](#derivatives-futures-info-reference-openbb-docs) - [derivatives/options/surface - Reference | OpenBB Docs](#derivatives-options-surface-reference-openbb-docs) - [derivatives/options/snapshots - Reference | OpenBB Docs](#derivatives-options-snapshots-reference-openbb-docs) - [derivatives/futures/instruments - Reference | OpenBB Docs](#derivatives-futures-instruments-reference-openbb-docs) - [derivatives/futures/historical - Reference | OpenBB Docs](#derivatives-futures-historical-reference-openbb-docs) - [derivatives/options/unusual - Reference | OpenBB Docs](#derivatives-options-unusual-reference-openbb-docs) - [ODP API | OpenBB Docs](#odp-api-openbb-docs) - [currency/search - Reference | OpenBB Docs](#currency-search-reference-openbb-docs) - [currency/reference_rates - Reference | OpenBB Docs](#currency-reference-rates-reference-openbb-docs) - [currency/price/historical - Reference | OpenBB Docs](#currency-price-historical-reference-openbb-docs) - [derivatives/options/chains - Reference | OpenBB Docs](#derivatives-options-chains-reference-openbb-docs) - [currency/snapshots - Reference | OpenBB Docs](#currency-snapshots-reference-openbb-docs) - [commodity/petroleum_status_report - Reference | OpenBB Docs](#commodity-petroleum-status-report-reference-openbb-docs) - [commodity/short_term_energy_outlook - Reference | OpenBB Docs](#commodity-short-term-energy-outlook-reference-openbb-docs) - [commodity/weather_bulletins_download - Reference | OpenBB Docs](#commodity-weather-bulletins-download-reference-openbb-docs) - [commodity/price/spot - Reference | OpenBB Docs](#commodity-price-spot-reference-openbb-docs) - [commodity/psd_data - Reference | OpenBB Docs](#commodity-psd-data-reference-openbb-docs) - [commodity/psd_report - Reference | OpenBB Docs](#commodity-psd-report-reference-openbb-docs) - [regulators/cftc/cot_search - Reference | OpenBB Docs](#regulators-cftc-cot-search-reference-openbb-docs) - [regulators/sec/htm_file - Reference | OpenBB Docs](#regulators-sec-htm-file-reference-openbb-docs) - [regulators/sec/cik_map - Reference | OpenBB Docs](#regulators-sec-cik-map-reference-openbb-docs) - [regulators/sec/institutions_search - Reference | OpenBB Docs](#regulators-sec-institutions-search-reference-openbb-docs) - [regulators/cftc/cot - Reference | OpenBB Docs](#regulators-cftc-cot-reference-openbb-docs) - [news/world - Reference | OpenBB Docs](#news-world-reference-openbb-docs) - [regulators/sec/sic_search - Reference | OpenBB Docs](#regulators-sec-sic-search-reference-openbb-docs) - [regulators/sec/schema_files - Reference | OpenBB Docs](#regulators-sec-schema-files-reference-openbb-docs) - [regulators/sec/rss_litigation - Reference | OpenBB Docs](#regulators-sec-rss-litigation-reference-openbb-docs) - [news/company - Reference | OpenBB Docs](#news-company-reference-openbb-docs) - [regulators/sec/filing_headers - Reference | OpenBB Docs](#regulators-sec-filing-headers-reference-openbb-docs) - [regulators/sec/symbol_map - Reference | OpenBB Docs](#regulators-sec-symbol-map-reference-openbb-docs) - [imf_utils/get_dataflow_dimensions - Reference | OpenBB Docs](#imf-utils-get-dataflow-dimensions-reference-openbb-docs) - [uscongress/bill_text_urls - Reference | OpenBB Docs](#uscongress-bill-text-urls-reference-openbb-docs) - [uscongress/bill_info - Reference | OpenBB Docs](#uscongress-bill-info-reference-openbb-docs) - [famafrench/factors - Reference | OpenBB Docs](#famafrench-factors-reference-openbb-docs) - [famafrench/country_portfolio_returns - Reference | OpenBB Docs](#famafrench-country-portfolio-returns-reference-openbb-docs) - [uscongress/bills - Reference | OpenBB Docs](#uscongress-bills-reference-openbb-docs) - [famafrench/us_portfolio_returns - Reference | OpenBB Docs](#famafrench-us-portfolio-returns-reference-openbb-docs) - [famafrench/breakpoints - Reference | OpenBB Docs](#famafrench-breakpoints-reference-openbb-docs) - [fixedincome/bond_indices - Reference | OpenBB Docs](#fixedincome-bond-indices-reference-openbb-docs) - [fixedincome/corporate/bond_prices - Reference | OpenBB Docs](#fixedincome-corporate-bond-prices-reference-openbb-docs) - [fixedincome/corporate/hqm - Reference | OpenBB Docs](#fixedincome-corporate-hqm-reference-openbb-docs) - [fixedincome/corporate/commercial_paper - Reference | OpenBB Docs](#fixedincome-corporate-commercial-paper-reference-openbb-docs) - [fixedincome/corporate/spot_rates - Reference | OpenBB Docs](#fixedincome-corporate-spot-rates-reference-openbb-docs) - [fixedincome/government/tips_yields - Reference | OpenBB Docs](#fixedincome-government-tips-yields-reference-openbb-docs) - [fixedincome/rate/ecb - Reference | OpenBB Docs](#fixedincome-rate-ecb-reference-openbb-docs) - [fixedincome/rate/dpcredit - Reference | OpenBB Docs](#fixedincome-rate-dpcredit-reference-openbb-docs) - [fixedincome/rate/ameribor - Reference | OpenBB Docs](#fixedincome-rate-ameribor-reference-openbb-docs) - [fixedincome/rate/effr - Reference | OpenBB Docs](#fixedincome-rate-effr-reference-openbb-docs) - [fixedincome/rate/effr_forecast - Reference | OpenBB Docs](#fixedincome-rate-effr-forecast-reference-openbb-docs) - [famafrench/regional_portfolio_returns - Reference | OpenBB Docs](#famafrench-regional-portfolio-returns-reference-openbb-docs) - [fixedincome/rate/iorb - Reference | OpenBB Docs](#fixedincome-rate-iorb-reference-openbb-docs) - [fixedincome/rate/sonia - Reference | OpenBB Docs](#fixedincome-rate-sonia-reference-openbb-docs) - [fixedincome/spreads/tcm_effr - Reference | OpenBB Docs](#fixedincome-spreads-tcm-effr-reference-openbb-docs) - [fixedincome/spreads/tcm - Reference | OpenBB Docs](#fixedincome-spreads-tcm-reference-openbb-docs) - [fixedincome/rate/estr - Reference | OpenBB Docs](#fixedincome-rate-estr-reference-openbb-docs) - [fixedincome/rate/overnight_bank_funding - Reference | OpenBB Docs](#fixedincome-rate-overnight-bank-funding-reference-openbb-docs) - [fixedincome/rate/sofr - Reference | OpenBB Docs](#fixedincome-rate-sofr-reference-openbb-docs) - [fixedincome/spreads/treasury_effr - Reference | OpenBB Docs](#fixedincome-spreads-treasury-effr-reference-openbb-docs) - [fixedincome/government/treasury_prices - Reference | OpenBB Docs](#fixedincome-government-treasury-prices-reference-openbb-docs) - [fixedincome/mortgage_indices - Reference | OpenBB Docs](#fixedincome-mortgage-indices-reference-openbb-docs) - [index/sectors - Reference | OpenBB Docs](#index-sectors-reference-openbb-docs) - [index/available - Reference | OpenBB Docs](#index-available-reference-openbb-docs) - [index/constituents - Reference | OpenBB Docs](#index-constituents-reference-openbb-docs) - [index/search - Reference | OpenBB Docs](#index-search-reference-openbb-docs) - [fixedincome/government/treasury_auctions - Reference | OpenBB Docs](#fixedincome-government-treasury-auctions-reference-openbb-docs) - [index/snapshots - Reference | OpenBB Docs](#index-snapshots-reference-openbb-docs) - [index/sp500_multiples - Reference | OpenBB Docs](#index-sp500-multiples-reference-openbb-docs) - [quantitative/performance/sortino_ratio - Reference | OpenBB Docs](#quantitative-performance-sortino-ratio-reference-openbb-docs) - [quantitative/rolling/variance - Reference | OpenBB Docs](#quantitative-rolling-variance-reference-openbb-docs) - [index/price/historical - Reference | OpenBB Docs](#index-price-historical-reference-openbb-docs) - [quantitative/stats/kurtosis - Reference | OpenBB Docs](#quantitative-stats-kurtosis-reference-openbb-docs) - [quantitative/stats/mean - Reference | OpenBB Docs](#quantitative-stats-mean-reference-openbb-docs) - [quantitative/stats/quantile - Reference | OpenBB Docs](#quantitative-stats-quantile-reference-openbb-docs) - [quantitative/stats/stdev - Reference | OpenBB Docs](#quantitative-stats-stdev-reference-openbb-docs) - [quantitative/stats/skew - Reference | OpenBB Docs](#quantitative-stats-skew-reference-openbb-docs) - [quantitative/stats/variance - Reference | OpenBB Docs](#quantitative-stats-variance-reference-openbb-docs) - [quantitative/summary - Reference | OpenBB Docs](#quantitative-summary-reference-openbb-docs) - [quantitative/rolling/mean - Reference | OpenBB Docs](#quantitative-rolling-mean-reference-openbb-docs) - [quantitative/unitroot_test - Reference | OpenBB Docs](#quantitative-unitroot-test-reference-openbb-docs) - [quantitative/rolling/stdev - Reference | OpenBB Docs](#quantitative-rolling-stdev-reference-openbb-docs) - [econometrics/panel_between - Reference | OpenBB Docs](#econometrics-panel-between-reference-openbb-docs) - [Economy | OpenBB Docs](#economy-openbb-docs) - [econometrics/autocorrelation - Reference | OpenBB Docs](#econometrics-autocorrelation-reference-openbb-docs) - [econometrics/cointegration - Reference | OpenBB Docs](#econometrics-cointegration-reference-openbb-docs) - [econometrics/ols_regression_summary - Reference | OpenBB Docs](#econometrics-ols-regression-summary-reference-openbb-docs) - [econometrics/panel_first_difference - Reference | OpenBB Docs](#econometrics-panel-first-difference-reference-openbb-docs) - [econometrics/panel_fmac - Reference | OpenBB Docs](#econometrics-panel-fmac-reference-openbb-docs) - [econometrics/panel_fixed - Reference | OpenBB Docs](#econometrics-panel-fixed-reference-openbb-docs) - [econometrics/panel_random_effects - Reference | OpenBB Docs](#econometrics-panel-random-effects-reference-openbb-docs) - [econometrics/correlation_matrix - Reference | OpenBB Docs](#econometrics-correlation-matrix-reference-openbb-docs) - [etf/equity_exposure - Reference | OpenBB Docs](#etf-equity-exposure-reference-openbb-docs) - [econometrics/residual_autocorrelation - Reference | OpenBB Docs](#econometrics-residual-autocorrelation-reference-openbb-docs) - [econometrics/unit_root - Reference | OpenBB Docs](#econometrics-unit-root-reference-openbb-docs) - [econometrics/causality - Reference | OpenBB Docs](#econometrics-causality-reference-openbb-docs) - [econometrics/panel_pooled - Reference | OpenBB Docs](#econometrics-panel-pooled-reference-openbb-docs) - [etf/countries - Reference | OpenBB Docs](#etf-countries-reference-openbb-docs) - [etf/discovery/gainers - Reference | OpenBB Docs](#etf-discovery-gainers-reference-openbb-docs) - [etf/discovery/losers - Reference | OpenBB Docs](#etf-discovery-losers-reference-openbb-docs) - [etf/discovery/active - Reference | OpenBB Docs](#etf-discovery-active-reference-openbb-docs) - [etf/nport_disclosure - Reference | OpenBB Docs](#etf-nport-disclosure-reference-openbb-docs) - [etf/search - Reference | OpenBB Docs](#etf-search-reference-openbb-docs) - [etf/sectors - Reference | OpenBB Docs](#etf-sectors-reference-openbb-docs) - [etf/price_performance - Reference | OpenBB Docs](#etf-price-performance-reference-openbb-docs) --- # Page Not Found | OpenBB Docs [Skip to main content](https://docs.openbb.co/*#__docusaurus_skipToContent_fallback) Page Not Found ============== We couldn't find what you were looking for. Please contact support@openbb.finance to report this broken link. [Go back to homepage](https://docs.openbb.co/) div> --- # OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace#__docusaurus_skipToContent_fallback) On this page OpenBB Workspace is a secure application for enterprise AI workflows. It combines flexible data integration, customizable UI components, and AI capabilities in a single solution. Explore OpenBB Workspace at [pro.openbb.co](https://pro.openbb.co/) . ![OpenBB Workspace Application Interface](https://openbb-cms.directus.app/assets/098ebeac-413e-4225-badf-1282c268e071.png) Watch Product Demo Core capabilities[​](https://docs.openbb.co/workspace#core-capabilities "Direct link to Core capabilities") ------------------------------------------------------------------------------------------------------------ ### Production-Ready UI Framework[​](https://docs.openbb.co/workspace#production-ready-ui-framework "Direct link to Production-Ready UI Framework") Transform your workflows with a fully customizable UI that adapts to your team's specific needs. OpenBB Workspace gives you complete control over every aspect of the interface, allowing you to tailor it precisely to your workflow requirements. Teams can collaborate through shared dashboards and applications, while the flexible framework enables you to build comprehensive solutions ranging from simple data visualizations to complex AI-powered workflows. ### Unified Data Integration[​](https://docs.openbb.co/workspace#unified-data-integration "Direct link to Unified Data Integration") OpenBB Workspace brings all your data sources together in one secure, scalable system. Whether you're working with proprietary internal data, licensed third-party feeds, or public datasets, the Workspace provides data access through a single interface. The system handles both structured and unstructured data with equal ease, and its open architecture supports flexibility as your needs evolve. ### AI Agent Integration[​](https://docs.openbb.co/workspace#ai-agent-integration "Direct link to AI Agent Integration") Deploy and manage AI agents in a secure, controlled environment that puts you in charge. OpenBB Workspace offers the flexibility to integrate any AI agent that supports your workflows, whether it's powered by a proprietary model, open-source solution, or third-party service. Agents run in a protected environment with carefully controlled data access, ensuring security and compliance when connecting AI capabilities to your existing processes. This integration happens naturally within your workflows, enhancing rather than disrupting your established practices. ### Enterprise-Grade Deployment[​](https://docs.openbb.co/workspace#enterprise-grade-deployment "Direct link to Enterprise-Grade Deployment") OpenBB Workspace provides the deployment flexibility modern enterprises demand. Deploy the Workspace on-premises or in your private cloud, maintaining complete control over your infrastructure and data. Your sensitive information never leaves your environment, staying protected within your existing security perimeter. The system includes detailed role-based access controls, allowing you to implement fine-grained security policies that align with your organization's requirements and compliance standards. Key concepts[​](https://docs.openbb.co/workspace#key-concepts "Direct link to Key concepts") --------------------------------------------------------------------------------------------- ### Widgets[​](https://docs.openbb.co/workspace#widgets "Direct link to Widgets") Widgets are the fundamental data units in OpenBB Workspace. Each widget represents a self-contained data component with: * **Data Source**: Integration with internal or external data sources * **Metadata**: Title, description, category, sub-category and source information * **Visual Layer**: Presentation through tables, charts, PDFs or images and other feed formats * **Parameters**: Configurable input parameters for data display and interaction ![Widget Metadata Structure and Components](https://openbb-cms.directus.app/assets/cffb6e08-31a2-4a4d-85cf-3cf0ae1d09eb.png) ### Dashboards[​](https://docs.openbb.co/workspace#dashboards "Direct link to Dashboards") Dashboards are your personal spaces in OpenBB Workspace, designed to adapt to your unique analytical style and requirements. Each dashboard starts as a blank canvas where you can create your perfect analytical environment by combining elements from your entire widget library, organizing and customizing them in ways that make sense for your specific workflows. The power of dashboards lies in their flexibility. You can add widgets and group them by linking their parameters - when you update a date range or a ticker symbol in one widget, related widgets will update automatically. This parameter grouping ensures your analysis remains synchronized across multiple data views. ![OpenBB Workspace Dashboard Interface](https://openbb-cms.directus.app/assets/9ef2b326-da32-49d0-b122-110bbc556ee7.png) Beyond dynamic data widgets, dashboards support a rich variety of content types. You can enhance your analysis by adding static files like PDFs, images, text documents, and spreadsheets, incorporating AI-generated artifacts directly from your chats, or writing notes to document your thought process and findings. This combination of dynamic data, static resources, and personal annotations creates a wide-ranging analytical workspace that captures both the quantitative and qualitative aspects of your research. Once you've crafted your perfect dashboard, sharing it with your organization is effortless. Team members can access your shared dashboards to benefit from your analytical setup. This transforms individual insights into collective intelligence, elevating your dashboards to become organizational assets and fostering collaboration and knowledge sharing. ### AI Agents[​](https://docs.openbb.co/workspace#ai-agents "Direct link to AI Agents") AI Agents make OpenBB Workspace an intelligent system that understands your data and automates complex workflows. These agents leverage the metadata from your widgets to query the right datasets with appropriate parameters. What makes AI Agents particularly powerful is their contextual awareness. They can access your entire dashboard ecosystem, understand relationships between different data sources and maintain context across multiple queries. This enables sophisticated multi-step analysis where agents can gather data from various widgets, perform calculations, generate insights, and even create new visualizations based on their findings. ![OpenBB Workspace AI Agents Interface](https://openbb-cms.directus.app/assets/cbc29ba3-e55b-4ea4-89be-55db92bd017a.png) AI Agents excel at both reactive and proactive analysis. They can respond to your specific queries about market conditions, company performance, or economic indicators while also monitoring your dashboards for anomalies, trends, or opportunities that require attention. You can configure agents with custom instructions and prompts, creating specialized assistants for different analytical tasks – from earnings analysis to risk assessment to market surveillance. The integration between AI Agents and your widget library creates a multiplier effect. Agents can dynamically combine data from multiple sources to apply advanced analytical techniques, and present results in formats that best suit your needs. ![OpenBB Workspace AI Agent Widget Integration](https://openbb-cms.directus.app/assets/4b79d88c-05c1-4dcb-b8de-31ca934e4066.png) Finally, AI agents can produce artifacts (text, tables, charts) that are added back to the dashboard, closing the feedback loop. ### Apps[​](https://docs.openbb.co/workspace#apps "Direct link to Apps") Apps are pre-built dashboard templates designed for specific workflows. Each app includes a curated set of widgets with parameters already linked, a pre-selection of an AI agent for the task at hand, and custom prompts relevant to that use case. When you change a ticker or date range, all connected widgets update together. ![OpenBB Workspace Multiple Applications View](https://openbb-cms.directus.app/assets/0410ebc4-13cb-4ec2-aa8a-9ee370d1b56a.png) Examples include portfolio management apps with position tracking and risk metrics, market surveillance apps with data monitoring and anomaly detection, and research apps with fundamental analysis and news sentiment tools. The workspace supports unlimited apps that can be shared across teams and customized to fit your exact needs. Explore our app gallery and use cases at [openbb.co/solutions](https://openbb.co/solutions) . ![OpenBB Workspace Applications Overview](https://openbb-cms.directus.app/assets/2dabe15f-a422-441e-b888-04eda6db3e1b.png) #### Prompts: Context-Aware Suggestions[​](https://docs.openbb.co/workspace#prompts-context-aware-suggestions "Direct link to Prompts: Context-Aware Suggestions") Prompts are query suggestions specific to each app. The AI agent knows your widget library and can automatically tag relevant widgets when responding to prompts. For example, in a portfolio app, prompts might suggest "Show me today's top performers" and automatically reference the position tracking and performance widgets. This context awareness means prompts always work with the actual data available in your app, eliminating guesswork and ensuring accurate, relevant responses. On this page * [Core capabilities](https://docs.openbb.co/workspace#core-capabilities) * [Production-Ready UI Framework](https://docs.openbb.co/workspace#production-ready-ui-framework) * [Unified Data Integration](https://docs.openbb.co/workspace#unified-data-integration) * [AI Agent Integration](https://docs.openbb.co/workspace#ai-agent-integration) * [Enterprise-Grade Deployment](https://docs.openbb.co/workspace#enterprise-grade-deployment) * [Key concepts](https://docs.openbb.co/workspace#key-concepts) * [Widgets](https://docs.openbb.co/workspace#widgets) * [Dashboards](https://docs.openbb.co/workspace#dashboards) * [AI Agents](https://docs.openbb.co/workspace#ai-agents) * [Apps](https://docs.openbb.co/workspace#apps) --- # Progressive Web App (PWA) | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/getting-started/pwa#__docusaurus_skipToContent_fallback) On this page OpenBB Workspace is now available as a Progressive Web App (PWA), providing a seamless, native-like experience across all your devices. ![PWA](https://openbb-cms.directus.app/assets/dcd283e9-cc7f-42af-9d48-655565a5f6df.png) Installing as a PWA offers several advantages: * **App-like Experience**: Runs in its own window without browser UI, providing a cleaner, focused workspace * **Quick Access**: Launch directly from your dock, taskbar, or home screen without opening a browser * **Cross-Platform**: Consistent experience across desktop and mobile devices * **Seamless Updates**: Automatically receives the latest features when you're online * **Better Performance**: Cached resources provide faster load times for frequently used components Desktop Installation[​](https://docs.openbb.co/workspace/getting-started/pwa#desktop-installation "Direct link to Desktop Installation") ----------------------------------------------------------------------------------------------------------------------------------------- The desktop PWA provides the most complete OpenBB experience, with full keyboard support and optimized screen real estate. ### Installation Steps[​](https://docs.openbb.co/workspace/getting-started/pwa#installation-steps "Direct link to Installation Steps") 1. Launch Chrome, Edge, or any Chromium-based browser 2. Navigate to [https://pro.openbb.co](https://pro.openbb.co/) 3. Click the install icon in the address bar (typically a plus sign or computer icon) 4. Follow the installation prompts to add OpenBB to your desktop Your browser does not support the video tag. Mobile Installation[​](https://docs.openbb.co/workspace/getting-started/pwa#mobile-installation "Direct link to Mobile Installation") -------------------------------------------------------------------------------------------------------------------------------------- ### iOS Devices[​](https://docs.openbb.co/workspace/getting-started/pwa#ios-devices "Direct link to iOS Devices") 1. Open Safari and navigate to [https://pro.openbb.co](https://pro.openbb.co/) 2. Tap the share button (square with upward arrow) at the bottom of the screen 3. Select "Add to Home Screen" from the share menu 4. Name the app "OpenBB" and tap "Add" 5. The OpenBB icon will appear on your home screen Your browser does not support the video tag. ### Android Devices[​](https://docs.openbb.co/workspace/getting-started/pwa#android-devices "Direct link to Android Devices") 1. Open Chrome and navigate to [https://pro.openbb.co](https://pro.openbb.co/) 2. Tap the three-dot menu in the top-right corner 3. Select "Add to Home screen" from the menu 4. Name the app "OpenBB" and tap "Add" 5. The OpenBB icon will appear on your home screen Your browser does not support the video tag. Using OpenBB PWA[​](https://docs.openbb.co/workspace/getting-started/pwa#using-openbb-pwa "Direct link to Using OpenBB PWA") ----------------------------------------------------------------------------------------------------------------------------- The PWA version of OpenBB Workspace provides a consistent experience across all your devices while maintaining full functionality. Key features include: * **Responsive Design**: Optimized layouts for desktop, tablet, and mobile screens * **Touch Support**: Intuitive touch controls for mobile devices * **Offline Capabilities**: Access key features without an internet connection * **Cross-Device Sync**: Seamlessly continue your work across different devices ### Best Practices[​](https://docs.openbb.co/workspace/getting-started/pwa#best-practices "Direct link to Best Practices") * Use Chrome or Edge for the best desktop experience * Keep your browser updated to the latest version * Ensure you have sufficient storage space on your device * Connect to a stable internet connection for initial setup ### Troubleshooting[​](https://docs.openbb.co/workspace/getting-started/pwa#troubleshooting "Direct link to Troubleshooting") If you encounter any issues during installation: 1. Clear your browser cache and try again 2. Ensure you're using a supported browser version 3. Check your device's storage space 4. Verify your internet connection Learn More[​](https://docs.openbb.co/workspace/getting-started/pwa#learn-more "Direct link to Learn More") ----------------------------------------------------------------------------------------------------------- For a deeper dive into the OpenBB PWA, including its development journey and technical implementation, read our detailed blog post: [OpenBB Workspace is Now Available on Mobile](https://openbb.co/blog/openbb-terminal-is-now-available-on-mobile) On this page * [Desktop Installation](https://docs.openbb.co/workspace/getting-started/pwa#desktop-installation) * [Installation Steps](https://docs.openbb.co/workspace/getting-started/pwa#installation-steps) * [Mobile Installation](https://docs.openbb.co/workspace/getting-started/pwa#mobile-installation) * [iOS Devices](https://docs.openbb.co/workspace/getting-started/pwa#ios-devices) * [Android Devices](https://docs.openbb.co/workspace/getting-started/pwa#android-devices) * [Using OpenBB PWA](https://docs.openbb.co/workspace/getting-started/pwa#using-openbb-pwa) * [Best Practices](https://docs.openbb.co/workspace/getting-started/pwa#best-practices) * [Troubleshooting](https://docs.openbb.co/workspace/getting-started/pwa#troubleshooting) * [Learn More](https://docs.openbb.co/workspace/getting-started/pwa#learn-more) --- # Enterprise | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/getting-started/enterprise#__docusaurus_skipToContent_fallback) On this page OpenBB Workspace Enterprise deploys within your infrastructure, ensuring data never leaves your environment. The platform operates without external dependencies while providing the same analytical capabilities as the cloud version. Deployment Control[​](https://docs.openbb.co/workspace/getting-started/enterprise#deployment-control "Direct link to Deployment Control") ------------------------------------------------------------------------------------------------------------------------------------------ Deploy on-premises within your data center for maximum control over hardware, network, and security configurations. Private cloud deployment in AWS, Azure, or GCP maintains infrastructure flexibility while keeping data within your security boundaries. Hybrid architectures combine on-premises data storage with cloud compute resources when required. All deployment options include unlimited users, unlimited data sources, and unlimited computational resources. No artificial restrictions exist on platform usage within your environment. [Data Control & Security Details →](https://docs.openbb.co/workspace/getting-started/enterprise/data-control) Team Operations[​](https://docs.openbb.co/workspace/getting-started/enterprise#team-operations "Direct link to Team Operations") --------------------------------------------------------------------------------------------------------------------------------- Multiple teams work within shared environments while maintaining separate access controls and data permissions. Shared dashboards distribute insights across departments. Real-time collaboration enables simultaneous analysis and commentary on the same datasets. Knowledge management captures institutional analytical approaches through shared widget libraries and template repositories. Team analytics show usage patterns, popular content, and collaboration effectiveness metrics. [Team Collaboration Features →](https://docs.openbb.co/workspace/getting-started/enterprise/team-collaboration) Administrative Control[​](https://docs.openbb.co/workspace/getting-started/enterprise#administrative-control "Direct link to Administrative Control") ------------------------------------------------------------------------------------------------------------------------------------------------------ Configure user access through role-based permissions at application, widget, data source, and AI feature levels. Import users from existing directory services or manage them locally. Customize platform appearance with corporate branding, colors, and logos. Monitor system performance, user activity, and resource consumption through administrative dashboards. Configure automated backups, retention policies, and maintenance schedules. [Administration Tools →](https://docs.openbb.co/workspace/getting-started/enterprise/administration) Implementation Support[​](https://docs.openbb.co/workspace/getting-started/enterprise#implementation-support "Direct link to Implementation Support") ------------------------------------------------------------------------------------------------------------------------------------------------------ Professional services include infrastructure assessment, deployment planning, security configuration, and data integration. The JumpStart package delivers operational capability within four weeks through custom app development and targeted training programs. Dedicated support provides priority response times with direct access to technical specialists. Customer success managers coordinate long-term platform optimization and adoption strategies. [Support & Services Options →](https://docs.openbb.co/workspace/getting-started/enterprise/support-services) Core Capabilities[​](https://docs.openbb.co/workspace/getting-started/enterprise#core-capabilities "Direct link to Core Capabilities") --------------------------------------------------------------------------------------------------------------------------------------- OpenBB Copilot operates entirely within your environment, processing prompts and generating responses without external communication. Custom AI agents incorporate organizational knowledge and analytical methodologies. The Excel Add-in connects spreadsheet workflows to platform data through real-time synchronization. Custom integrations connect internal systems, proprietary databases, and specialized data sources through secure network connections. Widget development creates tailored visualizations for specific analytical requirements. Platform Comparison[​](https://docs.openbb.co/workspace/getting-started/enterprise#platform-comparison "Direct link to Platform Comparison") --------------------------------------------------------------------------------------------------------------------------------------------- | Capability | Cloud | Enterprise | | --- | --- | --- | | Deployment | SaaS hosted by OpenBB | On-premises or private cloud | | Data location | OpenBB cloud infrastructure | Customer infrastructure | | User limits | Plan-based restrictions | Unlimited | | Customization | Standard themes | Full branding control | | Integrations | Public APIs only | Internal systems + public APIs | | Support | Standard response times | Priority support with SLA | | AI processing | Shared cloud models | Private model deployment | Target Organizations[​](https://docs.openbb.co/workspace/getting-started/enterprise#target-organizations "Direct link to Target Organizations") ------------------------------------------------------------------------------------------------------------------------------------------------ Investment banks use Enterprise for equity research, trading desk analysis, risk management, and M&A advisory work. Asset management firms apply it to portfolio management, quantitative research, performance analytics, and client reporting. Hedge funds leverage the platform for systematic strategies, fundamental analysis, risk monitoring, and alpha generation research. Corporate treasury teams, FP&A departments, investor relations groups, and strategic planning functions utilize Enterprise for internal financial analysis and reporting requirements. Getting Started[​](https://docs.openbb.co/workspace/getting-started/enterprise#getting-started "Direct link to Getting Started") --------------------------------------------------------------------------------------------------------------------------------- Contact [sales@openbb.finance](mailto:sales@openbb.finance) for requirements assessment and deployment planning. [Schedule a demonstration](https://openbb.co/schedule-demo) to see platform capabilities with your use cases. Proof-of-concept deployments enable testing with actual organizational data and workflows. The evaluation process includes technical demonstrations, proof-of-concept testing, commercial proposals, and implementation planning. Most deployments complete within 4-8 weeks depending on integration complexity and training requirements. On this page * [Deployment Control](https://docs.openbb.co/workspace/getting-started/enterprise#deployment-control) * [Team Operations](https://docs.openbb.co/workspace/getting-started/enterprise#team-operations) * [Administrative Control](https://docs.openbb.co/workspace/getting-started/enterprise#administrative-control) * [Implementation Support](https://docs.openbb.co/workspace/getting-started/enterprise#implementation-support) * [Core Capabilities](https://docs.openbb.co/workspace/getting-started/enterprise#core-capabilities) * [Platform Comparison](https://docs.openbb.co/workspace/getting-started/enterprise#platform-comparison) * [Target Organizations](https://docs.openbb.co/workspace/getting-started/enterprise#target-organizations) * [Getting Started](https://docs.openbb.co/workspace/getting-started/enterprise#getting-started) --- # Open source platform integration | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/getting-started/platform-installer#__docusaurus_skipToContent_fallback) On this page This section will highlight how you can run the open-source [ODP Python Package](https://github.com/OpenBB-finance/OpenBB) locally and integrate 350+ different datasets into the OpenBB Workspace in under 5 minutes. If you want to learn more about the open source ecosystem, check [our documentation](https://docs.openbb.co/odp/python) . Step by step[​](https://docs.openbb.co/workspace/getting-started/platform-installer#step-by-step "Direct link to Step by step") -------------------------------------------------------------------------------------------------------------------------------- Follow the quick start steps [here](https://docs.openbb.co/odp/python/quickstart) . note If you are using Brave/Safari you will need an HTTPS connection - see the Self-Signed Certificate section of the ODP Desktop [documentation](https://docs.openbb.co/odp/desktop/backends) for steps to run your server over HTTPS. These are some apps available out of the box: ![Table Widget Example](https://openbb-cms.directus.app/assets/9d5f9dba-1603-489c-ad47-ae0f9b7bd0da.png) Advanced - Access this data on mobile[​](https://docs.openbb.co/workspace/getting-started/platform-installer#advanced---access-this-data-on-mobile "Direct link to Advanced - Access this data on mobile") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- This section will use `ngrok` as the proxy between our platform API endpoints running locally and the internet. You can do this in ngrok free plan. 1. Install ngrok by following [these](https://ngrok.com/docs/getting-started/) instructions. 2. Open a terminal and run `ngrok http 6900`. This assume that the open source platform API is running on [`http://localhost:6900`](http://localhost:6900/) . If that runs correctly, you'll get an output similar to the following. ![ngrok](https://github.com/user-attachments/assets/e938b28b-359b-41e7-b822-6fc400e36819) Note the **Forwarding** row. That will contain a public URL that has access to your endpoint. 3. Update your localhost endpoint with the public URL provided by ngrok. ![ngrok-2](https://github.com/user-attachments/assets/1ceed65b-3601-4a7c-8fd5-ee79cdde3917) 4. Add a request header as authentication. Click on "Add Authentication" button, and add the following: Key: ngrok-skip-browser-warning Value: x Location: Header You have to include the request header `ngrok-skip-browser-warning` with any value in the request header, to bypass the Ngrok Browser Warning. ![ngrok-3](https://github.com/user-attachments/assets/03968960-e09a-46d8-98b9-718b6ae1b0db) You are now ready to access this data on your phone, just ensure that you keep running the API endpoint and ngrok locally. Advanced - Filter widgets[​](https://docs.openbb.co/workspace/getting-started/platform-installer#advanced---filter-widgets "Direct link to Advanced - Filter widgets") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- If you run the steps above, you will have access to a dozen different data vendors and hundreds of different widgets. However, some of these may not work because you haven't set up the API key for the data vendor or you may not be interested to bring some of those widgets into your OpenBB Workspace. This section will explore how you can filter the platform integration datasets that are made available on OpenBB. 1. Go to the [widgets filter page](https://my.openbb.co/app/platform/widgets) where you can set the data vendors you are interested and also select the widgets within. Once you are happy you can download the `widget_settings.json` configuration file by clicking on **Download**. ![widgets](https://github.com/user-attachments/assets/c978c28d-e53a-4f83-9488-dcb524572b86) 2. In the `OpenBB` folder that has been created when you installed the Platform. There must be a `Settings` folder within. This folder should be the destination of your widget settings file (`widget_settings.json`), which will serve as the configuration file for your custom backend. Now, similarly to the previous section, you should: * Run `OpenBB/openbb-api` * Set your PAT * Refresh the connection inside the ["Manage Backends"](https://pro.openbb.co/app) button or follow instructions above to add again. > Take into consideration that, if you change the default configurations on the OpenBB Platform settings, the URL ([`http://127.0.0.1:6900`](http://127.0.0.1:6900/) > ) might differ. ![widgets-filter](https://github.com/user-attachments/assets/692e8da3-57fb-4cff-b566-adf8d5539530) On this page * [Step by step](https://docs.openbb.co/workspace/getting-started/platform-installer#step-by-step) * [Advanced - Access this data on mobile](https://docs.openbb.co/workspace/getting-started/platform-installer#advanced---access-this-data-on-mobile) * [Advanced - Filter widgets](https://docs.openbb.co/workspace/getting-started/platform-installer#advanced---filter-widgets) --- # FAQs | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/getting-started/faqs#__docusaurus_skipToContent_fallback) On this page Find answers to common questions about OpenBB Workspace, organized by topic. * * * General Questions[​](https://docs.openbb.co/workspace/getting-started/faqs#general-questions "Direct link to General Questions") --------------------------------------------------------------------------------------------------------------------------------- ### What is the purpose of a custom backend in OpenBB Workspace?[​](https://docs.openbb.co/workspace/getting-started/faqs#what-is-the-purpose-of-a-custom-backend-in-openbb-workspace "Direct link to What is the purpose of a custom backend in OpenBB Workspace?") A custom backend allows you to integrate your own data sources into OpenBB Workspace, enabling the creation of personalized widgets, dashboards, and templates that display your data in various ways. This gives you complete control over your data pipeline while leveraging OpenBB's visualization and AI capabilities. For more details, see the [Data Integration Overview](https://docs.openbb.co/workspace/developers/data-integration) . ### What technologies are required to set up a custom backend?[​](https://docs.openbb.co/workspace/getting-started/faqs#what-technologies-are-required-to-set-up-a-custom-backend "Direct link to What technologies are required to set up a custom backend?") You'll need: * An API framework (FastAPI, Flask, Express, etc.) * A `widgets.json` file to define widget configurations * Optionally, an `apps.json` file for layout configurations Refer to the [Creating your own custom backend](https://docs.openbb.co/workspace/developers/data-integration) section for detailed setup instructions. * * * Setup and Configuration[​](https://docs.openbb.co/workspace/getting-started/faqs#setup-and-configuration "Direct link to Setup and Configuration") --------------------------------------------------------------------------------------------------------------------------------------------------- ### How do I start setting up a custom backend?[​](https://docs.openbb.co/workspace/getting-started/faqs#how-do-i-start-setting-up-a-custom-backend "Direct link to How do I start setting up a custom backend?") Start with our Hello World example that demonstrates the basic structure: 1. Create your API server 2. Define your widgets.json configuration 3. Connect to OpenBB Workspace Follow the complete guide in the [Getting Started](https://docs.openbb.co/workspace/developers/data-integration) section. ### What is the widgets.json file, and why is it important?[​](https://docs.openbb.co/workspace/getting-started/faqs#what-is-the-widgetsjson-file-and-why-is-it-important "Direct link to What is the widgets.json file, and why is it important?") The `widgets.json` file is the bridge between your backend and OpenBB Workspace. It defines: * Widget metadata (name, description, category) * Data endpoints * Display configurations * Parameter definitions This file tells OpenBB how to display and interact with your data. See the [Widgets Configuration Reference](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference) for complete documentation. ### How do I add authorization to my custom backend?[​](https://docs.openbb.co/workspace/getting-started/faqs#how-do-i-add-authorization-to-my-custom-backend "Direct link to How do I add authorization to my custom backend?") OpenBB Workspace supports passing custom headers or query parameters to your backend on every request. You can use these for authentication: 1. Configure the authentication method when adding your backend 2. Choose between Header or Query Parameter authentication 3. Verify the token/key in your backend to allow or deny access ![Authorization configuration](https://openbb-assets.s3.us-east-1.amazonaws.com/docs/pro/authorization.png) * * * Widgets and Apps[​](https://docs.openbb.co/workspace/getting-started/faqs#widgets-and-apps "Direct link to Widgets and Apps") ------------------------------------------------------------------------------------------------------------------------------ ### How can I create a new widget?[​](https://docs.openbb.co/workspace/getting-started/faqs#how-can-i-create-a-new-widget "Direct link to How can I create a new widget?") Creating a widget involves two steps: **1\. Define the widget in `widgets.json`:** * Set metadata (name, description, category) * Specify the data endpoint * Configure display options **2\. Create the data endpoint in your backend:** * Return data in the expected format * Handle any parameters See the [Widget Creation Guide](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference) for complete examples. ### Can I customize the appearance of widgets?[​](https://docs.openbb.co/workspace/getting-started/faqs#can-i-customize-the-appearance-of-widgets "Direct link to Can I customize the appearance of widgets?") Yes! Widget appearance is highly customizable through the `widgets.json` file: * **Size**: Use `gridData` to set widget dimensions * **Tables**: Configure columns with `columnDefs` * **Charts**: Set chart type, colors, and axes * **Layouts**: Define default positions and groupings Learn more in the [Widget Customization](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference) documentation. ### What are apps, and how do I use them?[​](https://docs.openbb.co/workspace/getting-started/faqs#what-are-apps-and-how-do-i-use-them "Direct link to What are apps, and how do I use them?") Apps are pre-configured collections of widgets, AI agents, and prompts designed for specific workflows. They provide: * Curated widget selections * Pre-linked parameters * Custom AI prompts * Ready-to-use dashboards Define apps in the `apps.json` file and serve them via your API. See the [Apps Documentation](https://docs.openbb.co/workspace/analysts/apps) for details. ### How do I implement dynamic dropdown options in widgets?[​](https://docs.openbb.co/workspace/getting-started/faqs#how-do-i-implement-dynamic-dropdown-options-in-widgets "Direct link to How do I implement dynamic dropdown options in widgets?") Dynamic dropdowns fetch options from your backend in real-time: 1. Set parameter `type: "endpoint"` 2. Specify an `optionsEndpoint` URL 3. Return options array from your backend This is perfect for data that changes frequently (e.g., available tickers, date ranges). See the [Dynamic Parameters](https://docs.openbb.co/workspace/developers/data-integration) guide. ### Can I group widgets to share parameters?[​](https://docs.openbb.co/workspace/getting-started/faqs#can-i-group-widgets-to-share-parameters "Direct link to Can I group widgets to share parameters?") Yes! Parameter grouping creates synchronized widget sets: * Use identical parameter names across widgets * When one updates, all linked widgets refresh * Perfect for creating cohesive dashboards Learn more in the [Parameter Grouping](https://docs.openbb.co/workspace/developers/data-integration) documentation. * * * Troubleshooting[​](https://docs.openbb.co/workspace/getting-started/faqs#troubleshooting "Direct link to Troubleshooting") --------------------------------------------------------------------------------------------------------------------------- ### I can't connect to my backend using Safari/Brave. What should I do?[​](https://docs.openbb.co/workspace/getting-started/faqs#i-cant-connect-to-my-backend-using-safaribrave-what-should-i-do "Direct link to I can't connect to my backend using Safari/Brave. What should I do?") Safari and Brave require HTTPS for local connections. You'll need to set up SSL certificates for your backend. **Setting up HTTPS for your API:** **Step 1:** Create a self-signed certificate and key: openssl req -x509 -days 3650 -out localhost.crt -keyout localhost.key \ -newkey rsa:4096 -nodes -sha256 \ -subj '/CN=localhost' -extensions EXT -config <( \ printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth") **Step 2:** Run your API with SSL: openbb-api --ssl_keyfile localhost.key --ssl_certfile localhost.crt **Step 3:** Trust the certificate: * Visit your API URL in the browser * Accept the security warning * Or add `localhost.crt` to your system's trust store > **Note**: For work devices, contact your system administrator if you need additional permissions. ### My widget data is not refreshing as expected. What could be wrong?[​](https://docs.openbb.co/workspace/getting-started/faqs#my-widget-data-is-not-refreshing-as-expected-what-could-be-wrong "Direct link to My widget data is not refreshing as expected. What could be wrong?") Check these common causes: 1. **Refetch Settings**: Verify `refetchInterval` and `staleTime` in your `widgets.json` 2. **Run Button**: If `runButton: true`, data only refreshes on manual trigger 3. **Cache Settings**: Ensure cache duration matches your needs 4. **Network Issues**: Check browser console for API errors See the [Data Refresh Configuration](https://docs.openbb.co/workspace/developers/data-integration) guide for optimal settings. ### How do I debug widget connection issues?[​](https://docs.openbb.co/workspace/getting-started/faqs#how-do-i-debug-widget-connection-issues "Direct link to How do I debug widget connection issues?") Follow this troubleshooting checklist: 1. **Check Backend Status**: Ensure your API is running and accessible 2. **Verify URL**: Confirm the backend URL in OpenBB settings 3. **Test Endpoints**: Use curl or Postman to test your endpoints directly 4. **Review Browser Console**: Look for CORS or network errors 5. **Validate JSON**: Ensure widgets.json has valid syntax For detailed debugging steps, see the [Troubleshooting Guide](https://docs.openbb.co/workspace/developers/data-integration) . On this page * [General Questions](https://docs.openbb.co/workspace/getting-started/faqs#general-questions) * [What is the purpose of a custom backend in OpenBB Workspace?](https://docs.openbb.co/workspace/getting-started/faqs#what-is-the-purpose-of-a-custom-backend-in-openbb-workspace) * [What technologies are required to set up a custom backend?](https://docs.openbb.co/workspace/getting-started/faqs#what-technologies-are-required-to-set-up-a-custom-backend) * [Setup and Configuration](https://docs.openbb.co/workspace/getting-started/faqs#setup-and-configuration) * [How do I start setting up a custom backend?](https://docs.openbb.co/workspace/getting-started/faqs#how-do-i-start-setting-up-a-custom-backend) * [What is the widgets.json file, and why is it important?](https://docs.openbb.co/workspace/getting-started/faqs#what-is-the-widgetsjson-file-and-why-is-it-important) * [How do I add authorization to my custom backend?](https://docs.openbb.co/workspace/getting-started/faqs#how-do-i-add-authorization-to-my-custom-backend) * [Widgets and Apps](https://docs.openbb.co/workspace/getting-started/faqs#widgets-and-apps) * [How can I create a new widget?](https://docs.openbb.co/workspace/getting-started/faqs#how-can-i-create-a-new-widget) * [Can I customize the appearance of widgets?](https://docs.openbb.co/workspace/getting-started/faqs#can-i-customize-the-appearance-of-widgets) * [What are apps, and how do I use them?](https://docs.openbb.co/workspace/getting-started/faqs#what-are-apps-and-how-do-i-use-them) * [How do I implement dynamic dropdown options in widgets?](https://docs.openbb.co/workspace/getting-started/faqs#how-do-i-implement-dynamic-dropdown-options-in-widgets) * [Can I group widgets to share parameters?](https://docs.openbb.co/workspace/getting-started/faqs#can-i-group-widgets-to-share-parameters) * [Troubleshooting](https://docs.openbb.co/workspace/getting-started/faqs#troubleshooting) * [I can't connect to my backend using Safari/Brave. What should I do?](https://docs.openbb.co/workspace/getting-started/faqs#i-cant-connect-to-my-backend-using-safaribrave-what-should-i-do) * [My widget data is not refreshing as expected. What could be wrong?](https://docs.openbb.co/workspace/getting-started/faqs#my-widget-data-is-not-refreshing-as-expected-what-could-be-wrong) * [How do I debug widget connection issues?](https://docs.openbb.co/workspace/getting-started/faqs#how-do-i-debug-widget-connection-issues) --- # Dashboards - OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/dashboards#__docusaurus_skipToContent_fallback) On this page Dashboards are the interactive environments where you bring financial data to life in OpenBB Workspace. They let you organize multiple widgets into cohesive analytical views, combining visualization and analysis in a flexible layout tailored to your needs. What are Dashboards?[​](https://docs.openbb.co/workspace/analysts/dashboards#what-are-dashboards "Direct link to What are Dashboards?") ---------------------------------------------------------------------------------------------------------------------------------------- Dashboards provide a canvas where you arrange and organize multiple data widgets into cohesive analytical views. They enable you to create custom layouts for different analysis workflows, monitor real-time market data and indicators, share insights with team members, and generate professional reports for documentation and presentations. The flexible layout system allows you to drag and drop widgets exactly where you need them, resizing and arranging components to emphasize important data and create visual hierarchies that match your analytical priorities. Dashboards refresh automatically so that your analysis always reflects current data conditions. Collaboration is built into the application through dashboard sharing capabilities. Team members can view shared dashboards and create their own copies for further customization while preserving the original configuration. Dashboard Folders[​](https://docs.openbb.co/workspace/analysts/dashboards#dashboard-folders "Direct link to Dashboard Folders") -------------------------------------------------------------------------------------------------------------------------------- Organize your analytical workspace by creating folders in the left sidebar to group related dashboards together. This organizational structure helps maintain clarity and efficiency as your collection of dashboards grows. To create a new folder, click the "+" icon in the sidebar and select "New Folder". Name your folder descriptively to reflect its contents, such as "Portfolio Analysis", "Market Research", or "Daily Reports". You can then drag and drop existing dashboards into these folders or use the "Move to" option from the dashboard's ellipsis menu. Folders can be nested to create hierarchical organization structures that match your workflow. For example, you might have a main "Research" folder with subfolders for different sectors or asset classes. This flexibility allows you to maintain a clean, navigable workspace even with dozens or hundreds of dashboards. Dashboard Management[​](https://docs.openbb.co/workspace/analysts/dashboards#dashboard-management "Direct link to Dashboard Management") ----------------------------------------------------------------------------------------------------------------------------------------- Access the management options through the ellipsis menu next to each dashboard in the sidebar: * **Rename** - Customize dashboard names for better organization * **Move to** - Organize dashboards into folders for structured workflows * **Duplicate** - Create copies with all widgets and settings intact * **Open in new window** - Expand across multiple monitors * **Share** - Collaborate with team members * **Delete** - Remove unused dashboards * **Refresh data** - Update all widget data immediately Dashboard Actions[​](https://docs.openbb.co/workspace/analysts/dashboards#dashboard-actions "Direct link to Dashboard Actions") -------------------------------------------------------------------------------------------------------------------------------- Right-clicking anywhere on the dashboard canvas provides quick access to essential functions: * **Add widget** - Quickly add a new widget to your dashboard * **Add data** - Import new data sources directly from the dashboard * **Refresh data** - Update all widget data with the latest information * **Refresh backends** - Reload backend connections and configurations (good for development purposes) * **Export apps.json** - Export your dashboard configuration as an `apps.json` * **Disable grouping** - Toggle widget grouping functionality Creating Your First Dashboard[​](https://docs.openbb.co/workspace/analysts/dashboards#creating-your-first-dashboard "Direct link to Creating Your First Dashboard") -------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1. Click the "+" button in the sidebar to create a new dashboard 2. Give your dashboard a descriptive name 3. Add widgets by clicking the "Add Widget" button (or right clicking and selecting "Add Widget") 4. Arrange widgets by dragging them to desired positions 5. Resize widgets to create your optimal layout 6. Add a navigation bar widget so you can separate widgets based on different categories 7. Save your dashboard to preserve your configuration On this page * [What are Dashboards?](https://docs.openbb.co/workspace/analysts/dashboards#what-are-dashboards) * [Dashboard Folders](https://docs.openbb.co/workspace/analysts/dashboards#dashboard-folders) * [Dashboard Management](https://docs.openbb.co/workspace/analysts/dashboards#dashboard-management) * [Dashboard Actions](https://docs.openbb.co/workspace/analysts/dashboards#dashboard-actions) * [Creating Your First Dashboard](https://docs.openbb.co/workspace/analysts/dashboards#creating-your-first-dashboard) --- # Agent Skills | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/agent-skills#__docusaurus_skipToContent_fallback) If you are building with an agent you can install the **openbb-app-builder skill** with: npx skills add https://github.com/openbb-finance/backends-for-openbb --skill openbb-app-builder More information [here](https://skills.sh/openbb-finance/backends-for-openbb/openbb-app-builder) . The raw SKILL folder can be found [here](https://github.com/OpenBB-finance/backends-for-openbb/tree/66c16c8ee59aacdb562bfd9abb262d542dbe685e/.claude/skills/openbb-app-builder) . * * * Skill ===== Loading content from GitHub... --- # Apps | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/apps#__docusaurus_skipToContent_fallback) On this page Apps in OpenBB Workspace are pre-configured dashboard templates that combine widgets, pre-selected AI agents, and custom prompts to create optimized analytical workflows. Unlike individual dashboards that you build from scratch, Apps provide instant access to complete analytical environments designed for specific use cases. ![OpenBB Workspace Multiple Applications View](https://openbb-cms.directus.app/assets/2fc9097e-0941-49df-8d83-7d6b5a87bb45.png) What are Apps?[​](https://docs.openbb.co/workspace/analysts/apps#what-are-apps "Direct link to What are Apps?") ---------------------------------------------------------------------------------------------------------------- Apps function as analytical templates that combine three core components: widgets, prompts, and pre-selected agents. ### Widgets[​](https://docs.openbb.co/workspace/analysts/apps#widgets "Direct link to Widgets") Apps include curated sets of widgets that are specifically optimized for their analytical workflow. These widgets come with parameter synchronization, automatically linking shared parameters to maintain analytical coherence across all components. The layout design positions and sizes widgets optimally for data visualization and workflow efficiency. ### Prompts[​](https://docs.openbb.co/workspace/analysts/apps#prompts "Direct link to Prompts") An App can include a custom library of pre-written prompts tailored to its analytical focus. These prompts provide app-aware AI instructions and enable more effective interactions with the specialized agent. E.g.: * "Please analyze my current portfolio holdings. What are the top 5 positions by weight? Are there any concentration risks I should be aware of?" * "What are the strongest correlations between my portfolio holdings? Which positions might provide good diversification benefits?" * "What is my current sector exposure compared to market benchmarks? What are the risks and opportunities in my current allocation?" These prompts are specifically crafted for the App's analytical context, enabling consistent analysis approaches and more targeted AI assistance. ### Agents[​](https://docs.openbb.co/workspace/analysts/apps#agents "Direct link to Agents") Apps can advertise a particular AI agent that is optimized for its analytical domain. When you click on an App with a specified agent ID, OpenBB Workspace automatically selects the corresponding AI agent. How Apps Differ from Dashboards[​](https://docs.openbb.co/workspace/analysts/apps#how-apps-differ-from-dashboards "Direct link to How Apps Differ from Dashboards") -------------------------------------------------------------------------------------------------------------------------------------------------------------------- While dashboards are blank canvases that you customize entirely yourself, Apps provide structured starting points: | **Apps** | **Dashboards** | | --- | --- | | Pre-configured templates with specific analytical purpose | Blank canvas for custom configuration | | Widgets with pre-linked parameters | Manual parameter configuration required | | Come with curated prompt libraries | Start with no predefined prompts | | Designed by domain experts for specific workflows | General-purpose analytical workspace | Once you click on an App, it gets immediately rendered as a dashboard that you can also customize. Apps Gallery[​](https://docs.openbb.co/workspace/analysts/apps#apps-gallery "Direct link to Apps Gallery") ----------------------------------------------------------------------------------------------------------- To see Apps examples that you can do, check [our solutions page](https://openbb.co/solutions) . Here's an example of a Portfolio Risk Management dashboard (converted from an App). ![Portfolio Risk Management Dashboard](https://openbb-cms.directus.app/assets/b1d5b799-3abe-4d45-b04c-601e2b652b18.png) On this page * [What are Apps?](https://docs.openbb.co/workspace/analysts/apps#what-are-apps) * [Widgets](https://docs.openbb.co/workspace/analysts/apps#widgets) * [Prompts](https://docs.openbb.co/workspace/analysts/apps#prompts) * [Agents](https://docs.openbb.co/workspace/analysts/apps#agents) * [How Apps Differ from Dashboards](https://docs.openbb.co/workspace/analysts/apps#how-apps-differ-from-dashboards) * [Apps Gallery](https://docs.openbb.co/workspace/analysts/apps#apps-gallery) --- # Data Integration | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/data-integration#__docusaurus_skipToContent_fallback) On this page OpenBB Workspace provides a powerful custom backend feature that enables you to integrate your own data sources and APIs directly into the platform. This integration capability allows you to: * Create personalized widgets that display your custom data * Leverage OpenBB's AI agents with your proprietary data * Build a seamless workflow between your data sources and OpenBB's analysis tools A custom backend is an API that returns data in a format that OpenBB Workspace understands, with specifications defined in a `widgets.json` file. This approach gives you complete flexibility in choosing your technology stack while ensuring compatibility with OpenBB Workspace. Getting Started: Hello World Example[​](https://docs.openbb.co/workspace/developers/data-integration#getting-started-hello-world-example "Direct link to Getting Started: Hello World Example") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Let's walk through a simple example to demonstrate how to integrate a custom backend. We'll create a basic "Hello World" application that you can use as a template for your own integrations. The complete example code is available in our [GitHub repository](https://github.com/OpenBB-finance/backend-examples-for-openbb-workspace/tree/main/getting-started/hello-world) . ### 0\. Prerequisites[​](https://docs.openbb.co/workspace/developers/data-integration#0-prerequisites "Direct link to 0. Prerequisites") Before we begin, ensure you have the following installed: pip install fastapi uvicorn ### 1\. Create the API Server[​](https://docs.openbb.co/workspace/developers/data-integration#1-create-the-api-server "Direct link to 1. Create the API Server") Create a `main.py` file with the following code: # Import required librariesimport jsonfrom pathlib import Pathfrom fastapi import FastAPIfrom fastapi.middleware.cors import CORSMiddlewarefrom fastapi.responses import JSONResponse# Initialize FastAPI application with metadataapp = FastAPI( title="Hello World", description="Hello World app for OpenBB Workspace", version="0.0.1")# Define allowed origins for CORS (Cross-Origin Resource Sharing)# This restricts which domains can access the APIorigins = [ "https://pro.openbb.co",]# Configure CORS middleware to handle cross-origin requests# This allows the specified origins to make requests to the APIapp.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], # Allow all HTTP methods allow_headers=["*"], # Allow all headers)@app.get("/")def read_root(): """Root endpoint that returns basic information about the API""" return {"Info": "Hello World example"}# Widgets configuration file for the OpenBB Workspace# it contains the information and configuration about all the# widgets that will be displayed in the OpenBB Workspace@app.get("/widgets.json")def get_widgets(): """Widgets configuration file for the OpenBB Workspace Returns: JSONResponse: The contents of widgets.json file """ # Read and return the widgets configuration file return JSONResponse( content=json.load((Path(__file__).parent.resolve() / "widgets.json").open()) )# Apps configuration file for the OpenBB Workspace# it contains the information and configuration about all the# apps that will be displayed in the OpenBB Workspace@app.get("/apps.json")def get_apps(): """Apps configuration file for the OpenBB Workspace Returns: JSONResponse: The contents of apps.json file """ # Read and return the apps configuration file return JSONResponse( content=json.load((Path(__file__).parent.resolve() / "apps.json").open()) )# Hello World endpoint - for it to be recognized by the OpenBB Workspace# it needs to be added to the widgets.json file endpoint@app.get("/hello_world")def hello_world(name: str = ""): """Returns a personalized greeting message. Args: name (str, optional): Name to include in the greeting. Defaults to empty string. Returns: str: A greeting message with the provided name in markdown format. """ # Return a markdown-formatted greeting with the provided name return f"# Hello World {name}" ### 2\. Configure Widgets[​](https://docs.openbb.co/workspace/developers/data-integration#2-configure-widgets "Direct link to 2. Configure Widgets") Create a `widgets.json` file to define your widget's properties. This file is your main configuration and defines widget properties such as name, description, category, endpoint, type of widget, and other information. Each widget will be defined in this file: { "hello_world": { "name": "Hello World", "description": "A simple markdown widget that displays Hello World", "category": "Hello World", "type": "markdown", "endpoint": "hello_world", "gridData": { "w": 12, "h": 4 }, "source": "None", "params": [ { "paramName": "name", "value": "", "label": "Name", "type": "text", "description": "Enter your name" } ] }} ### 3\. Configure App Layout (Optional)[​](https://docs.openbb.co/workspace/developers/data-integration#3-configure-app-layout-optional "Direct link to 3. Configure App Layout (Optional)") Create an `apps.json` file to define the app's layout. This makes it so that there is a new App on OpenBB with a single markdown widget that says Hello World: [ { "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": [] }] ### 4\. Run the Application[​](https://docs.openbb.co/workspace/developers/data-integration#4-run-the-application "Direct link to 4. Run the Application") Your project structure should look like this: backend/├── main.py├── widgets.json└── apps.json Start the server with: uvicorn main:app --reload --host 0.0.0.0 --port 7779 You should see output similar to: $ uvicorn main:app --reload --host 0.0.0.0 --port 7779INFO: Uvicorn running on http://0.0.0.0:7779 (Press CTRL+C to quit)INFO: Started reloader process [59166] using WatchFilesINFO: Started server process [59168]INFO: Waiting for application startup.INFO: Application startup complete. The application will be available at `http://127.0.0.1:7779`. ### 5\. Add to OpenBB[​](https://docs.openbb.co/workspace/developers/data-integration#5-add-to-openbb "Direct link to 5. Add to OpenBB") You can then add this backend to OpenBB Workspace by right clicking on the dashboard and clicking "Add data", and do the following: ![Apps](https://openbb-cms.directus.app/assets/80898c79-cb04-4361-afdd-945eb3e531be.png) ### 6\. Set up Authentication / or API keys[​](https://docs.openbb.co/workspace/developers/data-integration#6-set-up-authentication--or-api-keys "Direct link to 6. Set up Authentication / or API keys") Generally, it’s recommended to enable authentication for your backend to ensure secure access. Another common use case is when connecting to a third-party data provider that requires an API key. To handle this securely, we recommend including the key in a custom header (for example, X-API-KEY). Here are some benefits of using a custom header: * Security: you can keep credentials or API keys out of URLs and logs. * Flexibility: this method supports multiple API keys / credentials per request. Here’s an example of how you can add this to your main.py: from fastapi import FastAPI, Request, HTTPExceptionfrom dotenv import load_dotenvimport os# Load environment variables from .env file (recommended)load_dotenv()app = FastAPI(title="Custom Header Example", version="0.0.1")@app.get("/secure_hello")def secure_hello(request: Request, name: str = ""): """Returns a personalized message if the correct API key is provided.""" # ------------------------------------------------------------------------- # NOTE: # It is recommended to set your API keys as environment variables. # Example: create a `.env` file with the line below: # VALID_API_KEYS=my-secret-key,another-valid-key # # For quick local testing, you can also define keys directly in code: # valid_api_keys = ["my-secret-key", "another-valid-key"] # (Make sure to comment out the environment variable line below.) # ------------------------------------------------------------------------- # Get allowed API keys from environment variables valid_api_keys = os.getenv("VALID_API_KEYS", "").split(",") # Get API key from header api_key = request.headers.get("X-API-KEY") if not api_key: raise HTTPException( status_code=401, detail="API key required. Please include 'X-API-KEY' in the request headers." ) # Validate provided API key if api_key.strip() not in [k.strip() for k in valid_api_keys]: raise HTTPException(status_code=403, detail="Invalid API key") # Return a markdown-formatted greeting return f"# Hello {name}, your API key is valid!" Once configured, you can add your header values in the following way. These values will then be automatically passed along with any subsequent API calls. ![Authentication](https://openbb-cms.directus.app/assets/70cb3454-bf1b-41eb-af52-85bdebfd75f4.png) ![Authentication-Key-Value-Pair](https://openbb-cms.directus.app/assets/026b8815-555f-42dd-b3a0-25f991f4ca5e.png) ### 7\. Voila[​](https://docs.openbb.co/workspace/developers/data-integration#7-voila "Direct link to 7. Voila") ![Apps](https://openbb-cms.directus.app/assets/b34f315c-0f17-4e14-9b0d-0288d1cf7a5c.png) Reference Backend[​](https://docs.openbb.co/workspace/developers/data-integration#reference-backend "Direct link to Reference Backend") ---------------------------------------------------------------------------------------------------------------------------------------- The [reference backend](https://github.com/OpenBB-finance/backends-for-openbb/tree/main/getting-started/reference-backend) serves as a comprehensive example repository showcasing implementations of most widget types and configuration patterns available in OpenBB Workspace. This backend provides practical examples for: * **Complete Widget Type Coverage**: Examples for table, chart, metric, markdown, file viewer, and specialized widget implementations * **Advanced Configuration Patterns**: Demonstrations of parameter linking, dynamic dropdowns, render functions, and custom formatting * **Real-world Data Integration**: Working examples with external APIs, data transformation, and error handling * **Best Practice Implementations**: Production-ready code patterns with proper authentication, caching, and performance optimization The reference backend functions both as a learning resource and a foundation for your own backend development. You can clone the repository, study the implementations, and adapt the patterns to your specific data sources and analytical requirements. Whether you're implementing your first widget or exploring advanced features like sparklines and custom formatters, the reference backend provides tested, documented examples that demonstrate the full capabilities of the OpenBB integration framework. On this page * [Getting Started: Hello World Example](https://docs.openbb.co/workspace/developers/data-integration#getting-started-hello-world-example) * [0\. Prerequisites](https://docs.openbb.co/workspace/developers/data-integration#0-prerequisites) * [1\. Create the API Server](https://docs.openbb.co/workspace/developers/data-integration#1-create-the-api-server) * [2\. Configure Widgets](https://docs.openbb.co/workspace/developers/data-integration#2-configure-widgets) * [3\. Configure App Layout (Optional)](https://docs.openbb.co/workspace/developers/data-integration#3-configure-app-layout-optional) * [4\. Run the Application](https://docs.openbb.co/workspace/developers/data-integration#4-run-the-application) * [5\. Add to OpenBB](https://docs.openbb.co/workspace/developers/data-integration#5-add-to-openbb) * [6\. Set up Authentication / or API keys](https://docs.openbb.co/workspace/developers/data-integration#6-set-up-authentication--or-api-keys) * [7\. Voila](https://docs.openbb.co/workspace/developers/data-integration#7-voila) * [Reference Backend](https://docs.openbb.co/workspace/developers/data-integration#reference-backend) --- # Apps | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/apps#__docusaurus_skipToContent_fallback) On this page OpenBB Apps are powerful, customizable solutions that combine data widgets, prompts and AI agents to create optimized workflows for your specific needs. ![PWA](https://openbb-cms.directus.app/assets/b1d5b799-3abe-4d45-b04c-601e2b652b18.png) Built on the principle that there's no one-size-fits-all approach to financial analysis, Apps empower you to own your workflows end-to-end. Creating Your Own App[​](https://docs.openbb.co/workspace/developers/apps#creating-your-own-app "Direct link to Creating Your Own App") ---------------------------------------------------------------------------------------------------------------------------------------- 1. Integrate your data widgets in OpenBB Workspace. 2. Organize them in a certain layout 3. Group widgets together and/or change their display (e.g. table or charts) 4. Right click on the dashboard and select "Export apps.json". ![OpenBB Apps Example](https://openbb-cms.directus.app/assets/fd20914a-5557-43fd-a320-96dec1e70a38.png) 5. This will create a `apps.json` file with your configuration. ![OpenBB Apps Example](https://openbb-cms.directus.app/assets/2250bf63-e7e9-447d-b2e3-14d71d23fe92.png) This is what you should expect as a file: [ { "name": "Fama French Factors and Research Portfolio", "img": "https://github.com/user-attachments/assets/8b2409d6-5ddc-4cbc-b20c-89a29b1bd923", "img_dark": "", "img_light": "", "description": "Examine sample portfolio holdings distribution across countries, sectors, and industries, while also understanding how different assets correlate with each other over various time periods. This app provides insights into how portfolios respond to different market factors using Fama-French analysis, helping investors understand their portfolio's underlying drivers of returns and risk exposures.", "allowCustomization": true, "tabs": { "reference-data": { "id": "reference-data", "name": "Reference Data", "layout": [ { "i": "fama_french_info_custom_obb", "x": 0, "y": 2, "w": 12, "h": 25 }, { "i": "load_factors_custom_obb", "x": 12, "y": 13, "w": 28, "h": 14, "state": { "params": { "frequency": "monthly", "start_date": "2021-01-01", "end_date": "2025-03-27" }, "chartView": { "enabled": false, "chartType": "line" } } }, { "i": "load_portfolios_custom_obb", "x": 12, "y": 2, "w": 28, "h": 11, "state": { "params": { "portfolio": "Portfolios_Formed_on_OP", "start_date": "2021-01-01", "end_date": "2025-03-27" }, "chartView": { "enabled": false, "chartType": "line" } } } ] }, "portfolio-price--performance": { "id": "portfolio-price--performance", "name": "Portfolio Price & Performance", "layout": [ { "i": "portfolio_unit_price_custom_obb", "x": 0, "y": 2, "w": 40, "h": 24, "state": { "params": { "portfolio": "Client 2", "returns": "True" }, "chartView": { "enabled": true, "chartType": "line" } } } ] }, "portfolio-region-and-sector-exposure": { "id": "portfolio-region-and-sector-exposure", "name": "Portfolio Region and Sector Exposure", "layout": [ { "i": "portfolio_sectors_custom_obb", "x": 0, "y": 13, "w": 19, "h": 14, "state": { "chartView": { "enabled": true, "chartType": "pie" } } }, { "i": "portfolio_countries_custom_obb", "x": 0, "y": 2, "w": 19, "h": 11, "state": { "chartView": { "enabled": true, "chartType": "pie" } } }, { "i": "portfolio_industries_custom_obb", "x": 19, "y": 2, "w": 21, "h": 25, "state": { "params": { "portfolio": "Client 3" }, "chartView": { "enabled": true, "chartType": "pie" } } } ] }, "portfolio-holdings": { "id": "portfolio-holdings", "name": "Portfolio Holdings", "layout": [ { "i": "portfolio_holdings_custom_obb", "x": 0, "y": 2, "w": 40, "h": 25, "state": { "params": { "portfolio": "Client 2" }, "chartView": { "enabled": true, "chartType": "bar" } } } ] }, "portfolio-holdings-correlations": { "id": "portfolio-holdings-correlations", "name": "Portfolio Holdings Correlations", "layout": [ { "i": "holdings_correlation_custom_obb", "x": 0, "y": 2, "w": 40, "h": 26, "state": { "params": { "portfolio": "Client 2" } } } ] }, "portfolio-factor-correlations": { "id": "portfolio-factor-correlations", "name": "Portfolio Factor Attributions", "layout": [ { "i": "portfolio_factors_custom_obb", "x": 0, "y": 2, "w": 30, "h": 20, "state": { "params": { "portfolio": "Client 2" } } } ] } }, "groups": [ { "name": "Group 3", "type": "param", "paramName": "frequency", "defaultValue": "monthly", "widgetIds": [ "load_factors_custom_obb", "load_portfolios_custom_obb" ] }, { "name": "Group 2", "type": "param", "paramName": "start_date", "defaultValue": "2021-01-01", "widgetIds": [ "load_factors_custom_obb", "load_portfolios_custom_obb" ] }, { "name": "Group 4", "type": "param", "paramName": "end_date", "defaultValue": "2025-03-27", "widgetIds": [ "load_factors_custom_obb", "load_portfolios_custom_obb" ] }, { "name": "Group 5", "type": "param", "paramName": "region", "defaultValue": "america", "widgetIds": [ "load_factors_custom_obb", "load_portfolios_custom_obb" ] }, { "name": "Group 6", "type": "endpointParam", "paramName": "factor", "defaultValue": "america", "widgetIds": [ "load_factors_custom_obb", "load_portfolios_custom_obb" ] }, { "name": "Group 7", "type": "param", "paramName": "portfolio", "defaultValue": "Client 1", "widgetIds": [ "portfolio_sectors_custom_obb", "portfolio_countries_custom_obb", "portfolio_industries_custom_obb", "portfolio_holdings_custom_obb", "portfolio_unit_price_custom_obb", "holdings_correlation_custom_obb", "portfolio_factors_custom_obb" ] } ], "prompts": [ "Please analyze my current portfolio holdings. What are the top 5 positions by weight? Are there any concentration risks I should be aware of? How has each position performed over the last month?", "What are the strongest correlations between my portfolio holdings? Which positions might provide good diversification benefits? How do my holdings correlate with major market factors?", "What is my current sector exposure? Are there any sectors where I'm over or underweight compared to the market? What are the risks and opportunities in my current sector allocation?", "How does my portfolio respond to different market factors? What are my current factor exposures? Are there any factor tilts I should consider adjusting?" ] }] On this page * [Creating Your Own App](https://docs.openbb.co/workspace/developers/apps#creating-your-own-app) --- # Support & Services | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/getting-started/enterprise/support-services#__docusaurus_skipToContent_fallback) On this page Enterprise customers receive dedicated support and professional services to maximize platform value and ensure successful implementation. Production Support[​](https://docs.openbb.co/workspace/getting-started/enterprise/support-services#production-support "Direct link to Production Support") ----------------------------------------------------------------------------------------------------------------------------------------------------------- Enterprise support provides 8 hours daily coverage, 5 days weekly, with priority access to the support queue. Direct communication channels connect customers with technical specialists, bypassing standard routing. Priority handling ensures faster resolution of technical issues and implementation questions. Customer Success Partnership[​](https://docs.openbb.co/workspace/getting-started/enterprise/support-services#customer-success-partnership "Direct link to Customer Success Partnership") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Each enterprise customer receives a dedicated customer success manager for long-term platform optimization. Quarterly business reviews assess usage patterns, identify improvement opportunities, and align platform capabilities with evolving business objectives. Success managers provide best practices consultation based on knowledge from other enterprise deployments while maintaining appropriate confidentiality. They offer strategic guidance on expanding platform adoption across teams and integrating new analytical capabilities as organizational needs grow. JumpStart Package[​](https://docs.openbb.co/workspace/getting-started/enterprise/support-services#jumpstart-package "Direct link to JumpStart Package") -------------------------------------------------------------------------------------------------------------------------------------------------------- The JumpStart program delivers operational capability within weeks rather than months through structured implementation and training. This accelerated approach includes custom app development, comprehensive training, and organizational best practices establishment. Custom app development creates a production-ready application incorporating your specific data sources, analytical workflows, and organizational requirements. The application functions both as an immediate productivity tool and a development template for future projects. Knowledge transfer ensures internal teams can maintain and extend the custom application after deployment. Training components address different organizational roles including administrators, analysts, and specialized users. Best practices establishment covers workflow documentation, governance procedures, and platform optimization recommendations tailored to your environment. Learn more about JumpStart implementation at [openbb.link/jumpstart](https://openbb.link/jumpstart) . Professional Training Programs[​](https://docs.openbb.co/workspace/getting-started/enterprise/support-services#professional-training-programs "Direct link to Professional Training Programs") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Structured training programs provide role-specific education for administrators, analysts, and specialized users within your organization. Administrative training covers system configuration, user management, security implementation, and operational procedures. Analyst training focuses on dashboard development, data analysis methodologies, collaboration workflows, and platform feature utilization. Custom workshops address specific industry requirements, advanced use cases, and organizational analytical approaches. Training materials include comprehensive documentation, hands-on exercises, and reference resources for ongoing use. Follow-up sessions ensure knowledge retention and address implementation questions that arise during actual platform usage. Explore training options at [openbb.link/workshops](https://openbb.link/workshops) . Implementation Services[​](https://docs.openbb.co/workspace/getting-started/enterprise/support-services#implementation-services "Direct link to Implementation Services") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Professional implementation services include infrastructure assessment, deployment architecture design, and integration planning. The implementation team evaluates existing environments, recommends optimal configurations, and provides guidance throughout the deployment process. Security configuration assistance ensures proper integration with authentication systems, access controls, and audit frameworks. Data integration support facilitates connections to internal systems, databases, and external sources through appropriate methods and protocols. Enterprise Pricing[​](https://docs.openbb.co/workspace/getting-started/enterprise/support-services#enterprise-pricing "Direct link to Enterprise Pricing") ----------------------------------------------------------------------------------------------------------------------------------------------------------- OpenBB Enterprise uses a seat-based subscription model adapted to organizational requirements. Pricing factors include user count, deployment configuration (cloud, VPC, or on-premises), data integration complexity, and support level requirements. Base subscriptions include software licensing, standard support, regular updates, security patches, and documentation access. Additional services including JumpStart packages, custom development, enhanced support, and specialized training require separate pricing based on project scope. For detailed pricing information, visit [openbb.co/pricing](https://openbb.co/pricing) . Getting Started[​](https://docs.openbb.co/workspace/getting-started/enterprise/support-services#getting-started "Direct link to Getting Started") -------------------------------------------------------------------------------------------------------------------------------------------------- Contact the enterprise team at [sales@openbb.finance](mailto:sales@openbb.finance) for requirements assessment and pricing discussion. The evaluation process includes technical demonstrations, proof-of-concept testing with your data, and implementation planning sessions. Enterprise deployments typically complete within 1-4 weeks depending on integration requirements, customization needs, and training scope. Implementation timelines account for testing phases, user onboarding activities, and platform optimization. On this page * [Production Support](https://docs.openbb.co/workspace/getting-started/enterprise/support-services#production-support) * [Customer Success Partnership](https://docs.openbb.co/workspace/getting-started/enterprise/support-services#customer-success-partnership) * [JumpStart Package](https://docs.openbb.co/workspace/getting-started/enterprise/support-services#jumpstart-package) * [Professional Training Programs](https://docs.openbb.co/workspace/getting-started/enterprise/support-services#professional-training-programs) * [Implementation Services](https://docs.openbb.co/workspace/getting-started/enterprise/support-services#implementation-services) * [Enterprise Pricing](https://docs.openbb.co/workspace/getting-started/enterprise/support-services#enterprise-pricing) * [Getting Started](https://docs.openbb.co/workspace/getting-started/enterprise/support-services#getting-started) --- # Sandbox Widgets | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/widgets/sandbox-widgets#__docusaurus_skipToContent_fallback) On this page When you first log into OpenBB Workspace on [`pro.openbb.co`](https://pro.openbb.co/) , you'll discover a collection of pre-built widgets already available in your workspace. These demonstration widgets serve a single purpose: to showcase what OpenBB is capable of achieving as an analytical application. #### Purpose[​](https://docs.openbb.co/workspace/analysts/widgets/sandbox-widgets#purpose "Direct link to Purpose") These out-of-the-box widgets provide immediate examples of OpenBB's analytical capabilities without requiring any setup or configuration. They demonstrate the application's potential through realistic financial data scenarios and interactive functionality, giving you an instant understanding of what's possible within the workspace environment. #### Demonstration Value[​](https://docs.openbb.co/workspace/analysts/widgets/sandbox-widgets#demonstration-value "Direct link to Demonstration Value") The pre-built widgets highlight OpenBB's core strengths in financial analysis, data visualization, and workflow integration. They showcase different widget types, parameter linking capabilities, AI agent integration, and the overall user experience you can expect when building your own analytical dashboards. #### Important Understanding[​](https://docs.openbb.co/workspace/analysts/widgets/sandbox-widgets#important-understanding "Direct link to Important Understanding") These widgets exist purely for demonstration purposes. They illustrate the application's capabilities and provide inspiration for your own analytical workflows, but they are not intended as production tools for actual financial analysis or decision-making. The real value of OpenBB Workspace comes from connecting your own data sources, building custom widgets tailored to your specific analytical needs, and creating dashboards that reflect your unique research methodology and investment process. --- # Widgets Overview | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/widgets/overview#__docusaurus_skipToContent_fallback) On this page Widgets are the fundamental building blocks of OpenBB Workspace, transforming raw financial data into interactive, visual components that drive your analysis. Each widget is a self-contained unit that combines data, visualization, and interactivity into a powerful analytical tool. What is a Widget?[​](https://docs.openbb.co/workspace/analysts/widgets/overview#what-is-a-widget "Direct link to What is a Widget?") ------------------------------------------------------------------------------------------------------------------------------------- A widget is more than just a chart or table – it's a data container designed to answer a specific analytical question. ![Widget Metadata Structure and Components](https://openbb-cms.directus.app/assets/132e5cda-b062-4094-8036-8c2d41db1527.png) Anatomy of a Widget[​](https://docs.openbb.co/workspace/analysts/widgets/overview#anatomy-of-a-widget "Direct link to Anatomy of a Widget") -------------------------------------------------------------------------------------------------------------------------------------------- Every widget in OpenBB Workspace consists of four essential components that work together: ### 1\. Data Source[​](https://docs.openbb.co/workspace/analysts/widgets/overview#1-data-source "Direct link to 1. Data Source") The foundation of every widget – where the information comes from. This could be: data feeds, databases, custom data from your organization, static files you've uploaded and more. ### 2\. Metadata Layer[​](https://docs.openbb.co/workspace/analysts/widgets/overview#2-metadata-layer "Direct link to 2. Metadata Layer") The information that makes widgets discoverable and usable: * **Title**: Clear identification of what the widget shows * **Description**: Context about the data and its purpose * **Category**: Logical grouping (e.g., Equity, Fixed Income, Macro) * **Sub-category**: Further classification for better navigation * **Source**: Attribution and data provenance ### 3\. Visual Presentation[​](https://docs.openbb.co/workspace/analysts/widgets/overview#3-visual-presentation "Direct link to 3. Visual Presentation") How the data comes to life on your dashboard: * **Tables**: For detailed, sortable and filterable data exploration * **Charts**: For visual analysis and trend/pattern recognition * **PDFs**: For reports and static documents * **Custom Views**: Tailored to specific data types ### 4\. Parameters[​](https://docs.openbb.co/workspace/analysts/widgets/overview#4-parameters "Direct link to 4. Parameters") Interactive elements that customize what data your widget displays. Input parameters allow you to focus your analysis by setting date ranges, selecting specific tickers, or applying filters that narrow down the dataset to exactly what you need. Parameters that are linked via the grouping mechanism create synchronization across multiple widgets on your dashboard. When you change a ticker symbol or date range in one widget, all widgets in the group sharing that parameter will update automatically. This creates a cohesive experience where your dashboard responds automatically to your actions. ### 5\. Widget Controls[​](https://docs.openbb.co/workspace/analysts/widgets/overview#5-widget-controls "Direct link to 5. Widget Controls") Widget controls are specific to each widget type. They provide specialized functionality that matches the data and visualization format. These widget-specific controls give you powerful ways to interact with and manipulate your data directly within each widget. #### Universal controls[​](https://docs.openbb.co/workspace/analysts/widgets/overview#universal-controls "Direct link to Universal controls") ![Universal Widget Controls](https://openbb-web-assets.s3.us-east-1.amazonaws.com/docs/screenshots/universal-controls.jpg) Universal controls available across most widget types include refresh settings for managing data update frequency, export options for saving data in formats like CSV, JSON, and Excel, and view toggles that let you switch between visual representations and raw data tables. #### Table widgets[​](https://docs.openbb.co/workspace/analysts/widgets/overview#table-widgets "Direct link to Table widgets") ![Table Widget Controls](https://openbb-web-assets.s3.us-east-1.amazonaws.com/docs/screenshots/table-controls.jpg) Table widgets powered offer advanced data manipulation capabilities including column sorting, filtering, and grouping functions that let you slice and dice your data without leaving the widget. You can create custom filters, sort by multiple columns, and group data by categories to uncover patterns and insights within large datasets. Table widgets also generate Excel Add-in formulas automatically, allowing you to pull the same data directly into spreadsheets for hybrid analysis workflows. #### Chart widgets[​](https://docs.openbb.co/workspace/analysts/widgets/overview#chart-widgets "Direct link to Chart widgets") ![Chart Widget Controls](https://openbb-web-assets.s3.us-east-1.amazonaws.com/docs/screenshots/tv-controls.jpg) Chart widgets, particularly those using TradingView integration, provide sophisticated analytical tools including technical indicator overlays, and timeframe adjustments. Plotly charts allow to render any figure that is supported by Plotly. How Widgets Work[​](https://docs.openbb.co/workspace/analysts/widgets/overview#how-widgets-work "Direct link to How Widgets Work") ----------------------------------------------------------------------------------------------------------------------------------- Widgets operate on a simple yet powerful principle: they connect to data sources, apply your configurations, and render the results in real-time. Here's their data flow: 1. **Request**: Widget queries the data source with your parameters 2. **Processing**: Data sources prepare the data 3. **Delivery**: Formatted data returns to the widget 4. **Rendering**: Widget displays the information visually 5. **Interaction**: You can interact with the data in the widget Beyond this data flow, widgets exhibit two powerful features that transform them from simple displays into intelligent analytical tools. **Parameter linking** creates synchronization across your dashboard. When widgets share parameter names, changing a ticker symbol or date range in one widget automatically updates all linked widgets. **AI-readable metadata** exposes the widget metadata to AI agents so that they can interpret and act upon it. Unlike screen scraping, AI agents understand the underlying data source, parameter structure, and query methods for each widget. This understanding allows agents to dynamically request data with different parameters to answer your specific questions, accessing source datasets behind each widget rather than only the information that is currently displayed. ### Controlling AI Visibility[​](https://docs.openbb.co/workspace/analysts/widgets/overview#controlling-ai-visibility "Direct link to Controlling AI Visibility") Widgets support an optional `ai` configuration flag that controls whether a widget is exposed to AI agents. * When `ai` is set to `true`, the widget’s metadata and parameters can be accessed by AI agents to dynamically request and analyze data. * When `ai` is set to `false`, the widget will not be made available to AI workflows. This is useful for restricting access to sensitive, experimental, or internal-only widgets. Example configuration: { "paramName": "symbol", "type": "endpoint", "label": "Select Symbol", "optionsEndpoint": "/stock_search_options", "ai": false} This flag allows developers and analysts to explicitly control which widgets participate in AI-driven workflows within OpenBB Workspace. Your Widget Library[​](https://docs.openbb.co/workspace/analysts/widgets/overview#your-widget-library "Direct link to Your Widget Library") -------------------------------------------------------------------------------------------------------------------------------------------- OpenBB Workspace enables you to build a scalable library of widgets, instantly searchable and logically categorized to match your analytical workflow. This library centralizes your financial data visualizations, making them easily discoverable through search and category navigation. Bring up the Widget Library search interface by either: * Clicking the search field in the top left of the Workspace UI * Pressing `Cmd+K` (Mac) or `Ctrl+K` (Windows) keyboard shortcut * Clicking the plus `+` icon in the bottom right of any dashboard * Clicking the "Add Widget" button on any dashboard ![Widget Library Interface](https://openbb-web-assets.s3.us-east-1.amazonaws.com/docs/screenshots/widget-library.jpg) Widgets are grouped in ways that reflect real-world analytical workflows. Whether analyzing portfolios, tracking macro trends, or researching equities, relevant widgets are organized for quick access. Example: Searching for an equity widget, for example, gives you immediate access to price data, fundamentals, options chains, and analyst estimates. For portfolio analysis, position tracking, performance attribution, and risk metrics are grouped together. By organizing widgets through consistent metadata and categories, OpenBB Workspace reduces the time spent searching for data, allowing you to focus on analysis. The system supports new data sources and custom integrations while maintaining a clear structure that keeps thousands of widgets manageable and accessible. On this page * [What is a Widget?](https://docs.openbb.co/workspace/analysts/widgets/overview#what-is-a-widget) * [Anatomy of a Widget](https://docs.openbb.co/workspace/analysts/widgets/overview#anatomy-of-a-widget) * [1\. Data Source](https://docs.openbb.co/workspace/analysts/widgets/overview#1-data-source) * [2\. Metadata Layer](https://docs.openbb.co/workspace/analysts/widgets/overview#2-metadata-layer) * [3\. Visual Presentation](https://docs.openbb.co/workspace/analysts/widgets/overview#3-visual-presentation) * [4\. Parameters](https://docs.openbb.co/workspace/analysts/widgets/overview#4-parameters) * [5\. Widget Controls](https://docs.openbb.co/workspace/analysts/widgets/overview#5-widget-controls) * [How Widgets Work](https://docs.openbb.co/workspace/analysts/widgets/overview#how-widgets-work) * [Controlling AI Visibility](https://docs.openbb.co/workspace/analysts/widgets/overview#controlling-ai-visibility) * [Your Widget Library](https://docs.openbb.co/workspace/analysts/widgets/overview#your-widget-library) --- # Widgets.json | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference#__docusaurus_skipToContent_fallback) On this page The `widgets.json` file is your configuration file that connects custom backend data to the widgets displayed in the application. Key components include: * **Basic Information**: Defines the widget's name, description, and API endpoint that the data comes from. * **Metadata**: Provide categories for organization and AI enhancement. * **Display Settings**: Specifies widget type and grid dimensions. * **Data Configuration**: Details table and chart settings, including column level information and data types. * **Parameters**: Details query parameters that can be passed to the API endpoint for customization. Each entry in this file will directly map to a widget in the app. You can find example backends [here](https://github.com/OpenBB-finance/backend-examples-for-openbb-workspace/tree/main) , where each folder contains a `widgets.json` file specifying the available widgets. Below are all of the configurable fields and their descriptions. A `Widgets.json` table is a configuration structure with any of the named attributes listed below. ### Attributes[​](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference#attributes "Direct link to Attributes") * **name** _Type:_ `string` (required) Sets the display name of the widget shown to the user. _Example:_ `"Options EOD Data"` * **description** _Type:_ `string` (required) Provides a brief description of the widget for user info and selection menu. This is important for Copilot to understand what the widget does. _Example:_ `"Provides EOD data for all options chains for a given ticker."` * **endpoint** _Type:_ `string` (required) Specifies the backend API endpoint for retrieving data. _Example:_ `"chains"` _Possible values:_ Any valid API endpoint path as a string. * **wsEndpoint** _Type:_ `string` Specifies the WebSocket endpoint for live data updates. Only used with the Live Grid Widget. _Example:_ `"ws"` * **category** _Type:_ `string` Defines the category for organizing widgets. _Example:_ `"Equity"` _Possible values:_ Any string representing a category. * **subCategory** _Type:_ `string` Provides a secondary category for refining search results. _Example:_ `"Options"` * **imgUrl** _Type:_ `string` Image URL for the widget - will show a preview when hovering in search/add widget menu. _Example:_ `"https://myexample-imagelink.xyw/widget1"` * **type** _Type:_ `string` Sets the default visualization type for the widget. _Possible values:_ `"chart"`, `"table"`, `"table_ssrm"`, `"markdown"`, `"metric"`, `"note"`, `"multi_file_viewer"`, `"live_grid"`, `"newsfeed"`, `"advanced-chart"`, `"chart-highcharts"`, `"youtube"` _Default:_ `"table"` * **raw** _Type:_ `boolean` ONLY used for Plotly configuration. If true will create a button on the widget to switch between the chart and raw data. _Possible values:_ `true`, `false` _Default:_ `false` * **runButton** _Type:_ `boolean` If true, a run button will be displayed instead of the refresh button. _Possible values:_ `true`, `false` _Default:_ `false` * **gridData** _Type:_ object containing the following keys: * **w** _Type:_ `number` Sets the width of the widget in grid units. _Example:_ `20` _Maximum value:_ `40` * **h** _Type:_ `number` Sets the height of the widget in grid units. _Example:_ `9` _Maximum value:_ `100` * **minW** _Type:_ `number` Sets the minimum width of the widget in grid units. _Example:_ `10` * **minH** _Type:_ `number` Sets the minimum height of the widget in grid units. _Example:_ `10` * **maxW** _Type:_ `number` Sets the maximum width of the widget in grid units. _Example:_ `40` * **maxH** _Type:_ `number` Sets the maximum height of the widget in grid units. _Example:_ `100` * **data** _Type:_ object containing the following keys - This key is only used for widgets that utilize the AgGrid Table: * **dataKey** _Type:_ `string` A key to identify the data within the widget. _Example:_ `"customDataKey"` * **wsRowIdColumn** _Type:_ `string` The column that will be used to identify the row. This is important to set correctly to ensure the live updates are displayed correctly. This the key between your ws and the initial data. Only used with the Live Grid Widget. _Example:_ `"symbol"` * **table** _Type:_ object containing the following keys: * **enableCharts** _Type:_ `boolean` Enables chart visualization for table data. _Example:_ `true` * **showAll** _Type:_ `boolean` Displays all available data in the table. _Example:_ `true` * **transpose** _Type:_ `boolean` Displays transpose the data in the table. _Example:_ `true` * **enableAdvanced** _Type:_ `boolean` Indicates if the table should have advanced features enabled. When true, the side tab for "Columns" will show up on tables by default. _Example:_ `true` * **enableFormulas** _Type:_ `boolean` Indicates if the table should have formulas enabled. When true, the side tab for "Formulas" will show up on tables by default. _Example:_ `true` * **chartView** _Type:_ object containing the following keys: * **enabled** _Type:_ `boolean` Sets the chart view as the default view. _Example:_ `true` * **chartType** _Type:_ `string` Specifies the type of chart to display. _Example:_ `"column"` _Possible values:_ see [ChartView chart types](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference#chartview-chart-types) * **cellRangeCols** _Type:_ `object` Defines the default column mappings for different chart types. Each key represents a chart type, and the value is an array of column names that specify the category and series columns for that chart type. The array structure is: `[category, series1, series2, ...]` where: * First element: The category column (x-axis) * Remaining elements: The series columns (y-axis data) _Example:_ "cellRangeCols": { "line": ["ticker", "weight", "weight2"], "column": ["date", "price", "volume"]} * **ignoreCellRange** _Type:_ `boolean` Ignores stored cell range for the chart. _Example:_ `false` * **columnsDefs** _Type:_ list of objects, each containing the following keys: * **field** _Type:_ `string` The name of the field from the JSON data. _Example:_ `"column1"` * **headerName** _Type:_ `string` The display name of the column header. _Example:_ `"Column 1"` * **chartDataType** _Type:_ `string` Specifies how data is treated in a chart. _Example:_ `"category"` _Possible values:_ `"category"`, `"series"`, `"time"`, `"excluded"` * **cellDataType** _Type:_ `string` Specifies the data type of the cell. _Example:_ `"text"` _Possible values:_ `"text"`, `"number"`, `"boolean"`, `"date"`, `"dateString"`, `"object"` * **align** _Type:_ `string` Specifies the alignment of the text on the cell. _Example:_ `"center"` _Possible values:_ `"left"`, `"center"`, `"right"` * **enableCellChangeWs** _Type:_ `boolean` Controls whether the cell can be updated via WebSocket messages. Only used with the Live Grid Widget. _Default:_ `true` _Example:_ `false` * **formatterFn** _Type:_ `string` Specifies how to format the data. _Example:_ `"int"` _Possible values:_ see [`formatterFn`](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference#formatterfn) * **renderFn** _Type:_ `string` or `array` Specifies a rendering function for cell data. See [Render Functions](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions) for more information. _Example:_ `"titleCase"` _Possible values:_ `"greenRed"`, `"titleCase"`, `"hoverCard"`, `"cellOnClick"`, `"columnColor"`, `"showCellChange"` * **renderFnParams** _Type:_ `object` Required if `renderFn` is used. Specifies the parameters for the render function. _Example:_ `{"actionType": "sendToAgent", "sendToAgent": {"markdown": "Analyze **{company}** data"}}` * **actionType** _Type:_ `string` Specifies the action type for the render function. _Example:_ `"sendToAgent"` _Possible values:_ `"groupBy"`, `"sendToAgent"` * **groupBy** _Type:_ `object` Configuration for cell click grouping. Required when `actionType` is `"groupBy"`. Contains the following keys: * **paramName** _Type:_ `string` (required) The parameter name to update when a cell is clicked. _Example:_ `"symbol"` * **valueField** _Type:_ `string` (optional) Alternative field name to use for the parameter value (if different from the cell field). Use this when the cell displays one value (e.g., a company name) but you need to pass a different value (e.g., an ID) to the parameter. _Example:_ `"id"` _Example use case:_ If your table displays company names in the cell but your API expects company IDs, set `valueField: "companyId"` to use the ID field from the row data instead of the displayed name. * **colorValueKey** _Type:_ `string` Specifies which field to use for determining the color when showing cell changes. _Example:_ `"Analyst"` * **hoverCardData** _Type:_ `array of strings` Specifies columns to show in the hover card. _Example:_ `["column1", "column2"]` * **colorRules** _Type:_ `array of objects` An array of rules for conditional coloring. Each object contains the following keys: * **condition** _Type:_ `string` (required) The condition for applying the color. _Possible values:_ `"eq"`, `"ne"`, `"gt"`, `"lt"`, `"gte"`, `"lte"`, `"between"`, `"contains"`, `"notContains"` _Description:_ * `"eq"` - Equal to * `"ne"` - Not equal to * `"gt"` - Greater than * `"lt"` - Less than * `"gte"` - Greater than or equal to * `"lte"` - Less than or equal to * `"between"` - Between two values (requires `range` object) * `"contains"` - String contains the value (case-sensitive) * `"notContains"` - String does not contain the value (case-sensitive) * **value** _Type:_ `number` or `string` The value for the condition. For `contains` and `notContains`, use a string value. _Example:_ `50` or `"Active"` * **range** _Type:_ `object` (required for `"between"` condition) An object specifying `min` and `max` values for the between condition. _Example:_ `{"min": 50, "max": 90}` * **color** _Type:_ `string` (required) The color to apply. _Example:_ `"green"`, `"red"`, `"blue"`, or hex code like `"#22c55e"` * **fill** _Type:_ `boolean` Indicates if the color should fill the cell. _Example:_ `true` _Example:_ `[{"condition": "gt", "value": 50, "color": "green", "fill": true}]` _Example with contains:_ `[{"condition": "contains", "value": "Active", "color": "green", "fill": true}]` * **hoverCard** _Type:_ `object` Hover card configuration. Contains the following keys: * **cellField** _Type:_ `string` Field to display on table cell. _Example:_ `"value"` * **title** _Type:_ `string` Title for the hover card. _Example:_ `"Analyst Details"` * **markdown** _Type:_ `string` Markdown content for the hover card. _Example:_ `"### {value}\n- **Description:** {description}"` * **sendToAgent** _Type:_ `object` Configuration for sending data to an AI agent. Contains the following keys: * **markdown** _Type:_ `string` Markdown content to send to the agent, supports template variables from row data using curly braces. _Example:_ `"Please analyze the company **{company}** with revenue of ${revenue}M"` * **agentId** _Type:_ `string` (Optional) Specific agent ID to send the message to. _Example:_ `"financial-analyst-agent"` * **width** _Type:_ `number` Specifies the width of the column in pixels. _Example:_ `100` * **maxWidth** _Type:_ `number` Specifies the maximum width of the column in pixels. _Example:_ `200` * **minWidth** _Type:_ `number` Specifies the minimum width of the column in pixels. _Example:_ `50` * **hide** _Type:_ `boolean` Hides the column from the table. _Example:_ `false` * **pinned** _Type:_ `string` Pins the column to the left or right of the table. _Example:_ `"left"` _Possible values:_ `"left"`, `"right"` * **headerTooltip** _Type:_ `string` Tooltip text for the column header. _Example:_ `"This is a tooltip"` * **prefix** _Type:_ `string` Prefix to be added to the column header. _Example:_ `"$"` * **suffix** _Type:_ `string` Suffix to be added to the column header. _Example:_ `"USD"` * **sparkline** _Type:_ `object` Configuration for displaying sparklines within table cells. Contains the following keys: * **type** _Type:_ `string` Specifies the type of sparkline chart. _Example:_ `"line"` _Possible values:_ `"line"`, `"area"`, `"bar"` * **dataField** _Type:_ `string` Alternative field name to use for sparkline data (if different from main field). _Example:_ `"spark_data"` * **options** _Type:_ `object` Configuration options for the sparkline appearance and behavior. Contains the following keys: * **stroke** _Type:_ `string` Color of the line or border. _Example:_ `"#3366cc"` * **strokeWidth** _Type:_ `number` Width of the line or border in pixels. _Example:_ `2` * **fill** _Type:_ `string` Fill color for area and bar charts. _Example:_ `"#e3f2fd"` * **fillOpacity** _Type:_ `number` Opacity of the fill color (0-1). _Example:_ `0.3` * **min** _Type:_ `number` Minimum value constraint for the sparkline. _Example:_ `0` * **max** _Type:_ `number` Maximum value constraint for the sparkline. _Example:_ `100` * **direction** _Type:_ `string` Direction for bar charts. _Example:_ `"vertical"` _Possible values:_ `"vertical"`, `"horizontal"` * **markers** _Type:_ `object` Configuration for markers on line and area charts. Contains the following keys: * **enabled** _Type:_ `boolean` Whether to show markers. _Example:_ `true` * **size** _Type:_ `number` Size of the markers in pixels. _Example:_ `3` * **fill** _Type:_ `string` Fill color of the markers. _Example:_ `"#3366cc"` * **stroke** _Type:_ `string` Stroke color of the markers. _Example:_ `"#ffffff"` * **strokeWidth** _Type:_ `number` Width of the marker stroke. _Example:_ `1` * **pointsOfInterest** _Type:_ `object` Configuration for highlighting special data points. Contains the following keys: * **firstLast** _Type:_ `object` Styling for first and last data points. Contains `fill`, `stroke`, `strokeWidth`, and `size` properties. * **minimum** _Type:_ `object` Styling for minimum value points. Contains `fill`, `stroke`, `strokeWidth`, and `size` properties. * **maximum** _Type:_ `object` Styling for maximum value points. Contains `fill`, `stroke`, `strokeWidth`, and `size` properties. * **highlighted** _Type:_ `object` Styling for highlighted points on hover/interaction. Contains `fill`, `stroke`, `strokeWidth`, and `size` properties. * **positiveNegative** _Type:_ `object` Separate styling for positive and negative values. Contains the following keys: * **positive** _Type:_ `object` Styling for positive values. Contains `fill`, `stroke`, `strokeWidth`, and `size` properties. * **negative** _Type:_ `object` Styling for negative values. Contains `fill`, `stroke`, `strokeWidth`, and `size` properties. * **customFormatter** _Type:_ `string` JavaScript function as a string for complete control over individual data point styling. _Example:_ `"(params) => ({ fill: params.yValue >= 0 ? '#22c55e' : '#ef4444', stroke: params.yValue >= 0 ? '#16a34a' : '#dc2626' })"` * **padding** _Type:_ `object` Padding configuration for the sparkline. Contains the following keys: * **top** _Type:_ `number` Top padding in pixels. _Example:_ `5` * **right** _Type:_ `number` Right padding in pixels. _Example:_ `5` * **bottom** _Type:_ `number` Bottom padding in pixels. _Example:_ `5` * **left** _Type:_ `number` Left padding in pixels. _Example:_ `5` * **params** _Type:_ list of objects, each containing the following keys: * **type** _Type:_ `string` The type of the parameter. _Example:_ `"date"` _Possible values:_ `"date"`, `"text"`, `"ticker"`, `"number"`, `"boolean"`, `"endpoint"`, `"form"`, `"tabs"` * **paramName** _Type:_ `string` The name of the parameter in the URL. _Example:_ `"startDate"` * **value** _Type:_ `string`, `number`, `boolean` The default value of the parameter. _Example:_ `"2024-01-01"` * **label** _Type:_ `string` The label to display in the UI for the parameter. _Example:_ `"Start Date"` * **optionsEndpoint** _Type:_ `string` Endpoint to fetch options for the parameter. _Example:_ `"v1/test/values"` * **multiple** _Type:_ `boolean` If true, the parameter will be a dropdown with multiple selectable options that you can add add-hoc. _Example:_ `true` * **optionsParams** _Type:_ `object` Parameters to pass to the options endpoint. You can use the parameter name from the `params` array to pass a value to the options endpoint. _Example:_ `{"type": "$type"}` * **show** _Type:_ `boolean` Displays the parameter in the UI. _Example:_ `true` * **description** _Type:_ `string` Description of the parameter, shown on hover. _Example:_ `"The start date for the data"` * **roles** _Type:_ `array` Only used on the Multi-File Viewer Widget - Specifies which parameter is used to select the files. _Example:_ `["fileSelector"]` * **multiSelect** _Type:_ `boolean` Allows multiple values to be selected from your parameter options. _Example:_ `true` * **style** _Type:_ `object` Styling options for the parameter. Only popupWidth is currently supported minimum value is 200px max value is 1000px. _Example:_ `{"popupWidth": 450}` * **options** _Type:_ list of objects, each containing the following keys: * **label** _Type:_ `string` The label for a dropdown option. _Example:_ `"Option 1"` * **value** _Type:_ `string`, `number`, `boolean` The value for a dropdown option. _Example:_ `"option1"` * **extraInfo** _Type:_ `object` Additional information to display for the dropdown option. _Example:_ `{"description": "Technology Company", "rightOfDescription": "NASDAQ"}` Contains the following keys: * **description** _Type:_ `string` Additional descriptive text shown below the label. _Example:_ `"Technology Company"` * **rightOfDescription** _Type:_ `string` Text shown to the right of the description. _Example:_ `"NASDAQ"` * **source** _Type:_ array of strings Specifies the data source(s) for the widget. _Example:_ `["API", "Database"]` * **mcp\_tool** _Type:_ object Configuration for matching the widget to an MCP (Model Context Protocol) tool. When an MCP tool is invoked, OpenBB Workspace can automatically detect if there's a matching widget configured and provide a citation. Contains the following keys: * **mcp\_server** _Type:_ `string` (required) The name of the MCP server that must match exactly with the connected MCP server name. _Example:_ `"Financial Data"` * **tool\_id** _Type:_ `string` (required) The ID of the MCP tool that must match exactly with the tool name in the MCP server. _Example:_ `"get_company_revenue_data"` * **refetchInterval** _Type:_ `number` or `false` Time in milliseconds before the widget's data will refresh if on the page. Minimum value is `1000`. _Default:_ `900000` (15m) * **staleTime** _Type:_ `number` Time in milliseconds before the widget's data is considered stale and will refresh on the next visit to the dashboard. _Default:_ `300000` (5m) Example widgets.json[​](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference#example-widgets-json "Direct link to Example widgets.json") ------------------------------------------------------------------------------------------------------------------------------------------------------------------ Below is an example `widgets.json` with a single widget defined. This widget will default to a column chart but have the ability to switch between a table and chart view. The widget will have a start date parameter, a ticker parameter, and a colors parameter, all of which will be able to be selected on the widget in the application. { "custom_widget": { "name": "Custom Widget Example", "description": "A widget to demonstrate custom configuration", "endpoint": "custom-endpoint", "runButton": false, "data": { "dataKey": "customDataKey", "table": { "enableCharts": true, "showAll": true, "enableAdvanced": true, "enableFormulas": true, "chartView": { "enabled": true, "chartType": "column", "cellRangeCols" : { "line": ["ticker", "weight"] } }, "columnsDefs": [ { "field": "column1", "headerName": "Column 1", "chartDataType": "category", "cellDataType": "text", "formatterFn": "none", "renderFn": "titleCase", "width": 100, "maxWidth": 200, "minWidth": 50, "hide": false, "pinned": "left" }, { "field": "column2", "headerName": "Column 2", "chartDataType": "series", "cellDataType": "number", "formatterFn": "int", "renderFn": "greenRed", "width": 150 }, { "field": "status", "headerName": "Status", "cellDataType": "text", "renderFn": "columnColor", "renderFnParams": { "colorRules": [ { "condition": "contains", "value": "Active", "color": "green", "fill": true }, { "condition": "contains", "value": "Pending", "color": "yellow", "fill": true }, { "condition": "notContains", "value": "Active", "color": "red", "fill": true } ] }, "width": 150 }, { "field": "companyName", "headerName": "Company", "cellDataType": "text", "renderFn": "cellOnClick", "renderFnParams": { "actionType": "groupBy", "groupBy": { "paramName": "companyId", "valueField": "companyId" } }, "width": 200 }, { "field": "price_trend", "headerName": "Price Trend", "width": 200, "sparkline": { "type": "line", "options": { "stroke": "#3366cc", "strokeWidth": 2, "markers": { "enabled": true, "size": 3 }, "pointsOfInterest": { "maximum": { "fill": "#22c55e", "stroke": "#16a34a", "size": 5 }, "minimum": { "fill": "#ef4444", "stroke": "#dc2626", "size": 5 } } } } } ] } }, "params": [ { "type": "date", "paramName": "startDate", "value": "2024-01-01", "label": "Start Date", "show": true, "description": "The start date for the data", }, { "type": "text", "paramName": "ticker", "value": "AAPL", "label": "Ticker", "show": true, "description": "Stock ticker symbol", }, { "type": "text", "paramName": "colors", "value": "red", "label": "Colors", "show": true, "description": "Stock ticker symbol", "multiSelect": true, "options": [ { "label": "Red", "value": "red" }, { "label": "Green", "value": "green" }, { "label": "Blue", "value": "blue" } ], } ], "source": [ "My First API" ], "mcp_tool": { "mcp_server": "Financial Data", "tool_id": "get_company_revenue_data" }, "refetchInterval" : 900000, "staleTime": 300000 }} Special Properties[​](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference#special-properties "Direct link to Special Properties") ------------------------------------------------------------------------------------------------------------------------------------------------------------ ### Date Modifier[​](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference#date-modifier "Direct link to Date Modifier") This is used to display a dynamic date. The reference is `$currentDate` and if a user wants to add or subtract they need to append to the variable: * h, for hour * d, for day * w, for week * M, for month * y, for year For instance, `$currentDate-1w` stands for 1 week ago. If you don't want to set a date you can omit the value parameter or pass `null`. #### Examples[​](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference#examples "Direct link to Examples") [ { "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" }] ### ChartView chart types[​](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference#chartview-chart-types "Direct link to ChartView chart types") **`chartType`**: The type of chart to display by default. These charts are provided using the AgGrid library. Custom charts can also be created using Plotly. For examples, refer to the [GitHub repository](https://github.com/OpenBB-finance/backend-examples-for-openbb-workspace/tree/main) . **Allowed values:** column, groupedColumn, stackedColumn, normalizedColumn, bar, groupedBar, stackedBar, normalizedBar, line, scatter, bubble, pie, donut, doughnut, area, stackedArea, normalizedArea, histogram, radarLine, radarArea, nightingale, radialColumn, radialBar, sunburst, rangeBar, rangeArea, boxPlot, treemap, heatmap, waterfall ### formatterFn[​](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference#formatterfn "Direct link to formatterFn") `formatterFn` (optional): Specifies the function used to format the data in the table. The following values are allowed: * `int`: Formats the number as an integer. * `none`: Does not format the number. * `percent`: Adds `%` to the number. * `normalized`: Multiplies the number by 100. * `normalizedPercent`: Multiplies the number by 100 and adds `%` (e.g., `0.5` becomes `50 %`). * `dateToYear`: Converts a date to just the year. On this page * [Attributes](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference#attributes) * [Example widgets.json](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference#example-widgets-json) * [Special Properties](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference#special-properties) * [Date Modifier](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference#date-modifier) * [ChartView chart types](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference#chartview-chart-types) * [formatterFn](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference#formatterfn) --- # Python Interface - Quick Start | OpenBB Docs [Skip to main content](https://docs.openbb.co/odp/python/quickstart#__docusaurus_skipToContent_fallback) On this page Import[​](https://docs.openbb.co/odp/python/quickstart#import "Direct link to Import") --------------------------------------------------------------------------------------- To get started with the ODP Python Package, import it with: from openbb import obb Show the contents of any given path with: >>>obb.equity/equity /calendar /compare /darkpool /discovery /estimates /fundamental historical_market_cap market_snapshots /ownership /price profile screener search /shorts Each endpoint might have multiple data providers servicing it, and parameter choices may vary. Consult the docstring for details specific to your combination of installed extensions and available providers. # Docstring snippet from `obb.equity.price.historical`interval : str Time interval of the data to return. (provider: alpha_vantage, cboe, fmp, intrinio, polygon, tiingo, tmx, tradier, yfinance) Choices for alpha_vantage: '1m', '5m', '15m', '30m', '60m', '1d', '1W', '1M' Choices for cboe: '1m', '1d' Choices for fmp: '1m', '5m', '15m', '30m', '1h', '4h', '1d' Choices for intrinio: '1m', '5m', '10m', '15m', '30m', '60m', '1h', '1d', '1W', '1M', '1Q', '1Y' Choices for tradier: '1m', '5m', '15m', '1d', '1W', '1M' Choices for yfinance: '1m', '2m', '5m', '15m', '30m', '60m', '90m', '1h', '1d', '5d', '1W', '1M', '1Q' Query[​](https://docs.openbb.co/odp/python/quickstart#query "Direct link to Query") ------------------------------------------------------------------------------------ When the `provider` parameter is not supplied (default), it will pick the first available in alphabetical order. If a provider requires an API key for this endpoint, and has not been added to the [settings](https://docs.openbb.co/odp/python/settings/user_settings/api_keys) , it will skip and try the next. # Get the price of a stock >>> quote_data = obb.equity.price.quote(symbol="AAPL", provider="yfinance")>>> quote_dataOBBjectid: 06649f4e-896c-7b31-8000-52242b1605f2results: [{'symbol': 'AAPL', 'asset_type': 'EQUITY', 'name': 'Apple Inc.', 'exchang...provider: yfinancewarnings: Nonechart: Noneextra: {'metadata': {'arguments': {'provider_choices': {'provider': 'yfinance'}, 's...\ \ To output as a DataFrame, use the `to_df()` method.\ \ >>> quote_data.to_df().Tsymbol AAPLasset_type EQUITYname Apple Inc.exchange NMSbid 232.3bid_size 1ask 257.91ask_size 1last_price 245.27open 255.04high 256.38low 244.57volume 61999098prev_close 254.04year_high 260.1year_low 169.21ma_50d 237.0188ma_200d 222.25485volume_average 54836700.0volume_average_10d 43155290.0currency USD\ \ ### Historical Stock Prices[​](https://docs.openbb.co/odp/python/quickstart#historical-stock-prices "Direct link to Historical Stock Prices")\ \ Time series data will always have `start_date` and `end_date` parameters. The default date range will vary by function, in this example it is one year.\ \ >>> output = obb.equity.price.historical(symbol="AAPL", provider="yfinance").to_df()>>> df = output.to_df()>>> df open high low close volume dividenddate 2024-10-14 228.699997 231.729996 228.600006 231.300003 39882100 0.02024-10-15 233.610001 237.490005 232.369995 233.850006 64751400 0.02024-10-16 231.600006 232.119995 229.839996 231.779999 34082200 0.02024-10-17 233.429993 233.850006 230.520004 232.149994 32993800 0.02024-10-18 236.179993 236.179993 234.009995 235.000000 46431500 0.0... ... ... ... ... ... ...2025-10-06 257.989990 259.070007 255.050003 256.690002 44664100 0.02025-10-07 256.809998 257.399994 255.429993 256.480011 31955800 0.02025-10-08 256.519989 258.519989 256.109985 258.059998 36496900 0.02025-10-09 257.809998 258.000000 253.139999 254.039993 38322000 0.02025-10-10 254.940002 256.380005 244.000000 245.270004 61782400 0.0[249 rows x 6 columns]\ \ ### Technical Analysis[​](https://docs.openbb.co/odp/python/quickstart#technical-analysis "Direct link to Technical Analysis")\ \ Use the output to feed the input of data processing functions.\ \ >>> ta = obb.technical.donchian(data=output.results).to_df().dropna(how="any")>>> ta open high low close volume dividend DCL_20_20 DCM_20_20 DCU_20_20date 2024-11-08 227.169998 228.660004 226.410004 226.960007 38328800 0.25 219.710007 228.600006 237.4900052024-11-11 225.000000 225.699997 221.500000 224.229996 42005600 0.00 219.710007 228.600006 237.4900052024-11-12 224.550003 225.589996 223.360001 224.229996 40398300 0.00 219.710007 228.280006 236.8500062024-11-13 224.009995 226.649994 222.759995 225.119995 48566200 0.00 219.710007 228.280006 236.8500062024-11-14 225.020004 228.869995 225.000000 228.220001 44923900 0.00 219.710007 228.280006 236.850006... ... ... ... ... ... ... ... ... ...2025-10-06 257.989990 259.070007 255.050003 256.690002 44664100 0.00 225.949997 242.594994 259.2399902025-10-07 256.809998 257.399994 255.429993 256.480011 31955800 0.00 225.949997 242.594994 259.2399902025-10-08 256.519989 258.519989 256.109985 258.059998 36496900 0.00 226.649994 242.944992 259.2399902025-10-09 257.809998 258.000000 253.139999 254.039993 38322000 0.00 229.020004 244.129997 259.2399902025-10-10 254.940002 256.380005 244.000000 245.270004 61782400 0.00 235.029999 247.134995 259.239990[230 rows x 9 columns]\ \ Reference[​](https://docs.openbb.co/odp/python/quickstart#reference "Direct link to Reference")\ \ ------------------------------------------------------------------------------------------------\ \ All function metadata is available directly as a JSON dictionary.\ \ >>> obb.reference.keys()dict_keys(['openbb', 'info', 'paths', 'routers'])\ \ Example JSON Content\ \ { "deprecated": { "flag": null, "message": null }, "description": "Get summary, status, and other metadata for a specific bill.\n\nEnter the URL of the bill as: https://api.congress.gov/v3/bill/119/hr/131?\n\nURLs for bills can be found from the `uscongress.bills` endpoint.\n\nThe raw JSON response from the API will be returned along with a formatted\ntext version of the key information from the raw response.\n\nIn OpenBB Workspace, this command returns as a Markdown widget.", "examples": "\nExamples\n--------\n\n```python\nfrom openbb import obb\nobb.uscongress.bill_info(provider='congress_gov', bill_url=https://api.congress.gov/v3/bill/119/s/1947?)\n# The bill URL can be shortened to just the bill number (e.g., '119/s/1947').\nobb.uscongress.bill_info(bill_url=119/s/1947, provider='congress_gov')\n```\n\n", "parameters": { "standard": [], "congress_gov": [ { "name": "bill_url", "type": "str", "description": "Enter a base URL of a bill (e.g., 'https://api.congress.gov/v3/bill/119/s/1947?format=json'). Alternatively, you can enter a bill number (e.g., '119/s/1947').", "default": "", "optional": false, "choices": null } ] }, "returns": { "OBBject": [ { "name": "results", "type": "list[CongressBillInfo]", "description": "Serializable results." }, { "name": "provider", "type": "Optional[Literal['congress_gov']]", "description": "Provider name." }, { "name": "warnings", "type": "Optional[list[Warning_]]", "description": "list of warnings." }, { "name": "chart", "type": "Optional[Chart]", "description": "Chart object." }, { "name": "extra", "type": "dict[str, Any]", "description": "Extra info." } ] }, "data": { "standard": [], "congress_gov": [ { "name": "markdown_content", "type": "str", "description": "Aggregated metadata for the bill in Markdown format.", "default": "", "optional": false, "choices": null }, { "name": "raw_data", "type": "dict[str, Any]", "description": "Raw JSON data from the collected bill information.", "default": "", "optional": false, "choices": null } ] }, "model": "CongressBillInfo", "openapi_extra": { "model": "CongressBillInfo" }}\ \ Next Steps[​](https://docs.openbb.co/odp/python/quickstart#next-steps "Direct link to Next Steps")\ \ ---------------------------------------------------------------------------------------------------\ \ Go to the [Workspace](https://docs.openbb.co/odp/python/quickstart/workspace)\ page to get started using ODP as an OpenBB Workspace Backend.\ \ On this page\ \ * [Import](https://docs.openbb.co/odp/python/quickstart#import)\ \ * [Query](https://docs.openbb.co/odp/python/quickstart#query)\ * [Historical Stock Prices](https://docs.openbb.co/odp/python/quickstart#historical-stock-prices)\ \ * [Technical Analysis](https://docs.openbb.co/odp/python/quickstart#technical-analysis)\ \ * [Reference](https://docs.openbb.co/odp/python/quickstart#reference)\ \ * [Next Steps](https://docs.openbb.co/odp/python/quickstart#next-steps) --- # Core Widgets | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/widgets/core-widgets#__docusaurus_skipToContent_fallback) On this page OpenBB's core widgets form the foundation of your financial analysis workspace. These essential components enable you to organize information, capture insights, and integrate external data sources within a unified interface, creating a powerful environment for financial analysis and decision-making. Navigation Bar[​](https://docs.openbb.co/workspace/analysts/widgets/core-widgets#navigation-bar "Direct link to Navigation Bar") --------------------------------------------------------------------------------------------------------------------------------- The Navigation Bar serves as your dashboard's command center, providing tab-based organization for complex information. This powerful tool enables you to: * Create and manage multiple tabs for different analysis contexts * Organize information into logical sections * Separate research from analysis * Track different market sectors * Monitor various portfolios ![Navigation bar interface showing multiple tabs](https://openbb-web-assets.s3.amazonaws.com/docs/launch_oct_24/navigation_bar.png) Note Widget[​](https://docs.openbb.co/workspace/analysts/widgets/core-widgets#note-widget "Direct link to Note Widget") ------------------------------------------------------------------------------------------------------------------------ The Note widget transforms your dashboard into a dynamic research canvas, enabling you to capture and organize your insights effectively. This versatile tool allows you to: * Document real-time insights during market analysis * Record key findings and observations * Store and organize prompts for AI-powered analysis * Create a searchable knowledge base of your research ![Note widget interface showing text editing capabilities](https://openbb-web-assets.s3.amazonaws.com/docs/launch_oct_24/note_widget.png) Website and Iframe Widget[​](https://docs.openbb.co/workspace/analysts/widgets/core-widgets#website-and-iframe-widget "Direct link to Website and Iframe Widget") ------------------------------------------------------------------------------------------------------------------------------------------------------------------ The Website widget brings external data sources directly into your dashboard, creating a unified research environment. This powerful integration enables you to: * Access and interact with external websites without leaving OpenBB * Compare data from multiple sources side by side * Create a comprehensive research workspace * Maintain context while analyzing multiple data sources ![Website widget showing embedded webpage](https://openbb-web-assets.s3.amazonaws.com/docs/launch_oct_24/website.png) > **Note:** Some websites may restrict embedding. OpenBB automatically checks and only displays websites that permit embedding. RSS and Atom Feeds Widget[​](https://docs.openbb.co/workspace/analysts/widgets/core-widgets#rss-and-atom-feeds-widget "Direct link to RSS and Atom Feeds Widget") ------------------------------------------------------------------------------------------------------------------------------------------------------------------ The RSS Feeds widget serves as your personal news aggregator within OpenBB, keeping you informed with market-moving information. This widget supports both RSS and Atom feed formats. This essential tool provides: * Curated financial news from top sources * Customizable news feed preferences * Real-time market updates * Integrated news analysis within your research workflow * Support for both RSS (e.g. [https://feeds.bloomberg.com/markets/news.rss](https://feeds.bloomberg.com/markets/news.rss) ) and Atom feed formats (e.g. [https://karpathy.bearblog.dev/feed/](https://karpathy.bearblog.dev/feed/) ) ![RSS Feeds widget showing news headlines](https://openbb-web-assets.s3.amazonaws.com/docs/launch_oct_24/rss.png) Clock Widget[​](https://docs.openbb.co/workspace/analysts/widgets/core-widgets#clock-widget "Direct link to Clock Widget") --------------------------------------------------------------------------------------------------------------------------- The Clock widget helps you track global market hours and coordinate across time zones, essential for international trading and analysis. This tool is particularly valuable for: * Monitoring market open/close times across different regions * Coordinating with international teams * Planning trades across multiple time zones * Staying aware of global market events ![Clock widget showing multiple time zones](https://openbb-web-assets.s3.amazonaws.com/docs/launch_oct_24/clock.png) On this page * [Navigation Bar](https://docs.openbb.co/workspace/analysts/widgets/core-widgets#navigation-bar) * [Note Widget](https://docs.openbb.co/workspace/analysts/widgets/core-widgets#note-widget) * [Website and Iframe Widget](https://docs.openbb.co/workspace/analysts/widgets/core-widgets#website-and-iframe-widget) * [RSS and Atom Feeds Widget](https://docs.openbb.co/workspace/analysts/widgets/core-widgets#rss-and-atom-feeds-widget) * [Clock Widget](https://docs.openbb.co/workspace/analysts/widgets/core-widgets#clock-widget) --- # Troubleshooting | OpenBB Add-in for Excel Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/excel-addin/troubleshooting#__docusaurus_skipToContent_fallback) On this page If you face specific issues while using the add-in and the solutions provided here don't resolve them, don't hesitate to reach out to us for further assistance. You can contact us through [support@openbb.finance](mailto:support@openbb.finance) . ### #VALUE! Error[​](https://docs.openbb.co/workspace/analysts/excel-addin/troubleshooting#value-error "Direct link to #VALUE! Error") If you encounter a '#VALUE!' error when running an OBB function, first verify that you are using the correct syntax. Either [OBB.WIDGET](https://docs.openbb.co/workspace/analysts/excel-addin/obb-widget) or [OBB.GET](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get) . * If you have just opened your workbook and see this error, try recalculating the cell - this is a known issue with Excel add-ins that sometimes requires a refresh. ### Add-in Not Available[​](https://docs.openbb.co/workspace/analysts/excel-addin/troubleshooting#add-in-not-available "Direct link to Add-in Not Available") If the OBB functions are not appearing after installation, try these troubleshooting steps: * Verify that the OpenBB Add-in appears in your Excel ribbon * If not visible, go to **Insert** > **Get Add-ins** > **My Add-ins**, hover over the OpenBB add-in, click '...', remove it, and reinstall * If the issue persists, restart your computer or [clear the Office cache](https://learn.microsoft.com/en-us/office/dev/add-ins/testing/clear-cache) ### Permission Error[​](https://docs.openbb.co/workspace/analysts/excel-addin/troubleshooting#permission-error "Direct link to Permission Error") If you see the message "You don't have permission to use this add-in. Contact your system administrator to request access", try these solutions: * Confirm that your account has the necessary permissions to use the add-in * If permissions are correct, try restarting your computer or [clearing the Office cache](https://learn.microsoft.com/en-us/office/dev/add-ins/testing/clear-cache) ### Duplicate Ribbon Tab[​](https://docs.openbb.co/workspace/analysts/excel-addin/troubleshooting#duplicate-ribbon-tab "Direct link to Duplicate Ribbon Tab") If you notice duplicate 'OpenBB' tabs in the ribbon after editing a workbook in both browser and desktop versions, this is a known Excel issue. While there's no permanent fix, you can resolve it using these workarounds: * **Windows users**: Go to File > Info > Inspect Workbook > Check 'Task Pane Add-ins' > Click 'OK'. This will remove the duplicate add-in reference created by Excel in the browser * **Mac users**: 1. Rename your file from .xlsx to .zip 2. Use WinZip for Mac to unzip the file (the default unzip tool won't work for this) 3. Delete the webextension1.xml file from the webextensions folder 4. Rename the file back to .xlsx ### Connection Issues[​](https://docs.openbb.co/workspace/analysts/excel-addin/troubleshooting#connection-issues "Direct link to Connection Issues") If you're unable to retrieve data through OBB.WIDGET from your backend, check these common issues: * Ensure your backend server is running and accessible from your network * For Mac or Safari users: Verify that your backend is using HTTPS with a valid SSL certificate On this page * [#VALUE! Error](https://docs.openbb.co/workspace/analysts/excel-addin/troubleshooting#value-error) * [Add-in Not Available](https://docs.openbb.co/workspace/analysts/excel-addin/troubleshooting#add-in-not-available) * [Permission Error](https://docs.openbb.co/workspace/analysts/excel-addin/troubleshooting#permission-error) * [Duplicate Ribbon Tab](https://docs.openbb.co/workspace/analysts/excel-addin/troubleshooting#duplicate-ribbon-tab) * [Connection Issues](https://docs.openbb.co/workspace/analysts/excel-addin/troubleshooting#connection-issues) --- # Interacting With Data | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#__docusaurus_skipToContent_fallback) On this page OpenBB Workspace provides powerful tools for analysts to explore and visualize financial data through interactive tables and charts. Working With Parameters[​](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#working-with-parameters "Direct link to Working With Parameters") --------------------------------------------------------------------------------------------------------------------------------------------------------------------- Parameters are the foundation of interactive analysis in OpenBB Workspace, allowing you to customize what data your widgets display. ![Parameter selection interface](https://openbb-web-assets.s3.us-east-1.amazonaws.com/docs/screenshots/parameters.jpg) Input parameters let you focus your analysis by setting date ranges, selecting specific tickers, or applying filters that narrow down the dataset to exactly what you need. ### Grouping Widgets Through Parameter Linking[​](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#grouping-widgets-through-parameter-linking "Direct link to Grouping Widgets Through Parameter Linking") A powerful feature of parameters is their ability to be linked across multiple widgets. When widgets share parameter names and options, changing a value in one widget automatically updates all linked widgets, creating a cohesive analytical experience. ![Parameter linking across widgets](https://openbb-web-assets.s3.us-east-1.amazonaws.com/docs/screenshots/parameter-grouping.jpg) For example, when you change a ticker symbol or date range in one widget, all widgets in the same group that use that parameter will update automatically. This synchronization ensures your entire analysis remains focused on the same context without manual intervention. This capability transforms your dashboard from a collection of isolated visualizations into an intelligent, responsive workspace where your analytical focus drives all data presentation. Interactive Tables[​](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#interactive-tables "Direct link to Interactive Tables") ------------------------------------------------------------------------------------------------------------------------------------------------------ Interactive tables provide powerful data manipulation capabilities for detailed financial analysis. These tables have professional-grade features that allow you to explore and analyze large datasets. ![selection-charting](https://openbb-assets.s3.amazonaws.com/docs/pro/selection-charting-1.png) ### Key Features[​](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#key-features "Direct link to Key Features") * **Column Management**: Resize and reorder to focus on relevant data * **Sorting and filtering**: Click column headers to sort and filter data * **Data Selection**: Select specific data points or ranges to generate visualizations * **Sparklines**: Visualize trends directly within table cells using line, area, and bar sparklines * **Hover Cards**: Access additional context and detailed information on specific data points * **Chart-view Mode**: Transform the entire table into a dynamic chart with a single click ### Table to Chart Conversion[​](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#table-to-chart-conversion "Direct link to Table to Chart Conversion") The widget interface supports conversion between table and chart views, enabling you to switch between detailed data exploration and visual trend analysis as needed. 1. **Selection-based Charting**: Select desired data points, choose a chart type, and generate visualizations instantly 2. **Chart-view Mode**: Access the "Chart-view" icon to transform the entire table into a dynamic chart ![chartview](https://openbb-assets.s3.amazonaws.com/docs/pro/chartview-setting.png) ### Chart Customization[​](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#chart-customization "Direct link to Chart Customization") You can change the chart settings by clicking on the three dots and then the `Chart Settings` in the dropdown menu. ![chart](https://openbb-assets.s3.us-east-1.amazonaws.com/docs/pro/chart+settings.png) Here you can change the chart type, the chart settings, and some other settings in each tab. ![chart](https://openbb-assets.s3.us-east-1.amazonaws.com/docs/pro/chart+settings+2.png) The customization interface provides three main configuration areas: * **Visual Customization**: Modify chart appearance, including titles, colors, and styling elements. * **Data Series Management**: Control the visibility and configuration of data series. * **Chart Type Selection**: Choose from various chart types to best represent your data. Example of a customized chart with multiple visualization types: ![Customized chart example](https://openbb-assets.s3.amazonaws.com/docs/pro/combo-chart.png) The final example demonstrates how to combine different chart types for enhanced data visualization. Plotly Charts[​](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#plotly-charts "Direct link to Plotly Charts") --------------------------------------------------------------------------------------------------------------------------------------- Plotly charts give your developers complete freedom to create the right visualization for your data, whether you need a simple line chart or a complex 3D plot. The integration is straightforward, with charts automatically adapting to your workspace theme in both light and dark modes. ![Plotly Chart with Raw Data Switch](https://openbb-assets.s3.us-east-1.amazonaws.com/docs/pro/plotly+switch.png) As a user you will find everything you need for in-depth analysis: interactive toolbars with drawing tools and annotations. ### Raw Data Toggle[​](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#raw-data-toggle "Direct link to Raw Data Toggle") The raw data toggle is particularly useful for AI-assisted analysis. With a simple switch in the top-right corner, you can move between the visual representation and the underlying dataset. This gives the AI copilot direct access to the numbers behind the chart while keeping your dashboard clean and focused on insights. TradingView Charts[​](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#tradingview-charts "Direct link to TradingView Charts") ------------------------------------------------------------------------------------------------------------------------------------------------------ TradingView charts bring professional trading visualization tools directly into your workspace, using the same interface that traders around the world rely on for their analysis. ![TradingView Chart Example](https://openbb-cms.directus.app/assets/1e1dff4c-8698-4a82-9863-31e911e7cf3b.png) You get the full TradingView experience: real-time and historical market data, technical indicators, and all the drawing tools you need for your analysis. Whether you're drawing trend lines, applying Fibonacci retracement levels, or highlighting chart patterns, everything works just like it does in the native TradingView platform. The ability to switch between timeframes makes it easy to zoom in on short-term movements or step back for a broader market view. On this page * [Working With Parameters](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#working-with-parameters) * [Grouping Widgets Through Parameter Linking](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#grouping-widgets-through-parameter-linking) * [Interactive Tables](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#interactive-tables) * [Key Features](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#key-features) * [Table to Chart Conversion](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#table-to-chart-conversion) * [Chart Customization](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#chart-customization) * [Plotly Charts](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#plotly-charts) * [Raw Data Toggle](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#raw-data-toggle) * [TradingView Charts](https://docs.openbb.co/workspace/analysts/widgets/interacting-with-data#tradingview-charts) --- # Static Files | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/widgets/static-files#__docusaurus_skipToContent_fallback) On this page OpenBB provides an intuitive way to import data through file uploads. This feature supports a wide range of file formats, allowing you to integrate both structured and unstructured data into your analysis workflow. File Upload Process[​](https://docs.openbb.co/workspace/analysts/widgets/static-files#file-upload-process "Direct link to File Upload Process") ------------------------------------------------------------------------------------------------------------------------------------------------ The file upload interface is straightforward. You can either drag and drop them onto the dashboard or select files individually in the Add Data pop-up window. This flexibility supports importing multiple files simultaneously, regardless of their format. ![File upload interface showing the Add Data pop-up](https://openbb-web-assets.s3.amazonaws.com/docs/launch_oct_24/upload_file.png) To ensure optimal performance for all application users, OpenBB maintains a 25MB file size limit. ### Metadata Management[​](https://docs.openbb.co/workspace/analysts/widgets/static-files#metadata-management "Direct link to Metadata Management") Upon uploading your files, OpenBB automatically generates initial metadata for the widget, including the name and description. You might want to adjust these fields to better reflect the nuances of your data. Note that Enterprise customers can customize this automatic metadata generation feature. ![Metadata configuration interface](https://openbb-web-assets.s3.amazonaws.com/docs/launch_oct_24/metadata.png) ### Accessing Uploaded Data[​](https://docs.openbb.co/workspace/analysts/widgets/static-files#accessing-uploaded-data "Direct link to Accessing Uploaded Data") Once you've uploaded and configured your data, you can access the resulting widget through two primary methods: 1. The Search feature, which provides quick access to all your widgets 2. The Data Connector page, which offers a comprehensive view of your data sources ![Search interface showing widget results](https://openbb-web-assets.s3.amazonaws.com/docs/launch_oct_24/search_widget.png) ![Data Connector interface showing available widgets](https://openbb-web-assets.s3.amazonaws.com/docs/launch_oct_24/data_connector_widget.png) Supported File Types[​](https://docs.openbb.co/workspace/analysts/widgets/static-files#supported-file-types "Direct link to Supported File Types") --------------------------------------------------------------------------------------------------------------------------------------------------- OpenBB supports two main categories of data files, each with specific use cases and visualization capabilities. ### Structured Data[​](https://docs.openbb.co/workspace/analysts/widgets/static-files#structured-data "Direct link to Structured Data") Structured data files, including XLSX, JSON, and CSV formats, are ideal for quantitative analysis and data processing. Currently, XLSX files are limited to single-sheet imports. The system automatically converts these files into interactive widgets that display your data in a clear, organized format. ![Example of structured data visualization](https://openbb-web-assets.s3.amazonaws.com/docs/launch_oct_24/structured_data.png) ### Unstructured Data[​](https://docs.openbb.co/workspace/analysts/widgets/static-files#unstructured-data "Direct link to Unstructured Data") OpenBB supports three types of unstructured data, each serving different analytical needs: * Images (PNG and JPG): Perfect for visual analysis and documentation * PDF Documents: Ideal for research papers, reports, and documentation * Text Files (like TXT and DOCX): Suitable for notes, research, and qualitative analysis ![Example of unstructured data visualization](https://openbb-web-assets.s3.amazonaws.com/docs/launch_oct_24/unstructured_data.png) Note that scanned images are better handled when uploaded as images (PNG or JPG) rather than PDFs. On this page * [File Upload Process](https://docs.openbb.co/workspace/analysts/widgets/static-files#file-upload-process) * [Metadata Management](https://docs.openbb.co/workspace/analysts/widgets/static-files#metadata-management) * [Accessing Uploaded Data](https://docs.openbb.co/workspace/analysts/widgets/static-files#accessing-uploaded-data) * [Supported File Types](https://docs.openbb.co/workspace/analysts/widgets/static-files#supported-file-types) * [Structured Data](https://docs.openbb.co/workspace/analysts/widgets/static-files#structured-data) * [Unstructured Data](https://docs.openbb.co/workspace/analysts/widgets/static-files#unstructured-data) --- # AI-generated Widgets | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/widgets/ai-generated-widgets#__docusaurus_skipToContent_fallback) OpenBB's AI agents can generate various types of outputs such as text, tables, and charts. These outputs can be saved as widgets in your dashboard for future reference and analysis. ![Dashboard showing AI-generated widgets and analysis outputs](https://openbb-cms.directus.app/assets/1453ffb5-a51f-4967-944d-a651d4fa57d9.png) To save an AI agent's output as a widget: 1. Run your desired AI analysis command ![Terminal showing AI analysis command execution](https://openbb-cms.directus.app/assets/e9db86df-be8f-42b6-8999-fe02bafffcf0.png) 2. When the output is displayed, look for the "Create widget from X" button ![AI analysis output with 'Create widget' button highlighted](https://openbb-cms.directus.app/assets/fc32872b-68b4-4ba3-aa63-04a0846c644d.png) 3. Click the button to add the output to your dashboard ![Widget creation dialog showing name and description fields](https://openbb-cms.directus.app/assets/8cd1d032-6685-4178-bb49-c3807f870094.png) 4. Edit the name and description that have been selected based on AI ![Widget settings panel with editable metadata fields](https://openbb-cms.directus.app/assets/2d2d2d3b-3ac5-49d4-9d3b-b289cb5b5fdc.png) 5. Making it persistent The widget will be only accessible for this session. To ensure your AI-generated widgets persist across sessions: 1. Open the widget settings by clicking the gear icon on the widget ![Widget with gear icon for accessing settings](https://openbb-cms.directus.app/assets/0b1c5e6e-76bd-48ec-9c20-0ccd1b042036.png) 2. Edit the widget metadata: Name, description, category, subcategory and source ![Widget metadata editing form with fields for name, description, category, subcategory and source](https://openbb-cms.directus.app/assets/658af726-3c62-4d9b-b38b-491e53fbc21f.png) 3. Save the changes The widget will now persist in your dashboard and can be accessed in future sessions. --- # Matching widget to MCP tool | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-configuration/matching-widget-to-mcp-tool#__docusaurus_skipToContent_fallback) On this page When an MCP (Model Context Protocol) tool is invoked, OpenBB Workspace can automatically detect if there's a matching widget configured and provide a matching citation. This is achieved through configuration in your `widgets.json` file. How It Works[​](https://docs.openbb.co/workspace/developers/widget-configuration/matching-widget-to-mcp-tool#how-it-works "Direct link to How It Works") --------------------------------------------------------------------------------------------------------------------------------------------------------- OpenBB Workspace checks if a widget has been configured with matching MCP tool metadata. When a match is found: 1. The system shows a notification that a matching widget was found 2. A citation is automatically generated and attached to the MCP tool response 3. The citation includes widget details like name, description, and input parameters Configuration[​](https://docs.openbb.co/workspace/developers/widget-configuration/matching-widget-to-mcp-tool#configuration "Direct link to Configuration") ------------------------------------------------------------------------------------------------------------------------------------------------------------ important `mcp_server` and `tool_id` provided should match 1:1 the ones that are connected to OpenBB Copilot. To enable widget matching for MCP tools, add an `mcp_tool` property, like: "mcp_tool": { "mcp_server": "server_name", "tool_id": "tool_name"} The widget configuration in `widgets.json` should be like: { "widgetId": "your_widget_id", "name": "Your Widget Name", "description": "Widget description", ... "mcp_tool": { "mcp_server": "server_name", "tool_id": "tool_name" }} Example[​](https://docs.openbb.co/workspace/developers/widget-configuration/matching-widget-to-mcp-tool#example "Direct link to Example") ------------------------------------------------------------------------------------------------------------------------------------------ We will utilize this [repository example](https://github.com/OpenBB-finance/backends-for-openbb/tree/main/widget-examples/matching-widget-mcp-tool) as a way to demonstrate the flow. ### 1\. Connect MCP Server[​](https://docs.openbb.co/workspace/developers/widget-configuration/matching-widget-to-mcp-tool#1-connect-mcp-server "Direct link to 1. Connect MCP Server") First you want to connect the MCP Server to identify the server name and tool that you will need to reference in your `widgets.json` configuration. ![MCP Server connection dialog showing 'Financial Data' server name](https://openbb-cms.directus.app/assets/6d66dcf3-98c0-4150-aace-035a063df35a.png) In the case above, note that the name of MCP Server is "Financial Data" - this will be the value you need for the `mcp_server` field in your `widgets.json`. ![MCP tool configuration showing 'get_company_revenue_data' tool name](https://openbb-cms.directus.app/assets/643af141-6b8c-4828-b7dc-2242560d71f8.png) Similarly, the MCP tool is "get\_company\_revenue\_data" - this will be the value you need for the `tool_id` field in your `widgets.json`. ### 2\. Configure OpenBB widget with matching MCP[​](https://docs.openbb.co/workspace/developers/widget-configuration/matching-widget-to-mcp-tool#2-configure-openbb-widget-with-matching-mcp "Direct link to 2. Configure OpenBB widget with matching MCP") The important is for the widget configuration to include `mcp_tool` with the **EXACT** same names as the ones from your MCP Server: ![Widget configuration showing mcp_tool property with server and tool ID](https://openbb-cms.directus.app/assets/1603ad32-6bd2-43bc-a4cc-553cb4163c34.png) Notice how the `mcp_server` value "Financial Data" and `tool_id` value "get\_company\_revenue\_data" match exactly with the MCP server configuration from step 1. The name and URL of the backend can be ANYTHING. ![OpenBB backend connection interface showing name and URL fields](https://openbb-cms.directus.app/assets/77a2c0d8-3a9b-47a7-933e-85e7131ef954.png) ### 3\. Matching widget citation[​](https://docs.openbb.co/workspace/developers/widget-configuration/matching-widget-to-mcp-tool#3-matching-widget-citation "Direct link to 3. Matching widget citation") This is when the magic happens. If the user has that MCP tool enabled, and asks something like: > "Utilize financial data MCP tool and get company revenue data for AAPL" Then when the MCP tool is utilized, the user will see a toast like the following: ![Toast notification showing 'Matching widget found' message](https://openbb-cms.directus.app/assets/655482de-3d2b-426c-8315-dbb579c78f16.png) This indicates that a matching widget was found. ![Chat response showing matching widget citation with asterisk indicator](https://openbb-cms.directus.app/assets/d2c50edb-43e2-4771-9125-b31117501a61.png) The user will be able to see that this is a matching widget, by the property of having a `*` at the end. When hovering on top of that widget, the user will be able to add it to the dashboard to the same parameters as the ones that were utilized by the copilot. ![Widget hover tooltip showing option to add to dashboard](https://openbb-cms.directus.app/assets/a719abc4-9b2f-41c7-b1a8-dd84fc707b77.png) The advantage now is that the user can interact with the parameters, charting and all other OpenBB widgets properties. ![Interactive widget dashboard showing parameters, charting, and OpenBB properties](https://openbb-cms.directus.app/assets/6f0df91c-195f-48c4-9fbe-13ed589245a9.png) On this page * [How It Works](https://docs.openbb.co/workspace/developers/widget-configuration/matching-widget-to-mcp-tool#how-it-works) * [Configuration](https://docs.openbb.co/workspace/developers/widget-configuration/matching-widget-to-mcp-tool#configuration) * [Example](https://docs.openbb.co/workspace/developers/widget-configuration/matching-widget-to-mcp-tool#example) * [1\. Connect MCP Server](https://docs.openbb.co/workspace/developers/widget-configuration/matching-widget-to-mcp-tool#1-connect-mcp-server) * [2\. Configure OpenBB widget with matching MCP](https://docs.openbb.co/workspace/developers/widget-configuration/matching-widget-to-mcp-tool#2-configure-openbb-widget-with-matching-mcp) * [3\. Matching widget citation](https://docs.openbb.co/workspace/developers/widget-configuration/matching-widget-to-mcp-tool#3-matching-widget-citation) --- # Settings - ODP Python | OpenBB Docs [Skip to main content](https://docs.openbb.co/odp/python/settings#__docusaurus_skipToContent_fallback) ODP Python Package settings are `JSON` and `.env` files, all located in the `~/.openbb_platform` folder, at the root of the operating system's user account home. [User Settings\ \ Preferences, credentials, and defaults are located in \`user\_settings.json\`.](https://docs.openbb.co/odp/python/settings/user_settings) [System Settings\ \ FastAPI, Python, HTTP, Uvicorn, and logging settings are defined in \`system\_settings.json\`.](https://docs.openbb.co/odp/python/settings/system_settings) [MCP Settings\ \ MCP server settings and configurations are set in \`mcp\_settings.json\`.](https://docs.openbb.co/odp/python/settings/mcp_settings) [Environment Variables\ \ Store environment variables in a \`.env\` file.](https://docs.openbb.co/odp/python/settings/environment_variables) --- # Markdown | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-types/markdown#__docusaurus_skipToContent_fallback) On this page A simple widget that displays markdown content. ![Markdown Widget Example](https://openbb-cms.directus.app/assets/60cbbcb5-194e-4c03-905e-65f3de7f4efe.png) @register_widget({ "name": "Markdown Widget", "description": "A markdown widget", "type": "markdown", "endpoint": "markdown_widget", "gridData": {"w": 12, "h": 4},})@app.get("/markdown_widget")def markdown_widget(): """Returns a markdown widget""" return "# Markdown Widget" The gridData parameter specifies the widget's size in the OpenBB Workspace grid system. More on that can be found [here](https://docs.openbb.co/workspace/developers/widget-configuration/grid-size) . Data rich markdown[​](https://docs.openbb.co/workspace/developers/widget-types/markdown#data-rich-markdown "Direct link to Data rich markdown") ------------------------------------------------------------------------------------------------------------------------------------------------ ![markdown](https://openbb-assets.s3.us-east-1.amazonaws.com/docs/pro/markdown-widget.png) @register_widget({ "name": "Defi Llama Protocol Details", "description": "Details for a given protocol", "category": "Crypto", "defaultViz": "markdown", "endpoint": "defi_llama_protocol_details", "gridData": {"w": 20, "h": 9}, "source": "Defi Llama", "params": [ { "paramName": "protocol_id", "value": "aave", "label": "Protocol", "type": "text", "description": "Defi Llama ID of the protocol" } ]})@app.get("/defi_llama_protocol_details")def defi_llama_protocol_details(protocol_id: str = None): """Get details for a given protocol using Defi Llama""" data = requests.get(f'https://api.llama.fi/protocol/{protocol_id}') if data.status_code == 200: data = data.json() else: return JSONResponse(content={"error": data.text}, status_code=data.status_code) github_links = "" if 'github' in data and data['github']: github_links = "**GitHub:** " + ", ".join(data['github']) # Use HTML for multi-column layout markdown = dedent(f""" ![{data.get('name', 'N/A')} Logo]({data.get('logo', '')}) # {data.get('name', 'N/A')} ({data.get('symbol', 'N/A').upper()}) **Description:** {data.get('description', 'N/A')} --- ## Twitter **Twitter:** {data.get('twitter', 'N/A')} ## Links **Website:** {data.get('url', 'N/A')} {github_links} """) return markdown **Note:** The `dedent` function is used to remove leading whitespace from the markdown string. This is a good practice to ensure the markdown is formatted correctly. Markdown Widget with Local Image[​](https://docs.openbb.co/workspace/developers/widget-types/markdown#markdown-widget-with-local-image "Direct link to Markdown Widget with Local Image") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ A widget that displays markdown content with an embedded local image. The image is converted to base64 for display. ![Markdown Widget with Local Image Example](https://openbb-cms.directus.app/assets/f2847732-a01e-4146-8095-5dc389c98c7a.png) @register_widget({ "name": "Markdown Widget with Local Image", "description": "A markdown widget with a local image", "type": "markdown", "endpoint": "markdown_widget_with_local_image", "gridData": {"w": 20, "h": 20},})@app.get("/markdown_widget_with_local_image")def markdown_widget_with_local_image(): """Returns a markdown widget with a local image""" try: with open("img.png", "rb") as image_file: image_base64 = base64.b64encode(image_file.read()).decode('utf-8') return f"![Local Image]()" except FileNotFoundError: raise HTTPException( status_code=500, detail="Image file not found" ) from e except Exception as e: raise HTTPException( status_code=500, detail=f"Error reading image: {str(e)}" ) from e Markdown Widget with Image from URL[​](https://docs.openbb.co/workspace/developers/widget-types/markdown#markdown-widget-with-image-from-url "Direct link to Markdown Widget with Image from URL") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The Markdown widget also provides image handling capabilities, supporting both local and remote images. Images are converted to base64 format for displaying. Below is a markdown widget that displays markdown content with an image fetched from a URL. The image is converted to base64 for display. ![Markdown Widget with Image from URL Example](https://openbb-cms.directus.app/assets/bf26f507-ec62-45d8-bec2-531fe75624e4.png) @register_widget({ "name": "Markdown Widget with Image from URL", "description": "A markdown widget with an image from a URL", "type": "markdown", "endpoint": "markdown_widget_with_image_from_url", "gridData": {"w": 20, "h": 20},})@app.get("/markdown_widget_with_image_from_url")def markdown_widget_with_image_from_url(): """Returns a markdown widget with an image from a URL""" image_url = "https://api.star-history.com/svg?repos=openbb-finance/OpenBB&type=Date&theme=dark" try: response = requests.get(image_url, timeout=10) response.raise_for_status() content_type = response.headers.get('content-type', '') if not content_type.startswith('image/'): raise HTTPException( status_code=500, detail=f"URL did not return an image. Content-Type: {content_type}" ) image_base64 = base64.b64encode(response.content).decode('utf-8') return f"![OpenBB Logo](data:{content_type};base64,{image_base64})" except requests.RequestException as e: raise HTTPException( status_code=500, detail=f"Failed to fetch image: {str(e)}" ) from e except Exception as e: raise HTTPException( status_code=500, detail=f"Error processing image: {str(e)}" ) from e On this page * [Data rich markdown](https://docs.openbb.co/workspace/developers/widget-types/markdown#data-rich-markdown) * [Markdown Widget with Local Image](https://docs.openbb.co/workspace/developers/widget-types/markdown#markdown-widget-with-local-image) * [Markdown Widget with Image from URL](https://docs.openbb.co/workspace/developers/widget-types/markdown#markdown-widget-with-image-from-url) --- # Copilot Basics | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/ai-features/copilot-basics#__docusaurus_skipToContent_fallback) On this page The OpenBB Copilot is an AI-powered companion seamlessly integrated into the OpenBB Workspace, designed to enhance and accelerate your financial analysis workflow. This sophisticated assistant understands natural language queries, retrieves data from multiple sources, performs complex analysis, and generates actionable insights. Built for financial professionals, the Copilot transforms your workflow by accelerating analysis and providing context-aware insights based on your specific datasets and workspace configuration. ![OpenBB Copilot Interface](https://openbb-cms.directus.app/assets/0a5e0075-7c50-44cb-8d45-2be1817deab5.png) Structure[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-basics#structure "Direct link to Structure") ------------------------------------------------------------------------------------------------------------------------ ![Copilot interface structure](https://openbb-cms.directus.app/assets/d7efdb97-fecd-4d58-8094-84fa82bf4bd4.png) The Copilot interface is designed for intuitive interaction with a clean three-section layout: * **Header:** At the top, you'll find controls to manage your conversation. You can see which chat you're in, start a new one, clear the history, expand to full-screen mode, or hide the agent entirely. * **Body:** The main chat window where your conversation takes place. It displays the Copilot's answers, its step-by-step reasoning, and any output like charts, tables, or code. The chat automatically scrolls, keeping everything in chronological order. Hover over a message to see its timestamp. * **Footer:** Here, you can manage the data and widgets the Copilot uses as context for its answers. You can also add your own custom AI agents or open your prompt library. Full screen AI-chat[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-basics#full-screen-ai-chat "Direct link to Full screen AI-chat") ------------------------------------------------------------------------------------------------------------------------------------------------------ You can resize the AI panel by dragging the border. In side-panel mode, it provides quick access for simple queries while maintaining your primary workspace view. ![Full screen AI-chat](https://openbb-cms.directus.app/assets/1f9ba730-2516-4eac-b7c9-ca6e9382ba78.png) When expanded to full-screen mode, you gain maximum real estate for complex conversations, detailed reasoning steps, and large artifacts like comprehensive charts or extensive data tables. ![Full screen AI-chat](https://openbb-cms.directus.app/assets/7aa420b1-01b8-4785-b2d9-588ddd414842.png) This flexibility allows seamless transitions between quick consultations and deep analytical sessions without losing context or interrupting your workflow. You can also hide the AI agent entirely if you want to work solely with the dashboard. ![AI agent hidden](https://openbb-cms.directus.app/assets/9e9a76dc-7e4a-4e04-9211-086ee147c6c1.png) Prompt library[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-basics#prompt-library "Direct link to Prompt library") --------------------------------------------------------------------------------------------------------------------------------------- The integrated prompt library serves as a productivity multiplier by storing and organizing your most valuable queries. You can save complex prompts and even tag widgets, to ensure the right context is utilized for the right prompt. ![Prompt library](https://openbb-cms.directus.app/assets/f145bb2d-89bf-49f9-8fd7-af24d78e4dff.png) Model[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-basics#model "Direct link to Model") ------------------------------------------------------------------------------------------------------------ The OpenBB Copilot is specifically optimized for financial analysis and data interpretation tasks, leveraging the latest models from OpenAI. For enterprise deployments, OpenBB provides seamless integration with your organization's Azure OpenAI. This ensures compliance with internal security and data sovereignty policies. If you would like full control over your agent capabilities, here's [our open source repository](https://github.com/OpenBB-finance/agents-for-openbb) with examples of AI custom agents that you can build and integrate into the OpenBB Workspace. On this page * [Structure](https://docs.openbb.co/workspace/analysts/ai-features/copilot-basics#structure) * [Full screen AI-chat](https://docs.openbb.co/workspace/analysts/ai-features/copilot-basics#full-screen-ai-chat) * [Prompt library](https://docs.openbb.co/workspace/analysts/ai-features/copilot-basics#prompt-library) * [Model](https://docs.openbb.co/workspace/analysts/ai-features/copilot-basics#model) --- # Agents Integration | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/agents-integration#__docusaurus_skipToContent_fallback) On this page Integrate your own AI agent service with OpenBB Workspace using a simple HTTP contract. Your service accepts POST requests, streams responses back to Workspace and can access dashboard data when enabled. Architecture[​](https://docs.openbb.co/workspace/developers/agents-integration#architecture "Direct link to Architecture") --------------------------------------------------------------------------------------------------------------------------- * `/agents.json`: the metadata endpoint. Returns agent metadata and capabilities (name, description, image, URL of the query endpoint, features that the agent implements). * `/query`: the query endpoint. Receives a `QueryRequest` and streams responses via Server‑Sent Events (SSE). Recommended stack: FastAPI with `EventSourceResponse` from `sse_starlette` and OpenBB AI SDK (`openbb-ai`), although any framework that supports streaming SSEs in response to a POST request should work. See this repository to [get started](https://github.com/OpenBB-finance/agents-for-openbb) . Adding an Agent in Workspace[​](https://docs.openbb.co/workspace/developers/agents-integration#adding-an-agent-in-workspace "Direct link to Adding an Agent in Workspace") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1. Deploy your service (locally or remote). 2. In Workspace, click on the copilot and on the plus or pencil icon. ![No tab no param primary](https://openbb-cms.directus.app/assets/412540b0-ef86-4285-8303-b9faf83bdc66.png) 3. Enter your base URL; Workspace fetches `/agents.json` and uses `/query` for conversations. ![No tab no param primary](https://openbb-cms.directus.app/assets/ce3bebd7-98cf-4598-9d6c-68a2ecc1ba1c.png) Ensure CORS settings are correct and SSE are configured on your service. Example[​](https://docs.openbb.co/workspace/developers/agents-integration#example "Direct link to Example") ------------------------------------------------------------------------------------------------------------ Simplistic example that allows users to communicate with an agent that can optimize the user prompt. The code is open source [and available here](https://github.com/OpenBB-finance/agents-for-openbb/tree/main/20-financial-prompt-optimizer) . ![No tab no param primary](https://openbb-cms.directus.app/assets/d2eaa645-eb6e-4411-b9d1-74b70409483a.png) This agent does nothing else - it doesn't parse data added to context, doesn't pass data in the dashboard, doesn't share step-by-step reasoning or citations, doesn't create artifacts, etc. We will dive on each of these features in the AI features tab. from typing import AsyncGeneratorimport openaifrom fastapi import FastAPIfrom fastapi.middleware.cors import CORSMiddlewarefrom fastapi.responses import JSONResponsefrom sse_starlette.sse import EventSourceResponsefrom openbb_ai.models import MessageChunkSSE, QueryRequestfrom openbb_ai import message_chunkfrom openai.types.chat import ( ChatCompletionMessageParam, ChatCompletionUserMessageParam, ChatCompletionAssistantMessageParam, ChatCompletionSystemMessageParam,)app = FastAPI()app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"],)@app.get("/agents.json")def get_copilot_description(): """Agent descriptor for the OpenBB Workspace.""" return JSONResponse( content={ "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, }, } } )@app.post("/v1/query")async def query(request: QueryRequest) -> EventSourceResponse: """Stream a concise optimized prompt and rationale.""" openai_messages: list[ChatCompletionMessageParam] = [ ChatCompletionSystemMessageParam( role="system", content=( "You are a concise Financial Prompt Optimizer.\n" "Rewrite the user's prompt to be clearer, more specific, and immediately actionable for financial analysis.\n" "Always return exactly the improved prompt:\n" "Optimized Prompt: \n" ), ) ] for message in request.messages: if message.role == "human": openai_messages.append( ChatCompletionUserMessageParam(role="user", content=message.content) ) elif message.role == "ai" and isinstance(message.content, str): openai_messages.append( ChatCompletionAssistantMessageParam( role="assistant", content=message.content ) ) async def execution_loop() -> AsyncGenerator[MessageChunkSSE, None]: 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) return EventSourceResponse( content=( event.model_dump(exclude_none=True) async for event in execution_loop() ), media_type="text/event-stream", )if __name__ == "__main__": import uvicorn uvicorn.run("main:app", host="0.0.0.0", port=7777, reload=True) On this page * [Architecture](https://docs.openbb.co/workspace/developers/agents-integration#architecture) * [Adding an Agent in Workspace](https://docs.openbb.co/workspace/developers/agents-integration#adding-an-agent-in-workspace) * [Example](https://docs.openbb.co/workspace/developers/agents-integration#example) --- # Data Control & Security | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/getting-started/enterprise/data-control#__docusaurus_skipToContent_fallback) On this page OpenBB Workspace Enterprise ensures complete data sovereignty by running entirely within your infrastructure. Your data, AI models, and prompts never leave your secure environment while maintaining full control over sensitive financial information and meeting regulatory requirements. Data Sovereignty[​](https://docs.openbb.co/workspace/getting-started/enterprise/data-control#data-sovereignty "Direct link to Data Sovereignty") ------------------------------------------------------------------------------------------------------------------------------------------------- Deploy on-premises or in your private cloud (VPC) to maintain complete control over data location and access. All processing occurs within your infrastructure boundaries, ensuring compliance with data residency requirements and regulatory obligations. Deployment Options[​](https://docs.openbb.co/workspace/getting-started/enterprise/data-control#deployment-options "Direct link to Deployment Options") ------------------------------------------------------------------------------------------------------------------------------------------------------- On-premises installation provides maximum control by running directly on your servers. This approach works well for organizations with strict data residency requirements or air-gapped environments that require complete network isolation. Private cloud deployment in AWS, Azure, or GCP maintains cloud infrastructure flexibility while keeping data within your security perimeter. This option balances operational convenience with security requirements. Hybrid architecture combines on-premises core systems with cloud-based compute resources. This approach allows organizations to balance security requirements with scalability needs while maintaining data control. ![OpenBB Workspace Enterprise Architecture](https://openbb-cms.directus.app/assets/2ad71c09-ae83-422f-975d-d4cdaefd2c74.png) Enterprise Security Features[​](https://docs.openbb.co/workspace/getting-started/enterprise/data-control#enterprise-security-features "Direct link to Enterprise Security Features") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The platform integrates with existing security infrastructure including SSO support for Azure and Google authentication systems. Granular role-based access control (RBAC) manages permissions across applications, widgets, data sources, and AI features. Multi-factor authentication enforcement adds security layers for all user accounts. Detailed audit logging captures all user activities, system access, and configuration changes. The platform operates with no external product analytics and minimal operational logging to maintain privacy and security standards. Compliance and Audit Support[​](https://docs.openbb.co/workspace/getting-started/enterprise/data-control#compliance-and-audit-support "Direct link to Compliance and Audit Support") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Meet regulatory requirements through complete activity logging that tracks user actions, data access patterns, and system modifications. Export controls manage how data can be extracted or shared outside the platform. Retention policies automate data lifecycle management according to organizational and regulatory requirements. SOC 2 Type II compliance support provides standardized security controls and audit procedures. The platform maintains audit trails that support various regulatory frameworks and compliance requirements. ![Activity Log Interface](https://openbb-web-assets.s3.amazonaws.com/docs/onprem-mar-25/activity-log.png) Implementation Process[​](https://docs.openbb.co/workspace/getting-started/enterprise/data-control#implementation-process "Direct link to Implementation Process") ------------------------------------------------------------------------------------------------------------------------------------------------------------------- Begin with a security assessment of your current environment to understand deployment requirements and integration needs. Architecture design aligns the platform with existing security controls and network configurations. Security configuration includes authentication integration, access controls, and audit logging setup. Testing and validation ensure all security controls function correctly before production deployment. Ongoing management includes regular security reviews, access audits, and maintenance of security documentation and procedures. On this page * [Data Sovereignty](https://docs.openbb.co/workspace/getting-started/enterprise/data-control#data-sovereignty) * [Deployment Options](https://docs.openbb.co/workspace/getting-started/enterprise/data-control#deployment-options) * [Enterprise Security Features](https://docs.openbb.co/workspace/getting-started/enterprise/data-control#enterprise-security-features) * [Compliance and Audit Support](https://docs.openbb.co/workspace/getting-started/enterprise/data-control#compliance-and-audit-support) * [Implementation Process](https://docs.openbb.co/workspace/getting-started/enterprise/data-control#implementation-process) --- # Administration | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/getting-started/enterprise/administration#__docusaurus_skipToContent_fallback) On this page Enterprise administrators manage users, configure access controls, customize branding, and monitor system usage through a web-based interface. User Management[​](https://docs.openbb.co/workspace/getting-started/enterprise/administration#user-management "Direct link to User Management") ------------------------------------------------------------------------------------------------------------------------------------------------ Import users from CSV files or connect to directory services for automated provisioning. Bulk operations handle large user lists efficiently. Account creation includes role assignment during the onboarding process. User modifications update permissions as organizational responsibilities change. Offboarding revokes access immediately while preserving audit trails. ![Team Management Interface](https://openbb-web-assets.s3.amazonaws.com/docs/launch_oct_24/team_management.png) Single sign-on integrates with Azure Active Directory through OpenID Connect protocol. Google Workspace authentication uses OAuth 2.0 flows. Any SAML 2.0-compatible identity provider connects through standard configuration. Just-in-time provisioning creates accounts automatically when users first authenticate. Role-Based Access Control[​](https://docs.openbb.co/workspace/getting-started/enterprise/administration#role-based-access-control "Direct link to Role-Based Access Control") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Define custom roles that match organizational structure. Permission levels operate at four distinct layers: applications control access to entire modules, widgets govern individual analytical tools, data sources restrict information access, and AI features manage Copilot capabilities. ![Role Management Interface](https://openbb-web-assets.s3.amazonaws.com/docs/onprem-mar-25/create-role-user-list.png) Standard roles provide starting points for customization. Admin accounts have full system access and configuration capabilities. Analysts create and share dashboards with complete data access. Viewers access shared content in read-only mode. Data Managers handle source connections and data governance. Custom roles combine these permissions to match specific organizational needs. Theme and Branding Configuration[​](https://docs.openbb.co/workspace/getting-started/enterprise/administration#theme-and-branding-configuration "Direct link to Theme and Branding Configuration") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Customize visual appearance to match corporate identity. Table settings control general layouts, borders, spacing, headers, cells, icons, and typography. Each element accepts custom styling for both light and dark themes. Configuration changes apply immediately across all user sessions. ![](https://openbb-cms.directus.app/assets/c8c0241e-981c-4456-a8f2-66aafaab350a.png) Chart customization includes base themes, color palettes, core settings, input configurations, and background images. Color palettes define schemes for different data types and analytical contexts. Core settings manage axis, grid, and legend appearance. Background images add corporate watermarks or branding elements. ![](https://openbb-cms.directus.app/assets/364a1419-1b57-46ea-a482-98faef8c36f3.png) Preview functionality shows customizations before applying them system-wide: ![](https://openbb-cms.directus.app/assets/345da327-228b-4029-9480-ef4b8777a357.png) Brand Identity[​](https://docs.openbb.co/workspace/getting-started/enterprise/administration#brand-identity "Direct link to Brand Identity") --------------------------------------------------------------------------------------------------------------------------------------------- Select primary brand colors through a color picker interface. The system automatically generates complementary shades for consistent application throughout the platform. Color choices maintain accessibility compliance by ensuring readable contrast ratios. Changes propagate to all interface elements within seconds. ![](https://openbb-cms.directus.app/assets/815dc29f-d8a8-4c1d-8ee6-0766f9762cde.png) Logo upload supports PNG, SVG, and JPG formats with automatic sizing for different display contexts. The system generates favicons from uploaded logos for browser tab branding. Logo placement options include headers, login pages, and generated reports. ![](https://openbb-cms.directus.app/assets/b1055be1-ed02-400f-8876-372ae832d37c.png) On this page * [User Management](https://docs.openbb.co/workspace/getting-started/enterprise/administration#user-management) * [Role-Based Access Control](https://docs.openbb.co/workspace/getting-started/enterprise/administration#role-based-access-control) * [Theme and Branding Configuration](https://docs.openbb.co/workspace/getting-started/enterprise/administration#theme-and-branding-configuration) * [Brand Identity](https://docs.openbb.co/workspace/getting-started/enterprise/administration#brand-identity) --- # Team Collaboration | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/getting-started/enterprise/team-collaboration#__docusaurus_skipToContent_fallback) On this page Share dashboards, insights, and analyses securely within your organization. The collaboration system provides controlled access to analytical work while maintaining audit trails and data governance. Private Team Workspaces[​](https://docs.openbb.co/workspace/getting-started/enterprise/team-collaboration#private-team-workspaces "Direct link to Private Team Workspaces") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Create dedicated spaces for different teams and projects. Each workspace maintains its own set of dashboards, user permissions, and access controls. Teams can collaborate on analysis within their designated workspace while maintaining separation from other organizational units. Controlled Dashboard Sharing[​](https://docs.openbb.co/workspace/getting-started/enterprise/team-collaboration#controlled-dashboard-sharing "Direct link to Controlled Dashboard Sharing") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Share analytical dashboards with specific team members or groups. The sharing system allows dashboard owners to control who can view, interact with, or modify shared content. Recipients can access shared dashboards through their workspace interface while respecting the permissions set by the owner. ![Dashboard Sharing Interface](https://openbb-web-assets.s3.amazonaws.com/docs/launch_oct_24/sharing_dashboard.png) Dashboard sharing operates through permission levels that determine user capabilities. View-only access allows users to see dashboard content without making changes. Interactive access enables parameter modifications and data exploration while preserving the original dashboard structure. Audit Trails[​](https://docs.openbb.co/workspace/getting-started/enterprise/team-collaboration#audit-trails "Direct link to Audit Trails") ------------------------------------------------------------------------------------------------------------------------------------------- All collaborative activities generate detailed audit records. The system logs dashboard sharing events, access attempts, and modification history. User actions include timestamps, user identification, and affected resources. This information supports compliance requirements and security monitoring. Activity logging tracks when dashboards are shared, accessed, or modified. Permission changes receive separate audit entries showing who granted or revoked access to specific resources. Export activities log when data leaves the system through sharing or download functions. Export Controls[​](https://docs.openbb.co/workspace/getting-started/enterprise/team-collaboration#export-controls "Direct link to Export Controls") ---------------------------------------------------------------------------------------------------------------------------------------------------- Manage how data and analyses can be extracted from the platform. Users are allowed to export: * Individual datasets in formats such as CSV, Excel, PNG and JSON. * Export dashboards (with multiple tabs) as PDF or PNG. * Export a folder (i.e. multiple dashboards) as a ZIP file. AI Features Integration[​](https://docs.openbb.co/workspace/getting-started/enterprise/team-collaboration#ai-features-integration "Direct link to AI Features Integration") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- OpenBB Copilot operates within the collaborative environment while maintaining appropriate access controls. Team members can use AI features to analyze shared data and generate insights within their permission boundaries. AI interactions respect the same access controls that govern manual data analysis. Learn more about AI capabilities in the [Copilot documentation](https://docs.openbb.co/workspace/analysts/ai-features/copilot-basics) . Excel Integration[​](https://docs.openbb.co/workspace/getting-started/enterprise/team-collaboration#excel-integration "Direct link to Excel Integration") ---------------------------------------------------------------------------------------------------------------------------------------------------------- The Excel Add-in supports collaborative workflows by enabling team members to access shared data sources through familiar spreadsheet interfaces. Excel integration maintains the same permission structure as the web platform, ensuring data access consistency across tools. Team members can use Excel to analyze data from shared workspaces while respecting access controls established in the main platform. Changes to data permissions automatically affect Excel access without requiring separate configuration. Explore Excel integration details in the [Add-in documentation](https://docs.openbb.co/workspace/analysts/excel-addin/excel-overview) . Implementation Considerations[​](https://docs.openbb.co/workspace/getting-started/enterprise/team-collaboration#implementation-considerations "Direct link to Implementation Considerations") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Set up team workspaces according to organizational structure and project requirements. Define sharing policies that align with data governance requirements and compliance obligations. Establish audit review procedures to monitor collaborative activities and ensure appropriate access levels. Train team members on sharing capabilities, permission levels, and audit requirements. Regular reviews of shared content and access permissions help maintain security and compliance standards over time. On this page * [Private Team Workspaces](https://docs.openbb.co/workspace/getting-started/enterprise/team-collaboration#private-team-workspaces) * [Controlled Dashboard Sharing](https://docs.openbb.co/workspace/getting-started/enterprise/team-collaboration#controlled-dashboard-sharing) * [Audit Trails](https://docs.openbb.co/workspace/getting-started/enterprise/team-collaboration#audit-trails) * [Export Controls](https://docs.openbb.co/workspace/getting-started/enterprise/team-collaboration#export-controls) * [AI Features Integration](https://docs.openbb.co/workspace/getting-started/enterprise/team-collaboration#ai-features-integration) * [Excel Integration](https://docs.openbb.co/workspace/getting-started/enterprise/team-collaboration#excel-integration) * [Implementation Considerations](https://docs.openbb.co/workspace/getting-started/enterprise/team-collaboration#implementation-considerations) --- # OpenBB AI SDK | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#__docusaurus_skipToContent_fallback) On this page The OpenBB AI SDK simplifies building custom agents for OpenBB Workspace by providing type-safe models and helper functions that handle schema validation for streaming Server-Sent Events (SSE). Instead of manually crafting SSE messages and managing event types, you can use simple Python functions to stream text, show reasoning steps, fetch widget data, and create visualizations. Install the package in your agent backend: pip install openbb-ai The code is open source and is [available in this repository](https://github.com/OpenBB-finance/openbb-ai) . Building Your First Agent[​](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#building-your-first-agent "Direct link to Building Your First Agent") ------------------------------------------------------------------------------------------------------------------------------------------------------------- Every agent starts with a query handler that receives a `QueryRequest` object containing everything your agent needs: from openbb_ai.models import QueryRequestfrom openbb_ai import message_chunk, reasoning_stepasync 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() ### Understanding the QueryRequest[​](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#understanding-the-queryrequest "Direct link to Understanding the QueryRequest") The `QueryRequest` object contains all context your agent needs: #### Core Fields[​](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#core-fields "Direct link to Core Fields") **`messages`** - Chat conversation history for message in request.messages: if message.role == "human": user_query = message.content elif message.role == "ai": previous_response = message.content **`widgets`** - Widgets available to your agent # User-selected widgets (requires widget-dashboard-select feature)if request.widgets and request.widgets.primary: for widget in request.widgets.primary: print(f"User added: {widget.name}")# Dashboard widgets (requires widget-dashboard-search feature)if request.widgets and request.widgets.secondary: for widget in request.widgets.secondary: print(f"On dashboard: {widget.name}") See the [agents.json reference](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference) for details how to enable the `widget-dashboard-select` and `widget-dashboard-search` features. **`workspace_state`** - Current workspace context if request.workspace_state and request.workspace_state.current_dashboard_info: dashboard = request.workspace_state.current_dashboard_info print(f"Active tab: {dashboard.current_tab_id}") #### Additional Fields[​](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#additional-fields "Direct link to Additional Fields") * **`tools`** - MCP tools available for execution * **`urls`** - URLs shared in chat (max 4) * **`timezone`** - User's browser timezone (e.g., "America/New\_York") * **`api_keys`** - Custom API keys from user * **`workspace_options`** - Enabled feature flags (including custom ones) Requesting Widget Data[​](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#requesting-widget-data "Direct link to Requesting Widget Data") ---------------------------------------------------------------------------------------------------------------------------------------------------- Both `get_widget_data` and MCP tool calls are executed client-side. When you yield these function calls, the following sequence occurs: 1. **Agent sends tool call** - Your agent yields the function call (widget request or MCP tool) 2. **Connection closes** - The SSE stream is terminated, breaking the connection 3. **Frontend executes** - Workspace executes the requested tool call/widget request in the browser 4. **New request initiated** - Frontend sends a new POST `/query` request with the tool results 5. **Agent resumes** - Your agent receives a new `QueryRequest` with the execution results as a `tool` message This isn't a simple "pause" - it's a complete request/response cycle. Your agent must be stateless and handle being called multiple times. For a detailed sequence diagram of this flow, see the [OpenBB AI SDK repository](https://github.com/OpenBB-finance/openbb-ai#readme) . Example: from openbb_ai import WidgetRequest, message_chunk, reasoning_step, get_widget_datafrom openbb_ai.models import QueryRequest, ClientFunctionCallError, DataContentasync def query(request: QueryRequest): last_message = request.messages[-1] # Check if this is a tool response first is_tool_response = ( last_message and hasattr(last_message, "role") and last_message.role == "tool" and hasattr(last_message, "data") and last_message.data ) if is_tool_response: # Process widget data (Step 3) yield reasoning_step(event_type="INFO", message="Processing data...").model_dump() for item in last_message.data: if isinstance(item, DataContent): # Process the data and respond yield message_chunk("Here's what I found in the data...").model_dump() return # Check for orchestration requests orchestration_requested = ( last_message.role == "ai" and last_message.agent_id == "openbb-copilot" ) # Phase 1: Check if we need to fetch primary data (added to context) 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 widget data...").model_dump() yield get_widget_data(widget_requests).model_dump() return # EXIT AND WAIT # Phase 2: Process fetched data if hasattr(last_message, 'data'): yield reasoning_step(event_type="INFO", message="Processing data...").model_dump() for item in last_message.data: if isinstance(item, DataContent): # Process the data and respond yield message_chunk("Here's what I found in the data...").model_dump() Use `request.widgets.primary` for widgets the user selected in chat and `request.widgets.secondary` for widgets already on the dashboard (when the dashboard features are enabled). The SDK formats the tool call for you. Your only responsibility is to pause after yielding `get_widget_data` and handle the callback that arrives as a `tool` message. Streaming Responses[​](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#streaming-responses "Direct link to Streaming Responses") ------------------------------------------------------------------------------------------------------------------------------------------- The SDK provides several ways to stream content back to users: ### Text Streaming[​](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#text-streaming "Direct link to Text Streaming") from openbb_ai import message_chunk# Stream from LLM responseasync for event in await client.chat.completions.create( model="gpt-4o", messages=messages, stream=True,): if chunk := event.choices[0].delta.content: yield message_chunk(chunk).model_dump() ### Reasoning Steps[​](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#reasoning-steps "Direct link to Reasoning Steps") Show users what your agent is thinking: from openbb_ai import reasoning_step# Different event types for different statesyield reasoning_step(event_type="INFO", message="Analyzing market data").model_dump()yield reasoning_step(event_type="SUCCESS", message="Found 50 matching results").model_dump()yield reasoning_step(event_type="WARNING", message="Some data may be delayed").model_dump()yield reasoning_step(event_type="ERROR", message="Failed to fetch real-time data").model_dump()# Include additional detailsyield reasoning_step( event_type="SUCCESS", message="Data retrieved", details={"records": 1000, "timeframe": "1Y"}).model_dump() ### Tables[​](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#tables "Direct link to Tables") Create interactive data tables: from openbb_ai import tableyield table( data=[ {"Symbol": "AAPL", "Price": 150.25, "Change": "+2.5%"}, {"Symbol": "GOOGL", "Price": 2800.00, "Change": "-0.3%"}, {"Symbol": "MSFT", "Price": 380.50, "Change": "+1.2%"} ], name="Stock Prices", description="Current market prices").model_dump() ### Charts[​](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#charts "Direct link to Charts") Create visualizations with different chart types: from openbb_ai import chart# Line chart for time seriesyield chart( type="line", data=[ {"date": "2024-01-01", "price": 150.25}, {"date": "2024-01-02", "price": 151.30}, {"date": "2024-01-03", "price": 148.90} ], x_key="date", y_keys=["price"], name="Price History", description="Stock price over time").model_dump()# Bar chart for comparisonsyield 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() Supported chart types: `line`, `bar`, `scatter`, `pie`, `donut` Citations & Attribution[​](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#citations--attribution "Direct link to Citations & Attribution") ------------------------------------------------------------------------------------------------------------------------------------------------------ Always cite your data sources to maintain transparency: from openbb_ai import cite, citations# Create citations for widgets you usedcitation_list = []for widget in request.widgets.primary: citation_list.append( cite( widget=widget, input_arguments={ param.name: param.current_value for param in widget.params }, extra_details={"timeframe": "1D"} ) )# Send all citations at onceyield citations(citation_list).model_dump() Data Format Reference[​](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#data-format-reference "Direct link to Data Format Reference") ------------------------------------------------------------------------------------------------------------------------------------------------- Widget data can come in various formats: from openbb_ai.models import ( PdfDataFormat, ImageDataFormat, SpreadsheetDataFormat, RawObjectDataFormat, SingleDataContent, SingleFileReference)async def handle_widget_data(data: list[DataContent | DataFileReferences]): for result in data: for item in result.items: if isinstance(item.data_format, PdfDataFormat): # Handle PDF - use pdfplumber or similar if isinstance(item, SingleDataContent): pdf_bytes = base64.b64decode(item.content) elif isinstance(item, SingleFileReference): pdf_url = item.url elif isinstance(item.data_format, SpreadsheetDataFormat): # Handle Excel/CSV - use pandas df = pd.read_json(item.content) elif isinstance(item.data_format, ImageDataFormat): # Handle images - may need OCR image_data = base64.b64decode(item.content) else: # RawObjectDataFormat # Handle JSON/dict data data = json.loads(item.content) Complete Agent Example[​](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#complete-agent-example "Direct link to Complete Agent Example") ---------------------------------------------------------------------------------------------------------------------------------------------------- Here's a minimal but complete agent that demonstrates the key concepts: from openbb_ai import WidgetRequest, message_chunk, reasoning_step, cite, citations, table, get_widget_datafrom openbb_ai.models import QueryRequest, DataContent, ClientFunctionCallErrorimport jsonasync 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() Model Reference[​](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#model-reference "Direct link to Model Reference") ------------------------------------------------------------------------------------------------------------------------------- To see the available models check [https://github.com/OpenBB-finance/openbb-ai/blob/main/openbb\_ai/models.py](https://github.com/OpenBB-finance/openbb-ai/blob/main/openbb_ai/models.py) . On this page * [Building Your First Agent](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#building-your-first-agent) * [Understanding the QueryRequest](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#understanding-the-queryrequest) * [Requesting Widget Data](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#requesting-widget-data) * [Streaming Responses](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#streaming-responses) * [Text Streaming](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#text-streaming) * [Reasoning Steps](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#reasoning-steps) * [Tables](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#tables) * [Charts](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#charts) * [Citations & Attribution](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#citations--attribution) * [Data Format Reference](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#data-format-reference) * [Complete Agent Example](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#complete-agent-example) * [Model Reference](https://docs.openbb.co/workspace/developers/openbb-ai-sdk#model-reference) --- # Page Not Found | OpenBB Docs [Skip to main content](https://docs.openbb.co/404#__docusaurus_skipToContent_fallback) Page Not Found ============== We couldn't find what you were looking for. Please contact support@openbb.finance to report this broken link. [Go back to homepage](https://docs.openbb.co/) div> --- # Search the documentation | OpenBB Docs [Skip to main content](https://docs.openbb.co/search#__docusaurus_skipToContent_fallback) Search the documentation ======================== Powered by[](https://www.algolia.com/) --- # Markdown page example | OpenBB Docs [Skip to main content](https://docs.openbb.co/markdown-page#__docusaurus_skipToContent_fallback) You don't need React to write simple standalone pages. --- # OpenBB Docs [Skip to main content](https://docs.openbb.co/#__docusaurus_skipToContent_fallback) Build with OpenBB ================= Create powerful financial analysis applications with Workspace and the Open Data Platform. ![OpenBB Products](https://openbb-cms.directus.app/assets/0b402575-4034-4834-8a9d-b4f42fea9e0b.png) OpenBB Workspace ---------------- [### Get Started\ \ Build secure AI workflows with integrated data and customizable components.](https://docs.openbb.co/workspace) [### Enterprise\ \ Deploy within your infrastructure with complete data sovereignty](https://docs.openbb.co/workspace/getting-started/enterprise) [### Analysts\ \ Build interactive analysis tools with customizable widgets and components.](https://docs.openbb.co/workspace/analysts/widgets/overview) [### Developers\ \ Integrate custom data sources and APIs directly into your workspace.](https://docs.openbb.co/workspace/developers/data-integration) Open Data Platform ------------------ [### ODP Desktop\ \ Integrate any data source into AI applications and research dashboards.](https://docs.openbb.co/odp/desktop) [### ODP Python\ \ Build a unified API deployable across REST, Python, Jupyter, Excel, and more.](https://docs.openbb.co/odp/python) [### ODP CLI\ \ Automate data collection and interact with the platform from your terminal.](https://docs.openbb.co/odp/cli) --- # Apps.json Reference | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/json-specs/apps-json-reference#__docusaurus_skipToContent_fallback) On this page While it is expected for users to create their apps.json from the UI directly, as demonstrated in [Apps](https://docs.openbb.co/workspace/analysts/apps) . The `apps.json` file follows this structure: | Property | Type | Description | | --- | --- | --- | | `name` | string | The name of your app | | `description` | string | A detailed description of what your app does | | `img` | string | URL to the app's thumbnail image or base64 string | | `img_dark` | string | Optional URL to the app's thumbnail for dark mode or base64 string | | `img_light` | string | Optional URL to the app's thumbnail for light mode or base64 string | | `allowCustomization` | boolean | Whether users can customize the app | | `selected_agent` | string | Optional ID of the default AI agent for this app | | `authentication` | string | Optional authentication requirements | | `tabs` | object | Collection of tabs, each with an ID, name, and layout configuration | | `groups` | array | Defines synchronized parameter groups for widgets. | | `prompts` | array | A list of suggested prompts for the current agent. | Each tab contains: * `id`: Unique identifier for the tab * `name`: Display name for the tab * `layout`: Array of widget configurations with positioning and state Each group contains: * `name`: Display name for the group * `type`: Type of grouping (e.g., `param`, `endpointParam`). * `paramName`: The parameter being synchronized * `widgetIds`: Array of widget IDs in this group * `defaultValue`: Default value for the parameter Each prompt is a `string` that represents a question. For example: "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?"] Each layout contains a reference to a widget: * `i`: The id of the widget - This will be used to identify the widget in the app (if the widget endpoint is "test/widget\_1 the id will be test\_widget\_1") * `x`: The x position of the widget * `y`: The y position of the widget * `w`: The width of the widget * `h`: The height of the widget * `state`: The state of the widget ### Setting up the Apps endpoint[​](https://docs.openbb.co/workspace/developers/json-specs/apps-json-reference#setting-up-the-apps-endpoint "Direct link to Setting up the Apps endpoint") To serve custom apps, you need to define an endpoint in your FastAPI application that returns the content of your `apps.json` file. Here's how to define the `/apps.json` endpoint in your FastAPI application: from fastapi import FastAPIfrom fastapi.responses import JSONResponseapp = FastAPI()@app.get("/apps.json")async def get_apps(): # Load your apps.json file with open("path/to/your/apps.json", "r") as f: apps_config = json.load(f) return JSONResponse(content=apps_config) Your custom apps will appear in the OpenBB Workspace under the "Apps" tab in the "My Apps" section, as shown in here: ![OpenBB Workspace Multiple Applications View](https://openbb-cms.directus.app/assets/2fc9097e-0941-49df-8d83-7d6b5a87bb45.png) **Note**: The ideal image size is 250x200px Remember, the best part is that you can build your own apps tailored to your specific needs. Examples[​](https://docs.openbb.co/workspace/developers/json-specs/apps-json-reference#examples "Direct link to Examples") --------------------------------------------------------------------------------------------------------------------------- ### DTCC Trade Apps[​](https://docs.openbb.co/workspace/developers/json-specs/apps-json-reference#dtcc-trade-apps "Direct link to DTCC Trade Apps") DTCC Trade App Example [ { "name": "DTCC Swaps Trade Repository", "img": "https://media.licdn.com/dms/image/v2/C4D12AQG0nFj-PESmJg/article-cover_image-shrink_600_2000/article-cover_image-shrink_600_2000/0/1632343844606?e=2147483647&v=beta&t=M9BQQUK_UbW2fIIPNAs_kZ8iVCI1IKqjU3cKcOpbMG4", "img_dark": "", "img_light": "", "description": "A demonstration application utilizing data from the DTCC Trade Repository.", "allowCustomization": true, "tabs": { "": { "id": "", "name": "", "layout": [ { "i": "swap_rate_levels_custom_obb", "x": 0, "y": 0, "w": 20, "h": 11, "state": { "params": { "tenor": [ "2s10s", "1s5s" ] }, "chartView": { "enabled": true, "chartType": "line" }, "chartModel": { "modelType": "range", "chartType": "line", "chartOptions": { "theme": { "baseTheme": "ag-default-dark", "overrides": { "pie": { "series": { "calloutLabel": { }, "sectorLabel": { "enabled": true } } }, "donut": { "series": { "calloutLabel": { }, "sectorLabel": { "enabled": true } } }, "scatter": { "axes": { "number": { "title": { "fontSize": 11, "spacing": 10, "enabled": true, "text": "" } } } }, "common": { "axes": { "number": { "label": { } }, "angle-number": { "label": { } }, "radius-number": { "label": { } } }, "padding": { "top": 20, "bottom": 5, "left": 20, "right": 40 }, "background": { "visible": false }, "zoom": { "enabled": true, "anchorPointX": "pointer", "anchorPointY": "pointer", "minVisibleItems": 4, "autoScaling": { "enabled": true } }, "legend": { "position": "top", "maxHeight": 50, "spacing": 20, "item": { "paddingX": 32, "paddingY": 8, "marker": { "shape": "square", "padding": 5, "size": 11 }, "label": { "color": "#fff", "fontSize": 11 } } }, "title": { "fontSize": 12 } } } }, "common": { "axes": { "category": { "type": "category", "label": { "avoidCollisions": true, "fontSize": 11, "minSpacing": 5, "autoRotate": true }, "position": "bottom" }, "radius-category": { "type": "category", "label": { "avoidCollisions": true, "fontSize": 11, "minSpacing": 5 } }, "angle-category": { "type": "category", "label": { "avoidCollisions": true, "fontSize": 11, "minSpacing": 5 } }, "grouped-category": { "type": "category", "label": { "avoidCollisions": true, "fontSize": 11, "minSpacing": 5 } }, "number": { "type": "number", "position": "left", "crosshair": { "label": { } }, "label": { "fontSize": 11, "autoRotate": false, "avoidCollisions": true } }, "time": { "type": "time", "position": "bottom", "label": { "avoidCollisions": true, "fontSize": 11, "rotation": 0 } } }, "legend": { "position": "top", "maxHeight": 50, "spacing": 20, "item": { "paddingX": 32, "paddingY": 8, "marker": { "shape": "square", "padding": 5, "size": 11 }, "label": { "color": "#fff", "fontSize": 11 } } } }, "line": { "series": { "marker": { "enabled": false }, "connectMissingData": true, "label": { "enabled": false }, "tooltip": { "enabled": true } }, "legend": { "enabled": true, "position": "bottom", "item": { "marker": { "size": 10 }, "paddingX": 10, "paddingY": 10 } }, "title": { "enabled": true, "text": "Interest Rate Levels (%)" } }, "pie": { "series": { "tooltip": { "enabled": true }, "calloutLabel": { "enabled": true }, "sectorLabel": { "enabled": true } } }, "donut": { "series": { "tooltip": { "enabled": true }, "calloutLabel": { "enabled": true }, "sectorLabel": { "enabled": true } } }, "area": { "series": { "marker": { "enabled": false }, "label": { "enabled": false }, "tooltip": { "enabled": true } } }, "bubble": { "series": { "marker": { "enabled": false }, "label": { "enabled": false }, "tooltip": { "enabled": true } } }, "histogram": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "bar": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false, "placement": "outside-end" } } }, "scatter": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false, "placement": "top" } } }, "treemap": { "series": { "group": { "label": { "enabled": true } }, "tile": { "label": { "enabled": true } }, "tooltip": { "enabled": true } }, "padding": { "bottom": 10 } }, "sunburst": { "series": { "tooltip": { "enabled": true, "position": { "type": "pointer" }, "interaction": { "enabled": true } }, "label": { "enabled": true } }, "padding": { "bottom": 10 } }, "heatmap": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": true } }, "padding": { "bottom": 10 } }, "waterfall": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false, "placement": "inside" } } }, "radar-line": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "radar-area": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "radial-bar": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "radial-column": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "nightingale": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } } }, "cellRange": { "columns": [ "date", "ois_one_year_five_year_spread", "ois_two_year_ten_year_spread" ] }, "suppressChartRanges": true }, "columnState": { "default_undefined": { "version": "33.2.1", "sort": { "sortModel": [ { "colId": "date", "sort": "asc" } ] }, "columnPinning": { "leftColIds": [ "date" ], "rightColIds": [] } } } } }, { "i": "swap_rate_volume_custom_obb", "x": 20, "y": 0, "w": 19, "h": 11, "state": { "params": { "bucket": [] }, "chartView": { "enabled": true, "chartType": "line" }, "chartModel": { "modelType": "range", "chartType": "customCombo", "chartOptions": { "theme": { "baseTheme": "ag-default-dark", "overrides": { "pie": { "series": { "calloutLabel": { }, "sectorLabel": { "enabled": true } } }, "donut": { "series": { "calloutLabel": { }, "sectorLabel": { "enabled": true } } }, "scatter": { "axes": { "number": { "title": { "fontSize": 11, "spacing": 10, "enabled": true, "text": "" } } } }, "common": { "axes": { "number": { "label": { } }, "angle-number": { "label": { } }, "radius-number": { "label": { } } }, "padding": { "top": 20, "bottom": 5, "left": 20, "right": 40 }, "background": { "visible": false }, "zoom": { "enabled": true, "anchorPointX": "pointer", "anchorPointY": "pointer", "minVisibleItems": 4, "autoScaling": { "enabled": true } }, "legend": { "position": "top", "maxHeight": 50, "spacing": 20, "item": { "paddingX": 32, "paddingY": 8, "marker": { "shape": "square", "padding": 5, "size": 11 }, "label": { "color": "#fff", "fontSize": 11 } } }, "title": { "fontSize": 12 } } } }, "common": { "axes": { "category": { "type": "category", "label": { "avoidCollisions": true, "fontSize": 11, "minSpacing": 5, "autoRotate": true }, "position": "bottom" }, "radius-category": { "type": "category", "label": { "avoidCollisions": true, "fontSize": 11, "minSpacing": 5 } }, "angle-category": { "type": "category", "label": { "avoidCollisions": true, "fontSize": 11, "minSpacing": 5 } }, "grouped-category": { "type": "category", "label": { "avoidCollisions": true, "fontSize": 11, "minSpacing": 5 } }, "number": { "type": "number", "position": "left", "crosshair": { "label": { } }, "label": { "fontSize": 11, "autoRotate": false, "avoidCollisions": true } }, "time": { "type": "time", "position": "bottom", "label": { "avoidCollisions": true, "fontSize": 11, "rotation": 0 } } }, "legend": { "position": "bottom", "maxHeight": 50, "spacing": 10, "item": { "paddingX": 18, "paddingY": 5, "marker": { "shape": "square", "padding": 5, "size": 10 }, "label": { "color": "#fff", "fontSize": 11 } } }, "title": { "enabled": true, "text": "Notional Trading Volumes ($)" } }, "line": { "series": { "label": { "enabled": false }, "tooltip": { "enabled": true }, "strokeOpacity": 0.7, "marker": { "enabled": false }, "lineDash": [0], "strokeWidth": 2 }, "legend": { "position": "bottom", "item": { "marker": { "size": 10, "padding": 5 }, "paddingX": 18, "paddingY": 5 }, "spacing": 10 }, "title": { "enabled": true, "text": "Notional Trading Volumes ($)" } }, "pie": { "series": { "tooltip": { "enabled": true }, "calloutLabel": { "enabled": true }, "sectorLabel": { "enabled": true } } }, "donut": { "series": { "tooltip": { "enabled": true }, "calloutLabel": { "enabled": true }, "sectorLabel": { "enabled": true } } }, "area": { "series": { "label": { "enabled": false }, "tooltip": { "enabled": true } }, "legend": { "position": "bottom", "item": { "marker": { "size": 10, "padding": 5 }, "paddingX": 18, "paddingY": 5 }, "spacing": 10 }, "title": { "enabled": true, "text": "Notional Trading Volumes ($)" } }, "bubble": { "series": { "label": { "enabled": false }, "tooltip": { "enabled": true } } }, "histogram": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "bar": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false, "placement": "outside-end" } }, "legend": { "position": "bottom", "item": { "marker": { "size": 10, "padding": 5 }, "paddingX": 18, "paddingY": 5 }, "spacing": 10 }, "title": { "enabled": true, "text": "Notional Trading Volumes ($)" } }, "scatter": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false, "placement": "top" } } }, "treemap": { "series": { "group": { "label": { "enabled": true } }, "tile": { "label": { "enabled": true } }, "tooltip": { "enabled": true } }, "padding": { "bottom": 10 } }, "sunburst": { "series": { "tooltip": { "enabled": true, "position": { "type": "pointer" }, "interaction": { "enabled": true } }, "label": { "enabled": true } }, "padding": { "bottom": 10 } }, "heatmap": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": true } }, "padding": { "bottom": 10 } }, "waterfall": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false, "placement": "inside" } } }, "radar-line": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "radar-area": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "radial-bar": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "radial-column": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "nightingale": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } } }, "cellRange": { "columns": [ "date", "libor_volume", "ois_volume", "total_5d_ma_volume" ] }, "suppressChartRanges": true, "seriesChartTypes": [ { "colId": "libor_volume", "chartType": "groupedColumn", "secondaryAxis": false }, { "colId": "ois_volume", "chartType": "groupedColumn", "secondaryAxis": false }, { "colId": "total_5d_ma_volume", "chartType": "line", "secondaryAxis": false } ] }, "columnState": { "default_undefined": { "version": "33.2.1", "cellSelection": { "cellRanges": [ { "startRow": { "rowIndex": 0, "rowPinned": null }, "endRow": { "rowIndex": 0, "rowPinned": null }, "colIds": [ "libor_volume" ], "startColId": "libor_volume" } ] }, "columnPinning": { "leftColIds": [ "date" ], "rightColIds": [] }, "focusedCell": { "colId": "libor_volume", "rowIndex": 0, "rowPinned": null }, "rangeSelection": { "cellRanges": [ { "startRow": { "rowIndex": 0, "rowPinned": null }, "endRow": { "rowIndex": 0, "rowPinned": null }, "colIds": [ "libor_volume" ], "startColId": "libor_volume" } ] } } } } }, { "i": "trade_distribution_custom_obb", "x": 0, "y": 11, "w": 20, "h": 14, "state": { "params": { "swap_type": "OIS" }, "chartView": { "enabled": true, "chartType": "line" }, "chartModel": { "modelType": "range", "chartType": "groupedColumn", "chartOptions": { "theme": { "baseTheme": "ag-default-dark", "overrides": { "pie": { "series": { "calloutLabel": { }, "sectorLabel": { "enabled": true } } }, "donut": { "series": { "calloutLabel": { }, "sectorLabel": { "enabled": true } } }, "scatter": { "axes": { "number": { "title": { "fontSize": 11, "spacing": 10, "enabled": true, "text": "" } } } }, "common": { "axes": { "number": { "label": { } }, "angle-number": { "label": { } }, "radius-number": { "label": { } } }, "padding": { "top": 20, "bottom": 5, "left": 20, "right": 40 }, "background": { "visible": false }, "zoom": { "enabled": true, "anchorPointX": "pointer", "anchorPointY": "pointer", "minVisibleItems": 4, "autoScaling": { "enabled": true } }, "legend": { "position": "top", "maxHeight": 50, "spacing": 20, "item": { "paddingX": 32, "paddingY": 8, "marker": { "shape": "square", "padding": 5, "size": 11 }, "label": { "color": "#fff", "fontSize": 11 } } }, "title": { "fontSize": 12 } } } }, "common": { "axes": { "category": { "type": "category", "label": { "avoidCollisions": true, "fontSize": 11, "minSpacing": 5, "autoRotate": true }, "position": "bottom" }, "radius-category": { "type": "category", "label": { "avoidCollisions": true, "fontSize": 11, "minSpacing": 5 } }, "angle-category": { "type": "category", "label": { "avoidCollisions": true, "fontSize": 11, "minSpacing": 5 } }, "grouped-category": { "type": "category", "label": { "avoidCollisions": true, "fontSize": 11, "minSpacing": 5 } }, "number": { "type": "number", "position": "left", "crosshair": { "label": { } }, "label": { "fontSize": 11, "autoRotate": false, "avoidCollisions": true } }, "time": { "type": "time", "position": "bottom", "label": { "avoidCollisions": true, "fontSize": 11, "rotation": 0 } } }, "legend": { "position": "top", "maxHeight": 50, "spacing": 20, "item": { "paddingX": 32, "paddingY": 8, "marker": { "shape": "square", "padding": 5, "size": 11 }, "label": { "color": "#fff", "fontSize": 11 } } } }, "line": { "series": { "label": { "enabled": false }, "tooltip": { "enabled": true } } }, "pie": { "series": { "tooltip": { "enabled": true }, "calloutLabel": { "enabled": true }, "sectorLabel": { "enabled": true } } }, "donut": { "series": { "tooltip": { "enabled": true }, "calloutLabel": { "enabled": true }, "sectorLabel": { "enabled": true } } }, "area": { "series": { "label": { "enabled": false }, "tooltip": { "enabled": true } } }, "bubble": { "series": { "label": { "enabled": false }, "tooltip": { "enabled": true } } }, "histogram": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "bar": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false, "placement": "outside-end" } }, "title": { "enabled": true, "text": "Distribution Of Trades On Date ($)" } }, "scatter": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false, "placement": "top" } } }, "treemap": { "series": { "group": { "label": { "enabled": true } }, "tile": { "label": { "enabled": true } }, "tooltip": { "enabled": true } }, "padding": { "bottom": 10 } }, "sunburst": { "series": { "tooltip": { "enabled": true, "position": { "type": "pointer" }, "interaction": { "enabled": true } }, "label": { "enabled": true } }, "padding": { "bottom": 10 } }, "heatmap": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": true } }, "padding": { "bottom": 10 } }, "waterfall": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false, "placement": "inside" } } }, "radar-line": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "radar-area": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "radial-bar": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "radial-column": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "nightingale": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } } }, "cellRange": { "columns": [ "one_to_three_year", "three_to_four_year", "four_to_five_year", "five_to_seven_year", "seven_to_ten_year", "ten_to_fifteen_year", "fifteen_to_twenty_year" ] }, "switchCategorySeries": true, "suppressChartRanges": true }, "columnState": { "default_undefined": { "version": "33.2.1" } } } }, { "i": "swap_trades_custom_obb", "x": 20, "y": 11, "w": 19, "h": 14, "state": { "params": { "cleared_only": "false", "include_starting": "false" }, "chartView": { "enabled": true, "chartType": "line" }, "chartModel": { "modelType": "range", "chartType": "line", "chartOptions": { "bubble": { "legend": { "enabled": true }, "series": { "label": { "enabled": false }, "tooltip": { "enabled": true }, "marker": { "enabled": true, "size": 17 } }, "paired": true }, "line": { "legend": { "enabled": true, "position": "bottom", "item": { "marker": { "size": 10, "padding": 2 }, "paddingX": 10 }, "spacing": 21 }, "series": { "label": { "enabled": false }, "tooltip": { "enabled": true }, "marker": { "enabled": true, "size": 13 }, "strokeWidth": 0, "connectMissingData": true, "strokeOpacity": 1 }, "padding": { "top": 16, "right": 20, "bottom": 9, "left": 9 }, "axes": { "category": { "bottom": { "label": { "spacing": 9 } }, "top": { "label": { "spacing": 9 } } }, "number": { "bottom": { "gridLine": { "enabled": false }, "tick": { "enabled": true, "size": 5, "width": 2 }, "label": { "spacing": 7 }, "title": { "enabled": false, "text": "Time To Maturity" } }, "top": { "gridLine": { "enabled": false }, "tick": { "enabled": true, "size": 5, "width": 2 }, "label": { "spacing": 7 }, "title": { "enabled": false, "text": "Time To Maturity" } }, "left": { "title": { "enabled": false, "text": "Interest Rate (%)", "spacing": 11 } }, "right": { "title": { "enabled": false, "text": "Interest Rate (%)", "spacing": 11 } } } }, "title": { "enabled": true, "text": "Swaps Traded On Date (%)", "spacing": 20 } }, "theme": { "baseTheme": "ag-default-dark", "overrides": { "pie": { "series": { "calloutLabel": { }, "sectorLabel": { "enabled": true } } }, "donut": { "series": { "calloutLabel": { }, "sectorLabel": { "enabled": true } } }, "scatter": { "axes": { "number": { "title": { "fontSize": 11, "spacing": 10, "enabled": true, "text": "" } } } }, "common": { "axes": { "number": { "label": { } }, "angle-number": { "label": { } }, "radius-number": { "label": { } } }, "padding": { "top": 20, "bottom": 5, "left": 20, "right": 40 }, "background": { "visible": false }, "zoom": { "enabled": true, "anchorPointX": "pointer", "anchorPointY": "pointer", "minVisibleItems": 4, "autoScaling": { "enabled": true } }, "legend": { "position": "top", "maxHeight": 50, "spacing": 20, "item": { "paddingX": 32, "paddingY": 8, "marker": { "shape": "square", "padding": 5, "size": 11 }, "label": { "color": "#fff", "fontSize": 11 } } }, "title": { "fontSize": 12 } } } }, "common": { "axes": { "category": { "type": "category", "label": { "avoidCollisions": true, "fontSize": 11, "minSpacing": 5, "autoRotate": true }, "position": "bottom" }, "radius-category": { "type": "category", "label": { "avoidCollisions": true, "fontSize": 11, "minSpacing": 5 } }, "angle-category": { "type": "category", "label": { "avoidCollisions": true, "fontSize": 11, "minSpacing": 5 } }, "grouped-category": { "type": "category", "label": { "avoidCollisions": true, "fontSize": 11, "minSpacing": 5 } }, "number": { "type": "number", "position": "left", "crosshair": { "label": { } }, "label": { "fontSize": 11, "autoRotate": false, "avoidCollisions": true } }, "time": { "type": "time", "position": "bottom", "label": { "avoidCollisions": true, "fontSize": 11, "rotation": 0 } } }, "legend": { "position": "top", "maxHeight": 50, "spacing": 20, "item": { "paddingX": 32, "paddingY": 8, "marker": { "shape": "square", "padding": 5, "size": 11 }, "label": { "color": "#fff", "fontSize": 11 } } } }, "pie": { "series": { "tooltip": { "enabled": true }, "calloutLabel": { "enabled": true }, "sectorLabel": { "enabled": true } } }, "donut": { "series": { "tooltip": { "enabled": true }, "calloutLabel": { "enabled": true }, "sectorLabel": { "enabled": true } } }, "area": { "series": { "label": { "enabled": false }, "tooltip": { "enabled": true }, "marker": { "enabled": true, "size": 17 } } }, "histogram": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "bar": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false, "placement": "outside-end" } } }, "scatter": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false, "placement": "top" } } }, "treemap": { "series": { "group": { "label": { "enabled": true } }, "tile": { "label": { "enabled": true } }, "tooltip": { "enabled": true } }, "padding": { "bottom": 10 } }, "sunburst": { "series": { "tooltip": { "enabled": true, "position": { "type": "pointer" }, "interaction": { "enabled": true } }, "label": { "enabled": true } }, "padding": { "bottom": 10 } }, "heatmap": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": true } }, "padding": { "bottom": 10 } }, "waterfall": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false, "placement": "inside" } } }, "radar-line": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "radar-area": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "radial-bar": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "radial-column": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } }, "nightingale": { "series": { "tooltip": { "enabled": true }, "label": { "enabled": false } } } }, "cellRange": { "columns": [ "tenor", "pricing_rate", "cleared_and_spot_starting", "uncleared_and_forward_starting" ] }, "suppressChartRanges": true }, "columnState": { "default_undefined": { "version": "33.2.1" } } } } ] } }, "groups": [ { "name": "Group 1", "type": "param", "paramName": "period", "defaultValue": "1y", "widgetIds": [ "swap_rate_levels_custom_obb", "swap_rate_volume_custom_obb" ] }, { "name": "Group 2", "type": "param", "paramName": "currency", "defaultValue": "USD", "widgetIds": [ "swap_rate_levels_custom_obb", "swap_rate_volume_custom_obb", "trade_distribution_custom_obb", "swap_trades_custom_obb" ] }, { "name": "Group 3", "type": "param", "paramName": "swap_type", "defaultValue": "OIS", "widgetIds": [ "swap_rate_levels_custom_obb", "trade_distribution_custom_obb" ] }, { "name": "Group 4", "type": "param", "paramName": "stat", "defaultValue": "Notional", "widgetIds": [ "swap_rate_volume_custom_obb", "trade_distribution_custom_obb" ] } ], "prompts": [ "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?" ] }] ### FRED[​](https://docs.openbb.co/workspace/developers/json-specs/apps-json-reference#fred "Direct link to FRED") FRED App Example { "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?" ]} ### FED Net Liquidity[​](https://docs.openbb.co/workspace/developers/json-specs/apps-json-reference#fed-net-liquidity "Direct link to FED Net Liquidity") FED Net Liquidity App Example [ { "name": "Fed Net Liquidity", "img": "https://static.vecteezy.com/system/resources/thumbnails/027/221/813/small_2x/fed-text-in-wooden-circle-on-banknotes-background-credit-card-piggybank-calculator-federal-reserve-board-system-federal-reserve-interest-rate-hike-global-economy-recession-and-finance-concept-photo.jpg", "img_dark": "https://static.vecteezy.com/system/resources/thumbnails/027/221/813/small_2x/fed-text-in-wooden-circle-on-banknotes-background-credit-card-piggybank-calculator-federal-reserve-board-system-federal-reserve-interest-rate-hike-global-economy-recession-and-finance-concept-photo.jpg", "img_light": "https://static.vecteezy.com/system/resources/thumbnails/027/221/813/small_2x/fed-text-in-wooden-circle-on-banknotes-background-credit-card-piggybank-calculator-federal-reserve-board-system-federal-reserve-interest-rate-hike-global-economy-recession-and-finance-concept-photo.jpg", "description": "Data curated by @dharmatrade", "allowCustomization": true, "tabs": { "fed-net-liquidity": { "id": "fed-net-liquidity", "name": "FED Net Liquidity", "layout": [ { "i": "fed-net-liquidity", "x": 0, "y": 17, "w": 40, "h": 15 }, { "i": "fed-net-liquidity-all", "x": 0, "y": 32, "w": 40, "h": 15 }, { "i": "fed-net-liquidity-data", "x": 0, "y": 2, "w": 40, "h": 15, "state": { "chartView": { "enabled": false, "chartType": "line" } } } ] }, "mts-income-taxes": { "id": "mts-income-taxes", "name": "MTS Income Taxes", "layout": [ { "i": "mts-income-taxes-current-vs-prior", "x": 0, "y": 2, "w": 40, "h": 15 }, { "i": "mts-income-taxes-monthly-by-year", "x": 0, "y": 17, "w": 40, "h": 15 }, { "i": "mts-income-taxes-yoy-comparison", "x": 0, "y": 32, "w": 40, "h": 15 }, { "i": "mts-income-taxes-fytd", "x": 0, "y": 47, "w": 40, "h": 15 }, { "i": "mts-income-taxes-monthly", "x": 0, "y": 62, "w": 40, "h": 15 } ] }, "fed-balance-sheet": { "id": "fed-balance-sheet", "name": "FED Balance Sheet", "layout": [ { "i": "fed-balance-sheet", "x": 0, "y": 2, "w": 40, "h": 15 }, { "i": "fed-balance-sheet-weekly", "x": 0, "y": 17, "w": 40, "h": 19 } ] } }, "groups": [], "prompts": [ "What is the current Fed Net Liquidity?", "Show me the weekly changes in the Fed's balance sheet.", "What are the year-over-year changes in MTS income taxes?", "Display the monthly income tax receipts for the current fiscal year.", "How has the Fed's balance sheet evolved over the last year?" ] }] On this page * [Setting up the Apps endpoint](https://docs.openbb.co/workspace/developers/json-specs/apps-json-reference#setting-up-the-apps-endpoint) * [Examples](https://docs.openbb.co/workspace/developers/json-specs/apps-json-reference#examples) * [DTCC Trade Apps](https://docs.openbb.co/workspace/developers/json-specs/apps-json-reference#dtcc-trade-apps) * [FRED](https://docs.openbb.co/workspace/developers/json-specs/apps-json-reference#fred) * [FED Net Liquidity](https://docs.openbb.co/workspace/developers/json-specs/apps-json-reference#fed-net-liquidity) --- # Getting Started | OpenBB Add-in for Excel Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/excel-addin/excel-installation#__docusaurus_skipToContent_fallback) On this page Requirements[​](https://docs.openbb.co/workspace/analysts/excel-addin/excel-installation#requirements "Direct link to Requirements") ------------------------------------------------------------------------------------------------------------------------------------- * The OpenBB Add-in for Excel is available on the following platforms: Windows (Microsoft 365), Mac (Microsoft 365), Excel on the web. * Access to OpenBB Workspace. If you don't have access you can sign up [here](https://my.openbb.co/app/pro) . Installation[​](https://docs.openbb.co/workspace/analysts/excel-addin/excel-installation#installation "Direct link to Installation") ------------------------------------------------------------------------------------------------------------------------------------- The OpenBB Add-in for Excel is available on the [Microsoft AppSource](https://appsource.microsoft.com/product/office/wa200006381?tab=overview) . It can be installed by an administrator or by individual users. ### Individual user[​](https://docs.openbb.co/workspace/analysts/excel-addin/excel-installation#individual-user "Direct link to Individual user") 1. Open Microsoft Excel. 2. Go to **Home** tab. 3. Click in the **Add-ins** button and then **More add-ins**. 4. In the **Office Add-ins** dialog box **STORE** tab, search for **OpenBB** and select the add-in. 5. Click **Add**. ### Administrator[​](https://docs.openbb.co/workspace/analysts/excel-addin/excel-installation#administrator "Direct link to Administrator") 1. Go to Microsoft 365 admin center. 2. Click **Settings** > **Integrated apps**. 3. Click **Get apps**. 4. Search for **OpenBB** and select the add-in. 5. Click **Get in now**. 6. Go through the deployment wizard to complete the installation. On this page * [Requirements](https://docs.openbb.co/workspace/analysts/excel-addin/excel-installation#requirements) * [Installation](https://docs.openbb.co/workspace/analysts/excel-addin/excel-installation#installation) * [Individual user](https://docs.openbb.co/workspace/analysts/excel-addin/excel-installation#individual-user) * [Administrator](https://docs.openbb.co/workspace/analysts/excel-addin/excel-installation#administrator) --- # OBB.WIDGET | OpenBB Add-in for Excel Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/excel-addin/obb-widget#__docusaurus_skipToContent_fallback) On this page This is the most important formula that is available, as it allows you to access any dataset available from the OpenBB workspace. info * Make sure your backend's CORS settings allow requests coming from [https://excel.openbb.co](https://excel.openbb.co/) . * Requests via HTTP will be blocked by Excel. So if you are using the Add-in for Excel on Mac or Office on the web with Safari browser you need to run your backend via HTTPS. It has the following format: =OBB.WIDGET(, or , ) Where parameters, shows up as `{"param1","value1";"param2","value2"; ...}`. Here are a few examples: =OBB.WIDGET("DTCC Trades","swap_rate_levels_custom_obb",{"currency","USD";"swap_type","OIS";"period","1y"}) =OBB.WIDGET("DTCC Trades","Swap Trades",{"currency","USD";"date","2025-04-15";"cleared_only","true";"include_starting","false"}) =OBB.WIDGET("OpenBB Platform","economy_pce_fred_obb",{"category","personal_income";"provider","fred"}) =OBB.WIDGET("Custom Backend","Portugal CPI since 2000") ### Explicit parameters[​](https://docs.openbb.co/workspace/analysts/excel-addin/obb-widget#explicit-parameters "Direct link to Explicit parameters") The easiest way to pass optional parameters is to write them into cells and reference them in the function. For example, =OBB.WIDGET("DTCC Trades","swap_rate_levels_custom_obb",{"currency","USD";"swap_type","OIS";"period","1y"}) can be rewritten as: =OBB.WIDGET("DTCC Trades","swap_rate_levels_custom_obb",A1:B3) where: * A1 contains "currency" and B1 "USD" * A2 contains "swap\_type" and B2 "OIS" * A3 contains "period" and B3 "1y" On this page * [Explicit parameters](https://docs.openbb.co/workspace/analysts/excel-addin/obb-widget#explicit-parameters) --- # OpenBB Add-in for Excel Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/excel-addin/excel-overview#__docusaurus_skipToContent_fallback) On this page The OpenBB Add-in for Excel enables enterprise users to access all available data from their OpenBB Workspace through interactive widgets. OpenBB Widgets[​](https://docs.openbb.co/workspace/analysts/excel-addin/excel-overview#openbb-widgets "Direct link to OpenBB Widgets") --------------------------------------------------------------------------------------------------------------------------------------- Enterprise users with access to the OpenBB Add-in for Excel can utilize the **Excel formula** option in their widget settings to access widget data directly in Excel. ![Excel formula dropdown in widget settings](https://openbb-cms.directus.app/assets/cf39abef-9a93-42fa-b98f-d1e7a2e38c77.png) ### Dynamic Widgets with Implicit Parameters[​](https://docs.openbb.co/workspace/analysts/excel-addin/excel-overview#dynamic-widgets-with-implicit-parameters "Direct link to Dynamic Widgets with Implicit Parameters") When accessing the **Excel formula** dropdown, users will see the following interface: ![Excel formula interface](https://openbb-cms.directus.app/assets/fd7f2baf-edd3-48b9-a3d8-6bc3f33c0c68.png) The interface displays the widget name, backend information, and the corresponding Excel formula. For example: =OBB.WIDGET("DTCC Trades","swap_rate_levels_custom_obb",{"currency","USD";"swap_type","OIS";"period","1y"}) Note: The formula is displayed with indentation for better readability, but when copied to the clipboard, it will be formatted as a single line for Excel compatibility. Here's how it appears in Excel: ![Excel formula implementation](https://openbb-cms.directus.app/assets/7478fdf5-de07-472b-993f-45bfbef4b1e2.png) ### Dynamic Widgets with Explicit Parameters[​](https://docs.openbb.co/workspace/analysts/excel-addin/excel-overview#dynamic-widgets-with-explicit-parameters "Direct link to Dynamic Widgets with Explicit Parameters") Users can enable an alternative mode by selecting the "with explicit parameters" checkbox. This mode separates the parameters from the formula, creating a more flexible widget-like experience in Excel. ![Explicit parameters interface](https://openbb-cms.directus.app/assets/22ce67c6-efec-4021-886d-0452891a2af9.png) Implementation example: ![Explicit parameters in Excel](https://openbb-cms.directus.app/assets/aa48622e-a634-4565-a5e4-03ee0cfd5a3a.png) Note: The formula and parameters are initially set to cell A1, but users can modify the formula parameters to reference different cell ranges based on their specific needs. Dashboard to Excel Export[​](https://docs.openbb.co/workspace/analysts/excel-addin/excel-overview#dashboard-to-excel-export "Direct link to Dashboard to Excel Export") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Users can export entire dashboard data to Excel using the left sidebar export functionality. ![Dashboard export options](https://openbb-cms.directus.app/assets/6bf99ebf-7c9e-4a3a-b83b-ee5b466ffd9c.png) Three export options are available: ![Export options menu](https://openbb-cms.directus.app/assets/eb099308-327b-4bb5-8e5c-1e9d45534512.png) The first worksheet of the exported Excel file contains comprehensive dashboard information: ![Dashboard information in Excel](https://openbb-cms.directus.app/assets/c4f4973d-5f8e-411c-a238-370eb0f45ea9.png) This includes: * Widget metadata * Parameter configurations * Dashboard name * Export timestamp ### Static Data Export[​](https://docs.openbb.co/workspace/analysts/excel-addin/excel-overview#static-data-export "Direct link to Static Data Export") When exporting in static data mode, a progress dialog appears to indicate the export status: ![Static data export progress](https://openbb-cms.directus.app/assets/db4784db-630e-458c-b60e-699a4444e054.png) Each OpenBB widget is exported to a separate worksheet, containing both the parameters used and the corresponding data: ![Widget data in Excel](https://openbb-cms.directus.app/assets/a9864e6d-16cc-468f-8045-4e3b1689d6c4.png) ### Dynamic Export[​](https://docs.openbb.co/workspace/analysts/excel-addin/excel-overview#dynamic-export "Direct link to Dynamic Export") For dynamic exports (both implicit and explicit parameter modes), the exported Excel file will utilize the OpenBB Add-in formulas as described in the previous sections. On this page * [OpenBB Widgets](https://docs.openbb.co/workspace/analysts/excel-addin/excel-overview#openbb-widgets) * [Dynamic Widgets with Implicit Parameters](https://docs.openbb.co/workspace/analysts/excel-addin/excel-overview#dynamic-widgets-with-implicit-parameters) * [Dynamic Widgets with Explicit Parameters](https://docs.openbb.co/workspace/analysts/excel-addin/excel-overview#dynamic-widgets-with-explicit-parameters) * [Dashboard to Excel Export](https://docs.openbb.co/workspace/analysts/excel-addin/excel-overview#dashboard-to-excel-export) * [Static Data Export](https://docs.openbb.co/workspace/analysts/excel-addin/excel-overview#static-data-export) * [Dynamic Export](https://docs.openbb.co/workspace/analysts/excel-addin/excel-overview#dynamic-export) --- # OBB.GET | OpenBB Add-in for Excel Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#__docusaurus_skipToContent_fallback) On this page The `OBB.GET` function is a powerful data extraction tool that allows you to precisely slice and extract specific portions of data from any array or range in Excel. It's particularly useful when working with data returned by other OpenBB functions, enabling you to focus on exactly the information you need. Key Features[​](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#key-features "Direct link to Key Features") -------------------------------------------------------------------------------------------------------------------------- * Extract specific rows, columns, or both from any data range * Use either labels (like dates or column names) or numeric indices * Support for single values, ranges, and arrays * Negative indexing for accessing data from the end * Flexible input formats for dates and text Syntax[​](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#syntax "Direct link to Syntax") -------------------------------------------------------------------------------------------------------- =OBB.GET(array, [rows], [columns]) ### Parameters[​](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#parameters "Direct link to Parameters") | Parameter | Type | Description | Required | Examples | | --- | --- | --- | --- | --- | | array | Any | The source data range to slice. This can be any array, including results from other OBB functions. | Yes | `A1:D3`, `OBB.WIDGET(...)` | | rows | Any | Row selection using labels or indices. Can be a single value, range, or array. | No | `"2023/09/30"`, `2`, `{1,3}`, `-1` | | columns | Any | Column selection using labels or indices. Can be a single value, range, or array. | No | `"revenue"`, `3`, `{"A","C"}` | ### Return Value[​](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#return-value "Direct link to Return Value") Returns a subset of the input array based on the specified row and column selections. The return type matches the input data type. Examples[​](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#examples "Direct link to Examples") -------------------------------------------------------------------------------------------------------------- Suppose you have the following financial data in cells A1:D3: | period\_ending | revenue | cost\_of\_revenue | gross\_profit | | --- | --- | --- | --- | | 2023/09/30 | 383 285 000 000.00 | 214 137 000 000.00 | 169 148 000 000.00 | | 2022/09/24 | 394 328 000 000.00 | 223 546 000 000.00 | 170 782 000 000.00 | | 2021/09/25 | 365 817 000 000.00 | 212 981 000 000.00 | 152 836 000 000.00 | ### Common Use Cases[​](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#common-use-cases "Direct link to Common Use Cases") 1. **Get a Single Row by Date** =OBB.GET(A1:D3, "2023/09/30") Returns the entire row for September 30, 2023. 2. **Get a Single Column by Name** =OBB.GET(A1:D3, , "revenue") Returns all revenue values. 3. **Get a Single Cell by Index** =OBB.GET(A1:D3, 2, 3) Returns the value at row 2, column 3 (cost\_of\_revenue for 2022/09/24). 4. **Get Multiple Rows and Columns** =OBB.GET(A1:D3, {"2023/09/30", "2021/09/25"}, {"cost_of_revenue", "gross_profit"}) Returns a 2x2 array with cost\_of\_revenue and gross\_profit for 2023 and 2021. 5. **Using Negative Indices** =OBB.GET(A1:D3, -1, -2) Returns the last row and second-to-last column (gross\_profit for 2021/09/25). ### Advanced Usage[​](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#advanced-usage "Direct link to Advanced Usage") 1. **Using Cell References for Selections** =OBB.GET(A1:D3, E1:E2, F1:F2) Where E1:E2 contains dates and F1:F2 contains column names. 2. **Combining with Other OBB Functions** =OBB.GET(OBB.WIDGET("My backend", "income_statement", {"ticker","AAPL";"year","2023"}), "2023/09/30", "revenue") Directly extracts revenue from the income statement widget result. Best Practices[​](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#best-practices "Direct link to Best Practices") -------------------------------------------------------------------------------------------------------------------------------- 1. **Date Formats** * Use `YYYY/MM/DD` format for date labels * Use Excel's DATE function: `DATE(2023,9,30)` * Ensure dates match exactly with the data 2. **Column Names** * Use exact column names as they appear in the data * Case-sensitive matching * Include underscores and spaces exactly as in the data 3. **Performance** * For large datasets, prefer using indices over labels * Use cell references for repeated selections * Avoid unnecessary array operations Troubleshooting[​](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#troubleshooting "Direct link to Troubleshooting") ----------------------------------------------------------------------------------------------------------------------------------- | Issue | Solution | | --- | --- | | #N/A error | Verify that the row/column labels exist in the data | | #VALUE! error | Check that the array parameter is valid | | Empty result | Confirm that the selection criteria match the data format | | Date not found | Ensure date format matches exactly (YYYY/MM/DD) | Notes[​](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#notes "Direct link to Notes") ----------------------------------------------------------------------------------------------------- * When using date labels, ensure consistent date formatting across your workbook * Column names are case-sensitive * The function preserves the original data types of the selected cells * Empty or invalid selections will return appropriate error values * For best performance with large datasets, consider using numeric indices instead of labels On this page * [Key Features](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#key-features) * [Syntax](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#syntax) * [Parameters](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#parameters) * [Return Value](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#return-value) * [Examples](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#examples) * [Common Use Cases](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#common-use-cases) * [Advanced Usage](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#advanced-usage) * [Best Practices](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#best-practices) * [Troubleshooting](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#troubleshooting) * [Notes](https://docs.openbb.co/workspace/analysts/excel-addin/obb-get#notes) --- # agents.json Reference | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#__docusaurus_skipToContent_fallback) On this page The `agents.json` endpoint is an important component of custom AI agent integration in OpenBB Workspace. This endpoint provides metadata and configuration information that tells the workspace how to interact with your custom agent. When you add a custom AI agent to OpenBB Workspace, the system first queries your agent's `/agents.json` endpoint to discover its capabilities, configuration, and how to communicate with it. This configuration acts as a contract between your agent and the workspace. The `agents.json` endpoint should return a JSON object with your agent(s) configuration. The endpoint must: * Be accessible via HTTP GET request * Return `Content-Type: application/json` * Respond with a valid JSON structure * Be available at the path `/agents.json` relative to your agent's base URL Example: { "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, }, }} See more examples in the [Complete Examples section](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#complete-examples) . See the JSON Schema definition in the [JsonSchema section](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#jsonschema) . Field Reference[​](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#field-reference "Direct link to Field Reference") -------------------------------------------------------------------------------------------------------------------------------------------------- ### `agent_id`: Unique ID of the agent[​](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#agent_id-unique-id-of-the-agent "Direct link to agent_id-unique-id-of-the-agent") The `agent_id` serves as a unique identifier for your agent within the OpenBB Workspace. This should be a lowercase string with hyphens replacing spaces, following standard slug conventions. The agent ID becomes the object key in the JSON response. | Argument | Type | Required | Default | Example | | --- | --- | --- | --- | --- | | `agent_id` | string | Yes | `null` | `"financial_prompt_optimizer"` | ### `name`: Human-readable name[​](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#name-human-readable-name "Direct link to name-human-readable-name") The `name` field specifies the human-readable display name for your agent that appears in the OpenBB Workspace user interface. This should be a clear, descriptive title that helps users understand what your agent does. | Argument | Type | Required | Default | Example | | --- | --- | --- | --- | --- | | `name` | string | Yes | `null` | `"Financial Prompt Optimizer"` | ### `description`: Human-readable description[​](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#description-human-readable-description "Direct link to description-human-readable-description") The `description` provides a brief overview of your agent's capabilities and intended purpose. This text helps users understand when and how to use your agent effectively, and it's displayed as the welcome AI agent message when the chat is empty. It is important to keep it concise but informative. If multi-orchestrator mode is enabled, then this description will be utilized by the main OpenBB Copilot to understand in what situations it should trigger this agent. So highlighting the capabilities and when to use a custom agent on its description is recommended. | Argument | Type | Required | Default | Example | | --- | --- | --- | --- | --- | | `description` | string | Yes | `null` | `"Optimizes a user's prompt for finance: clearer, more specific, and actionable."` | ### `image`: Image thumbnail[​](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#image-image-thumbnail "Direct link to image-image-thumbnail") The image field accepts a URL pointing to your agent's logo or avatar image. For optimal display in the OpenBB Workspace interface, use a square image with dimensions of at least 256x256 pixels. The image should be hosted on a publicly accessible URL. | Argument | Type | Required | Default | Example | | --- | --- | --- | --- | --- | | `image` | string | No | `null` | `"https://example.com/agent-logo.png"` | ### `endpoints`: Communication endpoints[​](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#endpoints-communication-endpoints "Direct link to endpoints-communication-endpoints") The query endpoint specifies where OpenBB Workspace should send user queries and interactions. This can be either a relative path like `"/query"` (if your agent runs on the same domain) or a full URL pointing to your agent's query handler like `"http://localhost:7777/v1/query"`. This endpoint must accept POST requests and handle the QueryRequest format. | Argument | Type | Required | Default | Example | | --- | --- | --- | --- | --- | | `endpoints` | object | Yes | `null` | `{"query": "http://localhost:7777/v1/query"}` | | `endpoints.query` | string | Yes | `null` | `"/query"` or `"http://localhost:7777/v1/query"` | ### `features`: Features that your agent advertises[​](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#features-features-that-your-agent-advertises "Direct link to features-features-that-your-agent-advertises") Configuration object that declares the capabilities that your agent advertises to OpenBB Workspace. This allows the workspace to understand what features your agent supports and how to interact with it effectively. | Argument | Type | Required | Default | Example | | --- | --- | --- | --- | --- | | `features` | object | Yes | `null` | `{"streaming": true, "widget-dashboard-select": false}` | See continuation of this section for details on each feature. #### `streaming`: Streaming responses[​](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#streaming-streaming-responses "Direct link to streaming-streaming-responses") The streaming feature enables Server-Sent Events (SSE) for your agent's responses, allowing real-time streaming of content back to users. This provides a better user experience with progressive response rendering. This feature defaults to `True` for all agents even if not explicitly set. | Argument | Type | Required | Default | Example | | --- | --- | --- | --- | --- | | `streaming` | boolean | No | `true` | `true` | #### `widget-dashboard-select`: Explicit context widgets[​](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#widget-dashboard-select-explicit-context-widgets "Direct link to widget-dashboard-select-explicit-context-widgets") This feature grants your agent access to explicit context widgets (primary) - those that are currently selected or explicitly chosen by the user in the dashboard. When enabled, your agent will receive these widgets in the `widgets.primary` collection of the `QueryRequest`, allowing you to fetch and analyze their data. | Argument | Type | Required | Default | Example | | --- | --- | --- | --- | --- | | `widget-dashboard-select` | boolean | No | `false` | `true` | #### `widget-dashboard-search`: Dashboard context widgets[​](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#widget-dashboard-search-dashboard-context-widgets "Direct link to widget-dashboard-search-dashboard-context-widgets") This feature provides your agent with access to all widgets available on the current dashboard, not just the selected ones. When enabled, these widgets appear in the `widgets.secondary` collection of the `QueryRequest`, giving your agent broader context about the user's dashboard setup and available data sources. | Argument | Type | Required | Default | Example | | --- | --- | --- | --- | --- | | `widget-dashboard-search` | boolean | No | `false` | `true` | JsonSchema[​](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#jsonschema "Direct link to JsonSchema") ----------------------------------------------------------------------------------------------------------------------------------- { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "patternProperties": { "^[a-z0-9-]+$": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1 }, "description": { "type": "string", "minLength": 1 }, "image": { "type": ["string", "null"], "format": "uri" }, "endpoints": { "type": "object", "properties": { "query": { "type": "string", "minLength": 1 } }, "required": ["query"], "additionalProperties": false }, "features": { "type": "object", "properties": { "streaming": { "type": "boolean", "default": true }, "widget-dashboard-select": { "type": "boolean", "default": false }, "widget-dashboard-search": { "type": "boolean", "default": false } }, "additionalProperties": true } }, "required": ["name", "description", "endpoints", "features"], "additionalProperties": false } }, "additionalProperties": false} Complete Examples[​](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#complete-examples "Direct link to Complete Examples") -------------------------------------------------------------------------------------------------------------------------------------------------------- ### Basic Agent Configuration[​](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#basic-agent-configuration "Direct link to Basic Agent Configuration") { "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 } }} ### Agent with Widget Access[​](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#agent-with-widget-access "Direct link to Agent with Widget Access") { "data-analysis-agent": { "name": "Data Analysis Agent", "description": "An agent that can access and analyze dashboard widget data", "image": "https://api.example.com/static/data-agent-logo.png", "endpoints": { "query": "http://localhost:8000/v1/query" }, "features": { "streaming": true, "widget-dashboard-select": true, "widget-dashboard-search": true } }} ### Multiple Agents Configuration[​](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#multiple-agents-configuration "Direct link to Multiple Agents Configuration") { "general-assistant": { "name": "General Assistant", "description": "General-purpose financial assistant", "endpoints": { "query": "http://localhost:7777/general/query" }, "features": { "streaming": true, "widget-dashboard-select": true, "widget-dashboard-search": false } }, "market-analyst": { "name": "Market Analyst", "description": "Specialized in market analysis with dashboard data access", "image": "https://api.example.com/analyst-logo.png", "endpoints": { "query": "http://localhost:7777/analyst/query" }, "features": { "streaming": true, "widget-dashboard-select": true, "widget-dashboard-search": true } }, "research-assistant": { "name": "Research Assistant", "description": "Financial research and data processing", "endpoints": { "query": "http://localhost:7777/research/query" }, "features": { "streaming": true, "widget-dashboard-select": false, "widget-dashboard-search": false } }} On this page * [Field Reference](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#field-reference) * [`agent_id`: Unique ID of the agent](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#agent_id-unique-id-of-the-agent) * [`name`: Human-readable name](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#name-human-readable-name) * [`description`: Human-readable description](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#description-human-readable-description) * [`image`: Image thumbnail](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#image-image-thumbnail) * [`endpoints`: Communication endpoints](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#endpoints-communication-endpoints) * [`features`: Features that your agent advertises](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#features-features-that-your-agent-advertises) * [JsonSchema](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#jsonschema) * [Complete Examples](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#complete-examples) * [Basic Agent Configuration](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#basic-agent-configuration) * [Agent with Widget Access](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#agent-with-widget-access) * [Multiple Agents Configuration](https://docs.openbb.co/workspace/developers/json-specs/agents-json-reference#multiple-agents-configuration) --- # Categories and Subcategories | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-configuration/category-subcategory#__docusaurus_skipToContent_fallback) The category and subcategory specify the category and subcategory of the widget in the OpenBB Workspace. This is important to organize the widgets in the search for OpenBB Workspace and also for AI agents to find the best widgets to utilize for a given task. ![Markdown Widget with Category and Subcategory Example](https://openbb-cms.directus.app/assets/bdedbc4e-64ac-44b4-a176-8f2ca31b99cf.png) @register_widget({ "name": "Markdown Widget with Category and Subcategory", "description": "A markdown widget with category and subcategory", "type": "markdown", "category": "Widgets", "subcategory": "Markdown Widgets", "endpoint": "markdown_widget_with_category_and_subcategory", "gridData": {"w": 12, "h": 4},})@app.get("/markdown_widget_with_category_and_subcategory")def markdown_widget_with_category_and_subcategory(): """Returns a markdown widget with category and subcategory""" return f"# Markdown Widget with Category and Subcategory" --- # Error Handling | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-configuration/error-handling#__docusaurus_skipToContent_fallback) This is a simple widget that demonstrates how to handle errors in your widgets. We display the error detail message in the markdown widget that is returned from the endpoint. ![Markdown Widget with Error Handling Example](https://openbb-cms.directus.app/assets/c8671675-d4d0-4b3d-ada1-d4eae95ca859.png) @register_widget({ "name": "Markdown Widget with Error Handling", "description": "A markdown widget with error handling", "type": "markdown", "endpoint": "markdown_widget_with_error_handling", "gridData": {"w": 12, "h": 4},})@app.get("/markdown_widget_with_error_handling")def markdown_widget_with_error_handling(): """Returns a markdown widget with error handling""" raise HTTPException( status_code=500, detail="Error that just occurred" ) --- # Grid Size | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-configuration/grid-size#__docusaurus_skipToContent_fallback) On this page Widgets use a grid-based layout system where you can specify their width and height in the `gridData` object. Here's a simple example: ![Markdown Widget with Error Handling Example](https://openbb-cms.directus.app/assets/efd6fb45-063a-4aa7-ae42-64b440bc8682.png) @register_widget({ "name": "Markdown Widget", "description": "A markdown widget", "type": "markdown", "endpoint": "markdown_widget", "gridData": {"w": 12, "h": 4},})@app.get("/markdown_widget")def markdown_widget(): """Returns a markdown widget""" return "# Markdown Widget" The grid system works as follows: **Width (w)**: Horizontal span (10-40 units) * 12 units is a good default for most widgets * Use 40 units for full-width widgets **Height (h)**: Vertical span (4-100 units) * 4-8 units for simple widgets * 8-20 units for standard widgets * Larger values for detailed charts or tables ### Example[​](https://docs.openbb.co/workspace/developers/widget-configuration/grid-size#example "Direct link to Example") This is the code utilized to add the widgets in the image above. @register_widget({ "name": "Markdown Widget w-12 x h-20", "description": "A markdown widget", "type": "markdown", "endpoint": "markdown_widget2", "gridData": {"w": 12, "h": 20},})@app.get("/markdown_widget2")def markdown_widget2(): """Returns a markdown widget""" return "# Markdown Widget w-12 x h-20"@register_widget({ "name": "Markdown Widget w-40 x h-4", "description": "A markdown widget", "type": "markdown", "endpoint": "markdown_widget3", "gridData": {"w": 40, "h": 4},})@app.get("/markdown_widget3")def markdown_widget3(): """Returns a markdown widget""" return "# Markdown Widget w-40 x h-4"@register_widget({ "name": "Markdown Widget w-14 x h-12", "description": "A markdown widget", "type": "markdown", "endpoint": "markdown_widget4", "gridData": {"w": 14, "h": 12},})@app.get("/markdown_widget4")def markdown_widget4(): """Returns a markdown widget""" return "# Markdown Widget w-14 x h-12"@register_widget({ "name": "Markdown Widget w-28 x h-8", "description": "A markdown widget", "type": "markdown", "endpoint": "markdown_widget5", "gridData": {"w": 28, "h": 8},})@app.get("/markdown_widget5")def markdown_widget5(): """Returns a markdown widget""" return "# Markdown Widget w-28 x h-8"@register_widget({ "name": "Markdown Widget w-14 x h-6", "description": "A markdown widget", "type": "markdown", "endpoint": "markdown_widget6", "gridData": {"w": 14, "h": 6},})@app.get("/markdown_widget6")def markdown_widget6(): """Returns a markdown widget""" return "# Markdown Widget w-14 x h-6" On this page * [Example](https://docs.openbb.co/workspace/developers/widget-configuration/grid-size#example) --- # Run Button | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-configuration/run-button#__docusaurus_skipToContent_fallback) The run button allows you to run a widget by clicking it rather than having it run automatically when you change a parameter. It is located in the top right corner of the widget and replaces the refresh button. A Ctrl-click on the run button performs a hard refresh, while a regular click runs the new parameters. Setting the refreshInterval will allow you to still refresh the widget automatically, but it is off by default when using the run button. ![Markdown Widget with Run Button Example](https://openbb-cms.directus.app/assets/48d7d762-a39f-46f3-b205-2b1ffe13c3ef.png) @register_widget({ "name": "Markdown Widget with Run Button", "description": "A markdown widget with a run button", "type": "markdown", "endpoint": "markdown_widget_with_run_button", "gridData": {"w": 12, "h": 4}, "runButton": True,})@app.get("/markdown_widget_with_run_button")def markdown_widget_with_run_button(): """Returns a markdown widget with current time""" current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") return f"### Current time: {current_time}" --- # Stale Time | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-configuration/stale-time#__docusaurus_skipToContent_fallback) The stale time is the time after which the data will be considered stale. You will see a refresh button in the widget becoming orange to indicate that the data is stale. * Default: 300000 (5 minutes) * Data older than this value will trigger a refresh when the widget is viewed again * Should typically be less than or equal to `refetchInterval` * Set higher for data that updates infrequently ![Markdown Widget with Stale Time Example](https://openbb-cms.directus.app/assets/d601fda5-0ea3-40cc-8290-d0789ccb0e33.png) @register_widget({ "name": "Markdown Widget with Stale Time", "description": "A markdown widget with stale time", "type": "markdown", "endpoint": "markdown_widget_with_stale_time", "gridData": {"w": 12, "h": 4}, "staleTime": 5000})@app.get("/markdown_widget_with_stale_time")def markdown_widget_with_stale_time(): """Returns a markdown widget with current time""" current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") return f"### Current time: {current_time}" --- # Render Functions | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#__docusaurus_skipToContent_fallback) On this page In the `widgets.json` configuration, you can specify render functions to customize how the data is displayed in the widget - These functions are only compatible with widgets that use a `columnsDefs`. ### Available Render Functions[​](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#available-render-functions "Direct link to Available Render Functions") | Function | Description | | --- | --- | | `greenRed` | Applies a green or red color based on conditions | | `titleCase` | Converts text to title case | | `hoverCard` | Displays additional information when hovering over a cell | | `cellOnClick` | Triggers an action when a cell is clicked | | `columnColor` | Changes the color of a column based on specified rules | | `showCellChange` | Highlights cells when their values change via WebSocket updates. Only used with the [Live Grid Widget](https://docs.openbb.co/workspace/developers/widget-types/live-grid) | ### Render Function Parameters[​](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#render-function-parameters "Direct link to Render Function Parameters") | Parameter | Type | Description | | --- | --- | --- | | **actionType** | `string` | Specifies the action type for the render function (`"openUrl"`, `"groupBy"`, `"sendToAgent"`) | | **colorValueKey** | `string` | Specifies which field to use for determining the color when showing cell changes | | **hoverCardData** | `array of strings` | Specifies columns to show in the hover card | | **colorRules** | `array of objects` | An array of rules for conditional coloring | | **sendToAgent** | `object` | Configuration for sending data to an AI agent | ### Send to Agent Parameters[​](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#send-to-agent-parameters "Direct link to Send to Agent Parameters") | Parameter | Type | Description | | --- | --- | --- | | **markdown** | `string` | Markdown content to send to the agent, supports template variables from row data | | **agentId** | `string` | (Optional) Specific agent ID to send the message to | ### Color Rules Parameters[​](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#color-rules-parameters "Direct link to Color Rules Parameters") | Parameter | Type | Description | Options | | --- | --- | --- | --- | | **condition** | `string` | The condition for applying the color | `"eq"`, `"ne"`, `"gt"`, `"lt"`, `"gte"`, `"lte"`, `"between"`, `"contains"`, `"notContains"` | | **value** | `number` or `string` | The value for the condition. For `contains` and `notContains`, use a string value | \- | | **range** | `object` | An object specifying `min` and `max` values for the between condition | `{min: number, max: number}` | | **color** | `string` | The color to apply | Hex code or `"green"`, `"red"`, `"blue"` | | **fill** | `boolean` | Indicates if the color should fill the cell | `true`/`false` | Example Configurations[​](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#example-configurations "Direct link to Example Configurations") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### Column Color[​](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#column-color "Direct link to Column Color") To use the column color render function, you need to add it to the `columnsDefs` array in your `widgets.json` file for the column you want to apply it to. The below example would apply a green color to the cell if the value is between 50 and 90, a red color if the value is less than 50, and a blue color if the value is greater than 90. ![color example](https://openbb-assets.s3.us-east-1.amazonaws.com/docs/pro/color.png) { ... "columnsDefs": [ { "field": "Analyst", "headerName": "Analyst", "renderFn": "columnColor", "renderFnParams": { "colorRules": [ { "condition": "between", "range": { "min": 50, "max": 90 }, "color": "blue", "fill": true }, { "condition": "lt", "value": 50, "color": "red", "fill": true }, { "condition": "gt", "value": 90, "color": "green", "fill": true } ] } } ]} **Example using `contains` and `notContains` conditions:** { ... "columnsDefs": [ { "field": "status", "headerName": "Status", "cellDataType": "text", "renderFn": "columnColor", "renderFnParams": { "colorRules": [ { "condition": "contains", "value": "Active", "color": "green", "fill": true }, { "condition": "contains", "value": "Pending", "color": "yellow", "fill": true }, { "condition": "notContains", "value": "Active", "color": "red", "fill": true } ] } } ]} This example: * Colors cells green if the status contains "Active" * Colors cells yellow if the status contains "Pending" * Colors cells red if the status does not contain "Active" **Note:** The `contains` and `notContains` conditions work with string values only. ### Multiple Render Functions and Color Rules[​](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#multiple-render-functions-and-color-rules "Direct link to Multiple Render Functions and Color Rules") If you want to use multiple render functions, you can pass an array of render functions to the `renderFn` parameter. Below is an example of a column that uses both the `cellOnClick` and `columnColor` render functions. We also specify the `colorValueKey` so that the `columnColor` render function knows which field to use for determining the color. In this case we want to color the symbol cell based on the `Analyst` field. { ... "columnsDefs": [ { "field": "Symbol", "headerName": "Symbol", "renderFn": [ "cellOnClick", "columnColor" ], "renderFnParams": { "actionType": "groupBy", "groupBy": { "paramName": "symbol" }, "colorValueKey": "Analyst", "colorRules": [ { "condition": "eq", "value": "Sarah Johnson", "color": "blue", "fill": true } ] } }, ] } ### Using valueField for Custom Value Mapping[​](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#using-valuefield-for-custom-value-mapping "Direct link to Using valueField for Custom Value Mapping") The `valueField` option allows you to use a different field value than what's displayed in the cell. This is useful when your table displays human-readable values (like company names) but your API expects different values (like IDs). **Example:** A table displays company names, but clicking should pass the company ID to the parameter: { ... "columnsDefs": [ { "field": "companyName", "headerName": "Company", "cellDataType": "text", "renderFn": "cellOnClick", "renderFnParams": { "actionType": "groupBy", "groupBy": { "paramName": "companyId", "valueField": "companyId" } } } ]} In this example: * The cell displays the value from `companyName` field (e.g., "Apple Inc.") * When clicked, it passes the value from `companyId` field (e.g., "AAPL") to the `companyId` parameter * This allows you to show friendly names while using IDs for API calls **Data structure example:** [ { "companyName": "Apple Inc.", "companyId": "AAPL", "price": 150.25 }, { "companyName": "Microsoft Corporation", "companyId": "MSFT", "price": 350.50 }] ### Hover Card[​](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#hover-card "Direct link to Hover Card") To use the hover card render function, you need to add it to the `columnsDefs` array in your `widgets.json` file for the column you want to apply it to. ![color example](https://openbb-assets.s3.us-east-1.amazonaws.com/docs/pro/hover+data.png) { ... "columnsDefs": [ { "field": "analyst", "headerName": "Analyst", "renderFn": "hoverCard", "renderFnParams": { "hoverCard": { "cellField": "value", "title": "Analyst Details", "markdown": "### {value}\n- **Description:** {description}\n- **Additional Info:** {additionalInfo}" } } } ]} The hover card example would use the below data to display the hover card. [ { "id": 1, "name": "Item 1", "analyst": { "value": "Cool Guy 1", "description": "This is a detailed description for Item 1, but it's not as long as the others", "additionalInfo": "Some additional information about Item 1" } }, { "id": 2, "name": "Item 2", "analyst": { "value": "Cool Guy 2", "description": "This is a detailed description for Item 2, but it's a bit longer than the first one", "additionalInfo": "Some additional information about Item 2" } }, { "id": 3, "name": "Item 3", "analyst": { "value": "Cool Guy 3", "description": "This is a detailed description for Item 3, but it's the longest one yet and it's still going", "additionalInfo": "Some additional information about Item 3" } }] #### Additional Notes for Hover Card[​](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#additional-notes-for-hover-card "Direct link to Additional Notes for Hover Card") * You can pass a simple configuration to get a hover card with default settings, excluding the title and value. * The `hoverCard` render function allows for markdown customization, providing flexibility in how information is displayed. ### Prefix and Suffix[​](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#prefix-and-suffix "Direct link to Prefix and Suffix") The `prefix` and `suffix` parameters can also be used in the `columnsDefs` to add a prefix or suffix to the column values. [See the widgets-json-reference](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference) for more information. ### Send to Agent[​](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#send-to-agent "Direct link to Send to Agent") The `sendToAgent` action type allows users to click on table cells to send contextual data directly to an AI agent for analysis. This is particularly useful for getting insights about specific data points or rows. { ... "columnsDefs": [ { "field": "company", "headerName": "Company", "renderFn": "cellOnClick", "renderFnParams": { "actionType": "sendToAgent", "sendToAgent": { "markdown": "Please analyze the company **{company}** with the following details:\n\n- **Revenue:** ${revenue}M\n- **Growth Rate:** {growth_rate}%\n- **Market Cap:** ${market_cap}B\n- **Sector:** {sector}\n\nProvide insights on the company's financial performance, growth prospects, and market position." } } }, { "field": "revenue", "headerName": "Revenue (M)", "renderFn": "cellOnClick", "renderFnParams": { "actionType": "sendToAgent", "sendToAgent": { "markdown": "Analyze the revenue figure of **${revenue}M** for {company}. How does this compare to industry standards in the {sector} sector?", "agentId": "financial-analyst-agent" } } } ]} #### Template Variables[​](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#template-variables "Direct link to Template Variables") The `markdown` content in `sendToAgent` supports template variables using curly braces `{}`. You can reference any field from the row data: * `{company}` - References the company field value * `{revenue}` - References the revenue field value * `{growth_rate}` - References the growth\_rate field value * And so on for any field in your data On this page * [Available Render Functions](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#available-render-functions) * [Render Function Parameters](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#render-function-parameters) * [Send to Agent Parameters](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#send-to-agent-parameters) * [Color Rules Parameters](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#color-rules-parameters) * [Example Configurations](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#example-configurations) * [Column Color](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#column-color) * [Multiple Render Functions and Color Rules](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#multiple-render-functions-and-color-rules) * [Using valueField for Custom Value Mapping](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#using-valuefield-for-custom-value-mapping) * [Hover Card](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#hover-card) * [Prefix and Suffix](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#prefix-and-suffix) * [Send to Agent](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions#send-to-agent) --- # Metric | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-types/metric#__docusaurus_skipToContent_fallback) On this page A widget that displays key metrics with labels, values, and delta changes. Useful for showing important statistics and their trends. ![metric](https://openbb-assets.s3.us-east-1.amazonaws.com/docs/pro/metric-widget.png) @register_widget({ "name": "Metric Widget", "description": "A metric widget example", "category": "Test", "endpoint": "test_metric", "type": "metric"})@app.get("/test_metric")def test_metric(): """Example endpoint to provide metric data.""" # Example data structure data = { "label": "Example Label", "value": "12345", "delta": "5.67" } return JSONResponse(content=data) As you can see in the example the data structure is as follows: * `label`: The label of the metric. * `value`: The value of the metric. * `delta`: The delta of the metric. Multiple metrics[​](https://docs.openbb.co/workspace/developers/widget-types/metric#multiple-metrics "Direct link to Multiple metrics") ---------------------------------------------------------------------------------------------------------------------------------------- ![Metric Widget Example](https://openbb-cms.directus.app/assets/ba37bbbb-371a-40e8-a7e1-e48edcc6c0c8.png) @register_widget({ "name": "Metric Widget", "description": "A metric widget", "endpoint": "metric_widget", "gridData": { "w": 5, "h": 5 }, "type": "metric"})@app.get("/metric_widget")def metric_widget(): data = [ { "label": "Total Users", "value": "1,234,567", "delta": "12.5" }, { "label": "Active Sessions", "value": "45,678", "delta": "-2.3" }, { "label": "Revenue (USD)", "value": "$89,432", "delta": "8.9" }, { "label": "Conversion Rate", "value": "3.2%", "delta": "0.0" }, { "label": "Avg. Session Duration", "value": "4m 32s", "delta": "0.5" } ] return JSONResponse(content=data) On this page * [Multiple metrics](https://docs.openbb.co/workspace/developers/widget-types/metric#multiple-metrics) --- # Refetch Interval | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-configuration/refetch-interval#__docusaurus_skipToContent_fallback) On this page The refetch interval is the interval at which the widget will be refreshed. Use lower values for real-time data (e.g., 60000 for 1-minute updates). Higher values are recommended for static or slowly changing data. * Default: 900000 (15 minutes) (minimum 1000) * Set to `false` to disable automatic refreshing * Use lower values for real-time data (e.g., 60000 for 1-minute updates) * Higher values recommended for static or slowly changing data Note that when interacting with a particular widget this will trigger a refresh. ![Markdown Widget with Short Refetch Interval Example](https://openbb-cms.directus.app/assets/4b016db5-5265-4e3b-84f9-506aa4fd9c42.png) @register_widget({ "name": "Markdown Widget with Short Refetch Interval", "description": "A markdown widget with a short refetch interval", "type": "markdown", "endpoint": "markdown_widget_with_short_refetch_interval", "gridData": {"w": 12, "h": 4}, "refetchInterval": 1000})@app.get("/markdown_widget_with_short_refetch_interval")def markdown_widget_with_short_refetch_interval(): """Returns a markdown widget with current time""" current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") return f"### Current time: {current_time}" Refetch Interval with Stale Time[​](https://docs.openbb.co/workspace/developers/widget-configuration/refetch-interval#refetch-interval-with-stale-time "Direct link to Refetch Interval with Stale Time") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The refetch interval is set to 10000ms (10 seconds) and the stale time is set to 5000ms (5 seconds). Data older than stale time will make the refresh button in the widget become orange to indicate that the data is stale, and once it reaches the refetch interval, the widget will be refreshed and the indicator will turn green again. ![Markdown Widget with Refetch Interval and Stale Time Example](https://openbb-cms.directus.app/assets/9313f7e3-0ab6-42ae-877d-8868c84d044b.png) @register_widget({ "name": "Markdown Widget with Refetch Interval and Shorter Stale Time", "description": "A markdown widget with a short refetch interval and a shorter stale time", "type": "markdown", "endpoint": "markdown_widget_with_refetch_interval_and_shorter_stale_time", "gridData": {"w": 12, "h": 4}, "refetchInterval": 10000, "staleTime": 5000})@app.get("/markdown_widget_with_refetch_interval_and_shorter_stale_time")def markdown_widget_with_refetch_interval_and_shorter_stale_time(): """Returns a markdown widget with current time""" current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") return f"### Current time: {current_time}" Refetch interval with Run Button[​](https://docs.openbb.co/workspace/developers/widget-configuration/refetch-interval#refetch-interval-with-run-button "Direct link to Refetch interval with Run Button") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The refresh interval is set to 10000ms (10 seconds) but the run button is enabled, which means that the user can refresh the widget manually. ![Markdown Widget with Short Refetch Interval and Run Button Example](https://openbb-cms.directus.app/assets/24d777ae-d455-412d-9832-255e28eea11e.png) @register_widget({ "name": "Markdown Widget with Short Refetch Interval and a Run Button", "description": "A markdown widget with a short refetch interval and a run button", "type": "markdown", "endpoint": "markdown_widget_with_short_refetch_interval_and_run_button", "gridData": {"w": 12, "h": 4}, "refetchInterval": 10000, "runButton": True})@app.get("/markdown_widget_with_short_refetch_interval_and_run_button")def markdown_widget_with_short_refetch_interval_and_run_button(): """Returns a markdown widget with current time""" current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") return f"### Current time: {current_time}" On this page * [Refetch Interval with Stale Time](https://docs.openbb.co/workspace/developers/widget-configuration/refetch-interval#refetch-interval-with-stale-time) * [Refetch interval with Run Button](https://docs.openbb.co/workspace/developers/widget-configuration/refetch-interval#refetch-interval-with-run-button) --- # SSRM Mode | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#__docusaurus_skipToContent_fallback) On this page Server-Side Rendered Mode (SSRM) is an advanced widget implementation approach designed to handle large datasets efficiently in OpenBB Workspace. Unlike traditional widgets that load all data at once, SSRM mode enables server-side pagination, filtering, and sorting, making it ideal for displaying massive datasets without compromising performance. Key Features & Use Cases[​](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#key-features--use-cases "Direct link to Key Features & Use Cases") ------------------------------------------------------------------------------------------------------------------------------------------------------------------ SSRM mode is designed for enterprise applications that need to handle **large datasets** (200,000+ rows) efficiently. Instead of loading all data at once, it provides server-side operations that optimize performance and user experience. How SSRM Differs from Standard Table Widget[​](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#how-ssrm-differs-from-standard-table-widget "Direct link to How SSRM Differs from Standard Table Widget") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | Aspect | Standard Table Widget | SSRM Mode | | --- | --- | --- | | Data Loading | All data loaded at once | Data loaded on-demand | | Filtering | Client-side filtering | Server-side filtering | | Sorting | Client-side sorting | Server-side sorting | | Memory Usage | High for large datasets | Optimized memory usage | | Initial Load Time | Slower for large datasets | Fast initial load | | Network Traffic | High initial payload | Optimized payloads | | Complexity | Simple implementation | Advanced server logic | Widget Configuration[​](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#widget-configuration "Direct link to Widget Configuration") ------------------------------------------------------------------------------------------------------------------------------------------------------- To use SSRM mode, your widget configuration must specify the correct widget type: { "name": "SSRM Data Table", "description": "Server-side rendered table for large datasets", "type": "ssrm_table", "endpoint": "data-ssrm", "gridData": {"w": 12, "h": 8}} **Important**: The widget type must be set to `"ssrm_table"` to enable server-side row model functionality. This tells OpenBB Workspace to use the SSRM interface instead of the normal table widget. Implementation Overview[​](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#implementation-overview "Direct link to Implementation Overview") ---------------------------------------------------------------------------------------------------------------------------------------------------------------- The SSRM example implementation is built as a FastAPI server that handles AgGrid's Server-Side Row Model requests. For complete implementation examples and code samples, refer to the [SSRM Mode Examples Repository](https://github.com/OpenBB-finance/backends-for-openbb/tree/main/widget-examples/ssrm_mode) . Here's what the implementation provides: ### Core Architecture[​](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#core-architecture "Direct link to Core Architecture") * **FastAPI Server**: Main application handling SSRM requests from the widget * **Database Manager**: Multi-database interface supporting SQLite, MySql, and Snowflake * **Custom Models**: `AgGridOptions` and `AgRows` models for structured data handling * **Query Engine**: Modular system for converting AgGrid requests to optimized SQL queries ### Key Endpoint: `/data-ssrm`[​](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#key-endpoint-data-ssrm "Direct link to key-endpoint-data-ssrm") The main POST endpoint processes AgGrid SSRM requests and handles: * **Pagination**: Processes `startRow`/`endRow` parameters for efficient data paging * **Filtering**: Supports text, number, and set filters with various operators (contains, equals, greaterThan, etc.) * **Sorting**: Multi-column sorting with ascending/descending directions * **Grouping**: Row grouping with COUNT aggregation and hierarchical support ### Request/Response Flow[​](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#requestresponse-flow "Direct link to Request/Response Flow") 1. AgGrid frontend sends SSRM request with pagination, filters, sorting, and grouping parameters 2. Server converts request to a valid query using the `AgRows` model 3. Database manager executes query against the database 4. Results are formatted and returned with `rowData` and `rowCount` for AgGrid consumption AI Data[​](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#ai-data "Direct link to AI Data") ---------------------------------------------------------------------------------------------------------------- When using SSRM mode with AI functionality in OpenBB Workspace, there's an important limitation to understand: **"What You See Is What You Get"**: AI can only access and analyze the data that is currently visible in the table widget. This means: * AI will only see the specific rows that are loaded and displayed on screen * If your dataset has 15 million rows but only 100 are currently visible, AI can only work with those 100 rows * Pagination, filtering, and sorting affect what data is available to AI analysis * AI cannot access the entire dataset that exists in your database ### Current Implementation[​](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#current-implementation "Direct link to Current Implementation") This is the current approach for AI data access in SSRM mode. Future implementations are planned to make this more robust and provide broader data access capabilities for AI analysis. ### Best Practices for AI Integration[​](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#best-practices-for-ai-integration "Direct link to Best Practices for AI Integration") * Load relevant data subsets that you want AI to analyze * Use filtering to focus on specific data ranges before engaging AI * Consider the scope of your analysis when working with paginated data * Be aware that AI insights will be limited to the currently displayed dataset On this page * [Key Features & Use Cases](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#key-features--use-cases) * [How SSRM Differs from Standard Table Widget](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#how-ssrm-differs-from-standard-table-widget) * [Widget Configuration](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#widget-configuration) * [Implementation Overview](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#implementation-overview) * [Core Architecture](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#core-architecture) * [Key Endpoint: `/data-ssrm`](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#key-endpoint-data-ssrm) * [Request/Response Flow](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#requestresponse-flow) * [AI Data](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#ai-data) * [Current Implementation](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#current-implementation) * [Best Practices for AI Integration](https://docs.openbb.co/workspace/developers/widget-types/ssrm_mode#best-practices-for-ai-integration) --- # HTML | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-types/html#__docusaurus_skipToContent_fallback) On this page HTML widgets provide control over visualization design through server-rendered HTML, enabling the creation of custom styled dashboards and data displays. Security Note HTML widgets render static HTML content only. JavaScript code within the HTML will not be executed for security reasons. All interactivity must be achieved through server-side logic and HTML/CSS features only. ![HTML Widget Example](https://openbb-cms.directus.app/assets/8234f346-6b2e-49b2-b5de-7150c770a756.png) @register_widget({ "name": "HTML Widget", "description": "A HTML widget with interactive dashboard", "type": "html", "endpoint": "html_widget", "gridData": {"w": 40, "h": 20},})@app.get("/html_widget", response_class=HTMLResponse)def html_widget(): """Returns an HTML widget with mockup data""" return HTMLResponse(content="""

Portfolio Dashboard

Real-time market overview and analytics

$124,563
Total Portfolio Value
+5.4% today
42
Active Positions
+3 this week
$8,421
Daily P&L
+12.3%
0.87
Sharpe Ratio
-0.05

Performance Overview

Tech Stocks (68%)
Fixed Income (32%)

Recent Activity

  • AAPL - Bought 100 shares @ $182.50 2 hours ago
  • GOOGL - Sold 50 shares @ $141.20 5 hours ago
  • MSFT - Bought 75 shares @ $378.80 Yesterday
""") The gridData parameter specifies the widget's size in the OpenBB Workspace grid system. More on that can be found [here](https://docs.openbb.co/workspace/developers/widget-configuration/grid-size) . Key Features[​](https://docs.openbb.co/workspace/developers/widget-types/html#key-features "Direct link to Key Features") -------------------------------------------------------------------------------------------------------------------------- **Complete Design Control**: HTML widgets allow extensive customization through HTML markup and inline CSS styling, enabling the creation of professional-grade interfaces that match your organization's branding and design requirements. **Server-Side Rendering**: All content is generated server-side, ensuring security while allowing dynamic HTML generation based on real-time data, calculations, and API responses from your backend. **Rich Styling Options**: Leverage the full power of inline CSS for advanced styling including animations, gradients, responsive layouts, and professional visual design that creates engaging dashboard experiences. **Data Integration**: Generate HTML content dynamically on the server based on live data sources, enabling real-time portfolio monitoring, market data display, and dynamic performance tracking through server-side updates. Best Practices[​](https://docs.openbb.co/workspace/developers/widget-types/html#best-practices "Direct link to Best Practices") -------------------------------------------------------------------------------------------------------------------------------- * Use semantic HTML structure for accessibility and maintainability * Implement responsive design patterns using CSS flexbox and grid layouts * Generate all dynamic content server-side before returning the HTML response * Use CSS animations and transitions for visual effects instead of JavaScript * Handle all data fetching and processing in the Python backend before rendering * Consider using HTML forms with server endpoints for user interactions * Refresh widgets periodically to update data rather than relying on client-side updates On this page * [Key Features](https://docs.openbb.co/workspace/developers/widget-types/html#key-features) * [Best Practices](https://docs.openbb.co/workspace/developers/widget-types/html#best-practices) --- # Context Management | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#__docusaurus_skipToContent_fallback) On this page The Copilot employs a sophisticated context understanding system that prioritizes and processes multiple information sources simultaneously. This hierarchical approach ensures that the most relevant and specific data takes precedence when generating responses, while still maintaining awareness of broader workspace context and conversation history. Priority[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#priority "Direct link to Priority") ---------------------------------------------------------------------------------------------------------------------- The agent prioritizes context in the following order: | Priority | Context Type | Description | | --- | --- | --- | | 1 | Explicit | Widgets added to context specifically. | | 2 | MCP tool | Active MCP tools connected to the Copilot | | 3 | Attached files | Files uploaded directly to the Copilot | | 4 | Dashboard | All widgets currently on your dashboard (in all tabs). | | 5 | Conversation | The history of your current conversation. | | 6 | Global | All widgets available within the OpenBB Workspace. If Global Data enabled. | | 7 | Web search | Retrieve infromation from the web. If Web Search enabled. | Context Types[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#context-types "Direct link to Context Types") ------------------------------------------------------------------------------------------------------------------------------------- ### Explicit Context[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#explicit-context "Direct link to Explicit Context") Explicit context represents the highest priority information source, allowing you to precisely direct the Copilot's attention to specific datasets or widgets. This mechanism is particularly powerful for ensuring accuracy when working with multiple similar datasets or when you need analysis focused on a specific dataset. When you click on the "Add to context" button on any widget you're creating a direct reference that the Copilot will prioritize above all other available information. After sending the prompt, that widget will remain in context. ![Explicit context](https://openbb-cms.directus.app/assets/24947294-2053-4efc-a68b-7ec90bf9875c.png) When you use the "@" symbol followed by a widget name and the prompt is sent, the widget will disappear from context. This is meant to be a quick tag reference. ![Explicit context with @](https://openbb-cms.directus.app/assets/3ed47f6f-52f2-4515-b401-16bc8d6a971a.png) ### MCP Tools[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#mcp-tools "Direct link to MCP Tools") The second highest priority is active MCP tools connected to OpenBB Workspace. For more details, see the MCP tools documentation [here](https://docs.openbb.co/workspace/analysts/ai-features/mcp-tools) . Depending on your use case, MCP tools offer a powerful way to connect to third-party data providers or specialized financial tools using a standardized protocol. This would eliminate the need for custom development inside OpenBB Workspace. To use MCP tools, make sure to configure it (see how to do it [here](https://docs.openbb.co/workspace/analysts/ai-features/mcp-tools#configure-your-mcp-servers) , and then select all the desired MCP tools. ![Attached files](https://openbb-cms.directus.app/assets/31809471-52b2-4dcb-a5f0-9276def2ae29.png) When enabled, Copilot gains access to all active MCP tools. You can also explicitly call a specific MCP tool to guarantee it’s invoked. ![Attached files](https://openbb-cms.directus.app/assets/0a77e58a-6c9f-4cc8-8983-ec8668ecc1c6.png) ### Attached Files[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#attached-files "Direct link to Attached Files") The attachment system enables the Copilot to process documents and datasets that aren't part of your current workspace widgets. Supported file types include PDF, Excel, CSV, and various other document formats. The Copilot automatically extracts and indexes content from attached files, making them searchable and referenceable throughout your conversation. This capability is essential for performing ad-hoc analysis or incorporating external datasets and documents into your workflow. Please note that for PDF files, text must be selectable as Optical Character Recognition (OCR) is not supported. However, you can integrate your own agent that performs OCR. ![Attached files](https://openbb-cms.directus.app/assets/f3a3ab07-4ecf-4b76-af74-cd2bb1f4b3b2.png) ### Dashboard Context[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#dashboard-context "Direct link to Dashboard Context") The dashboard context provides the Copilot with comprehensive awareness of your currently active dashboard. All widgets on your active dashboard become automatically available as data sources, allowing the Copilot to understand the broader context of your work session. It also has access to the widgets metadata and the current parameters selected. ![Dashboard context](https://openbb-cms.directus.app/assets/2fc343e5-6eb2-4ef6-ba10-f687868bdff4.png) ### Conversation History[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#conversation-history "Direct link to Conversation History") Conversational context enables natural, iterative analysis by maintaining awareness of your entire dialogue history within the current session. The Copilot tracks your explicit questions and its responses. This memory allows for follow-up queries, refinement of analysis parameters, and building upon previous insights without needing to re-establish context. The system understands references to "the previous chart", "that analysis", or "the data we discussed" and can seamlessly continue complex analytical workflows across multiple conversation turns. ![Conversation history](https://openbb-cms.directus.app/assets/49ed1729-674a-4d45-bf73-ba9bd3918bed.png) ### Global Retrieval (ON/OFF flag)[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#global-retrieval-onoff-flag "Direct link to Global Retrieval (ON/OFF flag)") The global retrieval system provides the Copilot with access to the entire OpenBB Workspace widget library, extending far beyond your current dashboard widgets. When your current dashboard doesn't contain the specific data or analysis tool needed to answer a query, the Copilot can automatically identify and utilize the appropriate widgets from the entire widget library, effectively expanding your analytical capabilities on-demand without manual widget selection. This is only possible due to the metadata associated with each widget and is why it's important to invest time in specifying the metadata carefully. ![Global retrieval](https://openbb-cms.directus.app/assets/f5661493-50ec-45c0-931a-8abd70d3bc9a.png) ### Web Search (ON/OFF flag)[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#web-search-onoff-flag "Direct link to Web Search (ON/OFF flag)") The web search capability enables the Copilot to access real-time information from across the internet when: * The available workspace data is insufficient to fully answer your query. * The user asks to look for the information on the web. This feature automatically activates as a fallback mechanism, ensuring comprehensive responses even when dealing with breaking news, recent market developments, or information not available in your current workspace widgets. ![Web search](https://openbb-cms.directus.app/assets/3dffe668-2114-4c4c-b822-395da193f2a0.png) On this page * [Priority](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#priority) * [Context Types](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#context-types) * [Explicit Context](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#explicit-context) * [MCP Tools](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#mcp-tools) * [Attached Files](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#attached-files) * [Dashboard Context](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#dashboard-context) * [Conversation History](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#conversation-history) * [Global Retrieval (ON/OFF flag)](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#global-retrieval-onoff-flag) * [Web Search (ON/OFF flag)](https://docs.openbb.co/workspace/analysts/ai-features/copilot-context#web-search-onoff-flag) --- # Data Handling | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/ai-features/copilot-data-handling#__docusaurus_skipToContent_fallback) On this page Widget interaction[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-data-handling#widget-interaction "Direct link to Widget interaction") ---------------------------------------------------------------------------------------------------------------------------------------------------------- Dynamic parameter modification represents one of the OpenBB's Copilot most powerful capabilities. The system understands the parameter schemas of each widget and can intelligently modify settings like date ranges, asset symbols, calculation periods, and analysis parameters to match your specific requirements. This eliminates the need for manual widget configuration and enables the Copilot to perform iterative analysis with different parameters automatically, such as comparing the same analysis across different time periods or asset classes within a single conversation. ![Widget parameters](https://openbb-cms.directus.app/assets/1c0c7c36-30e8-4b89-b9ad-0b97694f2699.png) Structured data[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-data-handling#structured-data "Direct link to Structured data") ------------------------------------------------------------------------------------------------------------------------------------------------- The Copilot excels at processing and analyzing structured financial datasets through multiple specialized capabilities: * **Table widgets:** A natural language to SQL translation tool allows you to query tabular data from your widgets using plain English. Once your data is loaded in a tabular format, `text2sql` converts your questions into SQL queries under the hood and retrieves specific information from these tables. This allows you to explore and analyze your data through simple natural language questions. ![text2sql querying tabular data](https://openbb-cms.directus.app/assets/14b3bf0d-7569-4b31-9c4b-24053582b211.png) * **Plotly widgets:** Full-featured charting engine that not only generates interactive visualizations but also allows developers to provide the underlying data. The Copilot can extract specific data points, and create derivative analyses from existing visualizations. The AI agent will have better results in case the Plotly widget has raw data associated with it. ![Plotly chart with raw data switch](https://openbb-cms.directus.app/assets/0c9f06a6-c849-42e1-b4a0-5e572a7ff4b8.png) Unstructured data[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-data-handling#unstructured-data "Direct link to Unstructured data") ------------------------------------------------------------------------------------------------------------------------------------------------------- The Copilot's unstructured data processing capabilities enable comprehensive analysis of diverse document types and media: * **Document Processing (MD/PDF):** Advanced text extraction and comprehension. The system maintains document structure understanding, preserving context around tables and hierarchical information. This utilizes a sophisticated retrieval system that chunks large documents intelligently, maintains semantic relationships, and provides precise citations. The system can cross-reference information across multiple documents and identify contradictions or supporting evidence. ![Document processing with citations](https://openbb-cms.directus.app/assets/583b82f5-11c0-44d8-b286-4e6b3c1b364c.png) * **Web search:**: When the user provides a URL to the AI agent, it converts the web page to markdown for it to be parsed by the model - as done above. ![Web search markdown conversion](https://openbb-cms.directus.app/assets/e08c4afc-1f5c-48eb-8e21-f8a716c7e9a2.png) * **Image Analysis:** Image processing capabilities for charts, screenshots, financial diagrams, and infographics. The Copilot can extract data from visual representations, understand chart types, and incorporate visual information into broader analytical workflows. ![Image analysis extracting data from charts](https://openbb-cms.directus.app/assets/8ec86d09-faa1-4ee4-8820-76e93b8b1fae.png) On this page * [Widget interaction](https://docs.openbb.co/workspace/analysts/ai-features/copilot-data-handling#widget-interaction) * [Structured data](https://docs.openbb.co/workspace/analysts/ai-features/copilot-data-handling#structured-data) * [Unstructured data](https://docs.openbb.co/workspace/analysts/ai-features/copilot-data-handling#unstructured-data) --- # Step-by-Step Reasoning | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/ai-features/copilot-reasoning#__docusaurus_skipToContent_fallback) On this page Transparency and auditability are fundamental to the OpenBB's Copilot design, with comprehensive step-by-step reasoning displayed for every analysis. This detailed process visibility enables users to understand the logical flow, verify data sources, identify potential biases, and ensure compliance with analytical standards. The reasoning display serves both educational and quality assurance purposes, building user confidence while maintaining the ability to audit and reproduce analytical processes. ![Step-by-step reasoning](https://openbb-cms.directus.app/assets/93bf729b-3034-487a-9c1a-06d2d606f30e.png) Planning[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-reasoning#planning "Direct link to Planning") ------------------------------------------------------------------------------------------------------------------------ The planning phase demonstrates the Copilot's tactical thinking by decomposing complex analytical requests into logical, sequential sub-tasks. This planning process considers data dependencies, optimal execution order, and resource requirements. The displayed plan serves as a roadmap that users can review before execution, ensuring alignment with analytical objectives and providing clear expectations for the upcoming analysis workflow. ![Planning](https://openbb-cms.directus.app/assets/66e6496f-f9e0-4464-8e7c-0b720f0ff40f.png) Querying widgets[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-reasoning#querying-widgets "Direct link to Querying widgets") ------------------------------------------------------------------------------------------------------------------------------------------------ Widget query transparency provides complete visibility into data retrieval operations, including the specific widget accessed, all parameters used, and data source information. This documentation enables users to understand exactly what data was retrieved, verify parameter settings, and reproduce the analysis independently. The system also displays any parameter modifications made automatically, ensuring full awareness of how the Copilot adapted widget configurations to meet query requirements. ![Querying widgets](https://openbb-cms.directus.app/assets/2086a113-4dea-4693-a298-9643973d5782.png) Intermediate result artifact[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-reasoning#intermediate-result-artifact "Direct link to Intermediate result artifact") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Intermediate artifacts provide crucial visibility into the Copilot's analytical methodology by displaying generated code, SQL queries, calculation formulas, and other technical implementations. These artifacts serve multiple purposes: enabling technical review and validation, supporting learning and knowledge transfer, facilitating debugging and optimization, and ensuring compliance with analytical standards. Users can examine and reuse these artifacts, treating them as valuable analytical assets beyond their immediate application. ![Intermediate result artifact](https://openbb-cms.directus.app/assets/61c7d66b-5f96-4bab-8504-a603ad4f04cb.png) Artifact generated[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-reasoning#artifact-generated "Direct link to Artifact generated") ------------------------------------------------------------------------------------------------------------------------------------------------------ Final artifacts represent the culmination of the analytical process, displayed with complete context about their creation methodology. The step-by-step reasoning (status updates) maintain full provenance information, including data sources, transformation steps, and parameter settings used in their generation. The system preserves the relationship between artifacts and their creation process, enabling users to understand not just what was created, but how and why, supporting both immediate use and future reference or modification. ![Final artifact](https://openbb-cms.directus.app/assets/d1edea10-1940-422f-99dd-d6e7cc972e3d.png) On this page * [Planning](https://docs.openbb.co/workspace/analysts/ai-features/copilot-reasoning#planning) * [Querying widgets](https://docs.openbb.co/workspace/analysts/ai-features/copilot-reasoning#querying-widgets) * [Intermediate result artifact](https://docs.openbb.co/workspace/analysts/ai-features/copilot-reasoning#intermediate-result-artifact) * [Artifact generated](https://docs.openbb.co/workspace/analysts/ai-features/copilot-reasoning#artifact-generated) --- # MCP Tools | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/ai-features/mcp-tools#__docusaurus_skipToContent_fallback) On this page Model Context Protocol (MCP) integration enables seamless connection to third-party data providers, analytical services, and specialized financial tools without requiring custom development within the OpenBB Workspace. ![](https://openbb-cms.directus.app/assets/9e4121a3-a422-41fb-aaac-888f66b18fb2.png) We utilize the [use-mcp library](https://github.com/modelcontextprotocol/use-mcp) and support both MCP and SSE protocols, but not STDIO. If you are interested in STDIO support, we recommend exploring solutions like [https://github.com/supercorp-ai/supergateway](https://github.com/supercorp-ai/supergateway) . ### Configure your MCP Servers[​](https://docs.openbb.co/workspace/analysts/ai-features/mcp-tools#configure-your-mcp-servers "Direct link to Configure your MCP Servers") Clicking this button opens the MCP server enable/disable menu. ![](https://openbb-cms.directus.app/assets/2d50c181-6fa0-4ec4-81b6-3faa936af17e.png) Here you'll find the "+" icon that allows you to add or edit MCP servers. ![](https://openbb-cms.directus.app/assets/861831f2-9bfc-41d2-bdd7-bc673ad39656.png) Clicking the "+" icon opens the MCP Servers configuration dialog. ![](https://openbb-cms.directus.app/assets/1d12fdc5-4424-4858-8c34-85db9c18ba2e.png) Within this dialog, clicking "Add Server" opens the following pop-up window. ![](https://openbb-cms.directus.app/assets/15e88b0c-d9d0-4697-87f0-2c82f0213d0f.png) Clicking "Add" initiates the connection, regardless of OAuth configuration. Here's how OAuth appears when connecting to [Smithery.ai](https://smithery.ai/) , a directory containing over 6,000 MCP servers. ![](https://openbb-cms.directus.app/assets/0ef5c823-a1fe-4fec-9d17-9165e0d282b1.png) After connecting, you'll return to the Workspace and see "Authenticating..." displayed. ![](https://openbb-cms.directus.app/assets/2b3b1671-20c3-46de-9985-5c55ba22c2c5.png) In the MCP Servers Configuration dialog, clicking on a successfully connected server displays the discovered tools. You can then open these tools to view their descriptions. ![](https://openbb-cms.directus.app/assets/3d2e53ed-5d63-46e8-b369-d0e19c7017ef.png) ### Select MCP Server tools[​](https://docs.openbb.co/workspace/analysts/ai-features/mcp-tools#select-mcp-server-tools "Direct link to Select MCP Server tools") With the MCP Tools dialog open, you can enable or disable specific MCP tools for Copilot access. ![](https://openbb-cms.directus.app/assets/861831f2-9bfc-41d2-bdd7-bc673ad39656.png) Once an MCP Server is successfully connected, you can: 1. Select all or none of the tools of a specific MCP Server. This toggles all fine-grained tool-level controls simultaneously. It's the most efficient way to exclude an MCP Server from Copilot's context. 2. Turn ON/OFF a specific set of tools from an MCP Server. Note: Enabling all tools doesn't guarantee Copilot will use every tool; rather, it makes them available for selection. This granular control helps narrow OpenBB Copilot's context to what's most relevant to your needs. * * * If the MCP Server becomes disconnected, it will appear as disabled, as shown below: ![](https://openbb-cms.directus.app/assets/d983cab2-9cf0-4d2a-85d2-0226860b890d.png) ### MCP in action[​](https://docs.openbb.co/workspace/analysts/ai-features/mcp-tools#mcp-in-action "Direct link to MCP in action") When you submit a query to Copilot with MCP tools enabled, it can utilize one or more tools based on your prompt, including sequential tool usage when necessary. For example, accessing OpenBB documentation requires two tools from the same MCP Server. Copilot automatically determines and executes this sequence on your behalf. ![](https://openbb-cms.directus.app/assets/5a9ef8ee-89e0-4f7c-853c-77fda234de00.png) ### Matching widget to MCP tools[​](https://docs.openbb.co/workspace/analysts/ai-features/mcp-tools#matching-widget-to-mcp-tools "Direct link to Matching widget to MCP tools") As shown above, in the reasoning step, you can see when and at which point the MCP tool was called. In addition, you can configure a widget that shares identical metadata, or what we refer to as “matching”, to the corresponding MCP tool. Once a matching widget has been set up, a citation marked with an asterisk (\*) will appear at the end whenever the MCP tool is used. ![Widget hover tooltip showing option to add to dashboard](https://openbb-cms.directus.app/assets/d2c50edb-43e2-4771-9125-b31117501a61.png) Additionally, when you click “Add matching widget to dashboard,” the widget will be automatically added to your current dashboard, using the same parameters applied by Copilot. ![Interactive widget dashboard showing parameters, charting, and OpenBB properties](https://openbb-cms.directus.app/assets/a719abc4-9b2f-41c7-b1a8-dd84fc707b77.png) On this page * [Configure your MCP Servers](https://docs.openbb.co/workspace/analysts/ai-features/mcp-tools#configure-your-mcp-servers) * [Select MCP Server tools](https://docs.openbb.co/workspace/analysts/ai-features/mcp-tools#select-mcp-server-tools) * [MCP in action](https://docs.openbb.co/workspace/analysts/ai-features/mcp-tools#mcp-in-action) * [Matching widget to MCP tools](https://docs.openbb.co/workspace/analysts/ai-features/mcp-tools#matching-widget-to-mcp-tools) --- # YouTube | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-types/youtube#__docusaurus_skipToContent_fallback) On this page A widget that embeds and displays YouTube videos. The YouTube widget supports two modes: basic video playback and video with transcript support for AI context. Basic YouTube Widget[​](https://docs.openbb.co/workspace/developers/widget-types/youtube#basic-youtube-widget "Direct link to Basic YouTube Widget") ----------------------------------------------------------------------------------------------------------------------------------------------------- A simple widget that displays a YouTube video player. The endpoint returns the YouTube video URL as plain text. ![Basic YouTube Widget](https://openbb-cms.directus.app/assets/f30f91a8-340e-46f5-a690-18e01a9d7447.png) from fastapi import Queryfrom fastapi.responses import PlainTextResponsefrom typing import Listfrom pydantic import BaseModelclass FileOption(BaseModel): label: str value: str# Sample YouTube videos dataSAMPLE_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"]) The widget configuration specifies `"type": "youtube"` which tells OpenBB Workspace to render the returned URL in an embedded YouTube player. YouTube Widget with Transcript Support[​](https://docs.openbb.co/workspace/developers/widget-types/youtube#youtube-widget-with-transcript-support "Direct link to YouTube Widget with Transcript Support") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- This variant adds transcript support for AI assistants. When the `raw` configuration is set to `True`, the frontend will request the endpoint with `?raw=true` to get the transcript content instead of the video URL. ![YouTube Widget with Transcript Support](https://openbb-cms.directus.app/assets/da80b714-c121-49de-ac73-c4b9b587ed83.png)![YouTube Widget AI Context](https://openbb-cms.directus.app/assets/ef5c1a64-c009-4b19-b2e3-d0742ded8de4.png) from fastapi import Queryfrom fastapi.responses import PlainTextResponsefrom typing import Listfrom pydantic import BaseModelclass FileOption(BaseModel): label: str value: str# Sample YouTube videos data with transcriptsSAMPLE_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"]) ### How AI Context Works[​](https://docs.openbb.co/workspace/developers/widget-types/youtube#how-ai-context-works "Direct link to How AI Context Works") When `"raw": True` is set in the widget configuration: 1. **Normal viewing**: The frontend requests the endpoint without the `raw` parameter (or `raw=false`), and the endpoint returns the YouTube URL for the video player. 2. **AI context**: When an AI assistant needs to understand the widget content, the frontend requests the endpoint with `?raw=true`, and the endpoint returns the transcript in markdown format. This allows AI assistants to read and understand the video content without having to watch the video, enabling them to answer questions about the video or provide summaries. Key Configuration Options[​](https://docs.openbb.co/workspace/developers/widget-types/youtube#key-configuration-options "Direct link to Key Configuration Options") -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | Property | Type | Description | | --- | --- | --- | | `type` | `string` | Must be `"youtube"` for YouTube widgets | | `raw` | `boolean` | Set to `True` to enable transcript requests for AI context | | `endpoint` | `string` | The endpoint that returns the video URL (or transcript when `raw=true`) | | `gridData` | `object` | Widget dimensions (`w` for width, `h` for height) | Response Format[​](https://docs.openbb.co/workspace/developers/widget-types/youtube#response-format "Direct link to Response Format") -------------------------------------------------------------------------------------------------------------------------------------- * **Video URL**: Return as `PlainTextResponse` with the full YouTube URL (e.g., `https://www.youtube.com/watch?v=VIDEO_ID`) * **Transcript**: Return as `PlainTextResponse` with `media_type="text/markdown"` for formatted content On this page * [Basic YouTube Widget](https://docs.openbb.co/workspace/developers/widget-types/youtube#basic-youtube-widget) * [YouTube Widget with Transcript Support](https://docs.openbb.co/workspace/developers/widget-types/youtube#youtube-widget-with-transcript-support) * [How AI Context Works](https://docs.openbb.co/workspace/developers/widget-types/youtube#how-ai-context-works) * [Key Configuration Options](https://docs.openbb.co/workspace/developers/widget-types/youtube#key-configuration-options) * [Response Format](https://docs.openbb.co/workspace/developers/widget-types/youtube#response-format) --- # Environment Variables - ODP Python | OpenBB Docs [Skip to main content](https://docs.openbb.co/odp/python/settings/environment_variables#__docusaurus_skipToContent_fallback) On this page Environment variables are defined in a `.env` file. If this file does not exist, create it inside the same folder `user_settings.json` is located. * `OPENBB_DEBUG_MODE`: enables verbosity while running the program * `OPENBB_DEV_MODE`: applicable to the API; exposes, /system and /user, paths. * `OPENBB_AUTO_BUILD`: enables automatic SDK package build on import * `OPENBB_API_AUTH_EXTENSION`: specifies which API authentication extension to use * `OPENBB_API_AUTH`: enables API authentication for command endpoints * `OPENBB_API_USERNAME`: sets API username * `OPENBB_API_PASSWORD`: sets API password * `OPENBB_ALLOW_ON_COMMAND_OUTPUT`: enables OBBject extensions to perform additional operations before returning. * `OPENBB_ALLOW_MUTABLE_EXTENSIONS`: enables OBBject extensions to alter function output. Variables can be defined for current session only. import osos.environ["OPENBB_DEBUG_MODE"] = "True"from openbb import obb ### Proxy Networks[​](https://docs.openbb.co/odp/python/settings/environment_variables#proxy-networks "Direct link to Proxy Networks") info See [System Settings](https://docs.openbb.co/odp/python/settings/system_settings#http) for information on configuring global settings and the session object. API Keys[​](https://docs.openbb.co/odp/python/settings/environment_variables#api-keys "Direct link to API Keys") ----------------------------------------------------------------------------------------------------------------- In addition to `user_settings.json`, API keys can be defined as environment variables (openbb-core V1.4.8). For example, to define `fmp_api_key` as an environment variable, add the following to the `~/.openbb_platform/.env` file. If it doesn't exist, create it. FMP_API_KEY = "replaceWITHyourK3Y" Along with the installed providers' credentials, if an entry in the `.env` file ends with `_API_KEY`, it will be accessible as, `obb.user.credentials.some_key` On this page * [Proxy Networks](https://docs.openbb.co/odp/python/settings/environment_variables#proxy-networks) * [API Keys](https://docs.openbb.co/odp/python/settings/environment_variables#api-keys) --- # Highcharts Chart | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-types/highcharts#__docusaurus_skipToContent_fallback) On this page A widget that demonstrates how to use the Highcharts library to create a chart. This gives you the ability to create any interactive type of charts with the Highcharts ecosystem. For Highcharts integration, we're using the `highcharts_core` Python package to create and configure the chart. Install it with: pip install highcharts-core ![Basic Plotly Chart Example](https://openbb-cms.directus.app/assets/fc125d0e-f26b-45f7-84ae-0562c20befdf.png) @register_widget({ "name": "Chains TVL Highcharts", "description": "Get current TVL of all chains using Defi Llama and plot with Highcharts", "category": "crypto", "type": "chart-highcharts", "endpoint": "chains_highchart", "gridData": {"w": 20, "h": 9}})@app.get("/chains_highchart")def get_chains_highchart(theme: str = "dark"): """Get current TVL of all chains using Defi Llama""" response = requests.get("https://api.llama.fi/v2/chains") if response.status_code == 200: chains = response.json() # Sort by TVL and get top 30 top_30 = sorted(chains, key=lambda x: x.get('tvl', 0), reverse=True)[:30] # Extract categories and format TVL values (in billions) categories = [chain['name'] for chain in top_30] data = [round(chain['tvl'] / 1e9, 2) for chain in top_30] # Configure chart options with theme support chart_options = { 'chart': { 'type': 'column', 'backgroundColor': 'transparent' }, 'title': {'text': 'Top 30 Chains by TVL'}, 'xAxis': { 'categories': categories, 'title': {'text': 'Chain Name'}, 'labels': { 'style': { 'color': '#ffffff' if theme == 'dark' else '#000000' } } }, 'yAxis': { 'title': {'text': 'Total Value Locked (TVL in billions $)'}, 'labels': { 'style': { 'color': '#ffffff' if theme == 'dark' else '#000000' } } }, 'tooltip': { 'pointFormat': '${point.y:.2f}B' }, 'series': [{ 'name': 'Chain', 'data': data }] } # Apply theme-specific styling if theme == 'dark': chart_options.update({ 'title': {'text': 'Top 30 Chains by TVL', 'style': {'color': '#ffffff'}}, 'legend': {'itemStyle': {'color': '#ffffff'}}, 'xAxis': { **chart_options['xAxis'], 'title': {'text': 'Chain Name', 'style': {'color': '#ffffff'}}, 'lineColor': '#555555', 'tickColor': '#555555' }, 'yAxis': { **chart_options['yAxis'], 'title': {'text': 'Total Value Locked (TVL in billions $)', 'style': {'color': '#ffffff'}}, 'gridLineColor': '#333333' }, 'plotOptions': { 'series': { 'color': '#3498db' } } }) else: chart_options.update({ 'title': {'text': 'Top 30 Chains by TVL', 'style': {'color': '#333333'}}, 'legend': {'itemStyle': {'color': '#333333'}}, 'xAxis': { **chart_options['xAxis'], 'title': {'text': 'Chain Name', 'style': {'color': '#333333'}}, 'lineColor': '#cccccc', 'tickColor': '#cccccc' }, 'yAxis': { **chart_options['yAxis'], 'title': {'text': 'Total Value Locked (TVL in billions $)', 'style': {'color': '#333333'}}, 'gridLineColor': '#e6e6e6' }, 'plotOptions': { 'series': { 'color': '#2980b9' } } }) chart = Chart.from_options(chart_options) return chart.to_dict() return JSONResponse( content={"error": response.text}, status_code=response.status_code ) Note that for Highcharts, the `type` field is set to `"chart-highcharts"` instead of just `"chart"` which is used for Plotly charts. ### Theme Support[​](https://docs.openbb.co/workspace/developers/widget-types/highcharts#theme-support "Direct link to Theme Support") The example includes full theme support for both dark and light modes. The theme parameter is automatically provided by OpenBB Workspace based on the user's current display mode (dark/light). This enables dynamic chart styling that matches the workspace theme. * **Dark mode**: White text, dark grid lines, blue series color (#3498db) * **Light mode**: Dark text, light grid lines, darker blue series color (#2980b9) Additional Resources[​](https://docs.openbb.co/workspace/developers/widget-types/highcharts#additional-resources "Direct link to Additional Resources") -------------------------------------------------------------------------------------------------------------------------------------------------------- For more information on Highcharts configuration options, visit the [Highcharts API Documentation](https://api.highcharts.com/highcharts/) . You can find more examples of how to set up your own backend in the [Backend for OpenBB Workspace GitHub](https://github.com/OpenBB-finance/backend-examples-for-openbb-workspace) . On this page * [Theme Support](https://docs.openbb.co/workspace/developers/widget-types/highcharts#theme-support) * [Additional Resources](https://docs.openbb.co/workspace/developers/widget-types/highcharts#additional-resources) --- # OpenBB Snowflake Native App - Quick Start [Skip to main content](https://docs.openbb.co/snowflake#__docusaurus_skipToContent_fallback) On this page Welcome to the OpenBB Snowflake Native App! This guide walks you through the first steps after installing. Security Notice: Python Execution Capability[​](https://docs.openbb.co/snowflake#security-notice-python-execution-capability "Direct link to Security Notice: Python Execution Capability") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- **Important:** This app includes a Python notebook execution feature that allows users to run custom Python code within their Snowflake environment. **Security Characteristics:** * Code runs with `EXECUTE AS RESTRICTED CALLER` in a controlled Snowpark environment * Code runs with the customer's privileges, with additional restrictions * Execution is sandboxed within Snowflake's native Python runtime * No external network access from executed code (Snowflake's default sandbox blocks network egress) * All code execution is logged and auditable through Snowflake's query history **Recommended Usage:** * Grant the `app_user` role only to trusted users who need analytics capabilities * Review Snowflake query history regularly to monitor code execution * Limit warehouse size to control resource consumption * * * 1\. Installation and Warehouse Configuration[​](https://docs.openbb.co/snowflake#1-installation-and-warehouse-configuration "Direct link to 1. Installation and Warehouse Configuration") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ **How to bind the warehouse (required):** You must give the app access to the default warehouse for whatever user will be using the application. The App will install its own warehouse but that is for some app related setup / use. GRANT USAGE ON WAREHOUSE TO APPLICATION ;GRANT CALLER USAGE ON WAREHOUSE TO APPLICATION ; **What the App warehouse is used for:** * Executing Python notebook code via the `app_execute_py()` procedure * Backend operations that require compute resources * * * 2\. Grant Cortex AI Privileges (Required for AI Features)[​](https://docs.openbb.co/snowflake#2-grant-cortex-ai-privileges-required-for-ai-features "Direct link to 2. Grant Cortex AI Privileges (Required for AI Features)") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- For the AI/Agent functionality to work, you must enable Cortex cross-region support and grant Cortex database roles to the application. Some of these may already be true but this is the full list of commands to run. Run these commands as an **ACCOUNTADMIN**: -- Enable Cortex to work across regions (account-level setting)ALTER ACCOUNT SET CORTEX_ENABLED_CROSS_REGION = 'ANY_REGION';-- Grant Cortex database roles to the applicationGRANT DATABASE ROLE SNOWFLAKE.CORTEX_USER TO APPLICATION ;GRANT DATABASE ROLE SNOWFLAKE.CORTEX_AGENT_USER TO APPLICATION ; **Example:** ALTER ACCOUNT SET CORTEX_ENABLED_CROSS_REGION = 'ANY_REGION';GRANT DATABASE ROLE SNOWFLAKE.CORTEX_USER TO APPLICATION ;GRANT DATABASE ROLE SNOWFLAKE.CORTEX_AGENT_USER TO APPLICATION ; **Notes:** * The `ALTER ACCOUNT` command is required to enable Snowflake Cortex Agent functionality across regions * These grants require the `IMPORTED PRIVILEGES ON SNOWFLAKE DB` privilege (already declared in the app manifest) * These commands only need to be run once per account * * * 3\. Map App Roles to Your Account Roles (Optional)[​](https://docs.openbb.co/snowflake#3-map-app-roles-to-your-account-roles-optional "Direct link to 3. Map App Roles to Your Account Roles (Optional)") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The app defines two application roles: * **`app_user`** → run the app and access the UI * **`app_admin`** → manage the service (start/stop/monitor/scale) As an account admin, map these roles to your own roles: -- Example: grant app roles to a role named OPENBB_TESTERSCREATE ROLE IF NOT EXISTS OPENBB_TESTERS;GRANT APPLICATION ROLE .app_user TO ROLE OPENBB_TESTERS;GRANT APPLICATION ROLE .app_admin TO ROLE OPENBB_TESTERS;-- Assign that role to a userGRANT ROLE OPENBB_TESTERS TO USER ; 4\. Grant Database/Schema/Table access to the App (read-only)[​](https://docs.openbb.co/snowflake#4-grant-databaseschematable-access-to-the-app-read-only "Direct link to 4. Grant Database/Schema/Table access to the App (read-only)") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- By default, the app cannot see your data until it is explicitly shared with the application. As an admin, grant the APPLICATION access to the databases/schemas/tables you want the app to expose in its UI. The user will also need access to these Databases since every call is made as the user. > Replace `` with your installed application name (e.g., `openbb_native_app`), and adjust database/schema names to your environment. **Example (for an owned database):** -- Grant Access (Internal Database)GRANT CALLER USAGE ON DATABASE TO APPLICATION ;GRANT CALLER USAGE ON SCHEMA . TO APPLICATION ;GRANT INHERITED CALLER SELECT ON ALL TABLES IN SCHEMA . TO APPLICATION ;GRANT INHERITED CALLER SELECT ON ALL VIEWS IN SCHEMA . TO APPLICATION ;-- If you have procedures to bring inGRANT INHERITED CALLER USAGE ON ALL PROCEDURES IN SCHEMA . TO APPLICATION ; **Example (for a shared database):** Note : The syntax is a bit different for shared. -- Grant Access (Shared Database)GRANT CALLER USAGE ON DATABASE GLOBAL_WEATHER__CLIMATE_DATA_FOR_BI TO APPLICATION ;GRANT INHERITED CALLER USAGE ON ALL SCHEMAS IN DATABASE GLOBAL_WEATHER__CLIMATE_DATA_FOR_BI TO APPLICATION ;GRANT INHERITED CALLER SELECT ON ALL VIEWS IN DATABASE GLOBAL_WEATHER__CLIMATE_DATA_FOR_BI TO APPLICATION ;GRANT INHERITED CALLER SELECT ON ALL TABLES IN DATABASE GLOBAL_WEATHER__CLIMATE_DATA_FOR_BI TO APPLICATION ;GRANT IMPORTED PRIVILEGES ON ALL TABLES IN DATABASE GLOBAL_WEATHER__CLIMATE_DATA_FOR_BI TO ROLE ANALYTICS_USER;GRANT IMPORTED PRIVILEGES ON ALL VIEWS IN DATABASE GLOBAL_WEATHER__CLIMATE_DATA_FOR_BI TO ROLE ANALYTICS_USER; * * * Now when you refresh the workspace you will see your table and views as widgets in the search menu. Service Administration[​](https://docs.openbb.co/snowflake#service-administration "Direct link to Service Administration") --------------------------------------------------------------------------------------------------------------------------- 1\. Automatic Service Start[​](https://docs.openbb.co/snowflake#1-automatic-service-start "Direct link to 1. Automatic Service Start") --------------------------------------------------------------------------------------------------------------------------------------- The OpenBB services start **automatically** after installation completes. The app uses Snowflake's lifecycle callback system to automatically: * Create two compute pools (backend + app) * Create the warehouse used for the app * Start the backend service (database + Redis) * Start the app service (API + AI) after backend is ready **The services start automatically when:** * The app is first installed * A new version or patch is deployed * The app is upgraded **Check service status:** CALL .core.get_service_status();-- Returns: "Backend: READY, App: READY" **Note:** The services may take 3-5 minutes to fully start after installation. * * * 2\. Manual Service Control (Optional)[​](https://docs.openbb.co/snowflake#2-manual-service-control-optional "Direct link to 2. Manual Service Control (Optional)") ------------------------------------------------------------------------------------------------------------------------------------------------------------------- If you need to manually control the services, these procedures are available to admins: ### Start/Stop All Services[​](https://docs.openbb.co/snowflake#startstop-all-services "Direct link to Start/Stop All Services") -- Start all services (usually not needed - automatic on install/upgrade)CALL .core.start_openbb_service();-- Stop all services (suspends backend to preserve data, drops app service)CALL .core.stop_openbb_service();-- Restart all servicesCALL .core.restart_openbb_service(); ### Control Services Individually[​](https://docs.openbb.co/snowflake#control-services-individually "Direct link to Control Services Individually") -- Stop just the app service (safe - stateless)CALL .core.stop_app_service();-- Suspend backend service (preserves database data)CALL .core.suspend_backend_service();-- Resume backend service from suspended stateCALL .core.resume_backend_service(); **Important:** Never DROP the backend service directly - use `suspend_backend_service()` to preserve your Postgres data. * * * 3\. Scaling the App (Admin)[​](https://docs.openbb.co/snowflake#3-scaling-the-app-admin "Direct link to 3. Scaling the App (Admin)") ------------------------------------------------------------------------------------------------------------------------------------- Admins can adjust scaling parameters for the app pool and service: ### Adjust Compute Pool Size[​](https://docs.openbb.co/snowflake#adjust-compute-pool-size "Direct link to Adjust Compute Pool Size") -- Set app pool to scale between 1 and 3 nodes (max 5)CALL .core.set_app_pool_size(1, 3); ### Adjust Service Instance Count[​](https://docs.openbb.co/snowflake#adjust-service-instance-count "Direct link to Adjust Service Instance Count") -- Set app service to scale between 1 and 4 instances (max 8)CALL .core.set_app_service_scale(1, 4); **Notes:** * Backend pool is fixed at 1 node (required for block storage) * Contact OpenBB for limits higher than 5 nodes / 8 instances * * * Troubleshooting logs[​](https://docs.openbb.co/snowflake#troubleshooting-logs "Direct link to Troubleshooting logs") --------------------------------------------------------------------------------------------------------------------- 4\. Viewing Container Logs (Troubleshooting)[​](https://docs.openbb.co/snowflake#4-viewing-container-logs-troubleshooting "Direct link to 4. Viewing Container Logs (Troubleshooting)") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Admins can view logs from each container to troubleshoot issues: -- App service containersCALL .core.get_api_logs(100); -- API/UI containerCALL .core.get_ai_logs(100); -- ADA (AI copilot) container-- Backend service containersCALL .core.get_db_logs(100); -- PostgreSQL databaseCALL .core.get_redis_logs(100); -- Redis cache-- Generic procedure for any containerCALL .core.get_container_logs('core.openbb_app', 'api', 100);CALL .core.get_container_logs('core.openbb_backend', 'db', 100); * * * Quick Reference[​](https://docs.openbb.co/snowflake#quick-reference "Direct link to Quick Reference") ------------------------------------------------------------------------------------------------------ | Procedure | Description | | --- | --- | | `get_service_status()` | Check if services are running | | `start_openbb_service()` | Start all services | | `stop_openbb_service()` | Stop all services (safe) | | `restart_openbb_service()` | Restart all services | | `suspend_backend_service()` | Suspend backend (preserves data) | | `resume_backend_service()` | Resume backend from suspend | | `stop_app_service()` | Stop app service only | | `set_app_pool_size(min, max)` | Adjust app pool nodes (max 5) | | `set_app_service_scale(min, max)` | Adjust app instances (max 8) | | `get_api_logs(n)` | View API container logs | | `get_ai_logs(n)` | View ADA container logs | | `get_db_logs(n)` | View Postgres logs | | `get_redis_logs(n)` | View Redis logs | On this page * [Security Notice: Python Execution Capability](https://docs.openbb.co/snowflake#security-notice-python-execution-capability) * [1\. Installation and Warehouse Configuration](https://docs.openbb.co/snowflake#1-installation-and-warehouse-configuration) * [2\. Grant Cortex AI Privileges (Required for AI Features)](https://docs.openbb.co/snowflake#2-grant-cortex-ai-privileges-required-for-ai-features) * [3\. Map App Roles to Your Account Roles (Optional)](https://docs.openbb.co/snowflake#3-map-app-roles-to-your-account-roles-optional) * [4\. Grant Database/Schema/Table access to the App (read-only)](https://docs.openbb.co/snowflake#4-grant-databaseschematable-access-to-the-app-read-only) * [Service Administration](https://docs.openbb.co/snowflake#service-administration) * [1\. Automatic Service Start](https://docs.openbb.co/snowflake#1-automatic-service-start) * [2\. Manual Service Control (Optional)](https://docs.openbb.co/snowflake#2-manual-service-control-optional) * [Start/Stop All Services](https://docs.openbb.co/snowflake#startstop-all-services) * [Control Services Individually](https://docs.openbb.co/snowflake#control-services-individually) * [3\. Scaling the App (Admin)](https://docs.openbb.co/snowflake#3-scaling-the-app-admin) * [Adjust Compute Pool Size](https://docs.openbb.co/snowflake#adjust-compute-pool-size) * [Adjust Service Instance Count](https://docs.openbb.co/snowflake#adjust-service-instance-count) * [Troubleshooting logs](https://docs.openbb.co/snowflake#troubleshooting-logs) * [4\. Viewing Container Logs (Troubleshooting)](https://docs.openbb.co/snowflake#4-viewing-container-logs-troubleshooting) * [Quick Reference](https://docs.openbb.co/snowflake#quick-reference) --- # Live Grid | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-types/live-grid#__docusaurus_skipToContent_fallback) On this page A widget that displays real-time data updates in a table format using WebSocket connections. The live grid widget can be configured to only update certain cells when their values change or all of the cells. ![Live Grid Example](https://openbb-assets.s3.us-east-1.amazonaws.com/docs/pro/live_grid.png) import asynciofrom datetime import datetimefrom fastapi import FastAPI, WebSocket, WebSocketDisconnect, HTTPExceptionfrom fastapi.websockets import WebSocketStateimport numpy as npapp = FastAPI()# Sample data storeWS_DATA = { "AAPL": { "price": 150.0, "prev_close": 145.54, "volume": 1000000, "change": 4.46, "change_percent": 0.03, }, "GOOGL": { "price": 140.0, "prev_close": 138.20, "volume": 800000, "change": 1.80, "change_percent": 0.013, }, "MSFT": { "price": 350.0, "prev_close": 345.00, "volume": 1200000, "change": 5.00, "change_percent": 0.014, }, "AMZN": { "price": 178.0, "prev_close": 175.50, "volume": 900000, "change": 2.50, "change_percent": 0.014, }, "TSLA": { "price": 245.0, "prev_close": 240.00, "volume": 1500000, "change": 5.00, "change_percent": 0.021, },}def get_ws_data(symbol: str): """Generate real-time data for a symbol""" data = WS_DATA.get(symbol, {"price": 100.0, "prev_close": 100.0, "volume": 1000000}) price = data["price"] + np.random.uniform(-10, 10) volume = data["volume"] + np.random.randint(100, 1000) change = price - data["prev_close"] change_percent = change / data["prev_close"] WS_DATA[symbol].update(dict(price=price, volume=volume)) return { "symbol": symbol, "price": price, "change": change, "change_percent": change_percent, "volume": volume, }@register_widget({ "name": "Live Grid", "description": "Live Grid with real-time WebSocket updates", "type": "live_grid", "endpoint": "live_grid_data", "wsEndpoint": "live_grid_ws", "gridData": {"w": 20, "h": 9}, "data": { "wsRowIdColumn": "symbol", "table": { "showAll": True, "columnsDefs": [ { "field": "symbol", "headerName": "Symbol" }, { "field": "price", "headerName": "Price", "renderFn": "showCellChange", "renderFnParams": { "colorValueKey": "change" } }, { "field": "change_percent", "headerName": "Change %", "renderFn": "greenRed" }, { "field": "volume", "enableCellChangeWs": False, "headerName": "Volume" } ] } }, "params": [ { "paramName": "symbol", "description": "The symbol to get details for", "value": "TSLA", "label": "Symbol", "type": "text", "multiSelect": True, "options": [ {"label": "AAPL", "value": "AAPL"}, {"label": "GOOGL", "value": "GOOGL"}, {"label": "MSFT", "value": "MSFT"}, {"label": "AMZN", "value": "AMZN"}, {"label": "TSLA", "value": "TSLA"} ] } ]})@app.get("/live_grid_data")def get_live_grid_data(symbol: str): """Initial data endpoint for live grid""" symbols = symbol.split(",") return [ { "date": str(datetime.now().date()), **get_ws_data(sym), "market_cap": np.random.randint(1000000000, 2000000000), } for sym in symbols ]@app.websocket("/live_grid_ws")async def websocket_endpoint(websocket: WebSocket): """WebSocket endpoint for live updates""" await websocket.accept() try: await websocket_handler(websocket) except WebSocketDisconnect: return except Exception as e: await websocket.close(code=1011) raise HTTPException(status_code=500, detail=str(e))async def websocket_handler(websocket: WebSocket): """Handle WebSocket connections for live grid updates""" subbed_symbols: set[str] = set() async def consumer_handler(ws: WebSocket): try: async for data in ws.iter_json(): if symbols := data.get("params", {}).get("symbol"): if isinstance(symbols, str): symbols = symbols.split(",") subbed_symbols.clear() subbed_symbols.update(set(symbols)) except WebSocketDisconnect: pass except RuntimeError: await ws.close() async def producer_handler(ws: WebSocket): try: while websocket.client_state != WebSocketState.DISCONNECTED: current_symbols = list(subbed_symbols) np.random.shuffle(current_symbols) for symbol in current_symbols: await ws.send_json(get_ws_data(symbol)) await asyncio.sleep(np.random.uniform(0.5, 0.8)) await asyncio.sleep(np.random.uniform(0.1, 0.3)) except WebSocketDisconnect: pass except RuntimeError: await ws.close() consumer_task = asyncio.create_task(consumer_handler(websocket)) producer_task = asyncio.create_task(producer_handler(websocket)) done, pending = await asyncio.wait( [consumer_task, producer_task], return_when=asyncio.FIRST_COMPLETED ) for task in pending: task.cancel() ### Key Configuration Options[​](https://docs.openbb.co/workspace/developers/widget-types/live-grid#key-configuration-options "Direct link to Key Configuration Options") * **`wsEndpoint`**: The WebSocket endpoint for receiving live updates * **`wsRowIdColumn`**: The column used to identify rows for updating (e.g., "symbol") * **`enableCellChangeWs`**: Boolean to control whether a cell updates via WebSocket. By default `true` for fields sent in the WebSocket. Set to `false` to prevent updates for specific columns * **`renderFn`**: The function used to render the cell. See [Render Functions](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions) for more options ### How It Works[​](https://docs.openbb.co/workspace/developers/widget-types/live-grid#how-it-works "Direct link to How It Works") 1. **Initial Data**: The GET endpoint (`/live_grid_data`) provides the initial table data 2. **WebSocket Connection**: The WebSocket endpoint (`/live_grid_ws`) handles real-time updates 3. **Row Identification**: The `wsRowIdColumn` links WebSocket updates to specific table rows 4. **Cell Updates**: Only cells that receive new data via WebSocket are updated, with optional visual change indicators Additional Resources[​](https://docs.openbb.co/workspace/developers/widget-types/live-grid#additional-resources "Direct link to Additional Resources") ------------------------------------------------------------------------------------------------------------------------------------------------------- You can find more examples of how to set up your own backend in the [Backend for OpenBB Workspace GitHub](https://github.com/OpenBB-finance/backend-examples-for-openbb-workspace) . On this page * [Key Configuration Options](https://docs.openbb.co/workspace/developers/widget-types/live-grid#key-configuration-options) * [How It Works](https://docs.openbb.co/workspace/developers/widget-types/live-grid#how-it-works) * [Additional Resources](https://docs.openbb.co/workspace/developers/widget-types/live-grid#additional-resources) --- # Output Formats | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/ai-features/copilot-output#__docusaurus_skipToContent_fallback) On this page The Copilot's output system delivers comprehensive, contextual responses that synthesize all available information into actionable insights. Each response is structured to provide immediate answers while supporting deeper investigation, combining direct responses with supporting evidence, data visualizations, and clear pathways for follow-up analysis. Citations[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-output#citations "Direct link to Citations") ------------------------------------------------------------------------------------------------------------------------ Comprehensive citation system ensures full traceability and verification of all information sources used in responses. The citation system provides different levels of detail based on source type: * **Widget citations:** Direct links to widgets with parameters selected. Smart linking enables "Scroll to widget" functionality for existing dashboard widgets. If the widget doesn't exist in the dashboard or has modified parameters the linking will provide a "Add widget to dashboard" options to facilitate workspace workflow. ![Widget citations](https://openbb-cms.directus.app/assets/26f4da06-acc4-4aa2-8540-d56cec931f99.png) * **Document citations:** Precise page and section references for PDF documents with automatic highlighting of relevant content areas. ![Document citations](https://openbb-cms.directus.app/assets/05dfd0b0-b3b5-41a5-b916-0f89a8e50dd1.png) * **Web citations:** Full URL references when web pages are utilized. ![Web citations](https://openbb-cms.directus.app/assets/6073a901-0005-4927-8951-021243333c48.png) Create widgets from AI output[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-output#create-widgets-from-ai-output "Direct link to Create widgets from AI output") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ The widget creation system enables seamless integration of Copilot-generated content into your workspace environment. This capability transforms temporary conversational outputs into permanent analytical assets that can be referenced, shared, and incorporated into ongoing workflows. The system supports multiple artifact types including formatted text summaries, interactive data tables with sorting and filtering capabilities, and fully functional charts with preserved interactivity. * Text widget: ![Text widget from AI output](https://openbb-cms.directus.app/assets/517d6934-6d89-44df-ba5b-995520bcb1e6.png) * Table widget: ![Table widget from AI output](https://openbb-cms.directus.app/assets/c987377c-1dc9-4a96-b590-3694a6c764b4.png) * Chart widget: ![Chart widget from AI output](https://openbb-cms.directus.app/assets/9e7f2d80-1bd1-4238-bffc-099598c995a6.png) User feedback loop[​](https://docs.openbb.co/workspace/analysts/ai-features/copilot-output#user-feedback-loop "Direct link to User feedback loop") --------------------------------------------------------------------------------------------------------------------------------------------------- The thumbs up and down buttons in the agent output allow the user to provide feedback in terms of their experience with the copilot. That data can be utilized to create a flywheel that allows developers to understand how the AI agent can be improved. While the thumbs up does not prompt the user for any additional details. ![Thumbs up](https://openbb-cms.directus.app/assets/fc1ea4d0-e0b0-4669-ae40-23871ae67790.png) The thumbs down asks for clarification of what went wrong. ![Thumbs down](https://openbb-cms.directus.app/assets/e89e9f77-6d52-4921-8f81-b73d39260d6f.png) On this page * [Citations](https://docs.openbb.co/workspace/analysts/ai-features/copilot-output#citations) * [Create widgets from AI output](https://docs.openbb.co/workspace/analysts/ai-features/copilot-output#create-widgets-from-ai-output) * [User feedback loop](https://docs.openbb.co/workspace/analysts/ai-features/copilot-output#user-feedback-loop) --- # Open Data Platform by OpenBB | ODP Docs [Skip to main content](https://docs.openbb.co/odp#__docusaurus_skipToContent_fallback) Open Data Platform by OpenBB (ODP) is the open-source toolset that helps data engineers to integrate proprietary, licensed, and public data sources into downstream applications like AI copilots and research dashboards. ODP operates as the "connect once, consume everywhere" infrastructure layer that consolidates and exposes data to multiple surfaces at once: * Python environment for quants * OpenBB Workspace and Excel for analysts * MCP servers for AI agents * REST APIs for other applications It consists of three main components: [ODP Desktop\ \ A standalone desktop application providing a user-friendly interface for managing Python environments and application backend servers.](https://docs.openbb.co/odp/desktop) [ODP Python\ \ PyPI-installable Python packages for building and using Python SDKs, REST APIs, and MCP servers.](https://docs.openbb.co/odp/python) [ODP CLI\ \ A command-line interface wrapping the environnent's installed ODP Python packages. .](https://docs.openbb.co/odp/cli) All three tools share the same underlying infrastructure, so you can choose whichever interface fits your workflow. --- # TradingView Charts | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#__docusaurus_skipToContent_fallback) On this page This guide explains how to implement TradingView charts in OpenBB using TradingView's Universal Data Feed (UDF) protocol. The UDF protocol allows you to create custom data feeds for TradingView charts. ![Basic Plotly Chart Example](https://openbb-cms.directus.app/assets/36f110ab-3cfb-4a46-b3b4-3541acdd7f27.png) Prerequisites[​](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#prerequisites "Direct link to Prerequisites") ------------------------------------------------------------------------------------------------------------------------------------------- 1. FastAPI or similar web framework for implementing the UDF endpoints 2. Data source for market data (OHLCV) Required UDF Endpoints[​](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#required-udf-endpoints "Direct link to Required UDF Endpoints") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- To implement TradingView charts, you need to create the following UDF endpoints: ### 1\. Configuration Endpoint (`/udf/config`)[​](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#1-configuration-endpoint-udfconfig "Direct link to 1-configuration-endpoint-udfconfig") @app.get("/udf/config")async def get_config(): """UDF configuration endpoint""" return { "supported_resolutions": ["1", "5", "15", "30", "60", "D", "W", "M"], "supports_group_request": False, "supports_marks": False, "supports_search": True, "supports_timescale_marks": False, "supports_time": True, "exchanges": [ {"value": "", "name": "All Exchanges", "desc": ""}, {"value": "NASDAQ", "name": "NASDAQ", "desc": "NASDAQ Stock Exchange"} ], "symbols_types": [ {"name": "All types", "value": ""}, {"name": "Stocks", "value": "stock"} ] } ### 2\. Symbol Search Endpoint (`/udf/search`)[​](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#2-symbol-search-endpoint-udfsearch "Direct link to 2-symbol-search-endpoint-udfsearch") @app.get("/udf/search")async def search_symbols( query: str = Query("", description="Search query"), limit: int = Query(30, description="Limit of results")): """UDF symbol search endpoint""" results = [] # Implement your symbol search logic here return results ### 3\. Symbol Info Endpoint (`/udf/symbols`)[​](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#3-symbol-info-endpoint-udfsymbols "Direct link to 3-symbol-info-endpoint-udfsymbols") @app.get("/udf/symbols")async def get_symbol_info(symbol: str = Query(..., description="Symbol to get info for")): """UDF symbol info endpoint""" return { "name": symbol, "description": "Symbol Description", "type": "stock", "exchange": "NASDAQ", "pricescale": 100, "minmov": 1, "volume_precision": 0, "has_volume": True, "has_intraday": True, "has_daily": True, "has_weekly_and_monthly": True, "supported_resolutions": ["1", "5", "15", "30", "60", "D", "W", "M"], "session-regular": "0930-1600", "timezone": "America/New_York" } ### 4\. Historical Data Endpoint (`/udf/history`)[​](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#4-historical-data-endpoint-udfhistory "Direct link to 4-historical-data-endpoint-udfhistory") @app.get("/udf/history")async def get_history( symbol: str = Query(..., description="Symbol"), resolution: str = Query(..., description="Resolution"), from_time: int = Query(..., alias="from", description="From timestamp"), to_time: int = Query(..., alias="to", description="To timestamp")): """UDF historical data endpoint""" # Implement your data fetching logic here return { "s": "ok", "t": [timestamp1, timestamp2, ...], # Time array "o": [open1, open2, ...], # Open prices array "h": [high1, high2, ...], # High prices array "l": [low1, low2, ...], # Low prices array "c": [close1, close2, ...], # Close prices array "v": [volume1, volume2, ...] # Volume array } ### 5\. Server Time Endpoint (`/udf/time`)[​](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#5-server-time-endpoint-udftime "Direct link to 5-server-time-endpoint-udftime") @app.get("/udf/time")async def get_server_time(): """UDF server time endpoint""" return int(datetime.now().timestamp()) Widget Registration[​](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#widget-registration "Direct link to Widget Registration") ------------------------------------------------------------------------------------------------------------------------------------------------------------- To register the TradingView chart widget in OpenBB: @register_widget({ "name": "TradingView Chart", "description": "Advanced charting with TradingView", "category": "Finance", "type": "advanced_charting", "endpoint": "/udf", "gridData": { "w": 20, "h": 20 }, "data": { "defaultSymbol": "AAPL", "updateFrequency": 60000, } }})def tradingview_chart(): """Dummy function for TradingView chart widget registration""" pass Data Format Requirements[​](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#data-format-requirements "Direct link to Data Format Requirements") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The historical data endpoint must return data in the following format: { "s": "ok", # Status: ok "t": [timestamp1, timestamp2, ...], # Time array (Unix timestamps) "o": [open1, open2, ...], # Open prices array "h": [high1, high2, ...], # High prices array "l": [low1, low2, ...], # Low prices array "c": [close1, close2, ...], # Close prices array "v": [volume1, volume2, ...] # Volume array} Best Practices[​](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#best-practices "Direct link to Best Practices") ---------------------------------------------------------------------------------------------------------------------------------------------- 1. **Error Handling**: Implement proper error handling for all endpoints 2. **Data Validation**: Validate all input parameters 3. **Caching**: Implement caching for frequently accessed data 4. **Rate Limiting**: Add rate limiting to prevent abuse 5. **Security**: Implement proper authentication and authorization 6. **Performance**: Optimize data fetching and processing 7. **Documentation**: Document all endpoints and their parameters Example Implementation[​](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#example-implementation "Direct link to Example Implementation") ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- Here's a complete example of implementing the historical data endpoint with mock data: def generate_mock_price_data(symbol: str, from_time: int, to_time: int, resolution: str) -> dict: """Generate mock OHLCV data for a symbol""" resolution_minutes = { "1": 1, "5": 5, "15": 15, "30": 30, "60": 60, "D": 1440, "W": 10080, "M": 43200 }.get(resolution, 60) current_time = from_time timestamps = [] while current_time <= to_time: timestamps.append(current_time) current_time += resolution_minutes * 60 base_price = 100.0 prices = [] current_price = base_price for _ in timestamps: change = random.uniform(-2, 2) current_price += change current_price = max(current_price, 1.0) prices.append(current_price) opens = [] highs = [] lows = [] closes = [] volumes = [] for price in prices: is_bullish = random.random() > 0.5 if is_bullish: open_price = price * 0.99 close_price = price * 1.01 else: open_price = price * 1.01 close_price = price * 0.99 high_price = max(open_price, close_price) * 1.02 low_price = min(open_price, close_price) * 0.98 opens.append(open_price) highs.append(high_price) lows.append(low_price) closes.append(close_price) volume = int(1000000 * (1 + random.uniform(-0.2, 0.2))) volumes.append(volume) return { "s": "ok", "t": timestamps, "o": opens, "h": highs, "l": lows, "c": closes, "v": volumes } Additional Resources[​](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#additional-resources "Direct link to Additional Resources") ---------------------------------------------------------------------------------------------------------------------------------------------------------------- * [TradingView Charting Library Documentation](https://www.tradingview.com/charting-library-docs/) * [UDF Protocol Documentation](https://www.tradingview.com/charting-library-docs/latest/connecting_data/UDF) The charting technology is provided by TradingView — a platform for traders and investors offering real-time market data, crypto heatmaps, screeners, and other professional tools, making it easy to follow Bitcoin, [Ethereum price](https://www.tradingview.com/symbols/ETHUSD/) , and charts for any other asset. On this page * [Prerequisites](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#prerequisites) * [Required UDF Endpoints](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#required-udf-endpoints) * [1\. Configuration Endpoint (`/udf/config`)](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#1-configuration-endpoint-udfconfig) * [2\. Symbol Search Endpoint (`/udf/search`)](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#2-symbol-search-endpoint-udfsearch) * [3\. Symbol Info Endpoint (`/udf/symbols`)](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#3-symbol-info-endpoint-udfsymbols) * [4\. Historical Data Endpoint (`/udf/history`)](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#4-historical-data-endpoint-udfhistory) * [5\. Server Time Endpoint (`/udf/time`)](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#5-server-time-endpoint-udftime) * [Widget Registration](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#widget-registration) * [Data Format Requirements](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#data-format-requirements) * [Best Practices](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#best-practices) * [Example Implementation](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#example-implementation) * [Additional Resources](https://docs.openbb.co/workspace/developers/widget-types/tradingview-charts#additional-resources) --- # Commands And Arguments | ODP CLI Docs [Skip to main content](https://docs.openbb.co/odp/cli/commands-and-arguments#__docusaurus_skipToContent_fallback) On this page Commands are displayed on-screen in a lighter colour, compared with menu items, and they will not be prefaced with, `>`. Functions have a variety of parameters that differ by endpoint and provider. The --help dialogue will provide guidance on nuances of any particular command. The available data sources for each command are displayed on the right side of the screen, and are selected with the `--provider` argument. Help arguments[​](https://docs.openbb.co/odp/cli/commands-and-arguments#help-arguments "Direct link to Help arguments") ------------------------------------------------------------------------------------------------------------------------ The `help` command shows the current menu. The screen will display all the commands and menus that exist, including a short description for each of these. Adding `--help`, or `-h`, to any command will display the description and parameters for that particular function. Entering Parameters[​](https://docs.openbb.co/odp/cli/commands-and-arguments#entering-parameters "Direct link to Entering Parameters") --------------------------------------------------------------------------------------------------------------------------------------- Parameters are all defined through the same pattern, --argument, followed by a space, and then the value. If the parameter is a boolean (true/false), there is no value to enter. Adding the --argument flags the parameter to be the opposite of its default state. Use the auto-complete to prompt choices and reduce the amount of keystrokes required to run a complex function. Auto-complete[​](https://docs.openbb.co/odp/cli/commands-and-arguments#auto-complete "Direct link to Auto-complete") --------------------------------------------------------------------------------------------------------------------- The ODP CLI is equipped with an auto completion engine that presents choices based on the current menu and command. Whenever you start typing, suggestion prompts will appear for existing commands and menus. When the command contains arguments, pressing the `space bar` after typing the command will present the list of available arguments. This functionality dramatically reduces the number of key strokes required to perform tasks and, in many cases, eliminates the need to consult the help dialogue for reminders. Choices - where they are bound by a defined list - are scrollable with the up and down arrow keys. Global commands[​](https://docs.openbb.co/odp/cli/commands-and-arguments#global-commands "Direct link to Global commands") --------------------------------------------------------------------------------------------------------------------------- These are commands that can be used throughout the CLI and will work regardless of the menu where they belong. ### Help[​](https://docs.openbb.co/odp/cli/commands-and-arguments#help "Direct link to Help") `--help`, or `-h` can be attached to any command, as described above. ### CLS[​](https://docs.openbb.co/odp/cli/commands-and-arguments#cls "Direct link to CLS") The `cls` command clears the entire CLI screen. ### Quit[​](https://docs.openbb.co/odp/cli/commands-and-arguments#quit "Direct link to Quit") The `quit` command (can also use `q` or `..`) allows to leave the current menu to go one menu above. If the user is on the root, that will mean leaving the CLI. ### Exit[​](https://docs.openbb.co/odp/cli/commands-and-arguments#exit "Direct link to Exit") The `exit` command allows the user to exit the CLI. ### Reset[​](https://docs.openbb.co/odp/cli/commands-and-arguments#reset "Direct link to Reset") The `reset` command will reset the CLI to its default state. This is specially useful for development so you can refresh the CLI without having to close and open it again. ### Results[​](https://docs.openbb.co/odp/cli/commands-and-arguments#results "Direct link to Results") The `results` command will display the stack of `OBBjects` that have been generated during the session, which can be later injected on the data processing commands. On this page * [Help arguments](https://docs.openbb.co/odp/cli/commands-and-arguments#help-arguments) * [Entering Parameters](https://docs.openbb.co/odp/cli/commands-and-arguments#entering-parameters) * [Auto-complete](https://docs.openbb.co/odp/cli/commands-and-arguments#auto-complete) * [Global commands](https://docs.openbb.co/odp/cli/commands-and-arguments#global-commands) * [Help](https://docs.openbb.co/odp/cli/commands-and-arguments#help) * [CLS](https://docs.openbb.co/odp/cli/commands-and-arguments#cls) * [Quit](https://docs.openbb.co/odp/cli/commands-and-arguments#quit) * [Exit](https://docs.openbb.co/odp/cli/commands-and-arguments#exit) * [Reset](https://docs.openbb.co/odp/cli/commands-and-arguments#reset) * [Results](https://docs.openbb.co/odp/cli/commands-and-arguments#results) --- # AI Features — Interact with dashboard | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/ai-features/interact-with-dashboard#__docusaurus_skipToContent_fallback) On this page Receive the list of widgets on the current dashboard (`secondary`) and any explicitly selected (`primary`). Summarize what’s available and fetch data for a chosen widget. Reference implementation in [this GitHub repository](https://github.com/OpenBB-finance/agents-for-openbb/tree/main/40-vanilla-agent-dashboard-widgets/vanilla_agent_dashboard_widgets/main.py) . Example that highlights that the agent has access to data on the dashboard (secondary) and that there are no tabs. ![No tab no param no primary](https://openbb-cms.directus.app/assets/2dbcd500-a801-415f-a6d2-2052fa9abc17.png) Example that highlights that the agent still has access to data on the dashboard (secondary) but also has explicit context (primary) as a multi-file viewer widget. ![No tab no param primary](https://openbb-cms.directus.app/assets/16b8ea4b-9dc4-487e-b9ac-14b573602684.png) Example that highlights that the agent has access to data that lives on the dashboard (and on all the tabs!). ![Tab params](https://openbb-cms.directus.app/assets/a12edb2e-cf15-49ca-bb99-b8468fdfe65d.png) Architecture[​](https://docs.openbb.co/workspace/developers/ai-features/interact-with-dashboard#architecture "Direct link to Architecture") -------------------------------------------------------------------------------------------------------------------------------------------- Receive dashboard metadata and selected widgets, summarize what's available, and fetch a sample widget's data. `agents.json` configuration with `widget-dashboard-select` enabled so it accepts explicit context and `widget-dashboard-search` so it can retrieve widgets from the dashboard. return JSONResponse(content={ "vanilla_agent_dashboard_widgets": { "endpoints": {"query": "http://localhost:7777/v1/query"}, "features": { "widget-dashboard-select": True, "widget-dashboard-search": True, }, }}) ### Query flow[​](https://docs.openbb.co/workspace/developers/ai-features/interact-with-dashboard#query-flow "Direct link to Query flow") * Access both `widgets.primary` (user-selected) and `widgets.secondary` (dashboard) widget collections * Combine widget lists for comprehensive dashboard overview * Check `workspace_state.current_dashboard_info` for tab information * Stream formatted widget inventory with `message_chunk()`: * Widget names, types, and parameter configurations * Tab organization if present * Data availability status * Demonstrate data retrieval by fetching sample widget with `get_widget_data()` * Process returned data and show preview with metadata ### OpenBB AI SDK[​](https://docs.openbb.co/workspace/developers/ai-features/interact-with-dashboard#openbb-ai-sdk "Direct link to OpenBB AI SDK") * `WidgetCollection`: Contains `primary`, `secondary`, and `extra` widget groups * `Widget`: Individual widget with `uuid`, `name`, `type`, and `params` * `WidgetParam`: Parameter definition with `name`, `type`, `current_value` * `get_widget_data(widget_requests)`: Fetches data from specified widgets * `WorkspaceState`: Provides dashboard context and tab information * `message_chunk(text)`: Streams widget summaries and data previews Core logic[​](https://docs.openbb.co/workspace/developers/ai-features/interact-with-dashboard#core-logic "Direct link to Core logic") -------------------------------------------------------------------------------------------------------------------------------------- Unify primary and secondary widgets, render a summary, then fetch data for one widget: from openbb_ai import get_widget_data, WidgetRequest, message_chunkfrom openbb_ai.models import QueryRequestasync def query(request: QueryRequest) -> EventSourceResponse: async def execution_loop(): # Combine all available widgets all_widgets = [] primary_count = 0 secondary_count = 0 if request.widgets: if request.widgets.primary: all_widgets.extend(request.widgets.primary) primary_count = len(request.widgets.primary) if request.widgets.secondary: all_widgets.extend(request.widgets.secondary) secondary_count = len(request.widgets.secondary) if not all_widgets: yield message_chunk("No widgets found on your dashboard.").model_dump() return # Stream dashboard overview dashboard_info = "" if request.workspace_state and request.workspace_state.current_dashboard_info: dashboard_name = request.workspace_state.current_dashboard_info.name tab_count = len(request.workspace_state.current_dashboard_info.tabs) dashboard_info = f"Dashboard: **{dashboard_name}** ({tab_count} tabs)\n\n" widget_summary = f"""# Dashboard Widget Analysis{dashboard_info}## Widget Inventory- **Selected widgets (primary)**: {primary_count}- **Dashboard widgets (secondary)**: {secondary_count}- **Total available**: {len(all_widgets)}## Available Widgets""" for i, widget in enumerate(all_widgets[:5]): # Show first 5 widget_type = "🎯 Selected" if i < primary_count else "📊 Dashboard" param_count = len(widget.params) if widget.params else 0 widget_summary += f"- **{widget.name}** ({widget_type}) - {param_count} parameters\n" if len(all_widgets) > 5: widget_summary += f"- ... and {len(all_widgets) - 5} more widgets\n" yield message_chunk(widget_summary + "\n").model_dump() # Demonstrate data retrieval with last widget if all_widgets: sample_widget = all_widgets[-1] yield message_chunk(f"Let me fetch data from **{sample_widget.name}** as an example:\n\n").model_dump() yield get_widget_data([ WidgetRequest( widget=sample_widget, input_arguments={p.name: p.current_value for p in sample_widget.params} if sample_widget.params else {} ) ]).model_dump() return EventSourceResponse(execution_loop(), media_type="text/event-stream") On this page * [Architecture](https://docs.openbb.co/workspace/developers/ai-features/interact-with-dashboard#architecture) * [Query flow](https://docs.openbb.co/workspace/developers/ai-features/interact-with-dashboard#query-flow) * [OpenBB AI SDK](https://docs.openbb.co/workspace/developers/ai-features/interact-with-dashboard#openbb-ai-sdk) * [Core logic](https://docs.openbb.co/workspace/developers/ai-features/interact-with-dashboard#core-logic) --- # OpenBBUserData Folder | ODP CLI Docs [Skip to main content](https://docs.openbb.co/odp/cli/openbbuserdata#__docusaurus_skipToContent_fallback) On this page The OpenBBUserData folder is where exports, routines, and other user-related content is saved and stored. info If a new file is placed in the folder (like a Routine) the CLI will need to be reset before auto complete will recognize it. Default Location[​](https://docs.openbb.co/odp/cli/openbbuserdata#default-location "Direct link to Default Location") ---------------------------------------------------------------------------------------------------------------------- Its default location is the home of the system user account, similar to the following paths: * macOS: `Macintosh HD/Users//OpenBBUserData` * Windows: `C:/Users//OpenBBUserData` This folder contains all things user-created. For example: * Exported files * Styles and themes * Routines * Logs note **Note:** With a WSL-enabled Windows installation, this folder will be under the Linux partition Update Folder Location[​](https://docs.openbb.co/odp/cli/openbbuserdata#update-folder-location "Direct link to Update Folder Location") ---------------------------------------------------------------------------------------------------------------------------------------- The location of this folder can be set by the user by changing the user configuration file: `/home/your-user/.openbb_platform/user_settings.json`. {..."preferences": { "data_directory": "/path/to/NewOpenBBUserData", "export_directory": "/path/to/NewOpenBBUserData"},...} On this page * [Default Location](https://docs.openbb.co/odp/cli/openbbuserdata#default-location) * [Update Folder Location](https://docs.openbb.co/odp/cli/openbbuserdata#update-folder-location) --- # Installation | ODP CLI Docs [Skip to main content](https://docs.openbb.co/odp/cli/installation#__docusaurus_skipToContent_fallback) On this page Pre-Requisites[​](https://docs.openbb.co/odp/cli/installation#pre-requisites "Direct link to Pre-Requisites") -------------------------------------------------------------------------------------------------------------- ODP CLI is a wrapper around the [OpenBB Python Package](https://docs.openbb.co/odp/python) , and should be installed along side an existing OpenBB installation. * A Python virtual environment with a version between 3.9 and 3.11, inclusive, is required. Please refer to the [Python install documentation](https://docs.openbb.co/odp/python/installation) for instructions and more information. info If the ODP python package is not already installed, the `openbb-cli` package will install all available components. ### Windows[​](https://docs.openbb.co/odp/cli/installation#windows "Direct link to Windows") The machine may need to have an installation of Visual C++ Build Tools available. Download the elements highlighted in the images below. "Microsoft Visual C++ 14.0 or greater is required" Download and install [C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) , restart the machine, then continue. ![image](https://github.com/OpenBB-finance/OpenBBTerminal/assets/85772166/ceb57be0-6dae-42f2-aca6-bf62ce7d6135) ![image](https://github.com/OpenBB-finance/OpenBBTerminal/assets/85772166/f8aef8fc-a080-4164-bd36-460714ec44f3) ### Linux Requirements[​](https://docs.openbb.co/odp/cli/installation#linux-requirements "Direct link to Linux Requirements") Linux users will need to take additional steps prior to installation. #### Rust[​](https://docs.openbb.co/odp/cli/installation#rust "Direct link to Rust") Rust and Cargo must be installed, system-level, and in the PATH. Follow the instructions on-screen to install and add to PATH in the shell profile. curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh #### Webkit[​](https://docs.openbb.co/odp/cli/installation#webkit "Direct link to Webkit") Next, install webkit. * Debian-based / Ubuntu / Mint: `sudo apt install libwebkit2gtk-4.0-dev` * Arch Linux / Manjaro: `sudo pacman -S webkit2gtk` * Fedora: `sudo dnf install gtk3-devel webkit2gtk3-devel` PyPI[​](https://docs.openbb.co/odp/cli/installation#pypi "Direct link to PyPI") -------------------------------------------------------------------------------- Within your existing OpenBB environment, install `openbb-cli` with: pip install openbb-cli The installation script adds `openbb` to the PATH within your Python environment. The application can be launched from any path, as long as the environment is active. openbbWelcome to Open Data Platform CLI v1.0.0 Source[​](https://docs.openbb.co/odp/cli/installation#source "Direct link to Source") -------------------------------------------------------------------------------------- Follow the instructions [here](https://docs.openbb.co/odp/python/installation#source) to clone the GitHub repo and install the Open Data Platform from the source code. Next, navigate into the folder: `~/OpenBB/openbb_platform` tip The Python environment should have `poetry` installed. pip install poetry Finally, enter: python dev_install.py -e --cli Installing New Modules[​](https://docs.openbb.co/odp/cli/installation#installing-new-modules "Direct link to Installing New Modules") -------------------------------------------------------------------------------------------------------------------------------------- New extensions, or removals, are automatically added (removed) to the CLI on the next launch. On this page * [Pre-Requisites](https://docs.openbb.co/odp/cli/installation#pre-requisites) * [Windows](https://docs.openbb.co/odp/cli/installation#windows) * [Linux Requirements](https://docs.openbb.co/odp/cli/installation#linux-requirements) * [PyPI](https://docs.openbb.co/odp/cli/installation#pypi) * [Source](https://docs.openbb.co/odp/cli/installation#source) * [Installing New Modules](https://docs.openbb.co/odp/cli/installation#installing-new-modules) --- # Interactive Charts - | ODP CLI Docs [Skip to main content](https://docs.openbb.co/odp/cli/interactive-charts#__docusaurus_skipToContent_fallback) On this page Interactive charts open in a separate window ([PyWry](https://github.com/OpenBB-finance/pywry) ). The OpenBB charting library provides interactive and highly customizable charts. tip Not all commands have a charting output, the ones that do, will display a chart argument (`--chart`), which will trigger the charting output instead of the default table output. Example: `equity/price/historical --symbol AAPL --chart` Details Charting cheat sheet ![Group 653](https://user-images.githubusercontent.com/85772166/234313541-3d725e1c-ce48-4413-9267-b03571e0eccd.png) Toolbar[​](https://docs.openbb.co/odp/cli/interactive-charts#toolbar "Direct link to Toolbar") ----------------------------------------------------------------------------------------------- ![Chart Tools](https://user-images.githubusercontent.com/85772166/233247997-55c03cbd-9ca9-4f5e-b3fb-3e5a9c63b6eb.png) The toolbar is located at the bottom of the window, and provides methods for: * Panning and zooming. * Modifying the title and axis labels. * Adjusting the hover read out. * Toggling light/dark mode. * Annotating and drawing. * Exporting raw data. * Saving the chart as an image. * Adding supplementary external data as an overlay. The label for each tool is displayed by holding the mouse over it. The toolbar's visibility can be toggled utilizing the `ctrl + h` shortcut. Text Tools[​](https://docs.openbb.co/odp/cli/interactive-charts#text-tools "Direct link to Text Tools") -------------------------------------------------------------------------------------------------------- Annotate a chart by clicking on the `Add Text` button, or with the keyboard, `ctrl + t`. ![Annotate Charts](https://user-images.githubusercontent.com/85772166/233248056-d459d7a0-ba2d-4533-896a-79406ded859e.png) Enter some text, make any adjustments to the options, then `submit`. Place the crosshairs over the desired data point and click to place the text. ![Place Text](https://user-images.githubusercontent.com/85772166/233728645-74734241-4da2-4cff-af17-b68a62e95113.png) After placement, the text can be updated or deleted by clicking on it again. ![Delete Annotation](https://user-images.githubusercontent.com/85772166/233728428-55d2a8e5-a68a-4cd1-9dbf-4c1cd697187e.png) Change Titles[​](https://docs.openbb.co/odp/cli/interactive-charts#change-titles "Direct link to Change Titles") ----------------------------------------------------------------------------------------------------------------- The title of the chart is edited by clicking the button, `Change Titles`, near the middle center of the toolbar, immediately to the right of the `Add Text` button. Draw Tools[​](https://docs.openbb.co/odp/cli/interactive-charts#draw-tools "Direct link to Draw Tools") -------------------------------------------------------------------------------------------------------- ![Edit Colors](https://user-images.githubusercontent.com/85772166/233729318-8af947fa-ce2a-43e2-85ab-657e583ac8b1.png) The fourth group of icons on the toolbar are for drawing lines and shapes. * Edit the colors. * Draw a straight line. * Draw a freeform line. * Draw a circle. * Draw a rectangle. * Erase a shape. To draw on the chart, select one of the four drawing buttons and drag the mouse over the desired area. Click on any existing shape to modify it by dragging with the mouse and editing the color, or remove it by clicking the toolbar button, `Erase Active Shape`. The edit colors button will pop up as a floating icon, and clicking on that will display the color palette. Export Tools[​](https://docs.openbb.co/odp/cli/interactive-charts#export-tools "Direct link to Export Tools") -------------------------------------------------------------------------------------------------------------- The two buttons at the far-right of the toolbar are for saving the raw data or, to save an image file of the chart at the current panned and zoomed view. ![Export Tools](https://user-images.githubusercontent.com/85772166/233248436-08a2a463-403b-4b1b-b7d8-80cd5af7bee3.png) Overlay[​](https://docs.openbb.co/odp/cli/interactive-charts#overlay "Direct link to Overlay") ----------------------------------------------------------------------------------------------- The button, `Overlay chart from CSV`, provides an easy import method for supplementing a chart with additional data. Clicking on the button opens a pop-up dialogue to select the file, column, and whether the overlay should be a bar, candlestick, or line chart. As a candlestick, the CSV file must contain OHLC data. The import window can also be opened with the keyboard, `ctrl-o`. ![Overlay CSV](https://user-images.githubusercontent.com/85772166/233248522-16b539f4-b0ae-4c30-8c72-dfa59d0c0cfb.png) After choosing the file to overlay, select what to show and then click on `Submit`. ![Overlay Options](https://user-images.githubusercontent.com/85772166/233250634-44864da0-0936-4d3c-8de2-c8374d26c1d2.png) ![Overlay Chart](https://user-images.githubusercontent.com/85772166/233248639-6d12b16d-471f-4550-a8ab-8d8c18eeabb3.png) On this page * [Toolbar](https://docs.openbb.co/odp/cli/interactive-charts#toolbar) * [Text Tools](https://docs.openbb.co/odp/cli/interactive-charts#text-tools) * [Change Titles](https://docs.openbb.co/odp/cli/interactive-charts#change-titles) * [Draw Tools](https://docs.openbb.co/odp/cli/interactive-charts#draw-tools) * [Export Tools](https://docs.openbb.co/odp/cli/interactive-charts#export-tools) * [Overlay](https://docs.openbb.co/odp/cli/interactive-charts#overlay) --- # Data Sources | ODP CLI Docs [Skip to main content](https://docs.openbb.co/odp/cli/data-sources#__docusaurus_skipToContent_fallback) On this page Many commands have multiple data sources associated with it. This page describes how to select from multiple providers. important API credentials are defined in the `user_settings.json` file. Find all the current data providers maintained in the OpenBB repository [here](https://docs.openbb.co/odp/python/extensions) . Data Source In-Command[​](https://docs.openbb.co/odp/cli/data-sources#data-source-in-command "Direct link to Data Source In-Command") -------------------------------------------------------------------------------------------------------------------------------------- To specify the data vendor for that particular command, use the `--provider` argument. Parameter choices can be viewed from the help dialogue, `-h` or `--help`. /equity/price/historical -h usage: historical --symbol SYMBOL [SYMBOL ...] [--interval INTERVAL] [--start_date START_DATE] [--end_date END_DATE] [--chart] [--provider {fmp,intrinio,polygon,tiingo,yfinance}] [--start_time START_TIME] [--end_time END_TIME] [--timezone TIMEZONE] [--source {realtime,delayed,nasdaq_basic}] [--sort {asc,desc}] [--limit LIMIT] [--extended_hours] [--include_actions] [--adjustment {splits_and_dividends,unadjusted,splits_only}] [--adjusted] [--prepost] [-h] [--export EXPORT] [--sheet-name SHEET_NAME [SHEET_NAME ...]]Get historical price data for a given stock. This includes open, high, low, close, and volume.options: --interval INTERVAL Time interval of the data to return. --start_date START_DATE Start date of the data, in YYYY-MM-DD format. --end_date END_DATE End date of the data, in YYYY-MM-DD format. --chart Whether to create a chart or not, by default False. --provider {fmp,intrinio,polygon,tiingo,yfinance} The provider to use for the query, by default None. If None, the provider specified in defaults is selected or 'fmp' if there is no default. --extended_hours Include Pre and Post market data. (provider: polygon, yfinance) --adjustment {splits_and_dividends,unadjusted,splits_only} The adjustment factor to apply. Default is splits only. (provider: polygon, yfinance) -h, --help show this help message --export EXPORT Export raw data into csv, json, xlsx and figure into png or jpg --sheet-name SHEET_NAME [SHEET_NAME ...] Name of excel sheet to save data to. Only valid for .xlsx files.required arguments: --symbol SYMBOL [SYMBOL ...] Symbol to get data for. Multiple comma separated items allowed for provider(s): fmp, polygon, tiingo, yfinance.intrinio: --start_time START_TIME Return intervals starting at the specified time on the `start_date` formatted as 'HH:MM:SS'. --end_time END_TIME Return intervals stopping at the specified time on the `end_date` formatted as 'HH:MM:SS'. --timezone TIMEZONE Timezone of the data, in the IANA format (Continent/City). --source {realtime,delayed,nasdaq_basic} The source of the data.polygon: --sort {asc,desc} Sort order of the data. This impacts the results in combination with the 'limit' parameter. The results are always returned in ascending order by date. --limit LIMIT The number of data entries to return.yfinance: --include_actions Include dividends and stock splits in results. note Provider-specific parameters are listed at the bottom of the print out. They are ignored when entered, if it is not supported by the selected provider. Setting The Default Source[​](https://docs.openbb.co/odp/cli/data-sources#setting-the-default-source "Direct link to Setting The Default Source") -------------------------------------------------------------------------------------------------------------------------------------------------- The default data providers for each command can be defined within the user configuration file: `/home/your-user/.openbb_platform/user_settings.json`. You can set a single provider or a priority list. If a list is set, the command will use the first provider for which all required credentials set. See the example below for `obb.equity.price.historical` command: # user_settings.json{ "defaults": { "commands": { "equity.price.historical": { "provider": "fmp" }, "equity.fundamental.balance": { "provider": ["intrinio", "fmp", "polygon"] }, ... } }} On this page * [Data Source In-Command](https://docs.openbb.co/odp/cli/data-sources#data-source-in-command) * [Setting The Default Source](https://docs.openbb.co/odp/cli/data-sources#setting-the-default-source) --- # Newsfeed | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-types/newsfeed#__docusaurus_skipToContent_fallback) On this page A widget that displays articles in a clean, organized newsfeed format. Each article can include title, date, author, excerpt, and full body content with markdown support. ![newsfeed](https://openbb-assets.s3.us-east-1.amazonaws.com/docs/pro/newsfeed.png) Data Structure[​](https://docs.openbb.co/workspace/developers/widget-types/newsfeed#data-structure "Direct link to Data Structure") ------------------------------------------------------------------------------------------------------------------------------------ The newsfeed widget expects articles in a specific format: { "title": string, # Article title "date": string, # ISO 8601 formatted date "author": string, # Article author "excerpt": string, # Short preview of the article "body": string, # Full article text (can include markdown)} Basic Example[​](https://docs.openbb.co/workspace/developers/widget-types/newsfeed#basic-example "Direct link to Basic Example") --------------------------------------------------------------------------------------------------------------------------------- Here's a simple example that returns sample news articles: @register_widget({ "name": "Sample News Feed", "description": "A simple newsfeed widget with example articles", "type": "newsfeed", "endpoint": "sample_newsfeed", "gridData": { "w": 40, "h": 20 }, "source": "example", "params": [ { "paramName": "category", "label": "Category", "description": "Filter news by category", "type": "text", "value": "all", "options": [ {"label": "All", "value": "all"}, {"label": "Technology", "value": "tech"}, {"label": "Business", "value": "business"}, {"label": "Science", "value": "science"} ] }, { "paramName": "limit", "label": "Number of Articles", "description": "Maximum number of articles to display", "type": "number", "value": "5" } ]})@app.get("/sample_newsfeed")def get_sample_newsfeed(category: str = "all", limit: int = 5): """Returns sample news articles in the required newsfeed format""" # Sample news data organized by category sample_articles = { "tech": [ { "title": "AI Breakthrough: New Model Achieves Human-Level Reasoning", "date": (datetime.now() - timedelta(hours=2)).isoformat(), "author": "Sarah Johnson", "excerpt": "Researchers at TechLab have unveiled a groundbreaking AI model that demonstrates unprecedented reasoning capabilities...", "body": """# AI Breakthrough: New Model Achieves Human-Level ReasoningResearchers at TechLab have unveiled a groundbreaking AI model that demonstrates unprecedented reasoning capabilities, marking a significant milestone in artificial intelligence development.## Key Features- **Advanced reasoning**: The model can solve complex logical problems- **Multimodal understanding**: Processes text, images, and audio simultaneously- **Energy efficient**: Uses 40% less computational resources than previous modelsThe implications of this breakthrough extend across multiple industries, from healthcare to education, promising to revolutionize how we interact with AI systems.""" }, { "title": "Quantum Computing Startup Raises $500M in Series C Funding", "date": (datetime.now() - timedelta(hours=5)).isoformat(), "author": "Michael Chen", "excerpt": "QuantumLeap Technologies secures major funding round to accelerate development of commercial quantum processors...", "body": """# Quantum Computing Startup Raises $500M in Series C FundingQuantumLeap Technologies announced today that it has secured $500 million in Series C funding, led by prominent venture capital firms.The company plans to use the funding to:1. Scale manufacturing capabilities2. Expand research team by 200 engineers3. Develop partnerships with major cloud providersCEO Jane Smith stated, "This investment validates our approach to making quantum computing accessible to enterprises worldwide." """ } ], "business": [ { "title": "Global Markets Rally on Positive Economic Data", "date": (datetime.now() - timedelta(hours=1)).isoformat(), "author": "Robert Williams", "excerpt": "Stock markets across the globe surged today following the release of better-than-expected employment figures...", "body": """# Global Markets Rally on Positive Economic DataStock markets worldwide experienced significant gains today as investors responded positively to robust employment data and inflation reports.## Market Performance- S&P 500: +2.3%- NASDAQ: +2.8%- FTSE 100: +1.9%- Nikkei 225: +2.1%Analysts attribute the rally to renewed confidence in economic recovery and expectations of stable monetary policy.""" } ], "science": [ { "title": "Scientists Discover New Earth-like Exoplanet in Habitable Zone", "date": (datetime.now() - timedelta(hours=3)).isoformat(), "author": "Dr. Emily Rogers", "excerpt": "Astronomers using the James Webb Space Telescope have identified a potentially habitable exoplanet just 40 light-years away...", "body": """# Scientists Discover New Earth-like Exoplanet in Habitable ZoneA team of international astronomers has announced the discovery of an Earth-like exoplanet orbiting within the habitable zone of its star system.## Planet Characteristics- **Size**: 1.2 times Earth's radius- **Orbital period**: 385 days- **Surface temperature**: Estimated 15°C average- **Atmosphere**: Preliminary data suggests presence of water vaporThe discovery opens new possibilities for studying potentially habitable worlds beyond our solar system.""" } ] } # Collect articles based on category if category == "all": # Combine all categories all_articles = [] for cat_articles in sample_articles.values(): all_articles.extend(cat_articles) articles = all_articles else: # Get specific category or empty list if category doesn't exist articles = sample_articles.get(category, []) # Sort by date (newest first) and limit results articles.sort(key=lambda x: x["date"], reverse=True) articles = articles[:limit] # Add some variety with random additional recent articles if needed if len(articles) < limit and category == "all": # Generate some generic filler articles for i in range(limit - len(articles)): articles.append({ "title": f"Breaking News: Important Update #{i+1}", "date": (datetime.now() - timedelta(hours=8+i)).isoformat(), "author": "News Team", "excerpt": f"This is a sample news article demonstrating the newsfeed widget functionality...", "body": f"""# Breaking News: Important Update #{i+1}This is a sample article created to demonstrate the newsfeed widget's ability to display multiple articles.## SummaryThe newsfeed widget can display articles with:- Rich markdown formatting- Timestamps and author information- Excerpts for quick preview- Full article body with detailed contentStay tuned for more updates!""" }) return articles Live API Example with CoinDesk[​](https://docs.openbb.co/workspace/developers/widget-types/newsfeed#live-api-example-with-coindesk "Direct link to Live API Example with CoinDesk") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Here's an example that fetches real news from CoinDesk's API: from typing import Optional, List, TypedDictfrom datetime import datetimeimport requestsclass TransformedArticle(TypedDict): title: str date: str author: str excerpt: str body: str@register_widget({ "name": "CoinDesk News", "description": "Get the latest crypto news from CoinDesk", "type": "newsfeed", "endpoint": "coindesk_news", "gridData": { "w": 40, "h": 20 }, "source": "coindesk", "params": [ { "paramName": "limit", "label": "Number of Articles", "description": "The number of news articles to fetch", "type": "number", "value": "10" }, { "paramName": "lang", "label": "Language", "description": "The language of the news articles", "type": "text", "value": "EN", "options": [ {"label": "English", "value": "EN"}, {"label": "Spanish", "value": "ES"} ] }, { "paramName": "categories", "label": "Categories", "description": "Filter by news categories", "type": "text", "value": "" } ]})@app.get("/coindesk_news")def get_coindesk_news(limit: str = "10", lang: str = "EN", categories: Optional[str] = None): """Get news from CoinDesk API""" try: url = f"https://data-api.coindesk.com/news/v1/article/list?lang={lang}&limit={limit}" if categories: url += f"&categories={categories}" response = requests.get(url) if response.status_code != 200: raise HTTPException( status_code=response.status_code, detail=f"Failed to fetch news: {response.reason}" ) data = response.json() articles = [] for article in data.get("Data", []): # Convert UNIX timestamp to ISO format date = datetime.fromtimestamp(article["PUBLISHED_ON"]).isoformat() # Create excerpt from body (first 150 characters) body = article["BODY"] excerpt = f"{body[:150]}..." if len(body) > 150 else body articles.append({ "title": article["TITLE"], "date": date, "author": article["AUTHORS"], "excerpt": excerpt, "body": body }) return articles except Exception as e: return JSONResponse( content={"error": f"Failed to fetch news: {str(e)}"}, status_code=500 ) On this page * [Data Structure](https://docs.openbb.co/workspace/developers/widget-types/newsfeed#data-structure) * [Basic Example](https://docs.openbb.co/workspace/developers/widget-types/newsfeed#basic-example) * [Live API Example with CoinDesk](https://docs.openbb.co/workspace/developers/widget-types/newsfeed#live-api-example-with-coindesk) --- # API Keys & Credentials - ODP Python | OpenBB Docs [Skip to main content](https://docs.openbb.co/odp/python/settings/user_settings/api_keys#__docusaurus_skipToContent_fallback) On this page By default, authorization is not required to initialize and use the core services. Most data providers, however, require an API key to access their data. Keys are stored locally, in the `~/.openbb_platform/user_settings.json` file, under the `credentials` object. ### Local Configuration[​](https://docs.openbb.co/odp/python/settings/user_settings/api_keys#local-configuration "Direct link to Local Configuration") Credentials and user preferences are stored locally, `~/.openbb_platform/`, as a JSON file, `user_settings.json`. It is read upon initializing the Python client, or when the Fast API is authorized. If the file does not exist, it will be created on the first run. The schema below can be copy/pasted as a template: { "credentials": { "fmp_api_key": "REPLACE", "polygon_api_key": "REPLACE", "benzinga_api_key": "REPLACE", "fred_api_key": "REPLACE", "nasdaq_api_key": "REPLACE", "intrinio_api_key": "REPLACE", "alpha_vantage_api_key": "REPLACE", "biztoc_api_key": "REPLACE", "tradier_api_key": "REPLACE", "tradier_account_type": "sandbox OR live", "tradingeconomics_api_key": "REPLACE", "tiingo_token": "REPLACE" }} To set keys from the Python client for the current session only, access the Credentials class: obb.user.credentials.intrinio_api_key = "my_api_key" info See [Environment Variables](https://docs.openbb.co/odp/python/settings/environment_variables) & [System Settings](https://docs.openbb.co/odp/python/settings/system_settings) for more information on configuring the installation via `user_settings.json`. See [Extensions](https://docs.openbb.co/odp/python/extensions) for a current list of data provider extensions. On this page * [Local Configuration](https://docs.openbb.co/odp/python/settings/user_settings/api_keys#local-configuration) --- # Generative UI (Beta) | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/ai-features/generative-ui#__docusaurus_skipToContent_fallback) On this page When this feature is turned ON, copilot can manipulate widgets on the dashboard. Update widget parameters[​](https://docs.openbb.co/workspace/analysts/ai-features/generative-ui#update-widget-parameters "Direct link to Update widget parameters") -------------------------------------------------------------------------------------------------------------------------------------------------------------------- The system understands the parameter schemas of each widget and based on a user prompt it can automatically update the parameters used in widgets on the dashboard. ![Widget parameters](https://openbb-cms.directus.app/assets/82a99cb3-61ea-47cb-89f2-4eb1e888861a.png) Add widgets from Global Data[​](https://docs.openbb.co/workspace/analysts/ai-features/generative-ui#add-widgets-from-global-data "Direct link to Add widgets from Global Data") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- If global data is turned on, and the user asks information that the copilot believes exists in one of the widgets in the widget library - then that widget gets automatically added to the dashboard. ![Widget parameters](https://openbb-cms.directus.app/assets/b5798412-cba3-4deb-898c-dde7ccd636c1.png) Add markdown note widget[​](https://docs.openbb.co/workspace/analysts/ai-features/generative-ui#add-markdown-note-widget "Direct link to Add markdown note widget") -------------------------------------------------------------------------------------------------------------------------------------------------------------------- The copilot can also add any type of text into a markdown widget automatically on-the-fly. ![Widget parameters](https://openbb-cms.directus.app/assets/dc0391d6-283f-4a8c-8a83-ddb3b0ea7178.png) Support to add static artifacts (tables or charts) on-the-fly is still not supported. On this page * [Update widget parameters](https://docs.openbb.co/workspace/analysts/ai-features/generative-ui#update-widget-parameters) * [Add widgets from Global Data](https://docs.openbb.co/workspace/analysts/ai-features/generative-ui#add-widgets-from-global-data) * [Add markdown note widget](https://docs.openbb.co/workspace/analysts/ai-features/generative-ui#add-markdown-note-widget) --- # Interactive Tables - | ODP CLI Docs [Skip to main content](https://docs.openbb.co/odp/cli/interactive-tables#__docusaurus_skipToContent_fallback) On this page Interactive tables open in a separate window ([PyWry](https://github.com/OpenBB-finance/pywry) ). These provide methods for searching, sorting, filtering, exporting and even adapting settings directly on the table. tip All ODP CLI results are displayed in interactive tables by default, unless the interactive model is disabled from the `/settings` menu. Details Table cheat sheet ![Chart Intro (5)](https://user-images.githubusercontent.com/85772166/234315026-de098953-111b-4b69-9124-31530c01407a.png) Sorting[​](https://docs.openbb.co/odp/cli/interactive-tables#sorting "Direct link to Sorting") ----------------------------------------------------------------------------------------------- Columns can be sorted ascending/descending/unsorted, by clicking the controls to the right of each header title. The status of the filtering is shown as a blue indicator. ![Sort Columns](https://user-images.githubusercontent.com/85772166/233248754-20c18390-a7af-490c-9571-876447b1b0ae.png) Filtering[​](https://docs.openbb.co/odp/cli/interactive-tables#filtering "Direct link to Filtering") ----------------------------------------------------------------------------------------------------- The settings button, at the lower-left corner, displays choices for customizing the table. By selecting the `Type` to be `Advanced`, columns become filterable. ![Table Settings](https://user-images.githubusercontent.com/85772166/233248876-0d788ff4-974d-4d92-8186-56864469870a.png) The columns can be filtered with min/max values or by letters, depending on the content of each column. ![Filtered Tables](https://user-images.githubusercontent.com/85772166/233248923-45873bf1-de6b-40f8-a4aa-05e7c3d21ab0.png) Hiding columns[​](https://docs.openbb.co/odp/cli/interactive-tables#hiding-columns "Direct link to Hiding columns") -------------------------------------------------------------------------------------------------------------------- The table will scroll to the right as far as there are columns. Columns can be removed from the table by clicking the icon to the right of the settings button and unchecking it from the list. ![Select Columns](https://user-images.githubusercontent.com/85772166/233248976-849791a6-c126-437c-bb54-454ba6ea4fa2.png) Select rows per page[​](https://docs.openbb.co/odp/cli/interactive-tables#select-rows-per-page "Direct link to Select rows per page") -------------------------------------------------------------------------------------------------------------------------------------- The number of rows per page is defined in the drop down selection near the center, at the bottom. ![Rows per Page](https://user-images.githubusercontent.com/85772166/233249018-8269896d-72f7-4e72-a4d4-2715d1f11b96.png) Freeze the Index and Column Headers[​](https://docs.openbb.co/odp/cli/interactive-tables#freeze-the-index-and-column-headers "Direct link to Freeze the Index and Column Headers") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Right-click on the index name to enable/disable freezing when scrolling to the right. Column headers are frozen by default. ![Index Freeze](https://user-images.githubusercontent.com/85772166/234103702-0965dfbd-24ca-4a66-8c76-9fac28abcff8.png) Exporting Data[​](https://docs.openbb.co/odp/cli/interactive-tables#exporting-data "Direct link to Exporting Data") -------------------------------------------------------------------------------------------------------------------- At the bottom-right corner of the table window, there is a button for exporting the data. To the left, the drop down selection for `Type` can be defined as a CSV, XLSX, or PNG file. Exporting the table as a PNG file will create a screenshot of the table at its current view, and data that is not visible will not be captured. ![Export Data](https://user-images.githubusercontent.com/85772166/233249065-60728dd1-612e-4684-b196-892f3604c0f4.png) On this page * [Sorting](https://docs.openbb.co/odp/cli/interactive-tables#sorting) * [Filtering](https://docs.openbb.co/odp/cli/interactive-tables#filtering) * [Hiding columns](https://docs.openbb.co/odp/cli/interactive-tables#hiding-columns) * [Select rows per page](https://docs.openbb.co/odp/cli/interactive-tables#select-rows-per-page) * [Freeze the Index and Column Headers](https://docs.openbb.co/odp/cli/interactive-tables#freeze-the-index-and-column-headers) * [Exporting Data](https://docs.openbb.co/odp/cli/interactive-tables#exporting-data) --- # User Settings - ODP Python | OpenBB Docs [Skip to main content](https://docs.openbb.co/odp/python/settings/user_settings#__docusaurus_skipToContent_fallback) User settings for the ODP Python Package are defined in a JSON file, located in the `/.openbb_platform` folder, at the root of the operating system's user account home. [API Keys\ \ Setting data provider API keys and credentials.](https://docs.openbb.co/odp/python/settings/user_settings/api_keys) [Preferences\ \ Configurable user preferences for the ODP Python Package.](https://docs.openbb.co/odp/python/settings/user_settings/preferences) [Defaults\ \ Define default parameters for individual endpoints.](https://docs.openbb.co/odp/python/settings/user_settings/defaults) --- # Configuration & Settings - | ODP CLI Docs [Skip to main content](https://docs.openbb.co/odp/cli/configuration#__docusaurus_skipToContent_fallback) On this page In addition to the ODP's `user_settings.json` file, described [on the environment variables page](https://docs.openbb.co/odp/python/settings/environment_variables) , there are settings and environment variables affecting the CLI only. important API credentials are defined in the `user_settings.json` file. Find all the current data providers maintained in the OpenBB repository [on the extensions page](https://docs.openbb.co/odp/python/extensions) . Define default data sources by following the pattern outlined [on the data sources page](https://docs.openbb.co/odp/cli/data-sources) Settings Menu[​](https://docs.openbb.co/odp/cli/configuration#settings-menu "Direct link to Settings Menu") ------------------------------------------------------------------------------------------------------------ The `/settings` menu provides methods for customizing the look and feel of the CLI. The menu is divided into two sections: * Feature Flags * On/Off status is reflected by red/green text. * Status is toggled by entering the item as a command. * Preferences * Choices and options will be presented as a typical function. ### Feature Flags[​](https://docs.openbb.co/odp/cli/configuration#feature-flags "Direct link to Feature Flags") | Feature Flags | Description | | --- | --- | | `interactive` | Enable/disable interactive tables. Disabling prints the table directly on the CLI screen. | | `cls` | Clear the screen after each command. Default state is off. | | `promptkit` | Enable auto complete and history. Default state is on. | | `richpanel` | Displays a border around menus. Default state is on. | | `tbhint` | Display usage hints in the bottom toolbar. Default state is on. | | `exithelp` | Automatically print the screen after navigating back one menu. Default state is off. | | `overwrite` | Automatically overwrite exported files with the same name. Default state is off. | | `obbject_msg` | Displays a message whenever a new result is added to the registry. Default state is off. | | `version` | Displays the currently installed version number in the bottom right corner. | ### Preferences[​](https://docs.openbb.co/odp/cli/configuration#preferences "Direct link to Preferences") | Preferences | Description | | --- | --- | | `console_style` | apply a custom rich style to the CLI | | `flair` | choose flair icon | | `timezone` | pick timezone | | `language` | translation language | | `n_rows` | number of rows to show on non interactive tables | | `n_cols` | number of columns to show on non interactive tables | | `obbject_res` | define the maximum number of obbjects allowed in the registry | | `obbject_display` | define the maximum number of cached results to display on the help menu | On this page * [Settings Menu](https://docs.openbb.co/odp/cli/configuration#settings-menu) * [Feature Flags](https://docs.openbb.co/odp/cli/configuration#feature-flags) * [Preferences](https://docs.openbb.co/odp/cli/configuration#preferences) --- # Structure and Navigation | ODP CLI Docs [Skip to main content](https://docs.openbb.co/odp/cli/structure-and-navigation#__docusaurus_skipToContent_fallback) On this page Structure[​](https://docs.openbb.co/odp/cli/structure-and-navigation#structure "Direct link to Structure") ----------------------------------------------------------------------------------------------------------- The ODP CLI is a Command Line Interface (CLI) application. Functions (commands) are called through the keyboard with results returned as charts, tables, or text. Charts and tables (if enabled) are displayed in a new window, and are fully interactive, while text prints directly to the Terminal screen. A menu is a collection of commands (and sub-menus). A menu can be distinguished from a command because the former has a `>` on the left. The color of a command and a menu also differ. Navigation[​](https://docs.openbb.co/odp/cli/structure-and-navigation#navigation "Direct link to Navigation") -------------------------------------------------------------------------------------------------------------- Navigating through the CLI menus is similar to traversing folders from any operating system's command line prompt. The `/home` screen is the main directory where everything begins, and the menus are paths branched from the main. Instead of `C:\Users\OpenBB\Documents`, you'll have something like `/equity/price`. Instead of `cd ..`, you can do `..` to return the menu right above. To go back to the root menu you can do `/`. ### Absolute Paths[​](https://docs.openbb.co/odp/cli/structure-and-navigation#absolute-paths "Direct link to Absolute Paths") Absolute paths are also valid to-and-from any point. From the `/equity/price` menu, you can go directly to `crypto` menu with: `/crypto`. Note the forward slash at the start to denote the "absolute" path. ### Home[​](https://docs.openbb.co/odp/cli/structure-and-navigation#home "Direct link to Home") Return to the Home screen from anywhere by entering any of the following: * `/` * `home` On this page * [Structure](https://docs.openbb.co/odp/cli/structure-and-navigation#structure) * [Navigation](https://docs.openbb.co/odp/cli/structure-and-navigation#navigation) * [Absolute Paths](https://docs.openbb.co/odp/cli/structure-and-navigation#absolute-paths) * [Home](https://docs.openbb.co/odp/cli/structure-and-navigation#home) --- # Uninstall | ODP Desktop App Docs [Skip to main content](https://docs.openbb.co/odp/desktop/uninstall#__docusaurus_skipToContent_fallback) Uninstall the Open Data Platform application by selecting `Uninstall` from the tray icon menu. When confirmed, the process will remove Miniforge, environments, all application data, and optionally, the `OpenBBUserData` and `~./openbb_platform` folders. note On Windows, using `uninstall.exe` or removing via Control Panel will only remove the GUI. Environments and other files will not be removed. ![uninstall](https://github.com/user-attachments/assets/28419487-17db-4480-a306-8073753e53d2) --- # File Viewer | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-types/file-viewer#__docusaurus_skipToContent_fallback) On this page Single File[​](https://docs.openbb.co/workspace/developers/widget-types/file-viewer#single-file "Direct link to Single File") ------------------------------------------------------------------------------------------------------------------------------ The (multi) file viewer widget supports two methods for serving files: 1. Base64 Encoding: The file content is encoded in base64 and sent directly in the response. 2. URL Reference: A URL to the file is provided, which can be a presigned URL for secure access to files stored in cloud storage. The endpoint should return a JSON response with the following structure: { "headers": { "Content-Type": "application/json" }, "data_format": { "data_type": "pdf", "filename": "example.pdf" }, "content": "base64_encoded_content", // For base64 method // OR "file_reference": "https://example.com/path/to/file.pdf" // For URL method} Note: * **data\_format.data\_type**: The type of file (e.g., "pdf", "csv", "txt") * **data\_format.filename**: The name of the file to display * **content**: Base64-encoded file content (for base64 method) * **file\_reference**: URL to the file (for URL method) ### PDF Widget with Base64[​](https://docs.openbb.co/workspace/developers/widget-types/file-viewer#pdf-widget-with-base64 "Direct link to PDF Widget with Base64") A widget that displays a PDF file using base64 encoding. This method is useful for displaying PDFs directly in the workspace. ![PDF Widget with Base64 Example](https://openbb-cms.directus.app/assets/9e202a65-eb71-4e43-b111-5f5c79dfa6dc.png) @register_widget({ "name": "PDF Widget with Base64", "description": "Display a PDF file with base64 encoding", "endpoint": "pdf_widget_base64", "gridData": { "w": 20, "h": 20 }, "type": "pdf",})@app.get("/pdf_widget_base64")def get_pdf_widget_base64(): """Serve a file through base64 encoding.""" try: name = "sample.pdf" with open(ROOT_PATH / name, "rb") as file: file_data = file.read() encoded_data = base64.b64encode(file_data) content = encoded_data.decode("utf-8") except FileNotFoundError as exc: raise HTTPException( status_code=404, detail="File not found" ) from exc return JSONResponse( headers={"Content-Type": "application/json"}, content={ "data_format": { "data_type": "pdf", "filename": name, }, "content": content, }, ) ### PDF Widget with URL[​](https://docs.openbb.co/workspace/developers/widget-types/file-viewer#pdf-widget-with-url "Direct link to PDF Widget with URL") A widget that displays a PDF file using a direct URL. This method is more efficient for larger PDFs as it doesn't require base64 encoding. ![PDF Widget with URL Example](https://openbb-cms.directus.app/assets/7d4fc0e6-f458-49a1-9be9-161d2bec1886.png) @register_widget({ "name": "PDF Widget with URL", "description": "Display a PDF file", "type": "pdf", "endpoint": "pdf_widget_url", "gridData": { "w": 20, "h": 20 },})@app.get("/pdf_widget_url")def get_pdf_widget_url(): """Serve a file through URL.""" file_reference = "https://openbb-assets.s3.us-east-1.amazonaws.com/testing/sample.pdf" if not file_reference: raise HTTPException(status_code=404, detail="File not found") return JSONResponse( headers={"Content-Type": "application/json"}, content={ "data_format": { "data_type": "pdf", "filename": "Sample.pdf", }, "url": file_reference, }, ) Multi File Viewer[​](https://docs.openbb.co/workspace/developers/widget-types/file-viewer#multi-file-viewer "Direct link to Multi File Viewer") ------------------------------------------------------------------------------------------------------------------------------------------------ ### Multi File Viewer with Base64[​](https://docs.openbb.co/workspace/developers/widget-types/file-viewer#multi-file-viewer-with-base64 "Direct link to Multi File Viewer with Base64") A widget that displays multiple PDF files using base64 encoding. This method is useful for smaller files that you want to serve directly (vs URL). ![Multi PDF Viewer with Base64 Example](https://openbb-cms.directus.app/assets/610ec2bc-2768-4d48-9f0b-0ad08a69b41e.png) 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 PDF files dataSAMPLE_PDFS = [ { "name": "Sample", "location": "sample.pdf", "url": "https://openbb-assets.s3.us-east-1.amazonaws.com/testing/sample.pdf", }, { "name": "Bitcoin Whitepaper", "location": "bitcoin.pdf", "url": "https://openbb-assets.s3.us-east-1.amazonaws.com/testing/bitcoin.pdf", }]# Options endpoint for file selection@app.get("/get_pdf_options")async def get_pdf_options() -> List[FileOption]: """Get list of available PDFs""" return [ FileOption(label=pdf["name"], value=pdf["name"]) for pdf in SAMPLE_PDFS ]@register_widget({ "name": "Multi PDF Viewer - Base64", "description": "View multiple PDF files using base64 encoding", "type": "multi_file_viewer", "endpoint": "/multi_pdf_base64", "gridData": { "w": 20, "h": 10 }, "params": [ { "paramName": "pdf_name", "description": "PDF file to display", "type": "endpoint", "label": "PDF File", "optionsEndpoint": "/get_pdf_options", "show": False, "value": ["Bitcoin Whitepaper"], "multiSelect": True, "roles": ["fileSelector"] } ]})@app.post("/multi_pdf_base64")async def get_multi_pdf_base64( pdf_name: List[str] = Body(..., embed=True)) -> List[Union[DataContent, DataError]]: """Get multiple PDF files in base64 format""" files = [] for name in pdf_name: pdf = next((p for p in SAMPLE_PDFS if p["name"] == name), None) if not pdf: files.append( DataError( error_type="not_found", content=f"PDF '{name}' not found" ).model_dump() ) continue file_path = ROOT_PATH / pdf["location"] if not file_path.exists(): files.append( DataError( error_type="not_found", content=f"PDF file '{pdf['location']}' not found on disk" ).model_dump() ) continue with open(file_path, "rb") as file: base64_content = base64.b64encode(file.read()).decode("utf-8") files.append( DataContent( content=base64_content, data_format=FileDataFormat( data_type="pdf", filename=f"{pdf['name']}.pdf" ) ).model_dump() ) return JSONResponse( headers={"Content-Type": "application/json"}, content=files ) ### Multi File Viewer with URL[​](https://docs.openbb.co/workspace/developers/widget-types/file-viewer#multi-file-viewer-with-url "Direct link to Multi File Viewer with URL") A widget that displays multiple PDF files using URLs. This method is more efficient for larger files as they're loaded directly from the URL. ![Multi PDF Viewer with URL Example](https://openbb-cms.directus.app/assets/7d4fc0e6-f458-49a1-9be9-161d2bec1886.png) 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@register_widget({ "name": "Multi PDF Viewer - URL", "description": "View multiple PDF files using URLs", "type": "multi_file_viewer", "endpoint": "/multi_pdf_url", "gridData": { "w": 20, "h": 10 }, "params": [ { "paramName": "pdf_name", "description": "PDF file to display", "type": "endpoint", "label": "PDF File", "optionsEndpoint": "/get_pdf_options", "value": ["Sample"], "show": False, "multiSelect": True, "roles": ["fileSelector"] } ]})@app.post("/multi_pdf_url")async def get_multi_pdf_url( pdf_name: List[str] = Body(..., embed=True)) -> List[Union[DataUrl, DataError]]: """Get multiple PDF files via URLs""" files = [] for name in pdf_name: pdf = next((p for p in SAMPLE_PDFS if p["name"] == name), None) if not pdf: files.append( DataError( error_type="not_found", content=f"PDF '{name}' not found" ).model_dump() ) continue if url := pdf.get("url"): files.append( DataUrl( url=url, data_format=FileDataFormat( data_type="pdf", filename=f"{pdf['name']}.pdf" ) ).model_dump() ) else: files.append( DataError( error_type="not_found", content=f"URL not found for '{name}'" ).model_dump() ) return JSONResponse( headers={"Content-Type": "application/json"}, content=files ) Multi File Viewer with Category Filtering[​](https://docs.openbb.co/workspace/developers/widget-types/file-viewer#multi-file-viewer-with-category-filtering "Direct link to Multi File Viewer with Category Filtering") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ This multi-file-viewer widget introduces a parameter called `optionsParams` which allows you to pass the options to an endpoint from a different parameter. More information [here](https://docs.openbb.co/workspace/developers/widget-parameters/dependent-dropdown) . In our case we want to pass the options in the `type` parameter to the `/whitepapers/options` endpoint to filter the list of whitepapers. ![multi-file-viewer](https://openbb-assets.s3.us-east-1.amazonaws.com/docs/pro/multi-file-viewer.png) 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 ]@register_widget({ "name": "Whitepapers", "description": "A collection of crypto whitepapers.", "type": "multi_file_viewer", "endpoint": "/whitepapers/view-base64", "gridData": { "w": 40, "h": 10 }, "params": [ { "type": "endpoint", "paramName": "whitepaper", "value": ["Bitcoin"], "label": "Whitepaper", "description": "Whitepaper to display.", "optionsEndpoint": "/whitepapers/options", "show": False, "optionsParams": { "category": "$category" }, "multiSelect": True, "roles": ["fileSelector"] }, { "type": "text", "paramName": "category", "value": "all", "label": "Category", "description": "Category of whitepaper to fetch.", "options": [ { "label": "All", "value": "all" }, { "label": "L1", "value": "l1" }, { "label": "L2", "value": "l2" }, { "label": "Oracles", "value": "oracles" }, { "label": "Defi", "value": "defi" } ] } ]})@app.post("/whitepapers/view-base64")async def view_whitepapers_base64( whitepaper: List[str] = Body(..., embed=True),) -> List[Union[DataContent, DataError]]: """Get multiple whitepapers in base64 format""" files = [] for name in whitepaper: wp = next((w for w in WHITEPAPERS if w["name"] == name), None) if not wp: files.append( DataError( error_type="not_found", content=f"Whitepaper '{name}' not found" ).model_dump() ) continue file_path = ROOT_PATH / wp["location"] if file_path.exists(): with open(file_path, "rb") as file: base64_content = base64.b64encode(file.read()).decode("utf-8") files.append( DataContent( content=base64_content, data_format=FileDataFormat( data_type="pdf", filename=f"{wp['name']}.pdf" ), ).model_dump() ) else: files.append( DataError( error_type="not_found", content="Whitepaper file not found" ).model_dump() ) return JSONResponse(headers={"Content-Type": "application/json"}, content=files)# Alternative URL version@app.post("/whitepapers/view-url")async def view_whitepapers_url( whitepaper: List[str] = Body(..., embed=True),) -> List[Union[DataUrl, DataError]]: """Get multiple whitepapers via URLs""" files = [] for name in whitepaper: wp = next((w for w in WHITEPAPERS if w["name"] == name), None) if not wp: files.append( DataError( error_type="not_found", content=f"Whitepaper '{name}' not found" ).model_dump() ) continue if url := wp.get("url"): files.append( DataUrl( url=url, data_format=FileDataFormat( data_type="pdf", filename=f"{wp['name']}.pdf" ), ).model_dump() ) else: files.append( DataError( error_type="not_found", content=f"URL not found for '{name}'" ).model_dump() ) return JSONResponse(headers={"Content-Type": "application/json"}, content=files) More examples can be found on the github repository at [https://github.com/OpenBB-finance/backends-for-openbb](https://github.com/OpenBB-finance/backends-for-openbb) On this page * [Single File](https://docs.openbb.co/workspace/developers/widget-types/file-viewer#single-file) * [PDF Widget with Base64](https://docs.openbb.co/workspace/developers/widget-types/file-viewer#pdf-widget-with-base64) * [PDF Widget with URL](https://docs.openbb.co/workspace/developers/widget-types/file-viewer#pdf-widget-with-url) * [Multi File Viewer](https://docs.openbb.co/workspace/developers/widget-types/file-viewer#multi-file-viewer) * [Multi File Viewer with Base64](https://docs.openbb.co/workspace/developers/widget-types/file-viewer#multi-file-viewer-with-base64) * [Multi File Viewer with URL](https://docs.openbb.co/workspace/developers/widget-types/file-viewer#multi-file-viewer-with-url) * [Multi File Viewer with Category Filtering](https://docs.openbb.co/workspace/developers/widget-types/file-viewer#multi-file-viewer-with-category-filtering) --- # ODP CLI Docs [Skip to main content](https://docs.openbb.co/odp/cli#__docusaurus_skipToContent_fallback) On this page Overview[​](https://docs.openbb.co/odp/cli#overview "Direct link to Overview") ------------------------------------------------------------------------------- The ODP CLI is a command line interface wrapping the Open Data Platform by OpenBB. It offers a convenient way to interact with the Platform and its extensions, as well as automate data collection via OpenBB Routine Scripts. The CLI leverages the extendability of the ODP architecture in an easy-to-consume and script format. ![CLI Home](https://github.com/OpenBB-finance/OpenBBTerminal/assets/85772166/d1617c3b-c83d-4491-a7bc-986321fd7230) Guides & Documentation[​](https://docs.openbb.co/odp/cli#guides--documentation "Direct link to Guides & Documentation") ------------------------------------------------------------------------------------------------------------------------ [Installation\ \ An installation guide for the ODP CLI.](https://docs.openbb.co/odp/cli/installation) [Quick Start\ \ A quick start guide for the ODP CLI.](https://docs.openbb.co/odp/cli/quickstart) [Configuration & Settings\ \ An explanation of the settings and environment variables that customize the look and feel of the ODP CLI.](https://docs.openbb.co/odp/cli/configuration) [Data Sources\ \ How-to switch providers for a command, and define the default source for a function.](https://docs.openbb.co/odp/cli/data-sources) [OpenBBUserData Folder\ \ The OpenBBUserData folder is where exports, routines, and other related files are saved.](https://docs.openbb.co/odp/cli/openbbuserdata) [Interactive Tables\ \ Understand how to sort, filter, hide columns, display more rows or export data on our tables.](https://docs.openbb.co/odp/cli/interactive-tables) [Interactive Charts\ \ Explore how to overlay charts, change titles, draw lines, add text and much more on our charts.](https://docs.openbb.co/odp/cli/interactive-charts) * * * Want to contribute? Check out our [Development section](https://docs.openbb.co/odp/python/developer/architecture_overview) . On this page * [Overview](https://docs.openbb.co/odp/cli#overview) * [Guides & Documentation](https://docs.openbb.co/odp/cli#guides--documentation) --- # Omni, SQL, Python | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-types/omni#__docusaurus_skipToContent_fallback) On this page The Omni widget is a versatile widget type that can dynamically return different content formats (markdown, tables, or charts). Unlike other widgets that use GET requests, the Omni widget uses POST requests and passes all parameters in the request body. This widget requires the `prompt` parameter to be passed in the params section of the widget configuration. ![Basic Plotly Chart Example](https://openbb-cms.directus.app/assets/8740e757-a800-41b7-809c-f0ef3def1729.png) Basic Omni Widget[​](https://docs.openbb.co/workspace/developers/widget-types/omni#basic-omni-widget "Direct link to Basic Omni Widget") ----------------------------------------------------------------------------------------------------------------------------------------- Below is an example of a basic Omni widget that demonstrates the versatility by returning different content types based on the `type` parameter. In a real world example you might choose to dynamically return different content types based on your backend logic. ![Omni Widget Example](https://openbb-assets.s3.us-east-1.amazonaws.com/docs/pro/omni-widget.png) import jsonfrom fastapi import FastAPI, Bodyimport plotly.graph_objects as gofrom pydantic import BaseModel, Fieldfrom typing import Any, Literalapp = FastAPI()class DataFormat(BaseModel): data_type: str parse_as: Literal["text", "table", "chart"]class OmniWidgetResponse(BaseModel): content: Any data_format: DataFormat citable: bool = Field(default=False)@app.post("/omni-widget")async def get_omni_widget_post(data: str | dict = Body(...)): """Basic Omni Widget example showing different return types""" if isinstance(data, str): data = json.loads(data) prompt = data.get("prompt", "Hello World") if data.get("type") == "table": # 2x2 matrix with prompt value in all cells content = [ {"col1": prompt, "col2": prompt}, {"col1": prompt, "col2": prompt}, ] return OmniWidgetResponse( content=content, data_format=DataFormat(data_type="object", parse_as="table"), citable=False, ) if data.get("type") == "chart": fig = go.Figure() fig.add_trace( go.Scatter(x=[1, 2, 3], y=[1, 3, 2], mode="lines", line=dict(color="#26a69a")) ) fig.update_layout(title=prompt, showlegend=False) content = json.loads(fig.to_json()) return OmniWidgetResponse( content=content, data_format=DataFormat(data_type="object", parse_as="chart"), citable=False, ) # Default to markdown - just output the prompt return OmniWidgetResponse( content=prompt, data_format=DataFormat(data_type="object", parse_as="text"), citable=False, ) ### Widget Configuration[​](https://docs.openbb.co/workspace/developers/widget-types/omni#widget-configuration "Direct link to Widget Configuration") { "omni_widget": { "name": "Basic Omni Widget", "description": "A versatile omni widget that can display multiple types of content", "category": "General", "type": "omni", "endpoint": "omni-widget", "params": [ { "paramName": "prompt", "type": "text", "description": "The prompt to send to the widget", "label": "Prompt", "show": false }, { "paramName": "type", "type": "text", "description": "Type of content to return", "label": "Content Type", "show": true, "options": [ {"value": "markdown", "label": "Markdown"}, {"value": "chart", "label": "Chart"}, {"value": "table", "label": "Table"} ] } ], "gridData": {"w": 30, "h": 12} }} SQL Query Widget[​](https://docs.openbb.co/workspace/developers/widget-types/omni#sql-query-widget "Direct link to SQL Query Widget") -------------------------------------------------------------------------------------------------------------------------------------- This example demonstrates an Omni widget that executes SQL queries against mock data. The `language` parameter enables SQL syntax highlighting in the input. ![Basic Plotly Chart Example](https://openbb-cms.directus.app/assets/e7c186e2-753b-4ae9-8b86-990f0b93c008.png) import jsonimport sqlite3import refrom fastapi import FastAPI, Bodyapp = FastAPI()# Mock data for SQL widgetMOCK_DATA = [ {"id": 1, "symbol": "AAPL", "name": "Apple Inc.", "price": 150.25, "volume": 45000000, "sector": "Technology"}, {"id": 2, "symbol": "MSFT", "name": "Microsoft Corporation", "price": 350.50, "volume": 32000000, "sector": "Technology"}, {"id": 3, "symbol": "GOOGL", "name": "Alphabet Inc.", "price": 140.75, "volume": 28000000, "sector": "Technology"}, {"id": 4, "symbol": "AMZN", "name": "Amazon.com Inc.", "price": 178.25, "volume": 38000000, "sector": "Consumer Cyclical"}, {"id": 5, "symbol": "TSLA", "name": "Tesla Inc.", "price": 245.80, "volume": 52000000, "sector": "Automotive"}, {"id": 6, "symbol": "JPM", "name": "JPMorgan Chase", "price": 195.30, "volume": 12000000, "sector": "Financial"}, {"id": 7, "symbol": "V", "name": "Visa Inc.", "price": 275.40, "volume": 8000000, "sector": "Financial"}, {"id": 8, "symbol": "JNJ", "name": "Johnson & Johnson", "price": 155.60, "volume": 6500000, "sector": "Healthcare"}, {"id": 9, "symbol": "WMT", "name": "Walmart Inc.", "price": 165.20, "volume": 7200000, "sector": "Consumer Defensive"}, {"id": 10, "symbol": "PG", "name": "Procter & Gamble", "price": 158.90, "volume": 5800000, "sector": "Consumer Defensive"},]def execute_sql_on_mock_data(sql: str) -> list[dict]: """Execute SQL query against mock data using in-memory SQLite""" conn = sqlite3.connect(":memory:") conn.row_factory = sqlite3.Row cursor = conn.cursor() # Create table and insert mock data cursor.execute(""" CREATE TABLE stocks ( id INTEGER, symbol TEXT, name TEXT, price REAL, volume INTEGER, sector TEXT ) """) for row in MOCK_DATA: cursor.execute( "INSERT INTO stocks VALUES (?, ?, ?, ?, ?, ?)", (row["id"], row["symbol"], row["name"], row["price"], row["volume"], row["sector"]) ) conn.commit() # Execute the user's query (replace DATA with stocks) normalized_sql = re.sub(r'\bDATA\b', 'stocks', sql, flags=re.IGNORECASE) cursor.execute(normalized_sql) rows = cursor.fetchall() conn.close() return [dict(row) for row in rows]@app.post("/omni-sql-widget")async def get_omni_sql_widget(data: str | dict = Body(...)): """SQL Query Widget - executes SQL against mock stock data""" if isinstance(data, str): data = json.loads(data) sql_query = data.get("prompt", "SELECT * FROM DATA LIMIT 5") try: results = execute_sql_on_mock_data(sql_query) if not results: return OmniWidgetResponse( content="No results found for the query.", data_format=DataFormat(data_type="object", parse_as="text"), citable=False, ) return OmniWidgetResponse( content=results, data_format=DataFormat(data_type="object", parse_as="table"), citable=False, ) except Exception as e: error_content = f"""### SQL Query Error**Query:** `{sql_query}`**Error:** {str(e)}**Available columns:** id, symbol, name, price, volume, sector**Example queries:**- `SELECT * FROM DATA LIMIT 5`- `SELECT symbol, price FROM DATA WHERE sector = 'Technology'`- `SELECT sector, AVG(price) as avg_price FROM DATA GROUP BY sector`""" return OmniWidgetResponse( content=error_content, data_format=DataFormat(data_type="object", parse_as="text"), citable=False, ) ### SQL Widget Configuration[​](https://docs.openbb.co/workspace/developers/widget-types/omni#sql-widget-configuration "Direct link to SQL Widget Configuration") { "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} }} Note the `language: "sql"` parameter which enables SQL syntax highlighting in the input field. Python Widget[​](https://docs.openbb.co/workspace/developers/widget-types/omni#python-widget "Direct link to Python Widget") ----------------------------------------------------------------------------------------------------------------------------- This example demonstrates an Omni widget that executes Python code to create Plotly charts dynamically. ![Basic Plotly Chart Example](https://openbb-cms.directus.app/assets/a39f2dbb-12f5-47c5-93fa-9206c7435545.png) import jsonfrom fastapi import FastAPI, Bodyimport plotly.graph_objects as goapp = FastAPI()DEFAULT_PYTHON_CODE = '''# Create a simple bar chartfig = go.Figure()fig.add_trace(go.Bar( x=["Q1", "Q2", "Q3", "Q4"], y=[100, 150, 130, 180], name="Revenue", marker_color="#26a69a"))fig.add_trace(go.Bar( x=["Q1", "Q2", "Q3", "Q4"], y=[80, 120, 110, 150], name="Profit", marker_color="#ef5350"))fig.update_layout( title="Quarterly Performance", barmode="group", xaxis_title="Quarter", yaxis_title="Amount ($M)")'''@app.post("/omni-python-widget")async def get_omni_python_widget(data: str | dict = Body(...)): """Python Chart Widget - executes Python code to create Plotly charts""" if isinstance(data, str): data = json.loads(data) python_code = data.get("prompt", DEFAULT_PYTHON_CODE) try: # Create a restricted namespace for execution namespace = {"go": go} exec(python_code, namespace) fig = namespace.get("fig") if fig is None: return OmniWidgetResponse( content="Error: No 'fig' variable found. Please assign your Plotly figure to 'fig'.", data_format=DataFormat(data_type="object", parse_as="text"), citable=False, ) content = json.loads(fig.to_json()) return OmniWidgetResponse( content=content, data_format=DataFormat(data_type="object", parse_as="chart"), citable=False, ) except Exception as e: error_content = f"### Python Execution Error\n\n**Error:** {str(e)}\n\n**Example code:**\n\nfig = go.Figure()\nfig.add_trace(go.Bar(x=['A', 'B', 'C'], y=[1, 2, 3]))" return OmniWidgetResponse( content=error_content, data_format=DataFormat(data_type="object", parse_as="text"), citable=False, ) ### Python Widget Configuration[​](https://docs.openbb.co/workspace/developers/widget-types/omni#python-widget-configuration "Direct link to Python Widget Configuration") { "omni_python_widget": { "name": "Python Chart Widget", "description": "Write Python code to create Plotly charts. Use 'fig' as the figure variable.", "category": "General", "type": "omni", "endpoint": "omni-python-widget", "params": [ { "paramName": "prompt", "type": "text", "description": "Enter Python code to create a Plotly chart. Use 'go' for plotly.graph_objects.", "label": "Python Code", "show": false, "language": "python" } ], "gridData": {"w": 30, "h": 12} }} Note the `language: "python"` parameter which enables Python syntax highlighting in the input field. Important Implementation Notes[​](https://docs.openbb.co/workspace/developers/widget-types/omni#important-implementation-notes "Direct link to Important Implementation Notes") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ### POST Request Method[​](https://docs.openbb.co/workspace/developers/widget-types/omni#post-request-method "Direct link to POST Request Method") Unlike other widget types that use GET requests, the Omni widget uses POST requests. This allows for more complex parameter handling and larger payloads: @app.post("/omni-widget") # Note: POST, not GETasync def omni_endpoint( data: str | dict = Body(...) # Main parameters in request body): # Handle both string and dict formats if isinstance(data, str): data = json.loads(data) # All widget parameters are available in the 'data' object param_value = data.get("paramName") ### Dynamic Output Control[​](https://docs.openbb.co/workspace/developers/widget-types/omni#dynamic-output-control "Direct link to Dynamic Output Control") ![Basic Plotly Chart Example](https://openbb-cms.directus.app/assets/039a99d7-1b18-4501-b477-d233256b5ff7.png) The Omni widget can return different content types based on the parse\_as field in the DataFormat: * "text": For markdown/text content * "table": For tabular data (list of dictionaries) * "chart": For Plotly chart objects # Text/Markdown outputreturn OmniWidgetResponse( content="# Markdown content", data_format=DataFormat(data_type="object", parse_as="text")) # Table outputreturn OmniWidgetResponse( content=[{"col1": "val1", "col2": "val2"}], data_format=DataFormat(data_type="object", parse_as="table")) # Chart outputreturn OmniWidgetResponse( content={"data": [...], "layout": {...}}, data_format=DataFormat(data_type="object", parse_as="chart")) ### Language Parameter[​](https://docs.openbb.co/workspace/developers/widget-types/omni#language-parameter "Direct link to Language Parameter") The `language` parameter in widget configuration enables syntax highlighting for the input: { "paramName": "prompt", "type": "text", "language": "sql" // or "python" or nothing for text} ### Parameter Handling[​](https://docs.openbb.co/workspace/developers/widget-types/omni#parameter-handling "Direct link to Parameter Handling") All widget parameters defined in the widget configuration are passed in the POST request body, and the `prompt` parameter is required: { "params": [ { // Required parameter for the LLM to make queries or ask questions "paramName": "prompt", "type": "text", "description": "The prompt to send to the LLM to make queries or ask questions.", "label": "Prompt", "show": false } { "paramName": "user_input", "type": "text", "label": "User Input" }, { "paramName": "option_select", "type": "text", "options": [...] } ]} These parameters are accessible in your endpoint: @app.post("/omni-widget")async def omni_endpoint(data: dict = Body(...)): user_input = data.get("user_input") selected_option = data.get("option_select") prompt = data.get("prompt") # Process parameters... ### Hide text/SQL/Python Area[​](https://docs.openbb.co/workspace/developers/widget-types/omni#hide-textsqlpython-area "Direct link to Hide text/SQL/Python Area") You can edit the input area text and run each widget with the run button. ![Basic Plotly Chart Example](https://openbb-cms.directus.app/assets/8740e757-a800-41b7-809c-f0ef3def1729.png) But once you are happy you can hide that input area and when you want to run it again you can just click on the run button on the top left corner, and the business logic remains. ![Basic Plotly Chart Example](https://openbb-cms.directus.app/assets/4d32eeeb-2d39-4c4e-a7fd-54bdac58da20.png) Use Cases[​](https://docs.openbb.co/workspace/developers/widget-types/omni#use-cases "Direct link to Use Cases") ----------------------------------------------------------------------------------------------------------------- The Omni widget is particularly useful for: * AI/LLM Integration: Dynamic content generation based on user prompts * Multi-format Data Display: Single endpoint that can return different visualizations * SQL Query Interfaces: Execute queries and display results as tables * Code Execution: Run Python code to generate charts dynamically * Citation-heavy Applications: Research tools that need to track data sources On this page * [Basic Omni Widget](https://docs.openbb.co/workspace/developers/widget-types/omni#basic-omni-widget) * [Widget Configuration](https://docs.openbb.co/workspace/developers/widget-types/omni#widget-configuration) * [SQL Query Widget](https://docs.openbb.co/workspace/developers/widget-types/omni#sql-query-widget) * [SQL Widget Configuration](https://docs.openbb.co/workspace/developers/widget-types/omni#sql-widget-configuration) * [Python Widget](https://docs.openbb.co/workspace/developers/widget-types/omni#python-widget) * [Python Widget Configuration](https://docs.openbb.co/workspace/developers/widget-types/omni#python-widget-configuration) * [Important Implementation Notes](https://docs.openbb.co/workspace/developers/widget-types/omni#important-implementation-notes) * [POST Request Method](https://docs.openbb.co/workspace/developers/widget-types/omni#post-request-method) * [Dynamic Output Control](https://docs.openbb.co/workspace/developers/widget-types/omni#dynamic-output-control) * [Language Parameter](https://docs.openbb.co/workspace/developers/widget-types/omni#language-parameter) * [Parameter Handling](https://docs.openbb.co/workspace/developers/widget-types/omni#parameter-handling) * [Hide text/SQL/Python Area](https://docs.openbb.co/workspace/developers/widget-types/omni#hide-textsqlpython-area) * [Use Cases](https://docs.openbb.co/workspace/developers/widget-types/omni#use-cases) --- # AI Features — Create tables | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/ai-features/create-tables#__docusaurus_skipToContent_fallback) On this page Emit a table artifact with `table(...)`. Provide an array of objects; column names are inferred from object keys. Reference implementation in [this GitHub repository](https://github.com/OpenBB-finance/agents-for-openbb/tree/main/34-vanilla-agent-tables/vanilla_agent_tables/main.py) . ![Tables](https://openbb-cms.directus.app/assets/9024844b-2b40-4878-80d0-4be2309a8297.png) Architecture[​](https://docs.openbb.co/workspace/developers/ai-features/create-tables#architecture "Direct link to Architecture") ---------------------------------------------------------------------------------------------------------------------------------- Emit table artifacts in-line so tabular data renders below the answer. `agents.json` configuration: return JSONResponse(content={ "vanilla_agent_tables": { "endpoints": {"query": "http://localhost:7777/v1/query"}, "features": { "widget-dashboard-select": False, "widget-dashboard-search": False, }, }}) ### Query flow[​](https://docs.openbb.co/workspace/developers/ai-features/create-tables#query-flow "Direct link to Query flow") * Process user request and generate data (from widgets, analysis, or computation) * Stream explanatory text with `message_chunk()` * Create table data as list of dictionaries (column names from object keys) * Emit `table()` artifact with data, name, and description * Table renders below the streamed text in Workspace UI * Continue with additional content or complete response ### OpenBB AI SDK[​](https://docs.openbb.co/workspace/developers/ai-features/create-tables#openbb-ai-sdk "Direct link to OpenBB AI SDK") * `table(data, name, description)`: Creates `MessageArtifactSSE` for table display * `data`: List of dictionaries where keys become column headers * `name`: Table title displayed in UI * `description`: Optional table description * `message_chunk(text)`: Streams explanatory text before/after tables * Tables automatically handle data formatting and sorting in UI Core logic[​](https://docs.openbb.co/workspace/developers/ai-features/create-tables#core-logic "Direct link to Core logic") ---------------------------------------------------------------------------------------------------------------------------- from openbb_ai import message_chunk, tablefrom openbb_ai.models import QueryRequestasync def query(request: QueryRequest) -> EventSourceResponse: async def execution_loop(): # Stream introduction yield message_chunk("Let me analyze the financial data and create a summary table.\n\n").model_dump() # Generate or process data (from widgets, calculations, etc.) financial_data = [ {"symbol": "AAPL", "price": 150.25, "change": 2.5, "volume": 1200000}, {"symbol": "MSFT", "price": 280.75, "change": -1.2, "volume": 890000}, {"symbol": "GOOGL", "price": 2650.80, "change": 15.3, "volume": 560000}, ] # Create table artifact yield table( data=financial_data, name="Stock Market Summary", description="Current stock prices with daily changes and trading volume" ).model_dump() # Stream additional analysis yield message_chunk("\n\nThe table above shows the current market status. AAPL and GOOGL are up, while MSFT is down slightly.").model_dump() return EventSourceResponse(execution_loop(), media_type="text/event-stream") On this page * [Architecture](https://docs.openbb.co/workspace/developers/ai-features/create-tables#architecture) * [Query flow](https://docs.openbb.co/workspace/developers/ai-features/create-tables#query-flow) * [OpenBB AI SDK](https://docs.openbb.co/workspace/developers/ai-features/create-tables#openbb-ai-sdk) * [Core logic](https://docs.openbb.co/workspace/developers/ai-features/create-tables#core-logic) --- # AI Features — Highlight widget citations | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/ai-features/highlight-widget-citations#__docusaurus_skipToContent_fallback) On this page After retrieving widget data, attribute outputs to their sources. Build `cite(...)` entries and stream them with `citations(...)` so Workspace shows a citations panel next to the answer. Reference implementation in [this GitHub repository](https://github.com/OpenBB-finance/agents-for-openbb/tree/main/32-vanilla-agent-raw-widget-data-citations/vanilla_agent_raw_context_citations/main.py) . ![Citations](https://openbb-cms.directus.app/assets/0af85f66-b91f-476d-a231-973442a29957.png) Architecture[​](https://docs.openbb.co/workspace/developers/ai-features/highlight-widget-citations#architecture "Direct link to Architecture") ----------------------------------------------------------------------------------------------------------------------------------------------- This pattern extends "Parse widget data" by adding attribution. After data retrieval, emit citations to show provenance in Workspace. `agents.json` configuration with `widget-dashboard-select` feature enabled: return JSONResponse(content={ "vanilla_agent_raw_widget_data_citations": { "endpoints": {"query": "http://localhost:7777/v1/query"}, "features": { "streaming": True, "widget-dashboard-select": True, "widget-dashboard-search": False, }, }}) ### Query flow[​](https://docs.openbb.co/workspace/developers/ai-features/highlight-widget-citations#query-flow "Direct link to Query flow") * Early exit: fetch widget data when human message contains `widgets.primary` * On subsequent tool message: * Process widget data and include in LLM context * Match widget UUIDs from tool `input_arguments` to `request.widgets.primary` * Build `cite()` objects for each data source used * Stream citations with `citations()` after LLM response * Citations appear in Workspace UI panel for source verification ### OpenBB AI SDK[​](https://docs.openbb.co/workspace/developers/ai-features/highlight-widget-citations#openbb-ai-sdk "Direct link to OpenBB AI SDK") * `cite(widget, input_arguments, extra_details)`: Creates `Citation` objects * `citations(citation_list)`: Emits `CitationCollectionSSE` events * `Citation`: Links outputs to data sources with metadata * `SourceInfo`: Provides detailed source attribution data Core logic[​](https://docs.openbb.co/workspace/developers/ai-features/highlight-widget-citations#core-logic "Direct link to Core logic") ----------------------------------------------------------------------------------------------------------------------------------------- Build citations by matching the tool input arguments to widgets in the request: from openbb_ai import cite, citationsfrom openbb_ai.models import Citation, CitationHighlightBoundingBoxasync def execution_loop(): # ... stream LLM response ... # Build citations after response citations_list = [] # Process tool message to find data sources for message in request.messages: if message.role == "tool": for widget_data_request in message.input_arguments["data_sources"]: # Match widget by UUID matching_widgets = [ w for w in request.widgets.primary if str(w.uuid) == widget_data_request["widget_uuid"] ] if matching_widgets: widget = matching_widgets[0] citation = cite( widget=widget, input_arguments=widget_data_request["input_args"], extra_details={ "Widget Name": widget.name, "Data Source": widget.type, "Parameters Used": widget_data_request["input_args"] } ) citations_list.append(citation) # Emit citations for UI display if citations_list: yield citations(citations_list).model_dump() On this page * [Architecture](https://docs.openbb.co/workspace/developers/ai-features/highlight-widget-citations#architecture) * [Query flow](https://docs.openbb.co/workspace/developers/ai-features/highlight-widget-citations#query-flow) * [OpenBB AI SDK](https://docs.openbb.co/workspace/developers/ai-features/highlight-widget-citations#openbb-ai-sdk) * [Core logic](https://docs.openbb.co/workspace/developers/ai-features/highlight-widget-citations#core-logic) --- # AI Features — Share step-by-step reasoning | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/ai-features/share-step-by-step-reasoning#__docusaurus_skipToContent_fallback) On this page Stream status updates with `reasoning_step` so users can track multi‑stage actions (fetching data, running tools, post‑processing) as tokens arrive. Reference implementation in [this GitHub repository](https://github.com/OpenBB-finance/agents-for-openbb/tree/main/31-vanilla-agent-reasoning-steps/vanilla_agent_reasoning_steps/main.py) . ![Reasoning](https://openbb-cms.directus.app/assets/eaf36840-a06d-4958-9e0d-cb2570e5a08e.png) Architecture[​](https://docs.openbb.co/workspace/developers/ai-features/share-step-by-step-reasoning#architecture "Direct link to Architecture") ------------------------------------------------------------------------------------------------------------------------------------------------- Stream status updates alongside tokens so users see what the agent is doing. `agents.json` configuration: return JSONResponse(content={ "vanilla_agent_reasoning_steps": { "endpoints": {"query": "http://localhost:7777/v1/query"}, "features": { "streaming": True, "widget-dashboard-select": False, "widget-dashboard-search": False, }, }}) ### Query flow[​](https://docs.openbb.co/workspace/developers/ai-features/share-step-by-step-reasoning#query-flow "Direct link to Query flow") * Parse `QueryRequest.messages` and convert to OpenAI-compatible format * Add system message to define agent role and capabilities * Emit `reasoning_step()` at key processing stages: * Before starting LLM processing * During data preparation or analysis steps * After completing major operations * Stream LLM response tokens with `message_chunk()` * Send final reasoning step upon completion ### OpenBB AI SDK[​](https://docs.openbb.co/workspace/developers/ai-features/share-step-by-step-reasoning#openbb-ai-sdk "Direct link to OpenBB AI SDK") * `reasoning_step(event_type, message, details)`: Creates `StatusUpdateSSE` events * `event_type`: `"INFO"`, `"SUCCESS"`, `"WARNING"`, `"ERROR"` * `message`: Human-readable status description * `details`: Optional dictionary with key-value pairs for additional context * `message_chunk(text)`: Creates `MessageChunkSSE` for streaming LLM output * `LlmClientMessage`: Handles message conversion between formats Core logic[​](https://docs.openbb.co/workspace/developers/ai-features/share-step-by-step-reasoning#core-logic "Direct link to Core logic") ------------------------------------------------------------------------------------------------------------------------------------------- from openbb_ai import reasoning_step, message_chunkfrom openbb_ai.models import QueryRequest, LlmClientMessagefrom openai.types.chat import ChatCompletionSystemMessageParam, ChatCompletionUserMessageParamasync 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") On this page * [Architecture](https://docs.openbb.co/workspace/developers/ai-features/share-step-by-step-reasoning#architecture) * [Query flow](https://docs.openbb.co/workspace/developers/ai-features/share-step-by-step-reasoning#query-flow) * [OpenBB AI SDK](https://docs.openbb.co/workspace/developers/ai-features/share-step-by-step-reasoning#openbb-ai-sdk) * [Core logic](https://docs.openbb.co/workspace/developers/ai-features/share-step-by-step-reasoning#core-logic) --- # Installation | ODP Desktop App Docs [Skip to main content](https://docs.openbb.co/odp/desktop/installation#__docusaurus_skipToContent_fallback) On this page Requirements[​](https://docs.openbb.co/odp/desktop/installation#requirements "Direct link to Requirements") ------------------------------------------------------------------------------------------------------------ A modern laptop or desktop machine is recommended. It is not intended to be run in virtual machines or as a CI application. ### System[​](https://docs.openbb.co/odp/desktop/installation#system "Direct link to System") * Windows 11 or macOS (10.15+) * 2+ GB of usable storage space * 8 GB of RAM * Internet connection ### Permissions[​](https://docs.openbb.co/odp/desktop/installation#permissions "Direct link to Permissions") This application is scoped to the operating system user account, and the OS may ask you to grant permissions. The general needs of this application are: * Access the internet, download files, and install packages from repositories. * Packages can be installed from `conda` or `pip`. * Manage files in the user and temp directories. * Run background tasks and shell scripts. * Configure the operating system for the `Start at Login` feature. Installation[​](https://docs.openbb.co/odp/desktop/installation#installation "Direct link to Installation") ------------------------------------------------------------------------------------------------------------ Download the appropriate file for your machine from the link [here](https://github.com/OpenBB-finance/OpenBB/releases/ODP) ### macOS[​](https://docs.openbb.co/odp/desktop/installation#macos "Direct link to macOS") Open the DMG file and then drag-and-drop the app into the Applications folder. ### Windows[​](https://docs.openbb.co/odp/desktop/installation#windows "Direct link to Windows") Execute the installer file, and then start the application. First Run[​](https://docs.openbb.co/odp/desktop/installation#first-run "Direct link to First Run") --------------------------------------------------------------------------------------------------- When first run, you will be asked to select an installation location. This is where Miniforge, environments, and other application data will be stored. The user data directory is where the OpenBB Python packages should store data, such as data/HTTP cache. It is recommeneded to use separate locations for each. ![install-step-1](https://github.com/user-attachments/assets/e0785ef1-3702-4f16-a9e7-5acd4a4368c9) Click, Begin Installation, when you're ready. ![install-miniforge](https://github.com/user-attachments/assets/6529f996-42d9-4560-a62a-0b541d233a53) ### OpenBB Environment[​](https://docs.openbb.co/odp/desktop/installation#openbb-environment "Direct link to OpenBB Environment") After Miniforge is installed, you will be directed to pick a version of Python for the initial environment. ![install-step-2](https://github.com/user-attachments/assets/10ffb597-98d5-446f-bc8e-677b68287f43) Upon clicking the, Next Step, button, an `openbb` environment will be created with the core packages. ![install-initial-env](https://github.com/user-attachments/assets/26d193e0-7a6d-459c-9364-6086bec8cc1c) When complete, you can customize the environment by adding OpenBB Python modules or arbitrary libraries from PyPI. ![install-step-3](https://github.com/user-attachments/assets/9a39bf11-a41e-4067-b92b-a34ac9d36381) Finally, click the button to go to the [Environments](https://docs.openbb.co/odp/desktop/environments) page. ![install-complete](https://github.com/user-attachments/assets/8f115fe5-6128-4f38-8b79-17c892b8857b) On this page * [Requirements](https://docs.openbb.co/odp/desktop/installation#requirements) * [System](https://docs.openbb.co/odp/desktop/installation#system) * [Permissions](https://docs.openbb.co/odp/desktop/installation#permissions) * [Installation](https://docs.openbb.co/odp/desktop/installation#installation) * [macOS](https://docs.openbb.co/odp/desktop/installation#macos) * [Windows](https://docs.openbb.co/odp/desktop/installation#windows) * [First Run](https://docs.openbb.co/odp/desktop/installation#first-run) * [OpenBB Environment](https://docs.openbb.co/odp/desktop/installation#openbb-environment) --- # AI Features — Create charts | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/ai-features/create-charts#__docusaurus_skipToContent_fallback) On this page Stream visualizations (line, bar, scatter, pie, donut) with `chart(...)`. Charts appear below the message that emitted them. Reference implementation in [this GitHub repository](https://github.com/OpenBB-finance/agents-for-openbb/tree/main/33-vanilla-agent-charts/vanilla_agent_charts/main.py) . ![Charts](https://openbb-cms.directus.app/assets/e9d93282-20cb-4b3a-bf58-17032191e82a.png) Architecture[​](https://docs.openbb.co/workspace/developers/ai-features/create-charts#architecture "Direct link to Architecture") ---------------------------------------------------------------------------------------------------------------------------------- Emit chart artifacts so visualizations render below the answer. The example shows multiple chart types in one response. `agents.json` configuration with `widget-dashboard-select` feature enabled: return JSONResponse(content={ "vanilla_agent_charts": { "endpoints": {"query": "http://localhost:7777/v1/query"}, "features": { "widget-dashboard-select": False, "widget-dashboard-search": False, }, }}) ### Query flow[​](https://docs.openbb.co/workspace/developers/ai-features/create-charts#query-flow "Direct link to Query flow") * Process user request and prepare data for visualization * Stream explanatory text with `message_chunk()` * Create chart data as list of dictionaries * Choose appropriate chart type based on data characteristics: * **Line/Bar/Scatter**: Use `x_key` and `y_keys` for XY data * **Pie/Donut**: Use `angle_key` for values, `callout_label_key` for labels * Emit `chart()` artifacts with proper configuration * Charts render interactively below streamed content ### OpenBB AI SDK[​](https://docs.openbb.co/workspace/developers/ai-features/create-charts#openbb-ai-sdk "Direct link to OpenBB AI SDK") * `chart(type, data, x_key, y_keys, name, description)`: Creates `MessageArtifactSSE` for chart display * Chart types: `"line"`, `"bar"`, `"scatter"`, `"pie"`, `"donut"` * Chart parameters handled by specific models: * `LineChartParameters`, `BarChartParameters`, `ScatterChartParameters` * `PieChartParameters`, `DonutChartParameters` * `message_chunk(text)`: Streams explanatory text around charts * Charts support interactive features like zoom, hover, and data export Core logic[​](https://docs.openbb.co/workspace/developers/ai-features/create-charts#core-logic "Direct link to Core logic") ---------------------------------------------------------------------------------------------------------------------------- from openbb_ai import message_chunk, chartfrom openbb_ai.models import QueryRequestimport datetimeasync def query(request: QueryRequest) -> EventSourceResponse: async def execution_loop(): # Stream introduction yield message_chunk("Let me create some visualizations to illustrate the data trends.\n\n").model_dump() # Prepare time series data price_data = [ {"date": "2024-01-01", "price": 150.0, "volume": 1200000}, {"date": "2024-01-02", "price": 152.5, "volume": 1350000}, {"date": "2024-01-03", "price": 148.2, "volume": 1100000}, {"date": "2024-01-04", "price": 155.8, "volume": 1450000}, ] # Create line chart for price trend yield chart( type="line", data=price_data, x_key="date", y_keys=["price"], name="Stock Price Trend", description="Daily stock price movement over time" ).model_dump() yield message_chunk("\n\nThe line chart shows an overall upward trend. Now let's look at volume distribution:\n\n").model_dump() # Create bar chart for volume yield chart( type="bar", data=price_data, x_key="date", y_keys=["volume"], name="Trading Volume", description="Daily trading volume by date" ).model_dump() # Portfolio allocation pie chart portfolio_data = [ {"asset": "Stocks", "allocation": 60}, {"asset": "Bonds", "allocation": 25}, {"asset": "Cash", "allocation": 10}, {"asset": "Real Estate", "allocation": 5} ] yield message_chunk("\n\nHere's the portfolio allocation breakdown:\n\n").model_dump() yield chart( type="pie", data=portfolio_data, angle_key="allocation", callout_label_key="asset", name="Portfolio Allocation", description="Investment portfolio distribution by asset class" ).model_dump() return EventSourceResponse(execution_loop(), media_type="text/event-stream") On this page * [Architecture](https://docs.openbb.co/workspace/developers/ai-features/create-charts#architecture) * [Query flow](https://docs.openbb.co/workspace/developers/ai-features/create-charts#query-flow) * [OpenBB AI SDK](https://docs.openbb.co/workspace/developers/ai-features/create-charts#openbb-ai-sdk) * [Core logic](https://docs.openbb.co/workspace/developers/ai-features/create-charts#core-logic) --- # Troubleshooting | ODP Desktop App Docs [Skip to main content](https://docs.openbb.co/odp/desktop/troubleshooting#__docusaurus_skipToContent_fallback) On this page This page covers potential problems that might be encountered while using the ODP Desktop application. Console Logs[​](https://docs.openbb.co/odp/desktop/troubleshooting#console-logs "Direct link to Console Logs") --------------------------------------------------------------------------------------------------------------- The window has a console available by right-clicking anywhere and selecting "Inspect Element". Use this to find frontend components, user interactions, and JavaScript errors. For backend logs, quit the application and open it by running the `.exe`/`.bin` file in the operating system's default terminal shell. Installation[​](https://docs.openbb.co/odp/desktop/troubleshooting#installation "Direct link to Installation") --------------------------------------------------------------------------------------------------------------- Having trouble with the initial installation and setup? warning If the initial `openbb` environment failed during creation, you will be presented with the error, and a choice to try again or continue anyways. If you try again, select a new path or overwrite the existing. If you continue anyways, the environment will be in a partially-installed state and some user interactions may not worked as-expected. In most cases, you will want to address the error before use or reinstallation. If you need to remove the application entirely, uninstall via the standard operating system procedures, then remove the initial installation folder where Conda is installed. ### Timeout[​](https://docs.openbb.co/odp/desktop/troubleshooting#timeout "Direct link to Timeout") If you experienced a timeout error, this is most likely a network connection issue. Potentially transitory, trying again may resolve itself. The console logs may reveal additional context. ### Permission Error[​](https://docs.openbb.co/odp/desktop/troubleshooting#permission-error "Direct link to Permission Error") This typically happens when the operating system user does not have adequate permissions for the selected installation path. The safest place is usually the User home directory, and avoid installing where administrator privileges are required. In Windows Powershell, this command grants the current user full control to their user profile folder and all subfolders and files. icacls "$env:USERPROFILE" /grant "$env:USERNAME":(OI)(CI)F /T This command is an equivalent on macOS: chmod -R +a "user:$(whoami) allow list,add_file,search,add_subdirectory,delete_child,readattr,writeattr,readextattr,writeextattr,readsecurity,file_inherit,directory_inherit" "/Users/user_name" ### Failed Building Wheel[​](https://docs.openbb.co/odp/desktop/troubleshooting#failed-building-wheel "Direct link to Failed Building Wheel") This error will end with, "Failed to build installable wheels for some pyproject.toml based projects.", along with the failed package. These are typically CPython packages where precompiled binaries are not published to PyPI for your operating system and/or CPU architecture. It likely means that a system-level component could not be found on the machine, and needs to be installed or directed to the installation with environment variables. warning If you are running an Intel-based macOS machine, EOL for macOS is scheduled for the end of 2026, and major packages have already begun phasing out support of precompiled binaries. This may also be applicable to Apple Silicon machines where x86-based (Rosetta2) packages are being installed. Instructions Detail You will need to install additional system components (compilers). Start with X-Code: xcode-select --install Then install Homebrew: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" Then install CMake: brew install cmake Finally, install LLVM: brew install llvm@20 If you are on a Windows machine, this error might reference MSVC Microsoft Visual C++, and if so, download and install from the Microsoft [site](https://visualstudio.microsoft.com/downloads) by expanding the "Other Tools, Frameworks, and Redistributables" section. Backends[​](https://docs.openbb.co/odp/desktop/troubleshooting#backends "Direct link to Backends") --------------------------------------------------------------------------------------------------- If you experienced an installation error and elected to continue anyways, it is likely that the existing backends will not start because the packages were not installed. Removing or updating backends will have no impact on the environment. | Question | Answer | | --- | --- | | Backend stuck at _starting_. | After 30s, if an error is not detected the status will update as running. | | Backend URL displayed is incorrect. | The UI looks for a host:port pattern from the application startup. Check the logs for errors and report unexpected outcomes on [Github](https://github.com/OpenBB-finance/OpenBB/issues/)
. | | Startup traceback. | The GUI captures the full traceback and stops the service; open logs for details, fix code, then **Start** again. | | Port already in use. | Edit the backend and set the `--port` runtime argument, or stop the conflicting process. | | Port different than expected. | Launchers such as, `openbb-api`, will find the next available port. Is a service already running? | | How do I expose the API to my LAN? | Set the `--host` runtime argument as, `0.0.0.0`, and ensure the firewall allows the chosen port. | | Can I run non-Python services? | Yes – any executable/script is allowed as long as it runs inside the selected Conda environment. | | Status shows as running, but backend failed to start. | Refresh the window by right-clicking and selecting reload. Does the status change? Press **Stop**. Is the process terminated? Consult the logs and report unexpected outcomes on [Github](https://github.com/OpenBB-finance/OpenBB/issues/)
. | | Backend fails to terminate on ODP exit. | This is likely a bug, please report on [Github](https://github.com/OpenBB-finance/OpenBB/issues/)
, with context. | Environments[​](https://docs.openbb.co/odp/desktop/troubleshooting#environments "Direct link to Environments") --------------------------------------------------------------------------------------------------------------- If an environment gets corrupted, the best thing to do is remove it and recreate. If the environment can't be removed from the ODP `Environments` screen, open the installation folder and delete the folder manually. All environments are under the Conda folder, `{installation_path}/conda/envs/{env_name}`, and can be deleted safely at any time. GitHub Issues[​](https://docs.openbb.co/odp/desktop/troubleshooting#github-issues "Direct link to GitHub Issues") ------------------------------------------------------------------------------------------------------------------ If you are unable to resolve the error after troubleshooting, look at the open issues on [GitHub](https://github.com/OpenBB-finance/OpenBB/issues) and add to, or create, one. Please provide all relative context with conditions, the operating system version, CPU architecture type, along with error messages and screenshots. On this page * [Console Logs](https://docs.openbb.co/odp/desktop/troubleshooting#console-logs) * [Installation](https://docs.openbb.co/odp/desktop/troubleshooting#installation) * [Timeout](https://docs.openbb.co/odp/desktop/troubleshooting#timeout) * [Permission Error](https://docs.openbb.co/odp/desktop/troubleshooting#permission-error) * [Failed Building Wheel](https://docs.openbb.co/odp/desktop/troubleshooting#failed-building-wheel) * [Backends](https://docs.openbb.co/odp/desktop/troubleshooting#backends) * [Environments](https://docs.openbb.co/odp/desktop/troubleshooting#environments) * [GitHub Issues](https://docs.openbb.co/odp/desktop/troubleshooting#github-issues) --- # AgGrid Table Charts | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#__docusaurus_skipToContent_fallback) On this page Basic Table Widget[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#basic-table-widget "Direct link to Basic Table Widget") ----------------------------------------------------------------------------------------------------------------------------------------------------------- A widget that displays data in a tabular format. This example shows how to create a table with cryptocurrency data including TVL and price changes. ![Table Widget Example](https://openbb-cms.directus.app/assets/96f31526-87c1-40f3-8ecb-6cc869d2e910.png) @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 Table Widget from API[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-widget-from-api "Direct link to Table Widget from API") -------------------------------------------------------------------------------------------------------------------------------------------------------------------- A widget that fetches and displays data from an external API. This example demonstrates integration with the DeFi Llama API to show chain TVL data. ![Table Widget from API Example](https://openbb-cms.directus.app/assets/ab850520-843d-4fe2-b95c-c8346b41ac93.png) @register_widget({ "name": "Table Widget from API Endpoint", "description": "A table widget from an API endpoint", "type": "table", "endpoint": "table_widget_from_api_endpoint", "gridData": {"w": 12, "h": 4},})@app.get("/table_widget_from_api_endpoint")def table_widget_from_api_endpoint(): """Get current TVL of all chains using Defi LLama""" response = requests.get("https://api.llama.fi/v2/chains") if response.status_code == 200: return response.json() print(f"Request error {response.status_code}: {response.text}") raise HTTPException( status_code=response.status_code, detail=response.text ) Table Widget with Column Definitions[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-widget-with-column-definitions "Direct link to Table Widget with Column Definitions") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- A widget that displays data in a tabular format with customizable column definitions. The most important part of this widget is the "columnsDefs" key in the data object which allows for detailed column configuration. ![Table Widget with Column Definitions Example](https://openbb-cms.directus.app/assets/efea3aa4-fd2a-4098-bd64-1a7c825b6c96.png) @register_widget({ "name": "Table Widget with Column Definitions", "description": "A table widget with column definitions", "type": "table", "endpoint": "table_widget_with_column_definitions", "gridData": {"w": 20, "h": 6}, "data": { "table": { "columnsDefs": [ { "field": "name", "headerName": "Asset", "cellDataType": "text", "formatterFn": "none", "renderFn": "titleCase", "width": 120, "pinned": "left" }, { "field": "tvl", "headerName": "TVL (USD)", "headerTooltip": "Total Value Locked", "cellDataType": "number", "formatterFn": "int", "width": 150 }, { "field": "change_1d", "headerName": "24h Change", "cellDataType": "number", "formatterFn": "percent", "width": 120, "maxWidth": 150, "minWidth": 70, }, { "field": "change_7d", "headerName": "7d Change", "cellDataType": "number", "formatterFn": "percent", "width": 120, "maxWidth": 150, "minWidth": 70, "hide": True }, ] } },})@app.get("/table_widget_with_column_definitions")def table_widget_with_column_definitions(): """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 Table Widget with Render Functions[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-widget-with-render-functions "Direct link to Table Widget with Render Functions") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- A widget that demonstrates various rendering functions for table cells. The key feature is the "renderFn" key in the columnsDefs object which allows for custom cell rendering. ![Table Widget with Render Functions Example](https://openbb-cms.directus.app/assets/ba983638-e6bb-4a3f-9c80-b360f3577b11.png) @register_widget({ "name": "Table Widget with Render Functions", "description": "A table widget with render functions", "type": "table", "endpoint": "table_widget_with_render_functions", "gridData": {"w": 20, "h": 6}, "data": { "table": { "columnsDefs": [ { "field": "name", "headerName": "Asset", "cellDataType": "text", "formatterFn": "none", "renderFn": "titleCase", "width": 120, "pinned": "left" }, { "field": "tvl", "headerName": "TVL (USD)", "headerTooltip": "Total Value Locked", "cellDataType": "number", "formatterFn": "int", "width": 150, "renderFn": "columnColor", "renderFnParams": { "colorRules": [ { "condition": "between", "range": { "min": 30000000000, "max": 40000000000 }, "color": "blue", "fill": False }, { "condition": "lt", "value": 10000000000, "color": "#FFA500", "fill": False }, { "condition": "gt", "value": 40000000000, "color": "green", "fill": True } ] } }, { "field": "change_1d", "headerName": "24h Change", "cellDataType": "number", "formatterFn": "percent", "renderFn": "greenRed", "width": 120, "maxWidth": 150, "minWidth": 70, }, { "field": "change_7d", "headerName": "7d Change", "cellDataType": "number", "formatterFn": "percent", "renderFn": "greenRed", "width": 120, "maxWidth": 150, "minWidth": 70, } ] } },})@app.get("/table_widget_with_render_functions")def table_widget_with_render_functions(): """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 For more information on this, check [Render functions](https://docs.openbb.co/workspace/developers/widget-configuration/render-functions) . Table Widget with Hover Card[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-widget-with-hover-card "Direct link to Table Widget with Hover Card") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- A widget that demonstrates the hover card feature, allowing additional information to be displayed when hovering over table cells. ![Table Widget with Hover Card Example](https://openbb-cms.directus.app/assets/60a39927-8985-4f3a-8e14-0016e167b79f.png) @register_widget({ "name": "Table Widget with Hover Card", "description": "A table widget with hover card", "type": "table", "endpoint": "table_widget_with_hover_card", "gridData": {"w": 20, "h": 6}, "data": { "table": { "columnsDefs": [ { "field": "name", "headerName": "Asset", "cellDataType": "text", "formatterFn": "none", "width": 120, "pinned": "left", "renderFn": "hoverCard", "renderFnParams": { "hoverCard": { "cellField": "value", "title": "Project Details", "markdown": "### {value} (since {foundedDate})\n**Description:** {description}" } } }, { "field": "tvl", "headerName": "TVL (USD)", "headerTooltip": "Total Value Locked", "cellDataType": "number", "formatterFn": "int", "width": 150, "renderFn": "columnColor", }, { "field": "change_1d", "headerName": "24h Change", "cellDataType": "number", "formatterFn": "percent", "renderFn": "greenRed", "width": 120, "maxWidth": 150, "minWidth": 70, }, { "field": "change_7d", "headerName": "7d Change", "cellDataType": "number", "formatterFn": "percent", "renderFn": "greenRed", "width": 120, "maxWidth": 150, "minWidth": 70, } ] } },})@app.get("/table_widget_with_hover_card")def table_widget_with_hover_card(): """Returns a mock table data for demonstration""" mock_data = [ { "name": { "value": "Ethereum", "description": "A decentralized, open-source blockchain with smart contract functionality", "foundedDate": "2015-07-30" }, "tvl": 45000000000, "change_1d": 2.5, "change_7d": 5.2 }, { "name": { "value": "Bitcoin", "description": "The first decentralized cryptocurrency", "foundedDate": "2009-01-03" }, "tvl": 35000000000, "change_1d": 1.2, "change_7d": 4.8 }, { "name": { "value": "Solana", "description": "A high-performance blockchain supporting builders around the world", "foundedDate": "2020-03-16" }, "tvl": 8000000000, "change_1d": -0.5, "change_7d": 2.1 } ] return mock_data Table to Chart Widget[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-to-chart-widget "Direct link to Table to Chart Widget") -------------------------------------------------------------------------------------------------------------------------------------------------------------------- A widget that demonstrates how to convert table data into a chart view. The key feature is the "chartView" configuration in the data object. ![Table to Chart Widget Example](https://openbb-cms.directus.app/assets/72c0802d-34c9-4bd2-aa3f-77e7d89ccb7c.png) @register_widget({ "name": "Table to Chart Widget", "description": "A table widget", "type": "table", "endpoint": "table_to_chart_widget", "gridData": {"w": 20, "h": 12}, "data": { "table": { "enableCharts": True, "showAll": False, "chartView": { "enabled": True, "chartType": "column" }, "columnsDefs": [ { "field": "name", "headerName": "Asset", "chartDataType": "category", }, { "field": "tvl", "headerName": "TVL (USD)", "chartDataType": "series", }, ] } },})@app.get("/table_to_chart_widget")def table_to_chart_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 Table to Time Series Widget[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-to-time-series-widget "Direct link to Table to Time Series Widget") -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- A widget that demonstrates how to display time series data in a chart format. The key feature is the use of "chartDataType": "time" for date fields. ![Table to Time Series Widget Example](https://openbb-cms.directus.app/assets/f2b0f099-795a-4c97-8361-069d91aca150.png) @register_widget({ "name": "Table to Time Series Widget", "description": "A table widget", "type": "table", "endpoint": "table_to_time_series_widget", "gridData": {"w": 20, "h": 12}, "data": { "table": { "enableCharts": True, "showAll": False, "chartView": { "enabled": True, "chartType": "line" }, "columnsDefs": [ { "field": "date", "headerName": "Date", "chartDataType": "time", }, { "field": "Ethereum", "headerName": "Ethereum", "chartDataType": "series", }, { "field": "Bitcoin", "headerName": "Bitcoin", "chartDataType": "series", }, { "field": "Solana", "headerName": "Solana", "chartDataType": "series", } ] } },})@app.get("/table_to_time_series_widget")def table_to_time_series_widget(): """Returns a mock table data for demonstration""" mock_data = [ { "date": "2024-06-06", "Ethereum": 1.0000, "Bitcoin": 1.0000, "Solana": 1.0000 }, { "date": "2024-06-07", "Ethereum": 1.0235, "Bitcoin": 0.9822, "Solana": 1.0148 }, { "date": "2024-06-08", "Ethereum": 0.9945, "Bitcoin": 1.0072, "Solana": 0.9764 }, { "date": "2024-06-09", "Ethereum": 1.0205, "Bitcoin": 0.9856, "Solana": 1.0300 }, { "date": "2024-06-10", "Ethereum": 0.9847, "Bitcoin": 1.0195, "Solana": 0.9897 } ] return mock_data Table Widget with Sparklines[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-widget-with-sparklines "Direct link to Table Widget with Sparklines") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Sparklines allow you to display small charts directly within table cells, providing at-a-glance data visualization. Our implementation supports line, area, and bar sparklines with comprehensive styling options. ### Basic Sparkline with Min/Max Points[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#basic-sparkline-with-minmax-points "Direct link to Basic Sparkline with Min/Max Points") This example shows a basic sparkline with minimum and maximum points highlighted: ![Basic Sparkline with Min/Max Example](https://openbb-assets.s3.us-east-1.amazonaws.com/docs/pro/basic+sparklines.png) @register_widget({ "name": "Table Widget with Basic Sparklines", "description": "A table widget with basic sparklines showing min/max points", "type": "table", "endpoint": "table_widget_basic_sparklines", "gridData": {"w": 20, "h": 6}, "data": { "table": { "columnsDefs": [ { "field": "stock", "headerName": "Stock", "cellDataType": "text", "width": 120, "pinned": "left" }, { "field": "price_history", "headerName": "Price History", "width": 200, "sparkline": { "type": "line", "options": { "stroke": "#2563eb", "strokeWidth": 2, "markers": { "enabled": True, "size": 3 }, "pointsOfInterest": { "maximum": { "fill": "#22c55e", "stroke": "#16a34a", "size": 6 }, "minimum": { "fill": "#ef4444", "stroke": "#dc2626", "size": 6 } } } } }, { "field": "volume", "headerName": "Volume", "width": 150, "sparkline": { "type": "bar", "options": { "fill": "#6b7280", "stroke": "#4b5563", "pointsOfInterest": { "maximum": { "fill": "#22c55e", "stroke": "#16a34a" }, "minimum": { "fill": "#ef4444", "stroke": "#dc2626" } } } } } ] } },})@app.get("/table_widget_basic_sparklines")def table_widget_basic_sparklines(): """Returns mock data with sparklines""" mock_data = [ { "stock": "AAPL", "price_history": [150, 155, 148, 162, 158, 165, 170], "volume": [1000, 1200, 900, 1500, 1100, 1300, 1800] }, { "stock": "GOOGL", "price_history": [2800, 2750, 2900, 2850, 2950, 3000, 2980], "volume": [800, 950, 700, 1200, 850, 1100, 1400] }, { "stock": "MSFT", "price_history": [340, 335, 350, 345, 360, 355, 365], "volume": [900, 1100, 800, 1300, 950, 1200, 1600] } ] return mock_data ### Sparklines with Custom Formatters[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#sparklines-with-custom-formatters "Direct link to Sparklines with Custom Formatters") For complete control over styling individual data points, use custom formatters. This example shows profit/loss data with dynamic coloring: ![Sparklines with Custom Formatters Example](https://openbb-assets.s3.us-east-1.amazonaws.com/docs/pro/custom+formatter.png) @register_widget({ "name": "Table Widget with Custom Formatter", "description": "A table widget with custom sparkline formatter for profit/loss", "type": "table", "endpoint": "table_widget_custom_formatter", "gridData": {"w": 20, "h": 6}, "data": { "table": { "columnsDefs": [ { "field": "company", "headerName": "Company", "cellDataType": "text", "width": 150, "pinned": "left" }, { "field": "profit_loss", "headerName": "P&L Trend", "width": 200, "sparkline": { "type": "bar", "options": { "customFormatter": "(params) => ({ fill: params.yValue >= 0 ? '#22c55e' : '#ef4444', stroke: params.yValue >= 0 ? '#16a34a' : '#dc2626' })" } } }, { "field": "revenue_growth", "headerName": "Revenue Growth", "width": 200, "sparkline": { "type": "bar", "options": { "customFormatter": "(params) => ({ fill: params.yValue > 10 ? '#22c55e' : params.yValue < 0 ? '#ef4444' : '#f59e0b', fillOpacity: 0.3, stroke: params.yValue > 10 ? '#16a34a' : params.yValue < 0 ? '#dc2626' : '#d97706' })" } } } ] } },})@app.get("/table_widget_custom_formatter")def table_widget_custom_formatter(): """Returns mock data with custom formatter""" mock_data = [ { "company": "TechCorp", "profit_loss": [5, -2, 8, -3, 12, 7, -1], "revenue_growth": [15, 8, -5, 20, -8, 25, 18] }, { "company": "DataSoft", "profit_loss": [10, -5, 15, -8, 20, 12, -3], "revenue_growth": [12, 5, 8, -2, 15, 10, 22] }, { "company": "CloudInc", "profit_loss": [8, -15, 25, 12, -5, 18, 28], "revenue_growth": [8, -3, 12, 18, 6, 14, 9] } ] return mock_data ### Sparkline Configuration Options[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#sparkline-configuration-options "Direct link to Sparkline Configuration Options") #### Supported Sparkline Types[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#supported-sparkline-types "Direct link to Supported Sparkline Types") * **`line`** - Line chart * **`area`** - Area chart (filled line) * **`bar`** - Bar chart #### Points of Interest[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#points-of-interest "Direct link to Points of Interest") * **`firstLast`** - First and last data points * **`minimum`** - Points with minimum values * **`maximum`** - Points with maximum values * **`positiveNegative`** - Separate styling for positive and negative values * **`highlighted`** - Points highlighted on hover/interaction #### Custom Formatter Parameters[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#custom-formatter-parameters "Direct link to Custom Formatter Parameters") The formatter function receives parameters including: * _**`yValue`**_ - The data value * _**`first`**_ - Whether this is the first point * _**`last`**_ - Whether this is the last point * _**`min`**_ - Whether this is a minimum point * _**`max`**_ - Whether this is a maximum point * _**`highlighted`**_ - Whether this point is highlighted #### Styling Options[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#styling-options "Direct link to Styling Options") * **Basic styling**: `stroke`, `strokeWidth`, `fill`, `fillOpacity` * **Markers**: `enabled`, `size`, `fill`, `stroke`, `strokeWidth` * **Padding**: `top`, `right`, `bottom`, `left` * **Direction**: `vertical`, `horizontal` (for bar charts) For more detailed configuration options, refer to the [Widgets JSON Reference](https://docs.openbb.co/workspace/developers/json-specs/widgets-json-reference) or our examples backends [here](https://github.com/OpenBB-finance/backends-for-openbb/tree/main/getting-started/reference-backend) . OTHERS[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#others "Direct link to OTHERS") ----------------------------------------------------------------------------------------------------------------------- ### Table Interface[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-interface "Direct link to Table Interface") The Table widget offers comprehensive data manipulation and visualization capabilities: * **Column Resizing**: Adjust column widths manually or use the "Autosize all columns" feature for automatic optimization. * **Column Reorganization**: Implement drag-and-drop functionality to reorder columns. Click and hold any column header to reposition it. * **Column Filtering**: Toggle column visibility through column settings to focus on relevant data for your analysis. * **Sorting**: Click column headers to sort data in ascending or descending order. * **Data Selection**: Select specific data points or ranges to generate visualizations. ### Table to Chart Conversion[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-to-chart-conversion "Direct link to Table to Chart Conversion") The widget supports two primary methods for converting table data into charts: 1. **Selection-based Charting**: Select desired data points, choose a chart type, and generate visualizations instantly. This feature is particularly useful for quantitative analysis. The example below demonstrates data selection and right-click menu options for creating a line chart: ![selection-charting](https://openbb-assets.s3.amazonaws.com/docs/pro/selection-charting-1.png) 2. **ChartView Mode**: Access the "ChartView" icon to transform the table into a dynamic chart. This mode automatically updates the visualization as underlying data changes. The following example shows the ChartView interface: ![chartview](https://openbb-assets.s3.amazonaws.com/docs/pro/chartview-setting.png) The highlighted ChartView option enables seamless conversion between table and chart views. ### Available Chart Types[​](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#available-chart-types "Direct link to Available Chart Types") The built-in charts support a variety of types. Here are the allowed values: * **Column Charts**: `column`, `groupedColumn`, `stackedColumn`, `normalizedColumn` * **Bar Charts**: `bar`, `groupedBar`, `stackedBar`, `normalizedBar` * **Line and Scatter Charts**: `line`, `scatter`, `bubble` * **Pie and Donut Charts**: `pie`, `donut`, `doughnut` * **Area Charts**: `area`, `stackedArea`, `normalizedArea` * **Other Types**: `histogram`, `radarLine`, `radarArea`, `nightingale`, `radialColumn`, `radialBar`, `sunburst`, `rangeBar`, `rangeArea`, `boxPlot`, `treemap`, `heatmap`, `waterfall` On this page * [Basic Table Widget](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#basic-table-widget) * [Table Widget from API](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-widget-from-api) * [Table Widget with Column Definitions](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-widget-with-column-definitions) * [Table Widget with Render Functions](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-widget-with-render-functions) * [Table Widget with Hover Card](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-widget-with-hover-card) * [Table to Chart Widget](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-to-chart-widget) * [Table to Time Series Widget](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-to-time-series-widget) * [Table Widget with Sparklines](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-widget-with-sparklines) * [Basic Sparkline with Min/Max Points](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#basic-sparkline-with-minmax-points) * [Sparklines with Custom Formatters](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#sparklines-with-custom-formatters) * [Sparkline Configuration Options](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#sparkline-configuration-options) * [OTHERS](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#others) * [Table Interface](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-interface) * [Table to Chart Conversion](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#table-to-chart-conversion) * [Available Chart Types](https://docs.openbb.co/workspace/developers/widget-types/aggrid-table-charts#available-chart-types) --- # Orchestrator Mode | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#__docusaurus_skipToContent_fallback) On this page Orchestrator Mode enables OpenBB Copilot to coordinate with specialized AI agents for complex analytical workflows. When activated, OpenBB Copilot becomes a central coordinator that evaluates user requests, identifies the most appropriate agents for specific tasks, and delegates work to optimize results. Activating Orchestrator Mode[​](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#activating-orchestrator-mode "Direct link to Activating Orchestrator Mode") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ After adding AI agents to your workspace, you'll see agent management settings showing available agents: ![OpenBB Copilot as single enabled agent](https://openbb-cms.directus.app/assets/d8223d51-17a4-4b47-914b-ff5656316fd0.png) Initially, OpenBB Copilot operates as the only enabled agent. To activate Orchestrator Mode, toggle the switch next to OpenBB Copilot. This enables the copilot to delegate tasks to other available agents based on request complexity and agent specialization. ![Orchestrator Mode activated](https://openbb-cms.directus.app/assets/c6a46df6-d572-414c-8cb4-c74e70ae0a1a.png) Agent Detection and Routing[​](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#agent-detection-and-routing "Direct link to Agent Detection and Routing") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The orchestrator systematically evaluates available agents before processing user requests. It scans agent descriptions for domain-specific expertise that matches the user query and checks agent capabilities for specialized functions like data processing, mathematical calculations, or document analysis. Task categorization determines the optimal assignment approach. Preprocessing tasks include query optimization and prompt enhancement. Domain-specific tasks involve financial analysis, technical documentation, or mathematical computations. Processing tasks handle data transformation and content generation. Post-processing tasks manage output formatting and quality assurance. Agent selection follows a hierarchy of matching criteria. Primary matches occur when agent descriptions directly mention the task domain. Feature matches identify agents with relevant capabilities for the request. Specialization advantages favor agents offering superior expertise compared to general processing capabilities. Direct Agent Interaction vs. Orchestration[​](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#direct-agent-interaction-vs-orchestration "Direct link to Direct Agent Interaction vs. Orchestration") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Users can interact with agents directly or through orchestration. Direct interaction addresses the specific agent with targeted requests: ![Direct agent interaction example](https://openbb-cms.directus.app/assets/5ad54690-5aa4-42d6-a0d7-c7a31fe19d58.png) With Orchestrator Mode activated, users can submit general requests to OpenBB Copilot. The orchestrator analyzes the request and determines whether specialized agent assistance would improve results. For example, a minimal or unclear prompt triggers automatic routing to a prompt optimization agent: ![Orchestrator routing to prompt optimizer](https://openbb-cms.directus.app/assets/8a4b0c74-82b4-4e1c-ae2c-d905cf880d39.png) Or routing to an agent that is better suitable to parse specific data (like FOMC document): ![Orchestrator routing to FOMC Agent](https://openbb-cms.directus.app/assets/6486184f-2b36-44cf-829a-aa46bf1e41d5.png) Orchestration OFF[​](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#orchestration-off "Direct link to Orchestration OFF") --------------------------------------------------------------------------------------------------------------------------------------------------- When Orchestrator Mode is disabled, OpenBB Copilot cannot utilize any available sub-agents regardless of their specializations: ![Orchestrator Mode disabled limiting agent access](https://openbb-cms.directus.app/assets/f16d219e-98f2-487e-9969-9164377c87de.png) Task Delegation Process[​](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#task-delegation-process "Direct link to Task Delegation Process") --------------------------------------------------------------------------------------------------------------------------------------------------------------------- The orchestrator follows structured delegation protocols. Single agent assignments handle complete tasks where one agent possesses all required expertise. The orchestrator sets direct response parameters, meaning the assigned agent's output appears directly to users without additional processing. Multi-agent workflows coordinate complex requests requiring multiple specializations. The orchestrator breaks requests into discrete components, determines optimal execution sequences, and manages dependencies between tasks. Some tasks must complete before others begin, while parallel execution improves response speed for independent operations. When delegating tasks, the orchestrator provides agents with specific context including relevant data, constraints, formatting requirements, and success criteria. This ensures agents have sufficient information to complete their assigned portions effectively. Response Coordination[​](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#response-coordination "Direct link to Response Coordination") --------------------------------------------------------------------------------------------------------------------------------------------------------------- Single agent responses appear directly when the orchestrator delegates complete responsibility to one specialized agent. This reduces latency for straightforward requests while maintaining orchestration capabilities for complex workflows. Multi-agent responses require coordination and synthesis. The orchestrator ensures consistent formatting across agent contributions, eliminates redundancy, and maintains logical narrative flow. Error recovery mechanisms attempt alternative strategies when agents cannot complete assigned tasks. Memory and Context Management[​](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#memory-and-context-management "Direct link to Memory and Context Management") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The orchestrator maintains awareness of previous interactions and conversation history. It remembers recent widget additions, data retrievals, and analytical approaches to inform current delegation decisions. This contextual awareness prevents duplicate work and enables references to "this data" or "the previous analysis." When users reference earlier work, the orchestrator identifies the specific context and ensures relevant agents have access to that information. The system builds upon previous analyses rather than starting fresh for each request. Best Practices[​](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#best-practices "Direct link to Best Practices") ------------------------------------------------------------------------------------------------------------------------------------------ Provide clear context about analytical objectives when submitting requests that might benefit from specialized expertise. Specify data sources, time frames, and analytical approaches when you have preferences about task completion methods. Reference specific data, widgets, or previous analyses when building upon earlier work. The orchestrator uses these references to maintain context continuity and optimize agent selection for follow-up tasks. Break down extremely complex queries into logical components when the orchestrator's automatic decomposition might not match your intended approach. While orchestration handles multi-step workflows effectively, clearer initial requests lead to more efficient delegation. On this page * [Activating Orchestrator Mode](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#activating-orchestrator-mode) * [Agent Detection and Routing](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#agent-detection-and-routing) * [Direct Agent Interaction vs. Orchestration](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#direct-agent-interaction-vs-orchestration) * [Orchestration OFF](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#orchestration-off) * [Task Delegation Process](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#task-delegation-process) * [Response Coordination](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#response-coordination) * [Memory and Context Management](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#memory-and-context-management) * [Best Practices](https://docs.openbb.co/workspace/analysts/ai-features/orchestrator-mode#best-practices) --- # AI Features — Parse widget data | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/ai-features/parse-widget-data#__docusaurus_skipToContent_fallback) On this page Retrieve data for user‑selected widgets and pass it to your model. Enable `widget-dashboard-select` and call `get_widget_data` when the latest user message arrives. Reference implementation in [this GitHub repository](https://github.com/OpenBB-finance/agents-for-openbb/tree/main/30-vanilla-agent-raw-widget-data/vanilla_agent_raw_context/main.py) . ![Raw reply without context](https://openbb-cms.directus.app/assets/7bbbc4c9-7cd2-4bb0-9ad9-641588cf541e.png) Architecture[​](https://docs.openbb.co/workspace/developers/ai-features/parse-widget-data#architecture "Direct link to Architecture") -------------------------------------------------------------------------------------------------------------------------------------- This pattern uses a minimal FastAPI backend with two endpoints and OpenBB AI SDK helpers to retrieve widget data and stream results. `agents.json` configuration with `widget-dashboard-select` feature enabled: return JSONResponse(content={ "vanilla_agent_raw_context": { "endpoints": {"query": "http://localhost:7777/v1/query"}, "features": { "widget-dashboard-select": True, "widget-dashboard-search": False, }, }}) ### Query flow[​](https://docs.openbb.co/workspace/developers/ai-features/parse-widget-data#query-flow "Direct link to Query flow") * Check if latest message is human with `widgets.primary` populated * Build `WidgetRequest` objects with current parameter values * Early exit: yield `get_widget_data()` SSE immediately for UI to execute * On subsequent request with tool results: * Parse `DataContent` items from tool message * Extract and format widget data into context string * Append context to user messages for LLM processing * Stream LLM response with `message_chunk()` ### OpenBB AI SDK[​](https://docs.openbb.co/workspace/developers/ai-features/parse-widget-data#openbb-ai-sdk "Direct link to OpenBB AI SDK") * `get_widget_data(widget_requests)`: Creates `FunctionCallSSE` for widget data retrieval * `WidgetRequest(widget, input_arguments)`: Specifies widget and parameter values * `Widget`: Contains widget metadata (uuid, name, type, params) * `WidgetParam`: Individual parameter with name, type, current\_value * `DataContent`: Container for widget response data * `message_chunk(text)`: Creates `MessageChunkSSE` for streaming text Core logic[​](https://docs.openbb.co/workspace/developers/ai-features/parse-widget-data#core-logic "Direct link to Core logic") -------------------------------------------------------------------------------------------------------------------------------- from openbb_ai import get_widget_data, WidgetRequest, message_chunk@app.post("/v1/query")async def query(request: QueryRequest) -> EventSourceResponse: if ( request.messages[-1].role == "human" and request.widgets and request.widgets.primary ): widget_requests = [ WidgetRequest( widget=w, input_arguments={p.name: p.current_value for p in w.params}, ) for w in request.widgets.primary ] async def retrieve_widget_data(): # Function-call SSE that Workspace interprets and executes yield get_widget_data(widget_requests).model_dump() return EventSourceResponse(retrieve_widget_data(), media_type="text/event-stream") # Process tool message with widget data openai_messages = [ ChatCompletionSystemMessageParam( role="system", content="You are a helpful financial assistant." ) ] context_str = "" for message in request.messages: if message.role == "human": openai_messages.append( ChatCompletionUserMessageParam(role="user", content=message.content) ) elif message.role == "tool": # Extract widget data from latest tool result for data_content in message.data: for item in data_content.items: context_str += str(item.content) + "\n" # Append context to last user message if context_str and openai_messages: openai_messages[-1]["content"] += "\n\nContext:\n" + context_str async def execution_loop(): 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() return EventSourceResponse(execution_loop(), media_type="text/event-stream") Dashboard widgets vs explicit context[​](https://docs.openbb.co/workspace/developers/ai-features/parse-widget-data#dashboard-widgets-vs-explicit-context "Direct link to Dashboard widgets vs explicit context") ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The example above uses `request.widgets.primary` which contains widgets explicitly selected by the user. If you want to access all widgets available on the current dashboard instead, you can use `request.widgets.secondary`: # Access dashboard widgets instead of explicit contextif ( request.messages[-1].role == "human" and request.widgets and request.widgets.secondary # Dashboard widgets): widget_requests = [ WidgetRequest( widget=w, input_arguments={p.name: p.current_value for p in w.params}, ) for w in request.widgets.secondary # Use secondary instead of primary ] **Important**: To access dashboard widgets, you must enable the `widget-dashboard-search` feature in your `agents.json`: "features": { ... "widget-dashboard-search": True, # Dashboard widgets} This gives your agent broader context about the user's dashboard setup and available data sources, rather than just the widgets they've explicitly selected. On this page * [Architecture](https://docs.openbb.co/workspace/developers/ai-features/parse-widget-data#architecture) * [Query flow](https://docs.openbb.co/workspace/developers/ai-features/parse-widget-data#query-flow) * [OpenBB AI SDK](https://docs.openbb.co/workspace/developers/ai-features/parse-widget-data#openbb-ai-sdk) * [Core logic](https://docs.openbb.co/workspace/developers/ai-features/parse-widget-data#core-logic) * [Dashboard widgets vs explicit context](https://docs.openbb.co/workspace/developers/ai-features/parse-widget-data#dashboard-widgets-vs-explicit-context) --- # Environments | ODP Desktop App Docs [Skip to main content](https://docs.openbb.co/odp/desktop/environments#__docusaurus_skipToContent_fallback) On this page The Environments screen is for creating and managing **isolated Conda environments**. Each environment (package extensions and binaries) lives inside the OpenBB installation folder, contains its own Python interpreter, and can be modified or deleted at any time. Environments protect the system, and other external projects, by not using shared components. They make it easy to jump between projects, programming languages, and package versions without fear of contamination. ![environments-screen-initial](https://github.com/user-attachments/assets/863235c4-b307-4e68-a218-446b3c53e30e) Features[​](https://docs.openbb.co/odp/desktop/environments#features "Direct link to Features") ------------------------------------------------------------------------------------------------ * Create, customize, and manage Conda environments directly on-screen, no command line required. * Build environments from `pyproject.toml`, `requirements.txt`, or Conda environment `.yaml` files. * Safely update whole environments or individual packages. * Searchable environment package lists, with installed version. * Action buttons for opening system terminals and starting Python, iPython, Jupyter, or ODP CLI sessions. * Define a current working directory. * Monitor console output of an environment's Jupyter server. * Opens Jupyter Lab in a dedicated window. Every environment created from the screen will include a version of Python and `pip`, along with any Conda or PyPI installable package added by the user. The initial, `openbb`, environment will have a few extras that are included. Initial Environment[​](https://docs.openbb.co/odp/desktop/environments#initial-environment "Direct link to Initial Environment") --------------------------------------------------------------------------------------------------------------------------------- During the setup process, an environment is created, `openbb`, with the selected version of Python and extension choices. The extra tools included in this environment are: * iPython * Juptyer Lab and Notebook * ipywidget * anywidget * Python language server * NodeJS Environment Panel[​](https://docs.openbb.co/odp/desktop/environments#environment-panel "Direct link to Environment Panel") --------------------------------------------------------------------------------------------------------------------------- Each environment will have its own panel with dedicated action buttons for updating, removing, managing packages, and starting system shells. info Environments are updated with Conda's `libmamba` solver, where the packages to solve for were explicitly added to the environment or defined in the originally imported environment file. Conda itself will be updated before the environment is solved. Updating an individual package from the `Extensions` modal will not engage the environment solver and may have unintended outcomes, such as incompatibility. All environments use the same Current Working Directory (CWD), which by default is, the installation folder selected during the initial setup. ### Applications[​](https://docs.openbb.co/odp/desktop/environments#applications "Direct link to Applications") This button will open a modal listing the available applications for that environment. At miniumum, there will be one for opening a system shell with the environment active, and another for opening a system shell with a Python session started. The screenshot below displays all of the currently supported applications, and each will start in the current working directory. ![Screenshot 2025-10-22 at 2 02 40 PM](https://github.com/user-attachments/assets/e40c2387-b669-43ea-ad4c-8c46a168d8ee) Creating New Environments[​](https://docs.openbb.co/odp/desktop/environments#creating-new-environments "Direct link to Creating New Environments") --------------------------------------------------------------------------------------------------------------------------------------------------- There are two ways to create a new environment from the screen: ### **New Environment**[​](https://docs.openbb.co/odp/desktop/environments#new-environment "Direct link to new-environment") * Press the button and follow the steps to define and create the environment. * The basic OpenBB tooling will be installed in this environment, which includes: * openbb-core * Pydantic, FastAPI, Uvicorn, Pandas, Numpy, Requests, AIOHTTP, Ruff, PyJWT, UUID7, Python-Dotenv. * openbb-platform-api ### **From Environment File**[​](https://docs.openbb.co/odp/desktop/environments#from-environment-file "Direct link to from-environment-file") * Press **Import Environment** * Select a supported environment file: * `requirements.txt` * `pyproject.toml` * If this is a local Python package, it will be installed in "develop" mode instead of `site-packages`. * A Conda `YAML` environment definition. note When you import an environment from a file, it will be read and converted to a Conda YAML environment file. Changes to the original file will not be reflected in your environment. Find the Conda YAML environment files for each installed environment in: `~/.openbb_platform/environments/` When complete, press `Done` to return to the Environments screen. ![environments-create-done](https://github.com/user-attachments/assets/8d05694a-a253-4bab-8bed-0fa714415dd5) Adding/Modifying Packages[​](https://docs.openbb.co/odp/desktop/environments#addingmodifying-packages "Direct link to Adding/Modifying Packages") -------------------------------------------------------------------------------------------------------------------------------------------------- Press the `Extensions` button to open the modal for the desired environment and then click, `Add Extensions`. Define the package without a version to use the latest available. The modal supports installation of packages from Conda channels, and from PyPI. ![environments-add-extensions](https://github.com/user-attachments/assets/10d713fd-44e8-4303-86b7-a143ed0e0708) ### Version Pinning[​](https://docs.openbb.co/odp/desktop/environments#version-pinning "Direct link to Version Pinning") If an extension was already added to the environment, it can be pinned by using standard version markers - i.e, `numpy==2.2.0` - for the package name. Refresh Button[​](https://docs.openbb.co/odp/desktop/environments#refresh-button "Direct link to Refresh Button") ------------------------------------------------------------------------------------------------------------------ The top refresh button will update the UI completely and request new contents for each detected environment. Use this button if the UI is out-of-sync with the current state. It will not update any packages or make a network request. Clearing Caches[​](https://docs.openbb.co/odp/desktop/environments#clearing-caches "Direct link to Clearing Caches") --------------------------------------------------------------------------------------------------------------------- Conda and PyPI package caches can be cleared from the command line of any environment. 1. Press the `Applications` button and then `Open System Shell` 2. Enter: `conda clean -a -y` 3. Enter: `pip cache purge` 4. Enter: `exit` Troubleshooting & FAQ[​](https://docs.openbb.co/odp/desktop/environments#troubleshooting--faq "Direct link to Troubleshooting & FAQ") -------------------------------------------------------------------------------------------------------------------------------------- | Question | Answer | | --- | --- | | Can I use other package managers, such as UV? | Tools such as, UV or Poetry, can be installed in a Conda environment by adding it as a PyPI package. Using them within a global context may have unexpected results and should be configured to use the active environment explicitly. | | Where can I find the `.condarc` file? | Open the installation location, and enter the `conda` folder. It will likely be hidden, so enable Explorer/Finder to show system files, and then open it in any text editor. | | How do I remove a corrupt environment? | It is safe to manually remove any environment in the `InstallDirectory\conda\envs` folder by deleting it from Finder/Explorer. Press the `Refresh` button to update the screen's state. | | Importing an environment fails. | Check the output for errors and adjust where needed. The environment's base may have been created successfully, in which case open the system shell and attempt to install manually from the command line. Please report any bugs on [GitHub](https://github.com/OpenBB-finance/OpenBB/issues)
. | | "Directory does not exist" | Ensure the path is reachable by the OS user account. Network drives may require additional permissions. | | "FutureWarning" during install | These are non-fatal; the GUI continues automatically. | | "Prefix record insertion error" | A known Conda bug – the environment is usually created successfully. The GUI handles this automatically. | | How do I find the token for the Jupyter server when the window opens to the login page? | Press `Logs` on the environment's panel to open the console's output stream. It will be displayed with the final startup events. Alternatively, close the window and press the Jupyter button again to open a new one. | | How do I keep a Jupyter server running while I browse other pages? | The server will remain running in the background until shut down or quit the ODP application. | | Can I change how Jupyter is configured? | Yes - the Jupyter folder is located in the installation directory. See the official [documentation](https://jupyter-server.readthedocs.io/en/latest/users/configuration.html)
for more details. | | Can I edit `pyproject.toml` after import? | Yes – open the Extensions tab and manage packages as usual. See the note in the New Environments section for details. | On this page * [Features](https://docs.openbb.co/odp/desktop/environments#features) * [Initial Environment](https://docs.openbb.co/odp/desktop/environments#initial-environment) * [Environment Panel](https://docs.openbb.co/odp/desktop/environments#environment-panel) * [Applications](https://docs.openbb.co/odp/desktop/environments#applications) * [Creating New Environments](https://docs.openbb.co/odp/desktop/environments#creating-new-environments) * [**New Environment**](https://docs.openbb.co/odp/desktop/environments#new-environment) * [**From Environment File**](https://docs.openbb.co/odp/desktop/environments#from-environment-file) * [Adding/Modifying Packages](https://docs.openbb.co/odp/desktop/environments#addingmodifying-packages) * [Version Pinning](https://docs.openbb.co/odp/desktop/environments#version-pinning) * [Refresh Button](https://docs.openbb.co/odp/desktop/environments#refresh-button) * [Clearing Caches](https://docs.openbb.co/odp/desktop/environments#clearing-caches) * [Troubleshooting & FAQ](https://docs.openbb.co/odp/desktop/environments#troubleshooting--faq) --- # Quick Start - Usage | ODP CLI Docs [Skip to main content](https://docs.openbb.co/odp/cli/quickstart#__docusaurus_skipToContent_fallback) On this page Launch[​](https://docs.openbb.co/odp/cli/quickstart#launch "Direct link to Launch") ------------------------------------------------------------------------------------ * Configure any data provider credentials in the [`user_settings.json`](https://docs.openbb.co/odp/python/settings/user_settings/api_keys) file. * Open a Terminal and activate the environment where the `openbb-cli` package was installed. * On the command line, enter: `openbb` ![CLI Home](https://github.com/OpenBB-finance/OpenBBTerminal/assets/85772166/d1617c3b-c83d-4491-a7bc-986321fd7230) Menus[​](https://docs.openbb.co/odp/cli/quickstart#menus "Direct link to Menus") --------------------------------------------------------------------------------- info Menus are distinguishable from commands by the character, `>`, on the left of the screen. Enter a menu by typing it out and pressing return. economy ![Economy Menu](https://github.com/OpenBB-finance/OpenBBTerminal/assets/85772166/b68491fc-d6c3-42a7-80db-bfe2aa848a5a) ### Go Back One Level[​](https://docs.openbb.co/odp/cli/quickstart#go-back-one-level "Direct link to Go Back One Level") Return to the parent menu by entering either: * `..` * `q` ### Go Back To Home[​](https://docs.openbb.co/odp/cli/quickstart#go-back-to-home "Direct link to Go Back To Home") Return to the base menu by entering either: * `/` * `home` ### Jump Between Menus[​](https://docs.openbb.co/odp/cli/quickstart#jump-between-menus "Direct link to Jump Between Menus") Use absolute paths to navigate from anywhere, to anywhere. From: /equity/calendar/earnings To: /economy/calendar Commands[​](https://docs.openbb.co/odp/cli/quickstart#commands "Direct link to Commands") ------------------------------------------------------------------------------------------ Commands are displayed on-screen in a lighter colour, compared with menu items, and they will not have, `>`. Functions have a variety of parameters that differ by endpoint and provider. Use the `--help` dialogue to understand the nuances of any particular command. ### How To Enter Parameters[​](https://docs.openbb.co/odp/cli/quickstart#how-to-enter-parameters "Direct link to How To Enter Parameters") Parameters are all defined through the same pattern, `--argument`, followed by a space, and then the value. If the parameter is a boolean (true/false), there is no value to enter. Adding the `--argument` flags the parameter to be the opposite of its default state. danger The use of positional arguments is not supported. ❌ `historical AAPL --start_date 2024-01-01` ✅ `historical --symbol AAPL --start_date 2024-01-01` ### Use Auto Complete[​](https://docs.openbb.co/odp/cli/quickstart#use-auto-complete "Direct link to Use Auto Complete") The auto completion engine is triggered when the spacebar is pressed following any command, or parameter with a defined set of choices. After the first parameter has been set, remaining parameters will be triggered by entering `--`. historical --symbol AAPL --start_date 2024-01-01 -- ![Auto Complete](https://github.com/OpenBB-finance/OpenBBTerminal/assets/85772166/78e68bbd-094e-4558-bce0-92b8d556fcaf) ### Data Processing Commands[​](https://docs.openbb.co/odp/cli/quickstart#data-processing-commands "Direct link to Data Processing Commands") Data processing extensions, like `openbb-technical` accept `--data` as an input. info Command outputs are cached. These can be check using the `results` command and are selected with the `--data` parameter. # Store the command output/equity/price/historical --symbol SPY --start_date 2024-01-01 --provider yfinance# Check results contentresults# Use the results/technical/rsi --data OBB0 --chart ![SPY RSI](https://github.com/OpenBB-finance/OpenBBTerminal/assets/85772166/b480da04-92e6-48e2-bccf-cebc16fb083a) Help Dialogues[​](https://docs.openbb.co/odp/cli/quickstart#help-dialogues "Direct link to Help Dialogues") ------------------------------------------------------------------------------------------------------------ Display the help dialogue by attaching, `--help` or `-h`, to any command. info Use this to identify the providers compatible with each parameter, if applicable. calendar --help usage: calendar [--start_date START_DATE] [--end_date END_DATE] [--provider {fmp,nasdaq,tradingeconomics}] [--country COUNTRY] [--importance {Low,Medium,High}] [--group {interest rate,inflation,bonds,consumer,gdp,government,housing,labour,markets,money,prices,trade,business}] [-h] [--export EXPORT] [--sheet-name SHEET_NAME [SHEET_NAME ...]]Get the upcoming, or historical, economic calendar of global events.options: --start_date START_DATE Start date of the data, in YYYY-MM-DD format. --end_date END_DATE End date of the data, in YYYY-MM-DD format. --provider {fmp,nasdaq,tradingeconomics} The provider to use for the query, by default None. If None, the provider specified in defaults is selected or 'fmp' if there is no default. --country COUNTRY Country of the event. (provider: nasdaq, tradingeconomics) -h, --help show this help message --export EXPORT Export raw data into csv, json, xlsx and figure into png or jpg --sheet-name SHEET_NAME [SHEET_NAME ...] Name of excel sheet to save data to. Only valid for .xlsx files.tradingeconomics: --importance {Low,Medium,High} Importance of the event. --group {interest rate,inflation,bonds,consumer,gdp,government,housing,labour,markets,money,prices,trade,business} Grouping of events If the source selected was Nasdaq, `--provider nasdaq`, the `--importance` and `--group` parameters will be ignored. /economy/calendar --provider nasdaq --country united_states | date | country | event | actual | previous | consensus | description | | --- | --- | --- | --- | --- | --- | --- | | 2024-05-08 13:30:00 | United States | Fed Governor Cook Speaks | \- | \- | \- | | | cont... | | | | | | | Export Data[​](https://docs.openbb.co/odp/cli/quickstart#export-data "Direct link to Export Data") --------------------------------------------------------------------------------------------------- Data can be exported as a CSV, JSON, or XLSX file, and can also be exported directly from the interactive tables and charts. ### Named File[​](https://docs.openbb.co/odp/cli/quickstart#named-file "Direct link to Named File") This command exports the Nasdaq directory as a specific CSV file. The path to the file is displayed on-screen. /equity/search --provider nasdaq --export nasdaq_directory.csv Saved file: /Users/myusername/OpenBBUserData/nasdaq_directory.csv ### Unnamed File[​](https://docs.openbb.co/odp/cli/quickstart#unnamed-file "Direct link to Unnamed File") If only supplied with the file type, the export will be given a generic name beginning with the date and time. /equity/search --provider nasdaq --export csv Saved file: /Users/myusername/OpenBBUserData/20240508_145308_controllers_search.csv ### Specify Sheet Name[​](https://docs.openbb.co/odp/cli/quickstart#specify-sheet-name "Direct link to Specify Sheet Name") Exports can share the same `.xlsx` file by providing a `--sheet-name`. /equity/search --provider nasdaq --export directory.xlsx --sheet-name nasdaq Run Multiple Commands[​](https://docs.openbb.co/odp/cli/quickstart#run-multiple-commands "Direct link to Run Multiple Commands") --------------------------------------------------------------------------------------------------------------------------------- A chain of commands can be run from a single line, separate each process with `/`. The example below will draw two charts and can be pasted as a single line. /equity/price/historical --symbol AAPL,MSFT,GOOGL,AMZN,META,NVDA,NFLX,TSLA,QQQ --start_date 2022-01-01 --provider yfinance --chart/performance --symbol AAPL,MSFT,GOOGL,AMZN,META,NVDA,NFLX,TSLA,QQQ --provider finviz --chart Example Routine[​](https://docs.openbb.co/odp/cli/quickstart#example-routine "Direct link to Example Routine") --------------------------------------------------------------------------------------------------------------- To demonstrate how multiple commands are sequenced as a script, try running the example Routine. /exe --example On this page * [Launch](https://docs.openbb.co/odp/cli/quickstart#launch) * [Menus](https://docs.openbb.co/odp/cli/quickstart#menus) * [Go Back One Level](https://docs.openbb.co/odp/cli/quickstart#go-back-one-level) * [Go Back To Home](https://docs.openbb.co/odp/cli/quickstart#go-back-to-home) * [Jump Between Menus](https://docs.openbb.co/odp/cli/quickstart#jump-between-menus) * [Commands](https://docs.openbb.co/odp/cli/quickstart#commands) * [How To Enter Parameters](https://docs.openbb.co/odp/cli/quickstart#how-to-enter-parameters) * [Use Auto Complete](https://docs.openbb.co/odp/cli/quickstart#use-auto-complete) * [Data Processing Commands](https://docs.openbb.co/odp/cli/quickstart#data-processing-commands) * [Help Dialogues](https://docs.openbb.co/odp/cli/quickstart#help-dialogues) * [Export Data](https://docs.openbb.co/odp/cli/quickstart#export-data) * [Named File](https://docs.openbb.co/odp/cli/quickstart#named-file) * [Unnamed File](https://docs.openbb.co/odp/cli/quickstart#unnamed-file) * [Specify Sheet Name](https://docs.openbb.co/odp/cli/quickstart#specify-sheet-name) * [Run Multiple Commands](https://docs.openbb.co/odp/cli/quickstart#run-multiple-commands) * [Example Routine](https://docs.openbb.co/odp/cli/quickstart#example-routine) --- # AI Features — Parse PDF context | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/ai-features/parse-pdf-context#__docusaurus_skipToContent_fallback) On this page Extract text from PDF inputs supplied via widget data and append it to the model context. Optionally add citation highlights to reference quotes within the PDF. Reference implementation [here](https://github.com/OpenBB-finance/agents-for-openbb/tree/main/35-vanilla-agent-pdf/vanilla_agent_pdf/main.py) . ![Parse PDF](https://openbb-cms.directus.app/assets/b9e323b3-9416-4452-9d32-f6d6b8b50443.png) Architecture[​](https://docs.openbb.co/workspace/developers/ai-features/parse-pdf-context#architecture "Direct link to Architecture") -------------------------------------------------------------------------------------------------------------------------------------- Handle PDF data delivered by the UI through the widget data tool. Support both URL and base64 PDFs and add text to the LLM context. `agents.json` configuration with `widget-dashboard-select` feature enabled: return JSONResponse(content={ "vanilla_agent_pdf": { "endpoints": {"query": "http://localhost:7777/v1/query"}, "features": { "widget-dashboard-select": True, "widget-dashboard-search": False, }, }}) ### Query flow[​](https://docs.openbb.co/workspace/developers/ai-features/parse-pdf-context#query-flow "Direct link to Query flow") * Check for human message with `widgets.primary` containing PDF data * Early exit: yield `get_widget_data()` for UI execution * On subsequent tool message: * Iterate through `DataContent` items * Detect `PdfDataFormat` using `isinstance()` check * Handle both `SingleDataContent` (base64) and `SingleFileReference` (URL) * Extract text using `pdfplumber.open()` with `io.BytesIO()` * Append extracted text to context string * Process with LLM and stream response * Optionally create `cite()` with `CitationHighlightBoundingBox` for text highlighting ### OpenBB AI SDK[​](https://docs.openbb.co/workspace/developers/ai-features/parse-pdf-context#openbb-ai-sdk "Direct link to OpenBB AI SDK") * `PdfDataFormat`: Identifies PDF content in widget data * `SingleDataContent`: Contains base64-encoded PDF data * `SingleFileReference`: Contains URL reference to PDF * `DataContent`/`DataFileReferences`: Containers for data items * `CitationHighlightBoundingBox`: Defines text highlighting coordinates * `cite(widget, input_arguments, extra_details)`: Creates citations with bounding boxes * `get_widget_data()`: Requests PDF data from widgets Core logic[​](https://docs.openbb.co/workspace/developers/ai-features/parse-pdf-context#core-logic "Direct link to Core logic") -------------------------------------------------------------------------------------------------------------------------------- Detect PDF data, extract text, and accumulate as context: import base64import ioimport pdfplumberimport httpxfrom openbb_ai import get_widget_data, cite, citationsfrom openbb_ai.models import ( QueryRequest, WidgetRequest, PdfDataFormat, SingleDataContent, SingleFileReference, DataContent, DataFileReferences, CitationHighlightBoundingBox)async def _download_file(url: str) -> bytes: async with httpx.AsyncClient() as client: response = await client.get(url) return response.contentasync def _get_pdf_text(item) -> str: if isinstance(item, SingleDataContent): # Handle base64 PDF file_content = base64.b64decode(item.content) elif isinstance(item, SingleFileReference): # Handle URL PDF file_content = await _download_file(str(item.url)) with pdfplumber.open(io.BytesIO(file_content)) as pdf: document_text = "" for page in pdf.pages: document_text += page.extract_text() + "\n\n" return document_textasync def handle_widget_data(data: list[DataContent | DataFileReferences]) -> str: result_str = "--- PDF Content ---\n" for result_item in data: for item in result_item.items: if isinstance(item.data_format, PdfDataFormat): result_str += f"===== {item.data_format.filename} =====\n" result_str += await _get_pdf_text(item) result_str += "------\n" else: result_str += str(item.content) + "\n" return result_str Add citation highlights with bounding boxes: # Create citations with text highlightingcitations_list = []for widget in request.widgets.primary: citation = cite( widget=widget, input_arguments={p.name: p.current_value for p in widget.params}, extra_details={"filename": "document.pdf"} ) # Add bounding boxes for specific text regions citation.quote_bounding_boxes = [ [ CitationHighlightBoundingBox( text="Key financial metrics", page=1, x0=72.0, top=117, x1=259, bottom=135 ), CitationHighlightBoundingBox( text="Revenue increased 15%", page=1, x0=110.0, top=140, x1=275, bottom=160 ) ] ] citations_list.append(citation)if citations_list: yield citations(citations_list).model_dump() On this page * [Architecture](https://docs.openbb.co/workspace/developers/ai-features/parse-pdf-context#architecture) * [Query flow](https://docs.openbb.co/workspace/developers/ai-features/parse-pdf-context#query-flow) * [OpenBB AI SDK](https://docs.openbb.co/workspace/developers/ai-features/parse-pdf-context#openbb-ai-sdk) * [Core logic](https://docs.openbb.co/workspace/developers/ai-features/parse-pdf-context#core-logic) --- # AI Features — Custom agent features | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#__docusaurus_skipToContent_fallback) On this page Create agents that can dynamically enable or disable features based on workspace configuration. Agents can access user preferences through `workspace_options` and respond accordingly. Reference implementation in [this GitHub repository](https://github.com/OpenBB-finance/agents-for-openbb/tree/main/37-vanilla-agent-custom-features) . ![Custom agent features - on and off](https://openbb-cms.directus.app/assets/f304643a-654b-4156-a4c4-dea934d18012.png) ![Custom agent features - on and on](https://openbb-cms.directus.app/assets/aa51354c-b611-4c99-829c-cf6e35eb884b.png) Architecture[​](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#architecture "Direct link to Architecture") ------------------------------------------------------------------------------------------------------------------------------------------ Configure custom features in your agent's descriptor and access them through the query request payload. Features can have default states, descriptions, and labels. `agents.json` configuration with custom features: return JSONResponse(content={ "vanilla_agent_custom_features": { "name": "Vanilla Agent Custom Features", "description": "A simple agent that reports its feature status.", "endpoints": {"query": "/v1/query"}, "features": { "streaming": True, "widget-dashboard-select": False, "widget-dashboard-search": False, "deep-research": { "label": "Deep Research", "default": False, "description": "Allows the copilot to do deep research", }, "web-search": { "label": "Web Search", "default": True, "description": "Allows the copilot to search the web.", }, }, }}) ### Feature configuration[​](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#feature-configuration "Direct link to Feature configuration") * **Simple features**: Boolean values for basic on/off features * **Complex features**: Objects with `label`, `default`, and `description` properties * **Built-in features**: Standard features like `streaming`, `widget-dashboard-select`, `widget-dashboard-search` * **Custom features**: User-defined features with custom behavior ### Query flow[​](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#query-flow "Direct link to Query flow") * User enables/disables features in workspace settings * Features are passed to agent via `workspace_options` in request payload * Agent checks enabled features and adjusts behavior accordingly * Agent can report feature status back to user * Response content varies based on active features ### OpenBB AI SDK[​](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#openbb-ai-sdk "Direct link to OpenBB AI SDK") * `QueryRequest.workspace_options`: List of enabled feature names * `message_chunk(text)`: Streams response content with feature-aware messaging * Feature checking via simple list membership: `"feature-name" in workspace_options` Core logic[​](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#core-logic "Direct link to Core logic") ------------------------------------------------------------------------------------------------------------------------------------ from typing import AsyncGeneratorfrom openbb_ai import message_chunkfrom openbb_ai.models import MessageChunkSSE, QueryRequestfrom fastapi.responses import JSONResponsefrom sse_starlette.sse import EventSourceResponse@app.post("/v1/query")async def query(request: QueryRequest) -> EventSourceResponse: # Access workspace options from request payload workspace_options = getattr(request, "workspace_options", []) # Check which features are enabled deep_research_enabled = "deep-research" in workspace_options web_search_enabled = "web-search" in workspace_options # Build feature status message features_msg = ( f"- Deep Research: {'✅ Enabled' if deep_research_enabled else '❌ Disabled'}\n" f"- Web Search: {'✅ Enabled' if web_search_enabled else '❌ Disabled'}" ) # Include feature status in system prompt openai_messages = [ { "role": "system", "content": ( "You are a simple greeting agent.\n" "Greet the user and let them know their current feature settings:\n" f"{features_msg}\n" "Keep your response brief and friendly." ), } ] # Add conversation history for message in request.messages: if message.role == "human": openai_messages.append({"role": "user", "content": message.content}) elif message.role == "ai" and isinstance(message.content, str): openai_messages.append({"role": "assistant", "content": message.content}) async def execution_loop() -> AsyncGenerator[MessageChunkSSE, None]: 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) return EventSourceResponse( content=( event.model_dump(exclude_none=True) async for event in execution_loop() ), media_type="text/event-stream", ) Feature types[​](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#feature-types "Direct link to Feature types") --------------------------------------------------------------------------------------------------------------------------------------------- ### Boolean features[​](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#boolean-features "Direct link to Boolean features") Simple on/off switches in the agent descriptor: "features": { "streaming": True, "some-feature": False} ### Complex features[​](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#complex-features "Direct link to Complex features") Rich feature objects with metadata: "features": { "research-mode": { "label": "Research Mode", "default": True, "description": "Enables comprehensive research capabilities" }} ### Conditional behavior[​](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#conditional-behavior "Direct link to Conditional behavior") Adjust agent behavior based on enabled features: workspace_options = getattr(request, "workspace_options", [])if "research-mode" in workspace_options: # Enable research capabilities passif "web-search" in workspace_options: # Enable web search functionality pass On this page * [Architecture](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#architecture) * [Feature configuration](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#feature-configuration) * [Query flow](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#query-flow) * [OpenBB AI SDK](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#openbb-ai-sdk) * [Core logic](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#core-logic) * [Feature types](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#feature-types) * [Boolean features](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#boolean-features) * [Complex features](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#complex-features) * [Conditional behavior](https://docs.openbb.co/workspace/developers/ai-features/custom-agent-features#conditional-behavior) --- # AI Features — Citations for documents | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/ai-features/citations-for-documents#__docusaurus_skipToContent_fallback) On this page Extract and cite specific content from PDF documents with precise text highlighting. Use `pdfplumber` to get text positions and create visual citations in Workspace. Reference implementation [in this GitHub repository](https://github.com/OpenBB-finance/agents-for-openbb/tree/main/vanilla-agent-pdf-citations) . ![Document Citations](https://openbb-cms.directus.app/assets/c47a15c0-562c-4fc1-a221-a11cef487826.png) Architecture[​](https://docs.openbb.co/workspace/developers/ai-features/citations-for-documents#architecture "Direct link to Architecture") -------------------------------------------------------------------------------------------------------------------------------------------- This pattern extends widget citations by adding document-level text extraction and positioning. Extract PDF content with character-level precision for accurate highlighting. `agents.json` configuration: return JSONResponse(content={ "vanilla_agent_pdf_citations": { "name": "Vanilla Agent PDF Citations", "description": "A vanilla agent that handles PDF data with citation support.", "endpoints": {"query": "http://localhost:7777/v1/query"}, "features": { "streaming": True, "widget-dashboard-select": True, "widget-dashboard-search": False, }, }}) ### Query flow[​](https://docs.openbb.co/workspace/developers/ai-features/citations-for-documents#query-flow "Direct link to Query flow") * Extract PDF content when widget data contains PDF format * Use `pdfplumber` to get text with character positions * Store text positions for citation highlighting * Create multiple citation types: * Basic widget citation for data source * Highlighted citation for specific text passages * Stream citations with bounding boxes for visual highlighting ### OpenBB AI SDK[​](https://docs.openbb.co/workspace/developers/ai-features/citations-for-documents#openbb-ai-sdk "Direct link to OpenBB AI SDK") * `CitationHighlightBoundingBox`: Precise text highlighting with coordinates * `PdfDataFormat`: Identifies PDF content in widget data * `quote_bounding_boxes`: Attach visual highlights to citations * Text position tracking: `x0`, `top`, `x1`, `bottom` for accurate placement Core logic[​](https://docs.openbb.co/workspace/developers/ai-features/citations-for-documents#core-logic "Direct link to Core logic") -------------------------------------------------------------------------------------------------------------------------------------- Extract PDF text with positions for precise highlighting: import pdfplumberfrom openbb_ai import cite, citationsfrom openbb_ai.models import CitationHighlightBoundingBoxdef extract_pdf_with_positions(pdf_bytes: bytes) -> Tuple[str, List[Dict[str, Any]]]: """Extract text and positions from PDF.""" document_text = "" text_positions = [] with pdfplumber.open(io.BytesIO(pdf_bytes)) as pdf: for page_num, page in enumerate(pdf.pages, 1): # Extract character-level data for positioning if page.chars: # Group characters into lines lines = {} for char in page.chars: y = round(char['top']) if y not in lines: lines[y] = {'chars': [], 'x0': char['x0'], 'x1': char['x1']} lines[y]['chars'].append(char['text']) lines[y]['x0'] = min(lines[y]['x0'], char['x0']) lines[y]['x1'] = max(lines[y]['x1'], char['x1']) # Get first meaningful line for citation sorted_lines = sorted(lines.items()) for y_pos, line_data in sorted_lines[:5]: line_text = ''.join(line_data['chars']).strip() if line_text and len(line_text) > 10: text_positions.append({ 'text': line_text, 'page': page_num, 'x0': line_data['x0'], 'top': y_pos, 'x1': line_data['x1'], 'bottom': y_pos + 12 }) break # Extract full text for context page_text = page.extract_text() if page_text: document_text += page_text + "\\n\\n" return document_text, text_positions Create citations with line/word level highlighting in the PDF: async def handle_widget_data(data: list[DataContent | DataFileReferences]): """Process widget data and create PDF citations.""" widget_text, pdf_text_positions = await handle_widget_data(message.data) context_str += widget_text # Create citations for widget data for widget_data_request in message.input_arguments["data_sources"]: widget = matching_widgets[0] # Basic widget citation basic_citation = cite( widget=widget, input_arguments=widget_data_request["input_args"], ) citations_list.append(basic_citation) # PDF citation with highlighting if pdf_text_positions and len(pdf_text_positions) > 0: first_line = pdf_text_positions[0] pdf_citation = cite( widget=widget, input_arguments=widget_data_request["input_args"], extra_details={ "Page": first_line['page'], "Reference": "First sentence of document" } ) # Add precise text highlighting pdf_citation.quote_bounding_boxes = [[ CitationHighlightBoundingBox( text=first_line['text'][:100], page=first_line['page'], x0=first_line['x0'], top=first_line['top'], x1=first_line['x1'], bottom=first_line['bottom'] ) ]] citations_list.append(pdf_citation) On this page * [Architecture](https://docs.openbb.co/workspace/developers/ai-features/citations-for-documents#architecture) * [Query flow](https://docs.openbb.co/workspace/developers/ai-features/citations-for-documents#query-flow) * [OpenBB AI SDK](https://docs.openbb.co/workspace/developers/ai-features/citations-for-documents#openbb-ai-sdk) * [Core logic](https://docs.openbb.co/workspace/developers/ai-features/citations-for-documents#core-logic) --- # MCP Settings - ODP Python | OpenBB Docs [Skip to main content](https://docs.openbb.co/odp/python/settings/mcp_settings#__docusaurus_skipToContent_fallback) Configurations on this page assume that [`openbb-mcp`](https://docs.openbb.co/odp/python/extensions/interface/openbb-mcp) is installed. All settings can be configured via the `mcp_settings.json` file or as environment variables. | Setting | Environment Variable | Type | Default | Description | | --- | --- | --- | --- | --- | | `api_prefix` | `OPENBB_MCP_API_PREFIX` | string | `None` | Overrides the API prefix from SystemService. | | `name` | `OPENBB_MCP_NAME` | string | `"OpenBB MCP"` | Server name. | | `description` | `OPENBB_MCP_DESCRIPTION` | string | | Server description. | | `version` | `OPENBB_MCP_VERSION` | string | `None` | Server version. | | `default_tool_categories` | `OPENBB_MCP_DEFAULT_TOOL_CATEGORIES` | list\[string\] | `["all"]` | Default active tool categories on startup. | | `allowed_tool_categories` | `OPENBB_MCP_ALLOWED_TOOL_CATEGORIES` | list\[string\] | `None` | Restricts available tool categories to this list. | | `enable_tool_discovery` | `OPENBB_MCP_ENABLE_TOOL_DISCOVERY` | boolean | `True` | Enable tool discovery. | | `describe_responses` | `OPENBB_MCP_DESCRIBE_RESPONSES` | boolean | `False` | Include response types in tool descriptions. | | `system_prompt_file` | `OPENBB_MCP_SYSTEM_PROMPT_FILE` | string | `None` | Path to a text file for the system prompt. | | `server_prompts_file` | `OPENBB_MCP_SERVER_PROMPTS_FILE` | string | `None` | Path to a JSON file with a list of server prompt definitions. | | `cache_expiration_seconds` | `OPENBB_MCP_CACHE_EXPIRATION_SECONDS` | float | `None` | Cache expiration time in seconds. `0` to disable. | | `on_duplicate_tools` | `OPENBB_MCP_ON_DUPLICATE_TOOLS` | string | `None` | Behavior for duplicate tools (`warn`, `error`, `replace`, `ignore`). | | `on_duplicate_resources` | `OPENBB_MCP_ON_DUPLICATE_RESOURCES` | string | `None` | Behavior for duplicate resources. | | `on_duplicate_prompts` | `OPENBB_MCP_ON_DUPLICATE_PROMPTS` | string | `None` | Behavior for duplicate prompts. | | `resource_prefix_format` | `OPENBB_MCP_RESOURCE_PREFIX_FORMAT` | string | `None` | Format for resource URI prefixes (`protocol` or `path`). | | `mask_error_details` | `OPENBB_MCP_MASK_ERROR_DETAILS` | boolean | `None` | Mask error details from user functions. | | `dependencies` | `OPENBB_MCP_DEPENDENCIES` | list\[string\] | `None` | List of dependencies to install. | | `include_tags` | `OPENBB_MCP_INCLUDE_TAGS` | set\[string\] | `None` | Only expose components with these tags. | | `exclude_tags` | `OPENBB_MCP_EXCLUDE_TAGS` | set\[string\] | `None` | Exclude components with these tags. | | `module_exclusion_map` | `OPENBB_MCP_MODULE_EXCLUSION_MAP` | dict\[str, str\] | `None` | Map API tags to Python module names for exclusion. | | `uvicorn_config` | `OPENBB_MCP_UVICORN_CONFIG` | dict | `{"host": "127.0.0.1", "port": "8001"}` | Configuration for the Uvicorn server. | | `httpx_client_kwargs` | `OPENBB_MCP_HTTPX_CLIENT_KWARGS` | dict | `{}` | Configuration for the async httpx client. | | `client_auth` | `OPENBB_MCP_CLIENT_AUTH` | tuple\[string, string\] | `None` | `(username, password)` for client-side basic authentication (passed-through to HTTPX). | | `server_auth` | `OPENBB_MCP_SERVER_AUTH` | tuple\[string, string\] | `None` | `(username, password)` for server-side basic authentication. | note Runtime argument keys, in general, "-" and "\_" are interchangeable. Nested uvicorn arguments should use `_`. --- # Routines - | ODP CLI Docs [Skip to main content](https://docs.openbb.co/odp/cli/routines#__docusaurus_skipToContent_fallback) [Introduction to Routines\ \ Create repeatable workflows with OpenBB routines that you can share with colleagues.](https://docs.openbb.co/odp/cli/routines/introduction-to-routines) [Routine Macro Recorder\ \ Leverage the macro recorder to quickly build your favourite workflow routines.](https://docs.openbb.co/odp/cli/routines/routine-macro-recorder) [Advanced Routines\ \ Become an ODP CLI power user by understanding routines inputs, setting variables, creating loops and more.](https://docs.openbb.co/odp/cli/routines/advanced-routines) --- # Backends | ODP Desktop App Docs [Skip to main content](https://docs.openbb.co/odp/desktop/backends#__docusaurus_skipToContent_fallback) On this page The **Backends** screen is a central location for development server entry points and launch script configurations. info Presets for OpenBB API & OpenBB MCP are created with default settings during the initial environment installation. Features[​](https://docs.openbb.co/odp/desktop/backends#features "Direct link to Features") -------------------------------------------------------------------------------------------- * Configure, control, and monitor multiple application servers from a simple interface. * Use any executable available to the selected environment from the command line. * User-friendly environment variable management. * Start services on operating system login. * Generate X.509 certificates and PKCS#12 bundles to easily run over HTTPS. * All backends terminate on application exit. ![backenbds-page](https://github.com/user-attachments/assets/4c7b3984-e955-407c-9241-59cf75a868f0) tip A JavaScript server can be started from the `openbb` environment by using the `npm` executable. Node can be added to any envrionment as a Conda package, `nodejs`, independent of any global installations. Configuration[​](https://docs.openbb.co/odp/desktop/backends#configuration "Direct link to Configuration") ----------------------------------------------------------------------------------------------------------- Each backend created will appear on the screen as a new box, with details about its status and configuration. When the backend is running, the display will update to the server's URL after startup is complete. Edit the settings for an existing backend by clicking the gear icon, on the right-side of the panel. The configuration panels for creating or editing a service allows setting runtime arguments, environment variables, and the working directory. ![backends-configuration-panel](https://github.com/user-attachments/assets/cdd508ea-0c02-48b3-bda5-d0511f8fab78) ### Create New[​](https://docs.openbb.co/odp/desktop/backends#create-new "Direct link to Create New") 1. Click **New Backend**. 2. Fill the **Backend Name** (required). 3. Select the **Environment** that contains the required packages. 4. **Executable** – anything you would type in a shell, e.g. `openbb-api`, `uvicorn myapp:app --reload`, `python feed.py --ws`. 5. _(Optional)_ **Working Directory** – folder from which the command is executed. 6. _(Optional)_ **Environment File** – path to a `.env` file whose variables are exported before launch. 7. _(Optional)_ **Environment Variables** - multi-line text input where each line should be a KEY=VALUE pair. * Exported _after_ the `.env` file. 8. Enable **Start Automatically**, if desired. * Enable `Start at Login`, in the tray icon menu, to start on operating system login. 9. Press **Create**. The new backend appears in the list. Use the **Start** button to launch it. Logs[​](https://docs.openbb.co/odp/desktop/backends#logs "Direct link to Logs") -------------------------------------------------------------------------------- Pressing the `Logs` button opens a window with the console output (colors removed) from the running backend. Each backend will buffer up to 10K of the most recent lines, in memory, and are discarded on application quit. ![backends-logs](https://github.com/user-attachments/assets/9af2b65f-655c-4d22-a24e-933697a82782) tip Experiencing problems with a backend? Press the `Logs` button to see errors. Self-Signed Certificate[​](https://docs.openbb.co/odp/desktop/backends#self-signed-certificate "Direct link to Self-Signed Certificate") ----------------------------------------------------------------------------------------------------------------------------------------- Self-signed certificates can enable backends to run securely over HTTPS. This feature is the simplest way for anyone to generate the required files. No additional software, or technical knowledge, is required. important X.509 certificates and files are generated by standard OpenSSL binaries, compiled from the most recent version. No other encryption tools, or parameters beyond what is available in the screen, are available. ![backends-generate-certificate](https://github.com/user-attachments/assets/9deae828-63b1-4f67-95bd-054c650870ca) ### How To Generate[​](https://docs.openbb.co/odp/desktop/backends#how-to-generate "Direct link to How To Generate") 1. Click **Generate Certificate** 2. Enter the required fields: * Common Name (e.g., 127.0.0.1) * Address for which the certificate is valid. * Organization Name (e.g., My Organization) * Output Directory * Where the files will be created. 3. Enter any optional fields: * Alternative Names (e.g., localhost,0.0.0.0) * Aliases for the `Common Name` * Password (set for PKCS#12 bundle) * Days Valid (default 1 year) 4. Check the box to also add the certificate to the user's trust store. * An operating system dialog will open to confirm adding the certificate. * This allows making HTTPS requests to the server, from the machine, without any additional configuration. 5. Press **Generate** * Open the folder to inspect the results and move the `private.key` file to a secure destination. 6. Return to the `Backends` screen by clicking **X**, in the top-right. ### How To Use[​](https://docs.openbb.co/odp/desktop/backends#how-to-use "Direct link to How To Use") danger Do not store the `private.key` file in the same location as the public certificate. Use environment variables, or a `.env` file, to configure the backend for HTTPS. For backends using `uvicorn` or `openbb-api` as the executable, set the items below. UVICORN_SSL_CERTFILE = "/pathto/public_folder/certificate.pem"UVICORN_SSL_KEYFILE = "/pathto/private_folder/private.key" When opening a server URL (i.e. `/docs`) in a browser, you will need to manually allow the certificate through the warning dialog. Example: MCP Server[​](https://docs.openbb.co/odp/desktop/backends#example-mcp-server "Direct link to Example: MCP Server") ---------------------------------------------------------------------------------------------------------------------------- The REST API generated by the ODP python packages can be run as a MCP server, which can be added to the Agent Chat Interface in OpenBB Workspace. Before creating the backend, install the `openbb-mcp-server` extension to the target [environment](https://docs.openbb.co/odp/desktop/environments) (`openbb`). 1. Press the **New Backend** button. 2. Select `openbb` as the environment. 3. Give it a name like, `OpenBB MCP`. 4. Enter executable as, `openbb-mcp --port 6950`. * See the [documentation](https://docs.openbb.co/odp/python/extensions/interface/openbb-mcp) for additional configuration options. 5. Click **Create**. 6. **Start** the backend. 7. Open Workspace from the tray icon menu and add the MCP server address - i.e, `http://127.0.0.1:6950/mcp/` - from the chat window. * The server URL showing after startup will be missing the transport path, `/mcp/`. Be sure to include it as part of the URL. ![add-workspace-mcp](https://github.com/user-attachments/assets/60709625-c0ee-459d-a527-82b33c27407e) Troubleshooting & FAQ[​](https://docs.openbb.co/odp/desktop/backends#troubleshooting--faq "Direct link to Troubleshooting & FAQ") ---------------------------------------------------------------------------------------------------------------------------------- note Backend server management is intended for single-user, desktop operating systems. The operating system may close network connections when the machine sleeps, backend services may not reflect their status. Go to the [troubleshooting](https://docs.openbb.co/odp/desktop/troubleshooting) page for guidance and potential solutions. On this page * [Features](https://docs.openbb.co/odp/desktop/backends#features) * [Configuration](https://docs.openbb.co/odp/desktop/backends#configuration) * [Create New](https://docs.openbb.co/odp/desktop/backends#create-new) * [Logs](https://docs.openbb.co/odp/desktop/backends#logs) * [Self-Signed Certificate](https://docs.openbb.co/odp/desktop/backends#self-signed-certificate) * [How To Generate](https://docs.openbb.co/odp/desktop/backends#how-to-generate) * [How To Use](https://docs.openbb.co/odp/desktop/backends#how-to-use) * [Example: MCP Server](https://docs.openbb.co/odp/desktop/backends#example-mcp-server) * [Troubleshooting & FAQ](https://docs.openbb.co/odp/desktop/backends#troubleshooting--faq) --- # Routine Macro Recorder - Routines - Usage | ODP CLI Docs [Skip to main content](https://docs.openbb.co/odp/cli/routines/routine-macro-recorder#__docusaurus_skipToContent_fallback) OpenBB script routines can be captured with the macro recorder, controlled with global commands. Enter, `record`, to start saving commands, and then, `stop`, terminates the recording. This means that any command you run will be captured in the script; and on `stop`, it will be saved to the `~/OpenBBUserData/routines/` folder. For example: record -n sample/equity/price/historical --symbol SPY --provider cboe --interval 1m/home/derivatives/options/chains --symbol SPY --provider cboe/home/stop/r The final command after `stop`, `r`, resets the CLI so that the routine is presented as a choice in the `exe` command. It can now be played back by entering: /exe --file sample.openbb tip The routine can be edited to replace parameter values with input variables - e.g, `$ARGV[0]`, `$ARGV[1]`, etc. --- # AI Features — MCP Tools Integration | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/ai-features/mcp-tools#__docusaurus_skipToContent_fallback) On this page Enable agents to access and execute Model Context Protocol (MCP) tools, extending their capabilities with external tools and services. MCP tools allow agents to interact with databases, APIs, file systems, and other external resources. Reference implementation in [this GitHub repository](https://github.com/OpenBB-finance/agents-for-openbb/tree/main/38-vanilla-agent-mcp-tools/vanilla_agent_mcp_tools/main.py) . ![Charts](https://openbb-cms.directus.app/assets/bec55103-71cd-412d-bc05-fd4776a0838c.png) Architecture[​](https://docs.openbb.co/workspace/developers/ai-features/mcp-tools#architecture "Direct link to Architecture") ------------------------------------------------------------------------------------------------------------------------------ MCP tools integration enables agents to discover, execute, and process results from external tools. The agent acts as an orchestrator between the OpenBB workspace and MCP servers, translating tool calls into executable functions. `agents.json` configuration with MCP support: return JSONResponse(content={ "vanilla_agent_mcp": { "name": "Vanilla Agent with MCP", "description": "A vanilla agent that supports MCP tools and automatically retrieves widget data.", "endpoints": {"query": "/v1/query"}, "features": { "streaming": True, "widget-dashboard-select": True, "widget-dashboard-search": False, "mcp-tools": True, # Enable MCP tools support }, }}) ### Query flow[​](https://docs.openbb.co/workspace/developers/ai-features/mcp-tools#query-flow "Direct link to Query flow") * User sends query to agent with available MCP tools in request payload * Agent receives tool metadata including server ID, name, description, and input schema * Agent analyzes query and determines if MCP tools are needed * Agent generates OpenAI function call with appropriate parameters * Frontend executes MCP tool and returns results * Agent processes tool results and generates final response ### OpenBB AI SDK[​](https://docs.openbb.co/workspace/developers/ai-features/mcp-tools#openbb-ai-sdk "Direct link to OpenBB AI SDK") * `QueryRequest.tools`: List of available MCP tools with metadata * `FunctionCallSSE`: Server-sent event for function calls to frontend * `FunctionCallSSEData`: Function call data with server ID, tool name, and parameters * `message_chunk(text)`: Streams response content back to user * Tool results received as `message.role == "tool"` in conversation Core logic[​](https://docs.openbb.co/workspace/developers/ai-features/mcp-tools#core-logic "Direct link to Core logic") ------------------------------------------------------------------------------------------------------------------------ from typing import AsyncGeneratorimport jsonimport openaifrom openbb_ai import message_chunkfrom openbb_ai.models import ( MessageChunkSSE, QueryRequest, FunctionCallSSE, FunctionCallSSEData,)from sse_starlette.sse import EventSourceResponse@app.post("/v1/query")async def query(request: QueryRequest) -> EventSourceResponse: """Query the Copilot with MCP tools support.""" # Build system prompt with MCP tools information system_content = "You are a helpful financial assistant. Your name is 'Vanilla Agent'." # Add MCP tools to system prompt if available if request.tools: system_content += "\n\nYou have access to the following MCP tools:\n" for tool in request.tools: server_id = getattr(tool, "server_id", "unknown") system_content += f"\n- Tool: {tool.name} (Server ID: {server_id})\n" system_content += f" Description: {tool.description}\n" if hasattr(tool, "input_schema") and tool.input_schema: # Parse the schema to identify required parameters if isinstance(tool.input_schema, dict): properties = tool.input_schema.get("properties", {}) required = tool.input_schema.get("required", []) if properties: system_content += " Parameters:\n" for param_name, param_info in properties.items(): param_type = param_info.get("type", "unknown") param_desc = param_info.get("description", "") is_required = param_name in required req_str = " (REQUIRED)" if is_required else " (optional)" system_content += f" - {param_name}{req_str}: {param_type}" if param_desc: system_content += f" - {param_desc}" system_content += "\n" # Create OpenAI function definition for MCP tools functions = [] if request.tools: functions.append({ "name": "execute_agent_tool", "description": "Execute an MCP tool to retrieve data", "parameters": { "type": "object", "properties": { "server_id": { "type": "string", "description": "The ID of the MCP server", "enum": list(set( getattr(tool, "server_id", "unknown") for tool in request.tools )), }, "tool_name": { "type": "string", "description": "The name of the tool to execute", "enum": [tool.name for tool in request.tools], }, "parameters": { "type": "object", "description": "The arguments to pass to the tool", "additionalProperties": True, }, }, "required": ["server_id", "tool_name", "parameters"], }, }) # Handle conversation and tool results openai_messages = [{"role": "system", "content": system_content}] context_str = "" for index, message in enumerate(request.messages): if message.role == "human": openai_messages.append({"role": "user", "content": message.content}) elif message.role == "ai": if isinstance(message.content, str): openai_messages.append({"role": "assistant", "content": message.content}) # Handle tool results in the conversation context elif message.role == "tool" and index == len(request.messages) - 1: context_str += "## MCP OUTPUT\n" for result in message.data: for item in result.items: context_str += f"{item.content}\n\n" context_str += "## AI OUTPUT\n" context_str += "Now provide your analysis based on the MCP output above.\n\n" if context_str: openai_messages[-1]["content"] += "\n\n" + context_str async def execution_loop() -> AsyncGenerator[MessageChunkSSE | FunctionCallSSE, None]: client = openai.AsyncOpenAI() # Check if we have tool results from previous execution last_message = request.messages[-1] if request.messages else None if last_message and last_message.role == "tool": # Continue conversation with tool results async for event in await client.chat.completions.create( model="gpt-4o", messages=openai_messages, stream=True, # Don't pass functions to prevent another tool call ): if chunk := event.choices[0].delta.content: yield message_chunk(chunk).model_dump() return # Make function call if tools are available if functions: response = await client.chat.completions.create( model="gpt-4o", messages=openai_messages, functions=functions, stream=False, ) message = response.choices[0].message # Handle function calls if message.function_call and message.function_call.name == "execute_agent_tool": args = json.loads(message.function_call.arguments) # Send function call back to frontend for MCP execution function_call_data = FunctionCallSSEData( function="execute_agent_tool", input_arguments={ "server_id": args.get("server_id", ""), "tool_name": args.get("tool_name", ""), "parameters": args.get("parameters", {}), }, extra_state={ "copilot_function_call_arguments": { "server_id": args.get("server_id", ""), "tool_name": args.get("tool_name", ""), "tool_args": args.get("parameters", {}), "summary": f"Execute {args.get('tool_name', '')} MCP tool", } } ) yield FunctionCallSSE(data=function_call_data).model_dump() return # Return control to frontend # If no function call, stream the response if message.content: for char in message.content: yield message_chunk(char).model_dump() else: # Regular streaming without function calls 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() return EventSourceResponse( content=execution_loop(), media_type="text/event-stream", ) On this page * [Architecture](https://docs.openbb.co/workspace/developers/ai-features/mcp-tools#architecture) * [Query flow](https://docs.openbb.co/workspace/developers/ai-features/mcp-tools#query-flow) * [OpenBB AI SDK](https://docs.openbb.co/workspace/developers/ai-features/mcp-tools#openbb-ai-sdk) * [Core logic](https://docs.openbb.co/workspace/developers/ai-features/mcp-tools#core-logic) --- # Introduction | ODP Desktop App Docs [Skip to main content](https://docs.openbb.co/odp/desktop#__docusaurus_skipToContent_fallback) On this page ODP Desktop is a light-weight application (macOS & Windows) for installing and using the open-source tools, along with your favourite developer tools and resources. Its features are well-suited for building language-agnostic OpenBB Workspace [Applications](https://docs.openbb.co/workspace/analysts/apps) and agentic workflows. Application Screenshot ![backends-screen](https://github.com/user-attachments/assets/d9a885bb-7776-4926-b043-f9b5d49987d9) Quick Start[​](https://docs.openbb.co/odp/desktop#quick-start "Direct link to Quick Start") -------------------------------------------------------------------------------------------- Download and install the latest release from: [https://github.com/OpenBB-finance/OpenBB/releases/tag/ODP](https://github.com/OpenBB-finance/OpenBB/releases/tag/ODP) Installation Summary - See the [installation](https://docs.openbb.co/odp/desktop/installation) page for more details. The initial environment (`openbb`) is setup when you first run the application, and comes with: * OpenBB Core Python packages * `openbb-api` and `openbb-mcp` executables * Optional packages selected during installation * Jupyter Lab & Notebook in a dedicated window * Python langugage server * Isolated `npm` executable important When the application is started (except first launch), no window is created. Access it from the tray icon menu, or doubleclick on the shortcut again. ### **Step 1**[​](https://docs.openbb.co/odp/desktop#step-1 "Direct link to step-1") Go to the [API Keys](https://docs.openbb.co/odp/desktop/api-keys) page, add or import your provider credentials, if needed. ### **Step 2**[​](https://docs.openbb.co/odp/desktop#step-2 "Direct link to step-2") Navigate to the [Backends](https://docs.openbb.co/odp/desktop/backends) page by clicking on it in the header, or selecting from the tray icon's menu. ### **Step 3**[​](https://docs.openbb.co/odp/desktop#step-3 "Direct link to step-3") Press the, `Start`, button for the `OpenBB API` backend. info By default, this will run: `openbb-api --host 127.0.0.1 --port 6900` Application Screenshot ![backends-running](https://github.com/user-attachments/assets/2ec97b99-a19f-43ed-b735-f5757e51b4c4) 4. Open Workspace in your browser and connect to [http://127.0.0.1:6900](http://127.0.0.1:6900/) . You now have a fully local data stack. Workspace Screenshot ![Add To Workspace](https://openbb-cms.directus.app/assets/563aca68-1ec3-48c7-86d8-9129e0e5fd8c.png) note Number of widgets and applications will depend on packages and versions installed in the environment. Overview[​](https://docs.openbb.co/odp/desktop#overview "Direct link to Overview") ----------------------------------------------------------------------------------- The application operates as a system tray icon, and its main window has three, navigatable, screens: [Backends\ \ Define and control background servers such as \`openbb-api\` or any custom script.](https://docs.openbb.co/odp/desktop/backends) [Environments\ \ Create and manage isolated Conda Python environments.](https://docs.openbb.co/odp/desktop/environments) [API Keys\ \ Manage API Keys for use with the OpenBB Python packages and API.](https://docs.openbb.co/odp/desktop/api-keys) * * * Next Steps[​](https://docs.openbb.co/odp/desktop#next-steps "Direct link to Next Steps") ----------------------------------------------------------------------------------------- * Use the OpenBB Python Package as a Workspace [backend](https://docs.openbb.co/odp/python/quickstart/workspace) . * Create your own custom [Environments](https://docs.openbb.co/odp/desktop/environments) , or modify the existing. * Define custom [Backends](https://docs.openbb.co/odp/desktop/backends) to run independently, in any environment. On this page * [Quick Start](https://docs.openbb.co/odp/desktop#quick-start) * [**Step 1**](https://docs.openbb.co/odp/desktop#step-1) * [**Step 2**](https://docs.openbb.co/odp/desktop#step-2) * [**Step 3**](https://docs.openbb.co/odp/desktop#step-3) * [Overview](https://docs.openbb.co/odp/desktop#overview) * [Next Steps](https://docs.openbb.co/odp/desktop#next-steps) --- # AI Features — Create HTML artifacts | OpenBB Workspace Docs [Skip to main content](https://docs.openbb.co/workspace/developers/ai-features/create-html-artifacts#__docusaurus_skipToContent_fallback) On this page Stream custom HTML content with `html_artifact(...)`. HTML artifacts are rendered inline in the chat and can be converted to dashboard widgets by users. Reference implementation in [this GitHub repository](https://github.com/OpenBB-finance/agents-for-openbb/tree/main/39-vanilla-agent-html-artifacts) . ![Charts](https://openbb-cms.directus.app/assets/e74e0b8e-3858-47e8-bcd6-d59dfe1cbfe7.png) Architecture[​](https://docs.openbb.co/workspace/developers/ai-features/create-html-artifacts#architecture "Direct link to Architecture") ------------------------------------------------------------------------------------------------------------------------------------------ Emit HTML artifacts so custom visualizations render below the answer. HTML content is sanitized with DOMPurify before rendering for security. `agents.json` configuration: return JSONResponse(content={ "vanilla_agent_html": { "name": "HTML Artifacts Agent", "description": "An example agent that produces HTML artifacts rendered inline in the chat.", "endpoints": {"query": "/v1/query"}, "features": { "streaming": True, "widget-dashboard-select": False, "widget-dashboard-search": False, }, }}) ### Query flow[​](https://docs.openbb.co/workspace/developers/ai-features/create-html-artifacts#query-flow "Direct link to Query flow") * Process user request and prepare HTML content * Stream explanatory text with `message_chunk()` * Create HTML content as a string (inline styles supported) * Emit `html_artifact()` events with proper configuration * HTML renders inline below streamed content * Users can click widget icon to add artifacts to dashboard ### SSE event format[​](https://docs.openbb.co/workspace/developers/ai-features/create-html-artifacts#sse-event-format "Direct link to SSE event format") HTML artifacts are sent as SSE events with the following structure: { "event": "copilotMessageArtifact", "data": { "type": "html", "uuid": "unique-id", "name": "artifact_name", "description": "A description of the artifact", "content": "
Your HTML content here
" }} Core logic[​](https://docs.openbb.co/workspace/developers/ai-features/create-html-artifacts#core-logic "Direct link to Core logic") ------------------------------------------------------------------------------------------------------------------------------------ import jsonimport uuidfrom typing import AsyncGeneratorfrom openbb_ai import message_chunkfrom openbb_ai.models import QueryRequestfrom sse_starlette.sse import EventSourceResponsedef html_artifact(content: str, name: str, description: str) -> dict: """ Create an HTML artifact SSE event. Args: content: The HTML content to render name: A unique name for the artifact description: A description of the artifact Returns: SSE event dict with type="html" artifact """ return { "event": "copilotMessageArtifact", "data": json.dumps({ "type": "html", "uuid": str(uuid.uuid4()), "name": name, "description": description, "content": content, }), }# Example HTML templateDASHBOARD_CARD_HTML = """

Portfolio Summary

$124.5K
Total Value
+12.3%
Today's Change
"""@app.post("/v1/query")async def query(request: QueryRequest) -> EventSourceResponse: async def execution_loop() -> AsyncGenerator[dict, None]: client = openai.AsyncOpenAI() # Stream the LLM response 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() # Emit HTML artifact yield message_chunk("\n\nHere's a portfolio dashboard card:\n\n").model_dump() yield html_artifact( content=DASHBOARD_CARD_HTML, name="portfolio_dashboard", description="A portfolio summary dashboard card", ) yield message_chunk( "\n\nYou can click the widget icon to add this to your dashboard!" ).model_dump() return EventSourceResponse( content=execution_loop(), media_type="text/event-stream", ) Example templates[​](https://docs.openbb.co/workspace/developers/ai-features/create-html-artifacts#example-templates "Direct link to Example templates") --------------------------------------------------------------------------------------------------------------------------------------------------------- ### Metric cards[​](https://docs.openbb.co/workspace/developers/ai-features/create-html-artifacts#metric-cards "Direct link to Metric cards")
Revenue
$2.4M
↑ 14.2%
Users
48.2K
↑ 8.1%
### Alert box[​](https://docs.openbb.co/workspace/developers/ai-features/create-html-artifacts#alert-box "Direct link to Alert box")
!
Market Alert
Unusual trading volume detected in AAPL. Volume is 3.2x higher than the 20-day average.
Security considerations[​](https://docs.openbb.co/workspace/developers/ai-features/create-html-artifacts#security-considerations "Direct link to Security considerations") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The frontend sanitizes all HTML with DOMPurify before rendering. Keep the following in mind: | Element/Attribute | Status | | --- | --- | | `