OpenBB-finance/OpenBB · error · OpenBBError
Expected an ExcelFile object, got {type(file)} instead.
Error message
Expected an ExcelFile object, got {type(file)} instead. What it means
Transform-stage type guard in the EIA Petroleum Status Report model: transform_data expects the data dict to contain an openpyxl/pandas 'ExcelFile' object produced by aextract_data. If data['file'] is anything else (None, bytes, a DataFrame), this TypeError is wrapped in OpenBBError. In practice it signals a broken extract stage or direct misuse of transform_data with raw data.
Source
Thrown at openbb_platform/providers/eia/openbb_us_eia/models/petroleum_status_report.py:160
from functools import lru_cache
from numpy import nan
from pandas import Categorical, ExcelFile, concat, read_excel
from warnings import warn
category = query.category
_tables = (
query.table.split(",") # type: ignore
if query.table
else ["stocks"] if category == "weekly_estimates" else ["all"]
)
all_tables = list(WpsrTableMap[category])
tables = all_tables if "all" in _tables else _tables
file = data.get("file")
if not isinstance(file, ExcelFile):
raise OpenBBError(
TypeError(f"Expected an ExcelFile object, got {type(file)} instead.")
)
dfs: list = []
def replace_data_strings(text):
"""Replace the table strings with sortable numbers."""
pattern = r"Data (\d):"
def replacer(match):
"""Replace the matched string with a sortable number."""
return f"Data 0{match.group(1)}:"
return re.sub(pattern, replacer, text)
@lru_cache(maxsize=128)
def read_excel_file(file, category, table):
"""Read the ExcelFile for the sheet name and flatten the table."""View on GitHub (pinned to 3e071fcc2c)
Solutions
- Don't call transform_data directly — use the Fetcher class or the OpenBB router so aextract_data runs first.
- If you must build data manually, wrap bytes in ExcelFile(BytesIO(raw)) exactly like download_excel_file does.
- Check that the extract step did not fail (error 325/332 conditions) before transform runs.
- On exception, print type(file) to see what actually arrived.
Example fix
# before
result = EiaPetroleumStatusReport.transform_data(query, {'file': raw_bytes})
# after
from io import BytesIO
from pandas import ExcelFile
result = EiaPetroleumStatusReport.transform_data(query, {'file': ExcelFile(BytesIO(raw_bytes))}) Defensive patterns
Strategy: type-guard
Type guard
from pandas import ExcelFile
def is_extracted_payload(data: dict) -> bool:
return isinstance(data, dict) and isinstance(data.get('file'), ExcelFile) Try / catch
try:
out = EiaPetroleumStatusReport.transform_data(query, data)
except OpenBBError as e:
if 'Expected an ExcelFile object' in str(e):
raise TypeError('transform_data requires the aextract_data payload') from e
raise Prevention
- Use the Fetcher/router so extract runs before transform
- In tests, build payloads with ExcelFile(BytesIO(...)) to match the contract
When it happens
Trigger: Calling EiaPetroleumStatusReport.transform_data directly with a hand-built dict; a mocked/test extract that returned bytes instead of ExcelFile; the download step silently returning an error payload that got stuffed into data['file'].
Common situations: Writing unit tests that fake extract data incorrectly; refactoring the extract/transform pipeline and changing the intermediate contract; upstream changes to download_excel_file's return type.
Related errors
- 'all' is not a supported choice for {category}. Please choos
- Invalid table choice: {table}. Valid choices for {category}:
- Error extracting data -> {e}
- The data is empty.
- Error transforming the data -> {e}
AI-assisted analysis of OpenBB-finance/OpenBB@3e071fcc2c (2026-08-14).
Data as JSON: /api/errors/3c760e21aa25698d.
Report an issue: GitHub.