georest.usfs.vocab¶
Cached, searchable vocabularies for the FIADB-API.
FIADB-API’s /fullreport takes an estimate attribute, a row grouping,
a column grouping, and an evaluation. Live counts, measured against the
API:
Parameter |
Count |
What it selects |
|---|---|---|
|
752 |
Estimate attribute (numerator/denominator) |
|
96 |
Grouping variable (row / column / page) |
|
1143 |
Evaluation (state + year + eval group) |
That is a combinatorial space no one memorizes, and the published docs
still say “This page is under construction”. Nothing in the official
documentation mentions that the parameter endpoints accept
outputFormat=JSON, but they do, and that is what makes discovery
possible at all: the entire vocabulary is machine-readable, about 1.4 MB
in total, and changes per release rather than per query.
So it is cached, and search runs locally: a bundled snapshot ships with the package, a refreshed copy lives in a user cache, and the cache is revalidated after about 30 days.
Failure is always backward, never forward. A vocabulary lookup falls from user cache, to bundled snapshot, to an empty result. It does not raise, and it does not block on the network. Discovery is what people do before they know what they want; making it fragile makes the whole package feel fragile.
Copyright 2026 Ryan Rock and Ian Housman
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Module Attributes
FIA parameter catalogs, by the query-parameter name they populate. |
|
Aliases onto the three fetched catalogs. |
|
Refresh interval. |
Functions
Directory for refreshed catalogs. |
|
|
Prose documentation for a grouping variable, codes included. |
|
Search the 752 FIA estimate attributes. |
|
Search the 1,143 FIA evaluations. |
|
Search the 96 FIA grouping variables. |
|
Full record for one attribute number, or None. |
|
Full record for one evaluation group, or None. |
Every grouping label, exactly as |
|
|
Return one vocabulary, from memory, cache, bundle, or the network. |
|
Force-refresh every catalog. |
- georest.usfs.vocab.FIA_CATALOGS = ('snum', 'rselected', 'wc')¶
FIA parameter catalogs, by the query-parameter name they populate.
sdenomsharessnum’s vocabulary andcselected/pselectedsharerselected’s, so only the distinct ones are fetched.
- georest.usfs.vocab.FIA_CATALOG_ALIASES = {'cselected': 'rselected', 'pselected': 'rselected', 'sdenom': 'snum'}¶
Aliases onto the three fetched catalogs.
- georest.usfs.vocab.CACHE_TTL_SECONDS = 2592000¶
Refresh interval. These change when FIA publishes a new evaluation cycle, an annual-ish cadence, so 30 days picks changes up well before anyone notices and keeps the network essentially off the hot path.
- georest.usfs.vocab.cache_dir() Path[source]¶
Directory for refreshed catalogs.
~/.georest/usfs, beside the ArcGIS sign-in that georest keeps in~/.georest. Overridable withGEOREST_USFS_CACHEfor tests and for locked-down machines where the home directory is not writable.Example:
from georest.usfs import vocab vocab.cache_dir() # Path to ~/.georest/usfs in your home directory
- georest.usfs.vocab.load_catalog(name: str, *, refresh: bool = False) list[dict][source]¶
Return one vocabulary, from memory, cache, bundle, or the network.
- Parameters:
name – A catalog or alias: any of
snum,sdenom,rselected,cselected,pselected,wc.refresh – Force a network fetch, ignoring the TTL. Still falls back to cached data if the fetch fails.
- Returns:
List of records. Empty only when every source failed, which means discovery degrades rather than breaking.
Example:
from georest.usfs import vocab rows = vocab.load_catalog("wc") # every FIA evaluation, as dicts len(rows), sorted(rows[0])[:4]
- georest.usfs.vocab.refresh_all(*, quiet: bool = False) dict[str, int][source]¶
Force-refresh every catalog. Returns
{name: record_count}.The escape hatch for “a new evaluation just dropped and I do not want to wait out the TTL”. Normal use should never need it.
Example:
from georest.usfs import vocab vocab.refresh_all() # prints each catalog's record count; returns {name: count}
- georest.usfs.vocab.find_attributes(query: str = '', *, land_basis: str = '', eval_typ: str = '', limit: int | None = None) Any[source]¶
Search the 752 FIA estimate attributes.
- Parameters:
query – Free text matched against description and group, e.g.
"carbon","net growth volume","mortality".land_basis – Restrict to
"Forest land"or"Timberland".eval_typ – Restrict to an evaluation type:
EXPCURR,EXPVOL,EXPGROW,EXPMORT,EXPREMV,EXPCHNG,EXPDWM.limit – Return at most this many rows. By default every match is returned, best first.
- Returns:
A
pandas.DataFramewith the columns that matter for choosing an attribute: number, description, units, and the evaluation type it requires. The full record is available viaget_attribute().
Note
FIA’s own catalog contains duplicate descriptions: 7 of the 752 appear more than once.
snum209 and 956, for instance, are identical across description, estimate group, evaluation type, estimation basis and tree portion. Both are returned rather than silently de-duplicated, because they are distinct attribute numbers upstream and collapsing them would hide a real property of the catalog. Where descriptions match on every field, either number should produce the same estimate.Example:
from georest.usfs import fia # Every carbon attribute measured on forest land, best match first fia.find_attributes("carbon", land_basis="Forest land") # Attributes that need growth accounting (growth, removals, mortality) fia.find_attributes("mortality", eval_typ="EXPMORT")
- georest.usfs.vocab.get_attribute(snum: int) dict | None[source]¶
Full record for one attribute number, or None.
Example:
from georest.usfs import fia fia.get_attribute(2)["ATTRIBUTE_DESCR"] # 'Area of forest land, in acres'
- georest.usfs.vocab.find_groupings(query: str = '', *, limit: int | None = None) Any[source]¶
Search the 96 FIA grouping variables.
These are what
rselected/cselected/pselectedaccept, and they are passed as display strings, so the exactlabelin this result is what the query needs, character for character.- Parameters:
query – Free text matched against the label and database column.
limit – Return at most this many rows. By default every match is returned, best first.
Example:
from georest.usfs import fia fia.find_groupings("owner") # labels to pass as rselected= / cselected=
- georest.usfs.vocab.grouping_labels() list[str][source]¶
Every grouping label, exactly as
rselectedand friends need it.Example:
from georest.usfs import vocab "Forest type group" in vocab.grouping_labels() # True
- georest.usfs.vocab.describe_grouping(label: str) str[source]¶
Prose documentation for a grouping variable, codes included.
FIA ships this as
PRC_METADATA, an HTML fragment that usually enumerates what each code value means. It is the difference between a column of integers and a column you can interpret, so it is worth surfacing rather than leaving buried in the catalog.Example:
from georest.usfs import fia # What each code of a grouping means, as plain text fia.describe_grouping("Ownership group - Major")
- georest.usfs.vocab.find_evaluations(state: str = '', *, most_recent: bool = True, growth_only: bool = False, limit: int | None = None) Any[source]¶
Search the 1,143 FIA evaluations.
- Parameters:
state – State name, matched case-insensitively on a prefix.
most_recent – Keep only each state’s current evaluation. Almost always what you want; set False to see the back catalog.
growth_only – Keep only evaluations with growth accounting (
GROWTH_ACCT == 'Y'), which is a prerequisite for every growth, removals, and mortality attribute.limit – Return at most this many rows. By default every match is returned.
Example:
from georest.usfs import fia fia.find_evaluations("Oregon") # the current inventory fia.find_evaluations("Oregon", most_recent=False) # and every earlier one fia.find_evaluations("Oregon", growth_only=True) # usable for growth and mortality