call_report.fca.FCAInstitutionRegistry#
- class call_report.fca.FCAInstitutionRegistry(*, institutions: Iterable[FCAInstitution])[source]#
Bases:
Mapping[int,FCAInstitution]A read-only mapping of each UNINUM to its FCAInstitution.
Iterating yields UNINUMs in ascending order. Most callers build a registry with from_dataframe or from_rosters rather than from FCAInstitution objects directly.
- Parameters:
- institutionsIterable[FCAInstitution]
The histories making up the registry, in any order.
- Raises:
- InstitutionError
If institutions is empty, or two share a UNINUM.
See also
FCAInstitutionOne UNINUM’s name and address history.
Examples
>>> from call_report.fca import FCAInstitutionRegistry >>> texas = { ... "UNINUM": 610000, ... "SYSTEM": 6, ... "DIST": 10, ... "ASSOC": 0, ... "SHORTNAME": "FCB of Texas", ... "MAIL_ADDR": "P.O. Box 202590", ... "STREET_ADDR": "4801 Plaza on the Lake Drive", ... "CITY": "Austin", ... "STATE": "TX", ... "ZIP": "78746", ... } >>> agfirst = { ... "UNINUM": 620000, ... "SYSTEM": 6, ... "DIST": 20, ... "ASSOC": 0, ... "SHORTNAME": "AgFirst FCB", ... "MAIL_ADDR": "P. O. Box 1499", ... "STREET_ADDR": "1901 Main Street", ... "CITY": "Columbia", ... "STATE": "SC", ... "ZIP": "29201", ... } >>> registry = FCAInstitutionRegistry.from_rosters( ... rosters=[("2026-03-31", [texas, agfirst])] ... ) >>> list(registry) [610000, 620000] >>> registry[620000].most_recent_short_name 'AgFirst FCB'
- classmethod from_rosters(*, rosters: Iterable[tuple[str | date | ReportingPeriod, Any]]) FCAInstitutionRegistry[source]#
Build a registry from FCA institution rosters, one per quarter.
Every row across every roster is grouped by UNINUM, and each group becomes one FCAInstitution. The rosters can arrive in any order.
- Parameters:
- rostersIterable[tuple[str | datetime.date | ReportingPeriod, Any]]
(period, roster)pairs. A roster is either a native dataframe of any backend narwhals supports, such as the result of call_report.fca.institutions.read_institutions, or an iterable of row mappings. Each row must includeUNINUM,SYSTEM,DIST,ASSOC,SHORTNAME,MAIL_ADDR,STREET_ADDR,CITY,STATE, andZIP. Other columns are ignored.
- Returns:
- FCAInstitutionRegistry
One FCAInstitution per UNINUM found in rosters.
- Raises:
- InstitutionError
If rosters holds no rows, names the same quarter twice, or lists a UNINUM more than once in one quarter. Also for any row FCAInstitution.from_roster_rows rejects.
Examples
>>> from call_report.fca import FCAInstitutionRegistry >>> row = { ... "UNINUM": 722825, ... "SYSTEM": 7, ... "DIST": 22, ... "ASSOC": 825, ... "SHORTNAME": "Mid-America ACA", ... "MAIL_ADDR": "P.O. Box 34390", ... "STREET_ADDR": "1601 UPS Drive", ... "CITY": "Louisville", ... "STATE": "KY", ... "ZIP": "40223-4390", ... } >>> renamed = {**row, "SHORTNAME": "Farm Credit Mid-America ACA"} >>> registry = FCAInstitutionRegistry.from_rosters( ... rosters=[("2011-12-31", [renamed]), ("2011-09-30", [row])] ... ) >>> [v.value for v in registry[722825].short_name_history] ['Mid-America ACA', 'Farm Credit Mid-America ACA']
- classmethod from_dataframe(*, data: Any) FCAInstitutionRegistry[source]#
Build a registry from rosters stacked into one frame.
data is one row per UNINUM per quarter, with a
periodcolumn naming each row’s quarter. That is the shape FCACallReport.load_institutions returns, and the shape to_dataframe returns, so a registry round-trips through its own frame. Themost_recent_*columns are derived from the history, so they are ignored on the way in.- Parameters:
- dataAny
A native dataframe of any backend narwhals supports, eager or lazy, with a
periodcolumn and the roster columns from_rosters requires.
- Returns:
- FCAInstitutionRegistry
One FCAInstitution per UNINUM found in data.
- Raises:
- InstitutionError
If data has no
periodcolumn, or for any roster from_rosters rejects.
Examples
>>> from call_report.fca import FCAInstitutionRegistry >>> row = { ... "UNINUM": 722825, ... "SYSTEM": 7, ... "DIST": 22, ... "ASSOC": 825, ... "SHORTNAME": "Mid-America ACA", ... "MAIL_ADDR": "P.O. Box 34390", ... "STREET_ADDR": "1601 UPS Drive", ... "CITY": "Louisville", ... "STATE": "KY", ... "ZIP": "40223-4390", ... } >>> registry = FCAInstitutionRegistry.from_rosters( ... rosters=[("2011-09-30", [row]), ("2011-12-31", [row])] ... ) >>> FCAInstitutionRegistry.from_dataframe(data=registry.to_dataframe()) == ( ... registry ... ) True
- property first_period: ReportingPeriod[source]#
Return the earliest quarter any UNINUM in the registry was reported.
This is the smallest FCAInstitution.first_period in the registry.
- Returns:
- ReportingPeriod
The earliest quarter reported.
Examples
>>> from call_report.fca import FCAInstitutionRegistry >>> row = { ... "UNINUM": 722825, ... "SYSTEM": 7, ... "DIST": 22, ... "ASSOC": 825, ... "SHORTNAME": "Mid-America ACA", ... "MAIL_ADDR": "P.O. Box 34390", ... "STREET_ADDR": "1601 UPS Drive", ... "CITY": "Louisville", ... "STATE": "KY", ... "ZIP": "40223-4390", ... } >>> registry = FCAInstitutionRegistry.from_rosters( ... rosters=[("2011-09-30", [row]), ("2011-12-31", [row])] ... ) >>> registry.first_period.label '2011Q3'
- property last_period: ReportingPeriod[source]#
Return the latest quarter any UNINUM in the registry was reported.
This is the largest FCAInstitution.last_period in the registry.
- Returns:
- ReportingPeriod
The latest quarter reported.
Examples
>>> from call_report.fca import FCAInstitutionRegistry >>> row = { ... "UNINUM": 722825, ... "SYSTEM": 7, ... "DIST": 22, ... "ASSOC": 825, ... "SHORTNAME": "Mid-America ACA", ... "MAIL_ADDR": "P.O. Box 34390", ... "STREET_ADDR": "1601 UPS Drive", ... "CITY": "Louisville", ... "STATE": "KY", ... "ZIP": "40223-4390", ... } >>> registry = FCAInstitutionRegistry.from_rosters( ... rosters=[("2011-09-30", [row]), ("2011-12-31", [row])] ... ) >>> registry.last_period.label '2011Q4'
- as_of(*, period: str | date | ReportingPeriod) Mapping[int, FCAInstitutionSnapshot][source]#
Return the roster values for every UNINUM reported in one quarter.
Charters that did not file in period are left out.
- Parameters:
- periodstr, datetime.date, or ReportingPeriod
The quarter-end to take the snapshot at.
- Returns:
- Mapping[int, FCAInstitutionSnapshot]
A read-only mapping of UNINUM to its snapshot for period, in ascending UNINUM order.
- Raises:
- PeriodNotAvailableError
If no UNINUM in the registry was reported in period.
Examples
>>> from call_report.fca import FCAInstitutionRegistry >>> row = { ... "UNINUM": 722825, ... "SYSTEM": 7, ... "DIST": 22, ... "ASSOC": 825, ... "SHORTNAME": "Mid-America ACA", ... "MAIL_ADDR": "P.O. Box 34390", ... "STREET_ADDR": "1601 UPS Drive", ... "CITY": "Louisville", ... "STATE": "KY", ... "ZIP": "40223-4390", ... } >>> renamed = {**row, "SHORTNAME": "Farm Credit Mid-America ACA"} >>> registry = FCAInstitutionRegistry.from_rosters( ... rosters=[("2011-09-30", [row]), ("2011-12-31", [renamed])] ... ) >>> registry.as_of(period="2011-09-30")[722825].short_name 'Mid-America ACA'
- to_dataframe(*, latest_only: bool = False, backend: Literal['pandas', 'polars', 'pyarrow'] | None = None, dataframe_type: None = None) NativeDataFrame[source]#
- to_dataframe(*, latest_only: bool = False, backend: Literal['pandas', 'polars', 'pyarrow'] | None = None, dataframe_type: Literal['pandas']) pandas.DataFrame
- to_dataframe(*, latest_only: bool = False, backend: Literal['pandas', 'polars', 'pyarrow'] | None = None, dataframe_type: Literal['pyarrow_table']) pyarrow.Table
- to_dataframe(*, latest_only: bool = False, backend: Literal['pandas', 'polars', 'pyarrow'] | None = None, dataframe_type: Literal['polars_dataframe']) polars.DataFrame
- to_dataframe(*, latest_only: bool = False, backend: Literal['pandas', 'polars', 'pyarrow'] | None = None, dataframe_type: Literal['polars_lazyframe']) polars.LazyFrame
Return every UNINUM’s history as one dataframe.
By default this stacks FCAInstitution.to_dataframe for every UNINUM, giving one row per UNINUM per quarter. Join it onto FCACallReport.to_long_format or FCACallReport.to_wide_format output on
UNINUMandperiodto label each row with the name and address in effect that quarter.- Parameters:
- latest_onlybool, default False
Keep only each UNINUM’s last reported quarter, giving one row per UNINUM. The
periodcolumn then holds that last quarter.- backend{“pandas”, “polars”, “pyarrow”}, optional
The dataframe library used to build the frame. If omitted, uses whatever backend is currently configured via call_report.config.get_config. Most users can leave this at its default.
- dataframe_type{“pandas”, “pyarrow_table”, “polars_lazyframe”, “polars_dataframe”}, optional
The dataframe type to convert the result to as a final step, regardless of backend. Leave this
None(the default) to get back whatever backend produced. 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. The conversion is zero-copy when the requested type already matches.
- Returns:
- NativeDataFrame
A native dataframe with the columns FCAInstitution.to_dataframe returns, ordered by
UNINUMand thenperiod.
Examples
>>> from call_report.fca import FCAInstitutionRegistry >>> row = { ... "UNINUM": 722825, ... "SYSTEM": 7, ... "DIST": 22, ... "ASSOC": 825, ... "SHORTNAME": "Mid-America ACA", ... "MAIL_ADDR": "P.O. Box 34390", ... "STREET_ADDR": "1601 UPS Drive", ... "CITY": "Louisville", ... "STATE": "KY", ... "ZIP": "40223-4390", ... } >>> renamed = {**row, "SHORTNAME": "Farm Credit Mid-America ACA"} >>> registry = FCAInstitutionRegistry.from_rosters( ... rosters=[("2011-09-30", [row]), ("2011-12-31", [renamed])] ... ) >>> frame = registry.to_dataframe(dataframe_type="polars_dataframe") >>> frame.height 2 >>> latest = registry.to_dataframe( ... latest_only=True, dataframe_type="polars_dataframe" ... ) >>> latest.select("UNINUM", "period", "SHORTNAME").rows() [(722825, datetime.date(2011, 12, 31), 'Farm Credit Mid-America ACA')]
- to_json(*, indent: int | None = 2) str[source]#
Return the registry as a JSON string.
Each UNINUM’s history is stored in the shape FCAInstitution.to_json produces, in ascending UNINUM order.
- Parameters:
- indentint, optional
Passed through to json.dumps. The default of
2produces human-readable, diffable output. PassNonefor the most compact representation.
- Returns:
- str
A JSON object with one key,
institutions, holding a list of histories.
Examples
>>> from call_report.fca import FCAInstitutionRegistry >>> row = { ... "UNINUM": 722825, ... "SYSTEM": 7, ... "DIST": 22, ... "ASSOC": 825, ... "SHORTNAME": "Mid-America ACA", ... "MAIL_ADDR": "P.O. Box 34390", ... "STREET_ADDR": "1601 UPS Drive", ... "CITY": "Louisville", ... "STATE": "KY", ... "ZIP": "40223-4390", ... } >>> registry = FCAInstitutionRegistry.from_rosters( ... rosters=[("2011-09-30", [row])] ... ) >>> FCAInstitutionRegistry.from_json(text=registry.to_json()) == registry True
- classmethod from_json(*, text: str) FCAInstitutionRegistry[source]#
Reconstruct a registry from JSON built by to_json.
The inverse of to_json. Every history is validated the same way direct construction validates it.
- Parameters:
- textstr
A JSON string in the shape to_json produces.
- Returns:
- FCAInstitutionRegistry
The reconstructed registry.
- Raises:
- InstitutionError
If text is not valid JSON, is not a JSON object, or does not otherwise match the shape to_json produces.
Examples
>>> from call_report.fca import FCAInstitutionRegistry >>> row = { ... "UNINUM": 722825, ... "SYSTEM": 7, ... "DIST": 22, ... "ASSOC": 825, ... "SHORTNAME": "Mid-America ACA", ... "MAIL_ADDR": "P.O. Box 34390", ... "STREET_ADDR": "1601 UPS Drive", ... "CITY": "Louisville", ... "STATE": "KY", ... "ZIP": "40223-4390", ... } >>> text = FCAInstitutionRegistry.from_rosters( ... rosters=[("2011-09-30", [row])] ... ).to_json() >>> list(FCAInstitutionRegistry.from_json(text=text)) [722825]