Library / SDK
datamade/census avatar
datamade/census

census: a Python wrapper that hides the Census Bureau geography rules

A Python wrapper for the US Census API.

682 stars147 forksPythonBSD-3-Clause

At a glance

What is it?
The census package is a thin Python client for the United States Census Bureau API, covering the ACS and SF1 data sets, with convenience methods per geography and a client-side year default. Its weak point is not the code but the lag between data releases and package versions, since the newest tag adds 2023 support and was cut in April 2025.
Who is it for?
census fits a Python analyst who needs ACS or SF1 numbers with the geography spelled out for them, and who is willing to keep a copy of the us package alongside it for FIPS codes. It does not fit a project that needs a data set the wrapper does not expose, or a team that needs the library's release cadence to keep pace with the Census Bureau.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 161 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the wrapper actually wraps

The census package is described in the README as a simple wrapper for the United States Census Bureau's API, providing access to the ACS and SF1 data sets. The scope is narrow by design. There is no data cleaning, no caching layer, no local database and no statistical tooling; the package is a translation layer that turns a Python call into a Census API request and hands back the response. The underlying data set, the variable identifiers and the geography specification all still come from the Census Bureau, and the README points at the Census Data API User Guide for anything more detailed than the convenience methods. For someone who already knows what a table like B25034_010E means, the value is in not having to assemble URLs by hand, and for someone who does not yet know, the convenience methods at least get them to the right call.

A key, a constructor and one dataset object per dataset

The entry point is a Census object built with an API key, and you sign up for that key separately through the Census Bureau's key signup page. Once you have one, the client exposes one attribute per data set, and each attribute carries the years that data set supports. The README lists acs5, acs3 and acs1 for the ACS estimates, acs5dp, acs3dp and acs1dp for the ACS data profiles, acs5st for the subject tables, sf1 for Census Summary File 1, and pl for the Redistricting Data Summary File. The first year listed for each is the default, so a call with no year argument returns the most recent year that data set has. The wrapper also raises census.UnsupportedYearException when a convenience method is called with a year that data set does not support, which is the behaviour the README explicitly warns about: not every geography exists in every year.

get is the core, the helpers are sugar on top

The get method is described as the core data access method on both the ACS and SF1 data sets. It takes a column argument that is either a single string or a tuple of columns, and a geography dict with a for key and an optional in key. The for argument accepts a wildcard character or Census.ALL, and the README notes that the wildcard is not valid for the in parameter. The convenience methods exist because the geography specification can get complicated, and they differ by data set. The ACS5 set has the widest spread, covering state, state_county, state_county_blockgroup, state_county_subdivision, state_county_tract, state_place, congressional and legislative districts, us, and state_zipcode. ACS1 is much thinner, with only state, state_congressional_district and us. SF1 adds state_msa, state_csa and state_district_place, and the PL set adds back block groups and legislative districts. Getting the right one matters, because the year list behind each is different.

Years are per call, per client, or per data set

Three separate levers control which vintage of data you get, and confusing them is the easiest mistake to make. The default is the most recent year available for that data set. A single call can override it with a year parameter, as in the state helper for Maryland with year=2010, and the client itself can be constructed with a year, which then applies across calls. That third option is the one to be careful with, because a client-wide default silently overrides the per-data-set defaults. The year lists in the README show how uneven coverage is: acs5 runs from 2024 back to 2009, acs3 only offers 2013 and 2012, acs1 skips 2020, and sf1 offers 2010 alone while pl covers 2020, 2010 and 2000. There is also a specific gap in the acs1, acs5dp and acs1dp lists, where 2020 is missing while the 5 year estimates have it.

Bringing your own session when the default is not enough

If you need a customised requests.Session, for example to set your own User-Agent header or to route through a proxy, the constructor accepts one. The session can also be replaced on a single data set object afterwards, which is the escape hatch for when only one data set needs the different behaviour. The README shows both forms, creating a session with a headers update and passing it to the constructor, then setting c.sf1.session directly. That per-data-set assignment is worth knowing about, because it means the client is not a single transport, and a diagnostic that changes headers for one data set will not affect the others.

The us package takes over the states module

Geography codes are the part of the Census API that trips people up, and the package has moved that burden to a separate library. The README says the package previously had a census.states module but now uses the us package, which the text recommends installing alongside it since it helps you work out the FIPS codes for many geographies. The examples import states from us and use states.MD.fips for Maryland, and the state lookup works in the other direction too, turning a FIPS code into an abbreviation. A second benefit is the FIPS codes, which are the same identifiers the Census Bureau itself uses to join geography across datasets, so using the same package keeps your keys consistent with the geographic relationship files that the Census developer site publishes for comparing the 1990, 2000 and 2010 censuses.

The install path, and what a first call looks like

Installation is a pip install, and the recommended companion is the us package.

bash
pip install census
bash
pip install us

A first call builds the client with your key, then asks for a column and a geography.

python
from census import Census
from us import states

c = Census("MY_API_KEY")
c.acs5.get(('NAME', 'B25034_010E'),
          {'for': 'state:{}'.format(states.MD.fips)})

The README explains that this returns the name of the geographic area and the number of homes built before 1939 for Maryland. The convenience method does the same thing with less typing, since c.acs5.state(('NAME', 'B25034_010E'), states.MD.fips) is the shortcut for the same query, and earlier vintages come from adding year=2010 to that call.

A thin package with a lagging release trail

The repository is a single census/ package directory with the usual packaging files: setup.py and setup.cfg alongside pyproject.toml, requirements.txt, MANIFEST.in, CITATION.cff and a LICENSE, and the default branch is master. The dependency list is short, requests at 2.31 or newer and pytest at 2.9 or newer, which is consistent with a wrapper that does not want to constrain the environment it runs in. Licence is BSD-3-Clause, which is the permissive choice you want for a library that ends up inside other people's analysis scripts. The maintenance picture is the part to weigh. The last push to the repository was on 2026-05-15, and the release tags tell a slower story: v0.8.24 adds 2023 support and dates from 2025-04-08, v0.8.22 adds 2022 support from 2024-06-03, and v0.8.19 adds 2020 ACS support from 2022-04-27. The gap between a data set appearing and a tag shipping it is the practical risk. A wrapper that names itself after the API will always lag the API, and when a new vintage of the ACS lands, the default year in the wrapper may not be the newest one the Bureau publishes.

Editorial conclusion

census fits a Python analyst who needs ACS or SF1 numbers with the geography spelled out for them, and who is willing to keep a copy of the us package alongside it for FIPS codes. It does not fit a project that needs a data set the wrapper does not expose, or a team that needs the library's release cadence to keep pace with the Census Bureau. Before you depend on it, check the year list for the data set you need, since the newest tag, v0.8.24, adds 2023 support while the package also lists 2024 as a default, and confirm the key you sign up for is one you can keep, since the API key is passed straight into the constructor.

Frequently asked questions

How do I install the census Python package?

The README gives pip install census, and it recommends also installing the us package, which supplies the FIPS codes used for many geographies. The wrapper itself needs an API key from the Census Bureau's key signup page, passed to the Census constructor.

What is the difference between c.acs5.get and c.acs5.state?

get is the core access method, taking a column or tuple of columns and a geography dict with a for key and an optional in key. The convenience methods such as state are wrappers for common geographies, and the for argument also accepts a wildcard or Census.ALL, though the wildcard does not work for the in parameter.

How do I request an older year of Census data?

Pass a year parameter to the call, for example c.acs5.state(('NAME', 'B25034_010E'), states.MD.fips, year=2010), or set a default for the whole client with Census("MY_API_KEY", year=2010). Calling a convenience method with a year that the data set does not support raises census.UnsupportedYearException.

Which data sets does the census package expose?

The ACS estimates as acs5, acs3 and acs1, the data profiles as acs5dp, acs3dp and acs1dp, subject tables as acs5st, Census Summary File 1 as sf1, and the Redistricting Data Summary File as pl. The first year listed for each data set in the README is the default year.

Can I use my own requests session with census?

Yes. A custom configured session can be passed to the Census constructor, and the session can also be replaced for a single data set object, for example c.sf1.session = s, so different data sets can use different transport settings.

Official sources

  1. datamade/census on GitHub
  2. Issues
  3. License: BSD-3-Clause
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/datamade-census.svg)](https://hysenlabs.com/projects/datamade-census)

Was this useful?