Installation
Supported Python versions, extras, and runtime sources.
Troubleshooting
Most problems sit in one of four places: the Bloomberg runtime library, the native extension, the connection to Bloomberg, or the request itself. These checks narrow it down quickly.
xbbg.__version__ and xbbg.get_sdk_info() show what is installed and which Bloomberg runtime was found.
A first request, xbbg.is_connected(), and Engine.worker_health() show whether sessions are up.
Security lookup, field search, and result metadata explain empty or partial results.
Raise xbbg's native log level and register SDK logging for low-level detail.
xbbg does not need Bloomberg's blpapi Python package, only the shared runtime library (blpapi3_64.dll on Windows, libblpapi3_64.so on macOS and Linux). Check what was found:
import xbbg
print(xbbg.__version__)
info = xbbg.get_sdk_info()
print(info["active"], info["runtime_version"])
for source in info["sources"]:
print(source["name"], source["version"], source["path"])get_sdk_info() returns sources (every runtime found, each with name, version, and path), active (the name of the first source, or None), and runtime_version (the version of the linked runtime, or None). The result is cached for the process; since 1.8.0 each call returns a copy you can modify, and the call is thread-safe. Discovery no longer imports Bloomberg's blpapi package: it locates the package and reads its version from distribution metadata, so a broken blpapi install is still listed as a source. Sources are probed in this order:
name | Source |
|---|---|
manual | A directory set with xbbg.set_sdk_path(path) |
blpapi_python | Bloomberg's blpapi wheel, which ships the runtime library |
dapi | A Bloomberg Terminal (DAPI) install. On Windows xbbg probes \blp\DAPI on the system drive and on drive C:, Bloomberg\Blp\DAPI under the Program Files folders, and Bloomberg\DAPI and Bloomberg\Blp\DAPI under %LOCALAPPDATA%; on macOS and Linux, ~/blp/DAPI and /opt/bloomberg/DAPI |
sdk_env | The directory in the BLPAPI_ROOT environment variable |
Inside a source directory xbbg looks for the library at the top level and in lib/ (on Windows also in bin/, Lib/, lib/win64/, and lib/win32/). Since 1.8.0 the runtime library is prepared when the native extension first loads, on the first request rather than on import xbbg, and on Windows the highest-priority library is loaded by full path, so the process uses that copy only. To use a specific runtime, call xbbg.set_sdk_path("/path/to/blpapi") before the first request; it raises ValueError if the directory has no runtime library, takes precedence over every other source, and refreshes the cached get_sdk_info(). xbbg.clear_sdk_path() returns to auto-detection. The easiest runtime source is often Bloomberg's wheel:
pip install blpapi --index-url=https://blpapi.bloomberg.com/repository/releases/python/simple/Linux wheels are manylinux_2_28 x86_64 builds and need glibc 2.28 or newer (RHEL/Alma/Rocky 8+, Debian 10+, Ubuntu 20.04+, Amazon Linux 2023). On older systems pip cannot use the wheel. Supported Python versions are 3.11 to 3.15; since 1.8.0 the package declares no upper Python bound, so pip on a newer CPython installs the current release, building it from source when no wheel exists, instead of an old release line. See Installation for platforms.
Free-threaded CPython (cp314t, cp315t) wheels are published as a beta since 1.8.0 for Linux x86_64, Windows x64, and macOS arm64. PyArrow, pandas, and Narwhals work there; Polars, DuckDB, and the xbbg-langgraph adapter do not, because they or their dependencies publish no free-threaded wheels.
| Error | Cause and fix |
|---|---|
ImportError: ... DLL load failed / cannot open shared object file / Library not loaded | The native extension cannot load the Bloomberg runtime library. Install the blpapi wheel, set BLPAPI_ROOT, or call set_sdk_path(), then check get_sdk_info(). |
ImportError: xbbg._core (...) was built for xbbg X, but the installed xbbg is Y | The native extension and the Python files come from different builds, for example after an interrupted upgrade or pip and conda installing over each other. Reinstall with the tool that installed xbbg, for example pip install --force-reinstall --no-deps "xbbg==1.8.0". |
ImportError: Recursive import of _core detected | Raised in 1.7.0 and earlier when several threads first used xbbg at once; since 1.8.0 those threads wait for the first import instead. |
ModuleNotFoundError: No module named 'xbbg._core' | The native extension is missing or was built for another Python version. Reinstall a wheel for the interpreter you run. |
RuntimeWarning: xbbg._core in this source checkout was built from commit ... | Development checkouts only: rebuild the extension (pixi run install) after pulling. |
ImportError naming an optional backend | Install the matching extra, such as xbbg[pandas], xbbg[polars], xbbg[pyarrow], or xbbg[duckdb]. |
localhost:8194.auth_method, application name, TLS material, and failover servers in Configuration. Call configure() before the first request; calling it later shuts the running engine down, warns with RuntimeWarning, and restarts with the new settings on the next request.BlpInternalError: Internal error: failed to spawn worker 0: session start failed, after the SDK has retried num_start_attempts times (3 by default), which can take tens of seconds. Every request worker dying later raises BlpSessionError.request_pool_size=0, an unknown validation_mode, or an unknown sdk_log_level raise ValueError when the engine is created, before any connection attempt. Unknown keyword names raise TypeError from configure() and Engine() immediately.import xbbg
print(xbbg.is_connected()) # global engine: False until the first request creates it
with xbbg.Engine(host="localhost", port=8194) as engine:
print(engine.worker_health()) # [(0, "healthy"), (1, "healthy")]is_connected() reports whether the global engine exists and at least one request worker has a live session. A scoped xbbg.Engine(...) connects when it is created; its worker_health() returns (worker_id, status) pairs with status "healthy", "degraded", or "dead".
Empty results usually mean an input or an entitlement is wrong, not that the call failed:
from xbbg import blp
print(blp.blkp("Apple", yellowkey="YK_FILTER_EQTY")) # find the right ticker
print(blp.fieldSearch("vwap")) # find the right field mnemonic
print(blp.bflds(fields=["PX_LAST", "EQY_WEIGHTED_AVG_PX"])) # check a field's type and description<TICKER> <yellow key> (AAPL US Equity), /isin/<ISIN>, or /cusip/<CUSIP>. blkp finds tickers (yellowkey filters such as YK_FILTER_EQTY, YK_FILTER_CORP, YK_FILTER_INDX); ext.resolve_isins maps equity ISINs to tickers.bflds(search_spec=...) and blp.fieldSearch(...) search field mnemonics; bflds(fields=[...]) and blp.fieldInfo(...) describe known ones. validate_fields=True rejects unknown fields with BlpValidationError, naming a close match when there is one.security_errors and field_exceptions from the native, PyArrow, or pandas result, or pass include_security_errors=True to bdp (see Errors and warnings).xbbg.delay_status([...]) shows whether this session gets real-time data, and return_eids=True shows entitlement IDs (Entitlements). Exchange auction fields exist only on the venue listing (Exchange auctions).request_tz, UTC by default); see Dates and times.Requests have no timeout by default (request_timeout_ms=0): they wait until Bloomberg answers. Set one to fail with BlpTimeoutError instead:
import xbbg
xbbg.configure(request_timeout_ms=120_000)For large requests, split long historical and tick ranges into smaller date windows, enable sharding of wide multi-security bdp/bdh requests (shard_requests=True, see Request options), and size request_pool_size and the subscription settings for your infrastructure (Configuration).
In Jupyter, VS Code Interactive, and marimo, every sync call (bdp, bql, subscribe, the xbbg.ext helpers, and so on) runs through a managed background event loop while the notebook's loop is running. In any other running event loop, such as a FastAPI or other ASGI application, sync calls raise:
RuntimeError: bdp() cannot be used inside an async context. Use 'await abdp()' instead, or use xbbg.Engine(...) for scoped async engines.Use the a-prefixed async functions there; see Async.
xbbg has three log sources:
| Source | Control | Destination |
|---|---|---|
| Native engine (Rust) | xbbg.set_log_level(level) with trace, debug, info, warn (default), or error; warning and 0 to 4 also work. xbbg.get_log_level() returns the current level. A simple level in RUST_LOG (for example RUST_LOG=debug) sets the starting level when xbbg loads; per-module filters are not supported. | stderr |
| Bloomberg SDK | xbbg.enable_sdk_logging(level) or configure(sdk_log_level=...) with off (default), fatal, error, warn, info, debug, or trace (warning also works) | Forwarded to the native log, so it is filtered by set_log_level |
| Python modules | Standard logging under the xbbg logger; at INFO each request logs its service, operation, request_id, row count, timing, securities, and fields | Your logging handlers |
import logging
import xbbg
logging.basicConfig(level=logging.INFO) # per-request summaries from the xbbg logger
xbbg.set_log_level("debug") # native engine detail
xbbg.enable_sdk_logging("info") # Bloomberg SDK messages at INFO and aboveSDK logging is registered once per process: the first level other than off wins, whether it comes from enable_sdk_logging or sdk_log_level, so enable it before the first request. SDK messages arrive at the matching native level, so set_log_level must be at least as verbose to show them.
Open an issue on GitHub with:
xbbg.__version__), Python version, and operating system.xbbg.get_sdk_info(), with local paths redacted.set_log_level("debug") if the problem is in the engine.For a data problem that Bloomberg should look at, send Bloomberg support the request's bloomberg_request_id(s) from the result or the exception (Entitlements and provenance).
Supported Python versions, extras, and runtime sources.
Hosts, authentication, TLS, pools, timeouts, and logging settings.
What each exception means and how to handle it.
Event-loop rules for async applications.