Skip to content

Python agent tools

Bloomberg tools for LangChain and LangGraph agents.

The xbbg-langgraph adapter, imported as xbbg_langgraph, turns xbbg requests, recipes, finite live snapshots, and helpers into 35 bounded LangChain tools. Tool names match @xbbg/langgraph; Python arguments and factories use snake_case.

Not on PyPI

xbbg-langgraph has not been published to PyPI, so pip install xbbg-langgraph does not work. Install it from a checkout of the xbbg repository, as shown below.

Install ​

bash
git clone --depth 1 --branch v1.8.0 https://github.com/underloam/xbbg.git
pip install ./xbbg/py-xbbg-langgraph
# For the create_agent example below:
pip install langchain langchain-openai
# For custom graphs without the LangChain agent package:
pip install "langgraph>=1.2,<2"

Python 3.11–3.14

The adapter declares >=3.11,<3.15. xbbg itself also supports 3.15, but LangGraph's dependencies do not build there yet.

Dependencies

xbbg>=1.6.0,<2, langchain-core>=1.4.0,<2, and pydantic>=2.10,<3; on Python 3.14 also langsmith<0.9. Graph workflows target LangGraph 1.2 or newer.

Bloomberg runtime

Live calls need authorized Bloomberg connectivity and the SDK runtime, as for any xbbg request. Creating tools and reading their schemas does not import the native extension or start a session.

The v1.8.0 checkout builds xbbg-langgraph 0.1.0. Ordinary pip install xbbg installs no LangChain packages. See Installation for the Bloomberg runtime.

With xbbg 1.8.0 the adapter checks the size of each native cell and metadata value before copying it into a result. Older xbbg releases, which the xbbg>=1.6.0 floor still allows, copy them first and apply the limits afterwards.

Quick start ​

python
from langchain.agents import create_agent
from langchain_openai import ChatOpenAI
from xbbg_langgraph import BLOOMBERG_TOOL_INSTRUCTIONS, create_all_bloomberg_tools

tools = create_all_bloomberg_tools(
    max_securities=10,
    max_fields=25,
    max_rows=500,         # application artifact
    max_content_rows=50,  # model-facing preview
    disabled_tools={"xbbg_bql", "xbbg_bsrch"},
)

# Configure OPENAI_API_KEY and Bloomberg access before invoking.
agent = create_agent(
    model=ChatOpenAI(model="gpt-4.1"),
    tools=tools,
    system_prompt=BLOOMBERG_TOOL_INSTRUCTIONS,
)
result = agent.invoke({
    "messages": [{"role": "user", "content": "Get PX_LAST for IBM US Equity."}],
})

Custom LangGraph graphs ​

Bind the tools to your model and route tool calls through ToolNode:

python
from langchain_core.messages import SystemMessage
from langchain_openai import ChatOpenAI
from langgraph.graph import START, MessagesState, StateGraph
from langgraph.prebuilt import ToolNode, tools_condition
from xbbg_langgraph import BLOOMBERG_TOOL_INSTRUCTIONS, create_bloomberg_tools

tools = create_bloomberg_tools(max_securities=5, max_fields=5)
model = ChatOpenAI(model="gpt-4.1").bind_tools(tools)


def call_model(state: MessagesState) -> dict:
    response = model.invoke([SystemMessage(BLOOMBERG_TOOL_INSTRUCTIONS), *state["messages"]])
    return {"messages": [response]}


builder = StateGraph(MessagesState)
builder.add_node("model", call_model)
builder.add_node("tools", ToolNode(tools))
builder.add_edge(START, "model")
builder.add_conditional_edges("model", tools_condition)
builder.add_edge("tools", "model")
graph = builder.compile()

ToolNode produces ToolMessages whose content goes back to the model and whose artifact holds the application envelope described under Results.

Tool factories ​

FactoryReturns
create_all_bloomberg_tools()All 35 tools (BLOOMBERG_TOOL_NAMES)
create_bloomberg_tools()The 24 request, recipe, auction, and snapshot tools (BLOOMBERG_CORE_TOOL_NAMES)
create_bloomberg_ext_tools()The 11 helper tools (BLOOMBERG_EXT_TOOL_NAMES)
create_<name>_tool()One tool, named after the tool without its xbbg_ prefix: create_bdp_tool() builds xbbg_bdp, create_ext_chart_spec_tool() builds xbbg_ext_chart_spec
  • Every factory accepts either keyword options or a single BloombergToolsOptions instance, not both; mixing them raises TypeError.
  • disabled_tools removes tools from the three group factories. An unknown name fails validation, and calling an individual factory for a tool you disabled raises ValueError.
  • Each tool is a LangChain StructuredTool with response_format="content_and_artifact" and supports .invoke() and .ainvoke().
python
from xbbg_langgraph import BloombergToolsOptions, create_all_bloomberg_tools, create_bdp_tool

options = BloombergToolsOptions(max_rows=200, max_content_rows=20, request_timeout=30.0)
tools = create_all_bloomberg_tools(options)
bdp_only = create_bdp_tool(max_securities=3)

Agent instructions ​

BLOOMBERG_TOOL_INSTRUCTIONS is system-prompt text for the model. It tells the model to ask before choosing an ambiguous security, field, date range, or universe; never to invent tickers, fields, overrides, or BQL functions; to pass identifiers exactly as supplied (/isin/<ISIN>, /cusip/<CUSIP>); to look up uncertain fields with xbbg_bflds; to issue one request per dataset; and to report empty, truncated, or errored results instead of filling gaps.

get_bloomberg_tool_instructions(include_extension_guidance=True, include_limit_reminder=True) builds the same text with optional sections. Drop the helper guidance when the model does not get the helper tools:

python
from xbbg_langgraph import create_bloomberg_tools, get_bloomberg_tool_instructions

tools = create_bloomberg_tools()
prompt = get_bloomberg_tool_instructions(include_extension_guidance=False)

Options ​

BloombergToolsOptions is a frozen Pydantic model. Unknown keys are rejected, and integer limits are strict: booleans and floats are not accepted.

OptionDefaultConstraintBounds
engineNoneAn xbbg.blp.EngineEngine for every call; see Engines
max_securities25> 0Securities per call, ISIN lists, and pcs_overrides entries
max_fields25> 0Fields per call and entries per kwargs or override map; CDX bundles must fit
max_rows500> 0Rows retained in the artifact; chart-spec input rows
max_string_chars2,000> 0Characters per input string and per result string
max_result_bytes1,048,576≥ 256Serialized artifact, including its envelope
max_result_nodes50,000≥ 10Values and properties inspected while bounding one result
max_content_bytes65,536≥ 256Serialized model-facing content, including its envelope
max_content_rows50> 0Rows retained in model-facing content
max_bql_query_chars4,000> 0xbbg_bql queries and generated recipe queries
max_search_spec_chars1,000> 0search_spec for xbbg_bsrch and xbbg_bflds
max_stream_updates10> 0Largest max_updates a snapshot accepts
max_stream_wait_ms15,000> 0Largest and default snapshot timeout_ms
request_timeout60.0> 0, finiteSeconds allowed for each tool call
validate_fieldsNoneboolDefault field validation for xbbg_bdp, xbbg_bdh, xbbg_bds, and the CDX bundles; a per-call value wins
disabled_toolsemptyKnown tool namesTools left out by the group factories

The limits are also written into each tool's JSON schema, so the model sees them.

Results ​

Each call produces two independently bounded projections of the same result: model-facing content (max_content_rows, max_content_bytes) and an application artifact (max_rows, max_result_bytes). A smaller preview never shrinks the artifact. Invoke with a full tool call, as agents and ToolNode do, to receive a ToolMessage carrying both; bare arguments return only the content string, following LangChain's normal contract.

python
from xbbg_langgraph import create_bdp_tool

tool = create_bdp_tool(max_securities=1, max_fields=1)
message = tool.invoke({
    "type": "tool_call",
    "id": "reference-price",
    "name": "xbbg_bdp",
    "args": {"securities": ["IBM US Equity"], "fields": ["PX_LAST"]},
})
print(message.content)   # JSON envelope for the model
print(message.artifact)  # JSON-safe envelope for your application

Both projections use the same envelope keys as the JavaScript adapter:

KeyMeaning
toolTool name
dataThe bounded result
rowCountSource row count, or None when unknown; not the number of rows kept
truncatedTrue when anything was omitted or shortened
truncationOptional {"reasons": [...]} from max_rows, max_string_chars, max_result_bytes, max_result_nodes, max_result_depth, circular_reference, binary_data, unsupported_value, upstream_truncation
hasErrorsPresent and True when Bloomberg errors were detected, even if their details were clipped
  • For table results, data is a list of row objects or, when the Arrow table carries metadata, an object with rows, the raw metadata, and any parsed diagnostics: securityErrors, fieldErrors, fieldExceptions, eidData, and delayed (from the metadata keys xbbg.security_errors, xbbg.field_errors, xbbg.field_exceptions, xbbg.eid_data, and xbbg.delayed). fieldErrors holds the field ids Bloomberg refused, which xbbg 1.8.0 reports for xbbg_bflds even when no field was answered.
  • Errors, entitlement data, and delay status are kept ahead of ordinary rows. Diagnostic lists are never cut by the row limits, though byte, node, and string limits still apply.
  • xbbg 1.8.0 stores xbbg.field_exceptions as a compact dictionary. The adapter expands only the diagnostics it keeps and omits unreadable ones with the unsupported_value reason instead of failing the result.
  • Arrow rows are sliced before conversion. Dates and times become ISO strings, and non-finite numbers become null with the unsupported_value reason. Binary values, including sparse-update presence bitmaps, become {"encoding": "base64", "data": ..., "byteLength": ..., "truncated": ...} so null and absent stay distinguishable. Nesting is capped at depth 32.
  • Output caps do not limit what Bloomberg sends, so keep universes and date ranges bounded even when the preview is small. With xbbg releases before 1.8.0, native metadata getters and a single native cell can also allocate before projection.

Snapshots ​

Live data is exposed only as finite snapshots that always unsubscribe:

ToolServiceInputs
xbbg_stream_snapshot//blp/mktdatatickers, fields, max_updates
xbbg_mktbar_snapshot//blp/mktbarOne ticker, max_updates; fields may only be ["LAST_PRICE"], and bar_size=1 is added unless options sets bar_size
xbbg_depth_snapshot//blp/mktdepthdataOne ticker, max_updates; requests all available scalar fields unless you pass fields, and all_fields=False requires a nonempty list. Needs B-PIPE with depth entitlements
  • max_updates is required and at most max_stream_updates. timeout_ms defaults to max_stream_wait_ms (15 seconds) and cannot exceed it.
  • Optional controls: drain, all_fields, conflate (//blp/mktdata only), flush_threshold, stream_capacity, overflow_policy, and Bloomberg subscription options.
  • overflow_policy accepts drop_newest or block. When omitted, snapshots use drop_newest regardless of the engine's default, because snapshot rows cannot describe gaps; lossy delivery modes are not offered.
  • flush_threshold defaults to 1, so each update is one native read even though xbbg 1.8.0 engines batch up to 16 queued updates by default.
  • The result has updateCount, maxUpdates, timeoutMs, reason (max_updates, timeout, or done), and updates. If collection succeeded but releasing the subscription failed, the updates are kept and unsubscribeError reports the failure.
  • Subscriptions close on completion, timeout, error, or cancellation, and cleanup finishes even when the caller cancels. A timeout can return partial or zero updates; it does not prove there was no activity.
  • All updates in one snapshot share a single row allowance, so a snapshot cannot multiply the row budget.

See Streaming for open-ended subscriptions in application code.

Engines, timeouts, and cancellation ​

Without engine, tools use xbbg's global engine (set up with xbbg.configure()) or the engine scoped in the caller's context. Pass engine= to route every call through an application-owned xbbg.blp.Engine; each call enters it as a context manager. The adapter never configures, resets, or shuts down an engine.

With xbbg 1.8.0, the engine's key_column names the column that holds each row's security. The default, ticker, is deprecated and its results emit a FutureWarning; set key_column="security" with xbbg.configure() or blp.Engine() to switch.

python
from xbbg import blp
from xbbg_langgraph import create_all_bloomberg_tools

engine = blp.Engine(host="localhost", port=8194, request_timeout_ms=30_000)
tools = create_all_bloomberg_tools(engine=engine, request_timeout=45.0)

# ... run the agent ...

engine.shutdown()  # the application owns the engine's lifecycle
  • request_timeout is a coroutine deadline in seconds around each tool's Bloomberg work (default 60); bounding the result afterwards is not counted against it. It cannot preempt synchronous SDK startup or subscription cleanup. Set the engine's request_timeout_ms (default 0, no timeout) to bound requests inside the engine, and its connection settings for startup.
  • .invoke() runs the call on its own event loop and raises RuntimeError inside a running loop; use await tool.ainvoke(...) (and graph.ainvoke) in async code.
  • Cancelling the task that awaits .ainvoke() cancels the tool's coroutine. Snapshot tools still release their subscription, without draining, before the cancellation propagates.

See Configuration for engine settings.

Entitlements and delayed data ​

  • return_eids=True is accepted by xbbg_bdp, xbbg_bdh, xbbg_bds, xbbg_bdib, and xbbg_bdtick; the IDs appear as eidData in data. Pass them to xbbg_check_entitlements (eids, up to 10,000 positive IDs; service, default //blp/refdata), which returns {"entitled": ..., "failedEids": [...]}. Do not treat a truncated EID map as complete.
  • xbbg_delay_status returns one row per unique security with delayed, delay_minutes, exchange_delay, exch_code, realtime_eid1 to realtime_eid4, delayed_eid, and error. check_identity=True adds realtime_entitled and delayed_entitled and needs an EMRS-enrolled Desktop API user or SAPI/B-PIPE authorization.
  • on_delayed ("warn", "raise", or "ignore") on xbbg_bdp, xbbg_bdh, xbbg_bdib, and xbbg_bdtick checks delay alongside the request. raise fails the call when Bloomberg delivers delayed data; warn and ignore add a per-security delayed map to data, and warn also emits xbbg's BlpDelayedDataWarning in your process. History and intraday tools check only windows that reach the last 24 hours.

See Entitlements for the underlying xbbg calls.

Auction tools ​

xbbg_resolve_venues and xbbg_auction_snapshot take securities (tickers, bare ISINs, /isin/ or /bbgid/ topics, with explicit venue suffixes kept) and optional pcs_overrides mapping preferred-stock exchange names to pricing-source codes. They keep one row per input with status and error; failed venues keep their row with null data fields. xbbg_auction_snapshot takes optional fields; omitted or empty selects AUCTION.DEFAULT. Time-of-day values are terminal-local, and a snapshot does not report delay, so pair it with xbbg_delay_status. See Exchange Auctions.

Chart specs ​

xbbg_ext_chart_spec turns rows you already have, typically from an earlier data tool, into an inline Vega-Lite v5 specification. It neither fetches Bloomberg data nor renders anything.

python
from xbbg_langgraph import create_ext_chart_spec_tool

chart = create_ext_chart_spec_tool()
message = chart.invoke({
    "type": "tool_call",
    "id": "chart-1",
    "name": "xbbg_ext_chart_spec",
    "args": {
        "source": "bdh",
        "rows": [
            {"ticker": "AAPL US Equity", "date": "2024-01-02", "value": 190.1},
            {"ticker": "AAPL US Equity", "date": "2024-01-03", "value": 188.4},
        ],
        "x_field": "date",
        "y_fields": ["value"],
        "series_field": "ticker",
        "title": "AAPL PX_LAST",
    },
})
chart_data = message.artifact["data"]
  • Inputs: source (bdh, bdib, holdings, depth, or rows), rows (at most max_rows), and optional chart (line, area, bar, scatter, candlestick, or depth; the default follows source), title, max_points, x_field, y_fields, series_field, label_field, value_field, open_field, high_field, low_field, close_field, side_field, price_field, and size_field. Every named field must exist in the rows.
  • The result has kind ("xbbg.visualization"), version, component ("xbbg_chart"), renderer ("vega-lite"), rowCount, inputRowCount, truncatedInput, source, chart, summary, spec, and warnings.
  • Render only when data["spec"] is present and data.get("renderable") is not False. Truncation by max_points keeps a valid spec and adds a warning; clipping by the result budgets sets spec to None and renderable to False.

Python-specific boundaries ​

  • Recipe tickers must be fully qualified: <TICKER> <EXCHANGE> Equity for preferreds, corporate bonds, and ETF holdings, and <TICKER> Index for index members. The builders never guess a suffix. Recipe fields accept identifiers and argument-free BQL field access only; use xbbg_bql for expressions.
  • xbbg_bql accepts only query, and xbbg_bflds only fields or search_spec; other keyword options are rejected rather than ignored. Configure bql_app_name on the engine to set the BQL application context.
  • xbbg_corporate_bonds has no active_only input. Omitting ccy means all currencies, unlike the Python recipe's USD default.
  • CDX recovery_rate on xbbg_ext_cdx is a percentage from 0 to 100: 40 means 40%, not 0.40. On xbbg_yas, yield_val is in percentage points and spread in basis points.
  • kwargs and overrides carry Bloomberg request values only. Infrastructure and typed call options such as engine, backend, format, host, or port are rejected in either snake_case or camelCase. Per-security override maps must be keyed by a security in securities.
  • Dates accept YYYY-MM-DD or YYYYMMDD strings, integer YYYYMMDD values, or epoch milliseconds. Datetimes must be ISO 8601 with a time component (optional Z or offset) or epoch milliseconds. start must not be after end, and both must be either naive or offset-aware.

Compared with @xbbg/langgraph, Python bounds each call with request_timeout in seconds, where JavaScript sets engineConfig.requestTimeoutMs on lazily created engines only. Python content is the JSON envelope alone, without the JavaScript summary line, and its truncation carries only reasons.

Tool reference ​

Required inputs are listed first.

ToolPurposeInputs
xbbg_bdpReference datasecurities, fields; overrides, kwargs, format, include_security_errors, validate_fields, return_eids, on_delayed
xbbg_bdhHistorical seriessecurities, fields, start, end; format (adds semi_long), overrides, kwargs, validate_fields, return_eids, on_delayed
xbbg_bdsOne bulk or table fieldsecurities, field; overrides, kwargs, validate_fields, return_eids
xbbg_bdibIntraday barsticker, start, end, interval; event_type, request_tz, output_tz, kwargs, return_eids, on_delayed
xbbg_bdtickIntraday ticksticker, start, end; event_types, seven include_* flags, request_tz, output_tz, kwargs, return_eids, on_delayed
xbbg_check_entitlementsCheck entitlement IDseids; service
xbbg_delay_statusDelayed or real-time status per securitysecurities; check_identity
xbbg_bqlOne complete BQL expressionquery
xbbg_bsrchSaved search or gridsearch_spec; kwargs, overrides
xbbg_bqrFixed-income dealer quotesticker, start, end; event_types (default BID and ASK), include_broker_codes
xbbg_bfldsField metadata and search; with xbbg 1.8.0, results end with the field id columnExactly one of fields or search_spec
xbbg_beqsNamed Bloomberg equity screenscreen; asof, group, screen_type, kwargs, overrides
xbbg_yasYAS yield and spread analyticstickers, fields; settle_dt, yield_type (1–9), yield_val, price, spread, benchmark
xbbg_preferredsPreferreds of an issuerequity_ticker; fields
xbbg_corporate_bondsCorporate debt universe of a companyticker; ccy, fields
xbbg_index_membersIndex constituentsindex; asof, field (INDX_MWEIGHT, INDX_MEMBERS, INDX_MEMBERS3)
xbbg_resolve_isinsResolve raw ISINsisins
xbbg_issuer_isinsBond ISINs to issuer equity ISINsbond_isins
xbbg_resolve_venuesValidated auction venuessecurities; pcs_overrides
xbbg_auction_snapshotAuction and imbalance fields on primary venuessecurities; fields, pcs_overrides
xbbg_etf_holdingsETF holdingsetf_ticker; fields
xbbg_stream_snapshotFinite //blp/mktdata snapshottickers, fields, max_updates; snapshot controls
xbbg_mktbar_snapshotFinite //blp/mktbar snapshotticker, max_updates; fields, snapshot controls
xbbg_depth_snapshotFinite //blp/mktdepthdata snapshotticker, max_updates; fields, snapshot controls
xbbg_ext_tickerTicker hygieneoperation: parse_ticker (generic futures-style tickers only), normalize_tickers, filter_equity_tickers, is_specific_contract, validate_generic_ticker
xbbg_ext_futuresFutures contract construction and selectionoperation: build_futures_ticker, generate_candidates, contract_index, filter_candidates_by_cycle, filter_valid_contracts, get_futures_months
xbbg_ext_cdxCDX parsing, series, and data bundlesoperation: parse_cdx_ticker, previous_cdx_series, cdx_gen_to_specific, cdx_info, cdx_pricing, cdx_risk (recovery_rate 0–100)
xbbg_ext_currencyCurrency planning, not FX quotesoperation: build_fx_pair, same_currency, currencies_needing_conversion
xbbg_ext_bql_builderBuild, but do not run, recipe BQLoperation: build_preferreds_query, build_corporate_bonds_query, build_etf_holdings_query
xbbg_ext_chart_specVega-Lite spec from rowssource, rows; chart options
xbbg_ext_market_sessionRead-only session and timezone helpersoperation: derive_sessions, get_market_rule, infer_timezone, session_times_to_utc, default_turnover_dates, default_bqr_datetimes, get_exchange_override, list_exchange_overrides
xbbg_ext_yas_overridesYAS override pairs without a requestsettle_dt, yield_type, spread, yield_val, price, benchmark (all optional)
xbbg_ext_constantsConstant lookupsoperation: parse_date, fmt_date, get_month_code, get_month_name, get_futures_months, get_dvd_type, get_dvd_types, get_dvd_cols, get_etf_cols
xbbg_ext_columnsColumn rename mappingsoperation: rename_dividend_columns, rename_etf_columns, build_earning_header_rename
xbbg_ext_calculateLevel percentages for earnings hierarchiesoperation: calculate_level_percentages; values, levels (1, 2, or null; same length)

The helper tools run locally on xbbg's native helpers and never contact Bloomberg, except the cdx_info, cdx_pricing, and cdx_risk data bundles.

MCP Server

Give Claude Code, OpenCode, or Claude Desktop Bloomberg tools without writing an agent.

Entitlements

Entitlement IDs, identity checks, and delayed-data status.

xbbg is independent open-source software and is not affiliated with, endorsed by, sponsored by, or approved by Bloomberg Finance L.P.