Skip to content

Repository files navigation

eCFR Analyzer

An analytics platform that monitors the Electronic Code of Federal Regulations (eCFR), providing real-time insights into regulatory evolution across federal agencies.

ecfr

Functionality

Word Counts

https://ecfr-analyzer-chi.vercel.app/word-counts

http://localhost:3000/word-counts

  1. Agency Word Counts: A visualization of word counts across federal agencies, featuring:
    • Interactive bar chart with horizontal/vertical toggle
    • Raw data display option
    • Calculates aggregate word counts for agencies and their subordinate organizations
    • Comprehensive agency hierarchy representation by word count
    • Scrapes agency word counts from the eCFR API versioner endpoint and saves them to the database

components/ecfr/WordCountDisplay.tsx

components/ecfr/BarChart.tsx

Word Counts

Word Counts

Agency Titles & Text

https://ecfr-analyzer-chi.vercel.app/agency-titles

http://localhost:3000/agency-titles

  1. Agency CFR Titles & Text: An advanced search interface that:
    • Parses complex CFR references (title/subtitle/chapter/subchapter/part/subpart/section) from source XML and matches them to agency regulations
    • Displays mapped truncated subset text of all related CFR references
    • Leverages scraped data to display agency word counts along with the full text of all related CFR titles

Agency Titles React Component

Agency Titles

Agency Titles Multiple

Title Compare/Diff

https://ecfr-analyzer-chi.vercel.app/title-compare

http://localhost:3000/title-compare

  1. Historical Title Changes: A comparison tool that:
    • Allows selection of specific titles and date ranges
    • Fetches and parses XML data directly from the eCFR API
    • Provides visual diff analysis of regulatory changes of title between selected dates
    • Displays the full text of the CFR title between the selected dates

Title Compare React Component

Title Compare

Stack

Development

Local

http://localhost:3000

Prod

https://ecfr-analyzer-chi.vercel.app/

Devops

Backend

Django REST API backend deployed to https://ecfr-analyzer-production.up.railway.app/api/ through Railway

https://github.com/railwayapp-templates/django/tree/main

Frontend

Next.js/React with TypeScript frontend deployed to https://ecfr-analyzer-chi.vercel.app/ through Vercel

https://nextjs.org/docs/app/api-reference/cli/create-next-app

Database

PostgreSQL database through Supabase

Schema

Schema

Django Models

Getting Started

$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
$ brew install bun uv biome ruff
$ brew install --cask postgres-unofficial
$ export PATH=/Applications/Postgres.app/Contents/Versions/@latest/bin/:$PATH
$ git clone git@github.com:JohnDDuncanIII/ecfr-analyzer.git
$ bun install
$ cd ecfr-django
$ uv sync

Getting Started

Running the app

Core

<new tab>
$ cd ecfr-analyzer
$ bun --bun run dev
<new tab>
$ cd ecfr-analyzer/ecfr-django
$ uv run manage.py runserver

Open http://localhost:3000.

Core

Optional (dev)

<new tab>
$ cd ecfr-analyzer/ecfr-django
$ uv run manage.py dbshell

dbshell

<new tab>
$ cd ecfr-analyzer/ecfr-django
$ uv run manage.py shell_plus --ipython --print-sql

shell_plus

Scripts

$ uv run manage.py scrape_agencies
$ uv run manage.py scrape_cfr_text --title <title_number> --include-headers (optional)
$ uv run manage.py update_agencies_wordcounts

Agency and Title Scraper

CFR Full Text Scraper

Update Agencies Wordcounts

Bugs/issues/caveats/notes

There are overlapping Title/Chapter cfr_references for the following Agencies:

  • Title 40, Chapter VII is shared by:
    • Department of Defense
    • Department of Energy
  • Title 47, Chapter II is shared by:
    • National Security Council
    • Office of Science and Technology Policy
  • Title 47, Chapter IV is shared by:
    • National Telecommunications and Information Administration
    • National Highway Traffic Safety Administration
  • Title 50, Chapter IV is shared by:
    • National Oceanic and Atmospheric Administration
    • United States Fish and Wildlife Service
{
	"name": "National Telecommunications and Information Administration",
	...
	"cfr_references": [
		// this no longer exists the ecfr as of 2017-09-20 and was ignored in http://localhost:3000/agency-titles
		// https://www.ecfr.gov/current/title-15/chapter-XXIII
		{
			"title": 15,
			"chapter": "XXIII"
		},
	]
}
{
	"name": "Interstate Commerce Commission",
	...
	"cfr_references": [
		// this no longer exists the ecfr as of 2024-12-26 and was ignored in http://localhost:3000/agency-titles 
		// https://www.ecfr.gov/current/title-5/chapter-XL
		{
			"title": 5,
			"chapter": "XL"
		}
	]
}
In [1]: lst = list(Agency.objects.order_by("short_name").distinct("short_name").values_list("short_name", flat=True))

Short Names

{
	"name": "Gulf Coast Ecosystem Restoration Council",
	// this short_name is potentially wrong — should be GCERC
	"short_name": "Gulf Restoration Council",
}
{
	"name": "Military Compensation and Retirement Modernization Commission",
	// this short_name is seemingly wrong — should be "MCRMC"
	"short_name": "Military Compensation and Retirement Modernization Commission",
}

This API endpoint is strange — you would expect it to return truncated XML for queries with a date, title, and subtitle/chapter/subchapter, but even if you include any one of the three aforementionedsubset parameters, the endpoint returns the entire title's XML.

While this is explicitly stated in the API docs, it's not clear to me why the developers decided not to truncate the XML responses if a the subtitle/chapter/subchapter is provided.

I do this work manually in CFR Text Scraper.

Extract Text

For example, it's reasonable to assume https://www.ecfr.gov/api/versioner/v1/full/2025-02-06/title-1.xml?chapter=II or https://www.ecfr.gov/api/versioner/v1/full/2025-02-06/title-49.xml?subtitle=A would return the XML for just the chapter, subchapter, or subtitle, but it actually returns the entire title's full XML.

Requests can be for entire titles or part level and below. Downloadable XML document is returned for title requests. Processed XML is returned if part, subpart, section, or appendix is requested.

Sources

Code of Federal Regulations (ECFR) (Used to scrape 2024 data and to display 2010-2023 historical data through /api/versioner/v1/full/{date}/title-{title}.xml endpoint in Title Compare feature) https://www.ecfr.gov/api/admin/v1/agencies.json Federal Register Code of Federal Regulations (CFR) (Unused, bulk 2010-2023 data)

About

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages