call_report.fca.FCACallReport#

class call_report.fca.FCACallReport(*, start: str | date, end: str | date | None = None, schema_policy: Literal['union', 'intersection', 'strict'] = 'union', transport: FCATransport)[source]#

Bases: BaseCallReport

The estimator-style entry point for FCA Call Report data.

Follows the sklearn convention. __init__ only stores its parameters, doing no validation or I/O. fetch validates those parameters and resolves release files, populating trailing-underscore attributes. The load-family methods call fetch automatically if it has not run yet.

Parameters:
startstr or datetime.date

The first quarter-end in the requested range.

endstr or datetime.date, optional

The last quarter-end in the requested range (inclusive). Must be supplied explicitly. There is no single-quarter default, so a request’s bounds are never ambiguous.

schema_policy{“union”, “intersection”, “strict”}, default “union”

How to reconcile schema differences when stacking multiple periods’ data together for one schedule.

transportFCATransport

The transport used to resolve each period’s local files, e.g. a LocalDirectoryTransport pointed at a directory of already-extracted releases, or a PackagedArchiveTransport for the historical releases shipped with this repository.

Examples

>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> frame = report.load(schedule="RCB")
>>> frame.shape
(2240, 12)
fetch() Self[source]#

Validate parameters and resolve every requested period’s files.

Populates periods_, releases_, schedules_, and errors_. A period that is within FCA’s catalog bounds but whose local files cannot be resolved is skipped and recorded in errors_ rather than aborting the whole call. An out-of-bounds request, or one missing end, is an immediate error, since neither is a partial-data situation.

Returns:
Self

This instance, to support method chaining.

Raises:
InvalidPeriodError

If end was not supplied, or start/end is not a valid quarter-end date.

PeriodNotAvailableError

If the requested range falls outside FCA’s known-published bounds.

DownloadError

If every requested period failed to resolve.

Examples

>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> report.fetch() is report
True
>>> report.periods_
PeriodRange(start='2026Q1', end='2026Q1')
get_layout(*, schedule: FCASchedule | str, period: str | date | ReportingPeriod | None = None) FCALayout | dict[ReportingPeriod, FCALayout][source]#

Return a schedule’s layout for one period, or for every period in range.

Layouts can drift across periods, so callers can inspect either a single period’s layout or how it evolved across the whole range.

Parameters:
scheduleFCASchedule or str

The schedule to describe. A string is matched case-insensitively.

periodstr, datetime.date, ReportingPeriod, optional

A specific period to describe. If omitted, returns the layout for every period in the requested range that has schedule.

Returns:
FCALayout or dict[ReportingPeriod, FCALayout]

A single layout if period was supplied, otherwise a mapping from period to layout.

Raises:
InvalidPeriodError

If period was supplied but falls outside the fetched range.

ScheduleNotFoundError

If schedule is not present for the requested period (or, if period was omitted, for any period in range).

Examples

>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> layout = report.get_layout(schedule="RCB", period="2026-03-31")
>>> layout.scenario
'single_multiple'
get_schema(*, schedule: FCASchedule | str, period: str | date | ReportingPeriod | None = None) FieldSchema | dict[ReportingPeriod, FieldSchema][source]#

Return a schedule’s canonical schema as of one period, or every period.

The point-in-time counterpart to get_file_metadata: the fields the package believes schedule had at a given quarter, each narrowed to the definition that applied then rather than today’s. Pairs with get_layout, which returns what a fetched release actually declared, so the two can be compared on identical arguments.

Parameters:
scheduleFCASchedule or str

The schedule to describe. A string is matched case-insensitively.

periodstr, datetime.date, ReportingPeriod, optional

A specific period to describe. If omitted, returns the schema for every period in the requested range that has schedule.

Returns:
FieldSchema or dict[ReportingPeriod, FieldSchema]

A single schema if period was supplied, otherwise a mapping from period to schema.

Raises:
InvalidPeriodError

If period was supplied but falls outside the fetched range.

ScheduleNotFoundError

If schedule is not present for the requested period (or, if period was omitted, for any period in range).

PeriodNotAvailableError

If a fetched release has schedule for a period the canonical metadata says it was not published in. That is a disagreement between the release and the shipped metadata, not a missing schedule, so it is reported as its own error.

Examples

>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> schema = report.get_schema(schedule="RCB", period="2026-03-31")
>>> schema.names[:3]
('SYSTEM', 'DIST', 'ASSOC')
>>> schema["UNINUM"].versions[0].periods[0].label
'2026Q1'
get_file_metadata(*, schedule: FCASchedule | str) FileMetadata[source]#

Return a schedule’s canonical, cross-time field metadata.

This is the metadata this package ships, generated from FCA’s own published archives, covering the schedule’s whole known history rather than one period. It does not depend on this instance’s start, end, or transport, so it does not require fetch to have run. Use get_schema for a single period’s snapshot, or get_layout for what a fetched release actually declared.

Parameters:
scheduleFCASchedule or str

The schedule to describe. A string is matched case-insensitively.

Returns:
FileMetadata

schedule’s canonical, cross-time field metadata.

Raises:
ScheduleNotFoundError

If schedule does not name a known FCA schedule.

Examples

>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> metadata = report.get_file_metadata(schedule="RCB")
>>> metadata.first_period.label
'2000Q1'
>>> metadata.last_period.label
'2026Q1'
available_periods() tuple[ReportingPeriod, ...][source]#

Return every period FCA is known to publish.

Reflects FCA’s overall catalog (call_report.fca.catalog), independent of this instance’s start and end. It does not require fetch to have run.

Returns:
tuple[ReportingPeriod, …]

The known-available periods, oldest first.

Examples

>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> periods = report.available_periods()
>>> periods[0].label
'2000Q1'
>>> periods[-1].label
'2026Q1'
available_schedules() tuple[FCASchedule, ...][source]#

Return every schedule FCA’s format has ever used.

Does not require fetch to have run.

Returns:
tuple[FCASchedule, …]

Every FCASchedule member.

Examples

>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> schedules = report.available_schedules()
>>> len(schedules)
37
>>> schedules[:3]
(<FCASchedule.RC: 'RC'>, <FCASchedule.RC1: 'RC1'>, <FCASchedule.RCB: 'RCB'>)
available_domain_datasets() tuple[FCADomainDataset, ...][source]#

Return every curated domain dataset this package ships.

The domain-dataset counterpart to available_schedules. Does not require fetch to have run.

Returns:
tuple[FCADomainDataset, …]

Every FCADomainDataset member.

Examples

>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> report.available_domain_datasets()
(<FCADomainDataset.LOAN_PORTFOLIO: 'loan_portfolio'>,)
periods_available(*, schedule: FCASchedule | str) tuple[ReportingPeriod, ...][source]#

Return the requested periods in which a schedule is present.

The complement of periods_missing for the same schedule.

Parameters:
scheduleFCASchedule or str

The schedule to check. A string is matched case-insensitively.

Returns:
tuple[ReportingPeriod, …]

The subset of periods_ that have schedule.

Examples

>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> report.periods_available(schedule="RCB")
(ReportingPeriod(year=2026, quarter=<Quarter.Q1: 1>),)
periods_missing(*, schedule: FCASchedule | str) tuple[ReportingPeriod, ...][source]#

Return the requested periods in which a schedule is absent.

The complement of periods_available for the same schedule.

Parameters:
scheduleFCASchedule or str

The schedule to check. A string is matched case-insensitively.

Returns:
tuple[ReportingPeriod, …]

The subset of periods_ that do not have schedule.

Examples

>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> report.periods_missing(schedule="RCB")
()
to_wide_format(*, schedules: Iterable[FCASchedule | str] | None = None, dataframe_type: None = None) NativeDataFrame[source]#
to_wide_format(*, schedules: Iterable[FCASchedule | str] | None = None, dataframe_type: Literal['pandas']) pandas.DataFrame
to_wide_format(*, schedules: Iterable[FCASchedule | str] | None = None, dataframe_type: Literal['pyarrow_table']) pyarrow.Table
to_wide_format(*, schedules: Iterable[FCASchedule | str] | None = None, dataframe_type: Literal['polars_dataframe']) polars.DataFrame
to_wide_format(*, schedules: Iterable[FCASchedule | str] | None = None, dataframe_type: Literal['polars_lazyframe']) polars.LazyFrame

Stack every loaded schedule into one wide, (UNINUM, period)-grain frame.

Produces one row per institution per period and one column per schedule variable. A plain (non-code) field becomes {schedule}__{variable}. A field that repeats once per reported code becomes {schedule}__{code_column}_{code_value}__{variable} (e.g. RCB__INV_CODE_15__BKVAL). Works on every configured dataframe backend, including pyarrow, which lacks a native pivot (see call_report.core._backend.pivot).

Parameters:
schedulesIterable[FCASchedule or str], optional

The schedules to include. Each is matched case-insensitively. Leave this None (the default) to include every schedule discovered across the requested periods.

dataframe_type{“pandas”, “pyarrow_table”, “polars_lazyframe”, “polars_dataframe”}, optional

The dataframe type to convert the result to as a final step. Leave this None (the default) to get back whatever backend call_report.config.get_config currently has configured. Set it when the code that consumes this result needs a specific type, for example a pandas DataFrame while the package is configured to use polars.

Returns:
NativeDataFrame

A native dataframe of the configured backend, or of dataframe_type if it was supplied.

Raises:
ScheduleNotFoundError

If schedules resolves to zero schedules, or an explicitly named schedule has zero surviving periods.

ReshapeError

If, after melting every included schedule, the same (UNINUM, period, column) combination has more than one value, for example because of a duplicated row in the source data.

Examples

>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> wide = report.to_wide_format(schedules=["RC", "RCB"])
>>> "RCB__INV_CODE_15__BKVAL" in wide.columns
True
to_long_format(*, schedules: Iterable[FCASchedule | str] | None = None, dataframe_type: None = None) NativeDataFrame[source]#
to_long_format(*, schedules: Iterable[FCASchedule | str] | None = None, dataframe_type: Literal['pandas']) pandas.DataFrame
to_long_format(*, schedules: Iterable[FCASchedule | str] | None = None, dataframe_type: Literal['pyarrow_table']) pyarrow.Table
to_long_format(*, schedules: Iterable[FCASchedule | str] | None = None, dataframe_type: Literal['polars_dataframe']) polars.DataFrame
to_long_format(*, schedules: Iterable[FCASchedule | str] | None = None, dataframe_type: Literal['polars_lazyframe']) polars.LazyFrame

Stack every loaded schedule into one long, tidy-shaped frame.

Produces one row per (UNINUM, period, schedule, code_column, code_value, variable_name). A plain (non-code) field has code_column and code_value null and is_multiple False. A field that repeats once per reported code has them set to the code’s field name and value, with is_multiple True, matching ~call_report.fca.layout.FCALayout’s own “single”/”multiple” scenario vocabulary. value, and code_value when present, is always Float64, the most generic type that represents every schedule’s measures. See ~call_report.fca.convert_long_format_to_wide_format to pivot this back to to_wide_format’s shape.

Columns are always returned in the order UNINUM, period, schedule, code_column, code_value, variable_name, value, is_multiple. That order is part of the contract, so a positional read of this frame matches one built by the other route.

Parameters:
schedulesIterable[FCASchedule or str], optional

The schedules to include. Each is matched case-insensitively. Leave this None (the default) to include every schedule discovered across the requested periods.

dataframe_type{“pandas”, “pyarrow_table”, “polars_lazyframe”, “polars_dataframe”}, optional

The dataframe type to convert the result to as a final step. Leave this None (the default) to get back whatever backend call_report.config.get_config currently has configured. Set it when the code that consumes this result needs a specific type, for example a pandas DataFrame while the package is configured to use polars.

Returns:
NativeDataFrame

A native dataframe of the configured backend, or of dataframe_type if it was supplied.

Raises:
ScheduleNotFoundError

If schedules resolves to zero schedules, or an explicitly named schedule has zero surviving periods.

ReshapeError

If (UNINUM, period, schedule, code_column, code_value, variable_name) is not a unique grain, for example because of a duplicated row in the source data.

Examples

>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> long = report.to_long_format(schedules=["RC", "RCB"])
>>> list(long.columns)
['UNINUM', 'period', 'schedule', 'code_column', 'code_value', 'variable_name', 'value', 'is_multiple']
get_params(*, deep: bool = True) dict[str, Any][source]#

Return this instance’s constructor parameters and current values.

Parameter names are discovered by introspecting the concrete subclass’s __init__ signature, so subclasses never need to redeclare them here.

Parameters:
deepbool, default True

Reserved for future nested-estimator composition, matching the sklearn convention. It has no effect for the sources currently in this package.

Returns:
dict[str, Any]

A mapping from constructor parameter name to its current value.

Examples

>>> from call_report.fca import FCACallReport
>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> report.get_params()["start"]
'2026-03-31'
>>> sorted(report.get_params())
['end', 'schema_policy', 'start', 'transport']
load(*, schedule: Any, dataframe_type: DataFrameType | None = None) NativeDataFrame[source]#

Load a single schedule, stacked across every requested period.

Concrete sources implement _load rather than this method. load itself cannot be overridden, so every source applies dataframe_type the same way, in one place.

Parameters:
scheduleAny

The schedule to load, in whatever form the concrete source accepts (typically an enum member or a case-insensitive name).

dataframe_type{“pandas”, “pyarrow_table”, “polars_lazyframe”, “polars_dataframe”}, optional

The dataframe type to convert the result to as a final step. Leave this None (the default) to get back whatever backend call_report.config.get_config currently has configured. Set it when the code that consumes this result needs a specific type, for example a pandas DataFrame while the package is configured to use polars.

Returns:
NativeDataFrame

A native dataframe of the configured backend, or of dataframe_type if it was supplied.

Examples

>>> from call_report.fca import FCACallReport
>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> frame = report.load(schedule="RCB")
>>> frame.shape
(2240, 12)
load_all(*, dataframe_type: Literal['pandas', 'pyarrow_table', 'polars_lazyframe', 'polars_dataframe'] | None = None) dict[Any, Any][source]#

Load every schedule discovered across the requested periods.

Equivalent to calling load once per schedule returned by available_schedules that is actually present in range. Concrete sources implement _load_all rather than this method. load_all itself cannot be overridden, so every source applies dataframe_type the same way, in one place.

Parameters:
dataframe_type{“pandas”, “pyarrow_table”, “polars_lazyframe”, “polars_dataframe”}, optional

The dataframe type to convert every result to. Leave this None (the default) to get back whatever backend call_report.config.get_config currently has configured.

Returns:
dict[Any, NativeDataFrame]

A mapping from schedule to its stacked native dataframe.

Examples

>>> from call_report.fca import FCACallReport
>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> frames = report.load_all()
>>> len(frames)
35
load_institutions(*, dataframe_type: DataFrameType | None = None) NativeDataFrame[source]#

Load the institution roster, stacked across every requested period.

The roster is handled separately from load since it describes institutions themselves rather than a financial schedule. Concrete sources implement _load_institutions rather than this method. load_institutions itself cannot be overridden, so every source applies dataframe_type the same way, in one place.

Parameters:
dataframe_type{“pandas”, “pyarrow_table”, “polars_lazyframe”, “polars_dataframe”}, optional

The dataframe type to convert the result to as a final step. Leave this None (the default) to get back whatever backend call_report.config.get_config currently has configured. Set it when the code that consumes this result needs a specific type, for example a pandas DataFrame while the package is configured to use polars.

Returns:
NativeDataFrame

A native dataframe of the configured backend, or of dataframe_type if it was supplied.

Examples

>>> from call_report.fca import FCACallReport
>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> institutions = report.load_institutions()
>>> institutions.shape
(64, 13)
set_params(**params: Any) Self[source]#

Update one or more constructor parameters in place.

This does not re-run fetch, so any previously fetched state becomes stale until fetch is called again.

Parameters:
**paramsAny

Parameter name/value pairs. Each name must be one of this instance’s constructor parameters.

Returns:
Self

This instance, to support method chaining.

Raises:
ValueError

If a name in params is not a valid constructor parameter.

Examples

>>> from call_report.fca import FCACallReport
>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> report.set_params(schema_policy="strict") is report
True
>>> report.schema_policy
'strict'
to_code_grain_format(*, schedules: Iterable[FCASchedule | str] | None = None, dataframe_type: None = None) NativeDataFrame[source]#
to_code_grain_format(*, schedules: Iterable[FCASchedule | str] | None = None, dataframe_type: Literal['pandas']) pandas.DataFrame
to_code_grain_format(*, schedules: Iterable[FCASchedule | str] | None = None, dataframe_type: Literal['pyarrow_table']) pyarrow.Table
to_code_grain_format(*, schedules: Iterable[FCASchedule | str] | None = None, dataframe_type: Literal['polars_dataframe']) polars.DataFrame
to_code_grain_format(*, schedules: Iterable[FCASchedule | str] | None = None, dataframe_type: Literal['polars_lazyframe']) polars.LazyFrame

Stack every loaded schedule at the grain of the code it reports.

The third architecture, alongside to_wide_format and to_long_format. Produces one row per (UNINUM, period, code_column, code_value) and one {schedule}__{variable} column per variable, so the code stays a row key that can be filtered and grouped on instead of being folded into hundreds of column names. Two schedules reporting at the same code contribute columns to the same row, which is what a sub-architecture such as a loan-portfolio dataset needs.

Only code-bearing schedules take part. A "single"-scenario schedule (~call_report.fca.layout.FCALayout’s own vocabulary) reports no code, so it has no code grain. Leaving schedules unset skips those, the same leniency None already has elsewhere. Naming one explicitly is an error instead, since the request cannot be honored. A single_multiple_single schedule’s trailing single-occurrence fields are institution-level in the same way and are dropped too.

Schedules whose code columns differ are stacked, not joined. code_column is part of the grain, so RCB’s INV_CODE rows and RCF’s LOANSTATUS rows coexist, each populating only its own schedule’s columns. Two schedules can even share a code column name while using different code universes (RCF’s LOANSTATUS is a performance status, RCF1’s is a loan portfolio), which the schedule-prefixed column names keep separable.

Parameters:
schedulesIterable[FCASchedule or str], optional

The schedules to include. Each is matched case-insensitively. Leave this None (the default) to include every schedule discovered across the requested periods.

dataframe_type{“pandas”, “pyarrow_table”, “polars_lazyframe”, “polars_dataframe”}, optional

The dataframe type to convert the result to as a final step. Leave this None (the default) to get back whatever backend call_report.config.get_config currently has configured. Set it when the code that consumes this result needs a specific type, for example a pandas DataFrame while the package is configured to use polars.

Returns:
NativeDataFrame

A native dataframe of the configured backend, or of dataframe_type if it was supplied.

Raises:
ScheduleNotFoundError

If schedules resolves to zero code-bearing schedules, or an explicitly named schedule has zero surviving periods.

ReshapeError

If an explicitly named schedule has no code column, or if (UNINUM, period, code_column, code_value, column) is not a unique grain, for example because of a duplicated row in the source data.

Examples

>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> code_grain = report.to_code_grain_format(schedules=["RCB", "RCF1"])
>>> list(code_grain.columns)[:4]
['UNINUM', 'period', 'code_column', 'code_value']
to_domain_dataset(*, domain_dataset: FCADomainDataset | str, include_totals: bool = False, wide: bool = False, dataframe_type: None = None) NativeDataFrame[source]#
to_domain_dataset(*, domain_dataset: FCADomainDataset | str, include_totals: bool = False, wide: bool = False, dataframe_type: Literal['pandas']) pandas.DataFrame
to_domain_dataset(*, domain_dataset: FCADomainDataset | str, include_totals: bool = False, wide: bool = False, dataframe_type: Literal['pyarrow_table']) pyarrow.Table
to_domain_dataset(*, domain_dataset: FCADomainDataset | str, include_totals: bool = False, wide: bool = False, dataframe_type: Literal['polars_dataframe']) polars.DataFrame
to_domain_dataset(*, domain_dataset: FCADomainDataset | str, include_totals: bool = False, wide: bool = False, dataframe_type: Literal['polars_lazyframe']) polars.LazyFrame

Build one curated domain dataset over the requested periods.

A domain dataset is a view this package curates rather than derives: which schedules compose it, which code each row is keyed by, and what every output column is called are all chosen. Rows are keyed by (UNINUM, period, code_column, code_value), and each column is named for what it measures, such as charge_off or allowance, with no schedule prefix, unlike to_code_grain_format. Use call_report.fca.get_domain_dataset_codes to turn the codes into names.

Only the schedules a dataset declares are loaded, and only those of them present in the requested range. A range that spans a schedule split loads both sides and keeps the series in one column.

Parameters:
domain_datasetFCADomainDataset or str

The domain dataset to look up. A string is matched case-insensitively.

include_totalsbool, default False

Whether to keep the codes the dataset marks as reported subtotals. The default excludes them, so an aggregation over every returned row does not double count. Set this True to also get the source’s own reported subtotal rows.

widebool, default False

Whether to pivot every code into its own set of columns. The default keys rows by (UNINUM, period, code_column, code_value), one column per measure. Set this True to key rows by (UNINUM, period) alone, with one column per {code_value}__{measure} combination, e.g. 100__accruing.

dataframe_type{“pandas”, “pyarrow_table”, “polars_lazyframe”, “polars_dataframe”}, optional

The dataframe type to convert the result to as a final step. Leave this None (the default) to get back whatever backend call_report.config.get_config currently has configured. Set it when the code that consumes this result needs a specific type, for example a pandas DataFrame while the package is configured to use polars.

Returns:
NativeDataFrame

A native dataframe of the configured backend, or of dataframe_type if it was supplied.

Raises:
DomainDatasetNotFoundError

If domain_dataset does not name a shipped dataset.

ScheduleNotFoundError

If none of the dataset’s schedules is present in any requested period.

ReshapeError

If the resulting grain ((UNINUM, period, code_column, code_value, column), or (UNINUM, period, column) when wide is True) is not unique, for example because of a duplicated row in the source data.

Examples

>>> from call_report.fca.transport import PackagedArchiveTransport
>>> report = FCACallReport(
...     start="2026-03-31",
...     end="2026-03-31",
...     transport=PackagedArchiveTransport(),
... )
>>> loans = report.to_domain_dataset(domain_dataset="loan_portfolio")
>>> list(loans.columns)[:4]
['UNINUM', 'period', 'code_column', 'code_value']
>>> agribusiness = loans[
...     (loans["UNINUM"] == 620000) & (loans["code_value"] == 110.0)
... ].iloc[0]
>>> float(agribusiness["accruing"])
3265454.0
>>> wide = report.to_domain_dataset(
...     domain_dataset="loan_portfolio", wide=True
... )
>>> "110__accruing" in wide.columns
True