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) |
Links
- Docs: districtapi.dev/docs
- Dashboard: districtapi.dev/dashboard
- Pricing: districtapi.dev/pricing
- GitHub: github.com/districtapi/districtapi-python
- Issues: github.com/districtapi/districtapi-python/issues
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)
| 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)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| 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.