Skip to main content

districtapi

Python SDK for districtapi.dev — US school district and school data from NCES federal datasets.

The killer feature: look up any US address and get back the school district serving it, with full enrollment, demographics, finances, school list, and GeoJSON boundary — all in one call.

Install

pip install districtapi

Quick start

Get a free API key at districtapi.dev/dashboard — no credit card, 250 requests/month free forever.

from districtapi import DistrictAPI

client = DistrictAPI(api_key="sk_live_...")

# Address → district (the killer feature)
district = client.districts.get(address="123 Main St, Apple Valley, CA")
print(district.name)                           # Apple Valley Unified School District
print(district.enrollment.total)               # 17432
print(district.finance.per_pupil_expenditure)  # 9823.45
print(district.geo.boundary)                   # GeoJSON MultiPolygon

# Lat/lng lookup
district = client.districts.get(lat=34.4988, lng=-117.1858)

# By NCES ID
district = client.districts.fetch("0600017")

# Search by name/state
results = client.districts.search(name="Apple Valley", state="CA")
for d in results:
    print(d.nces_id, d.name, d.enrollment_total)

# Schools in a district
schools = client.districts.schools("0600017")
for school in schools:
    print(school.name, school.grades.low, school.grades.high)

# Schools near an address
nearby = client.schools.near(address="123 Main St, Apple Valley, CA", radius_miles=3.0)

# A specific school
school = client.schools.fetch("060001700123")
print(school.name, school.flags.is_charter)

# School → district
district = client.schools.district("060001700123")

Async support

import asyncio
from districtapi import AsyncDistrictAPI

async def main():
    async with AsyncDistrictAPI(api_key="sk_live_...") as client:
        district = await client.districts.get(address="123 Main St, Apple Valley, CA")
        print(district.name)

asyncio.run(main())

Context manager

with DistrictAPI(api_key="sk_live_...") as client:
    district = client.districts.get(address="1600 Pennsylvania Ave, Washington, DC")

Error handling

from districtapi import DistrictAPI, NotFoundError, AuthenticationError, RateLimitError

client = DistrictAPI(api_key="sk_live_...")

try:
    district = client.districts.get(address="123 Nowhere St")
except NotFoundError:
    print("No district found for that address")
except AuthenticationError:
    print("Invalid API key")
except RateLimitError:
    print("Rate limit exceeded — upgrade at districtapi.dev/pricing")

Response types

All methods return typed dataclasses. Key types:

Type Fields
District nces_id, name, state, county, enrollment, finance, students, geo, schools_count
DistrictSummary nces_id, name, state, county, enrollment_total, lat, lng
School nces_id, nces_district_id, name, state, grades, flags, enrollment, address, geo
DistrictEnrollment total, year, demographics
DistrictFinance per_pupil_expenditure, total_revenue, federal_revenue_pct, fiscal_year
GeoPoint lat, lng, boundary (GeoJSON)

Metadata

Release files for districtapi 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for districtapi 0.3.1
File Size Uploaded Provenance Actions
districtapi-0.3.1.tar.gz 8.2 kB Without provenance Details for districtapi-0.3.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for districtapi 0.3.1
File Interpreter ABI Platform Actions
districtapi-0.3.1-py3-none-any.whl Python 3 none any Details for districtapi-0.3.1-py3-none-any.whl

Total release size: 18.7 kB

Release files / districtapi-0.3.1.tar.gz

Download URL districtapi-0.3.1.tar.gz
Size 8.2 kB
Tags Source
SHA-256 checksum
How to use checksums
f1431d8fe515942e3194afa619fe08ba33329f71af415c01a26b5a18aaf65482
BLAKE2b-256 checksum
How to use checksums
93cd2a2cf206d70e8264693092bf8c6b18058a421903fc8fc219fa7c019b01e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / districtapi-0.3.1-py3-none-any.whl

Download URL districtapi-0.3.1-py3-none-any.whl
Size 10.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3c9802dfdc8d8ec336103c5f9c531b2926861d61b85db5bda072e95a5d5f4b2c
BLAKE2b-256 checksum
How to use checksums
28fc7ece6bcfa257c562a344c5b4c9b9c8ab4e2094b6cfc8e3c83d737dccc31d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for districtapi 0.3.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page