A lightweight Flask web application for browsing accreditation snapshots for New Jersey municipalities. It surfaces data parsed from annual Urban & Community Forestry (UCF) accreditation reports and links each result directly to the page in the source PDF. The dashboard exposes a searchable web UI as well as JSON APIs that can be reused by other tools.
- Data extraction: The
scripts/extract_reports.pyscript reads PDF reports in thecontext/directory usingPyPDF2, pulls out municipality, county, accreditation status, plan year, update date, and the report year inferred from the filename, then writes the consolidated dataset todata/reports.json. - Application:
app/__init__.pyloadsreports.json, builds common filter lists (counties, years), and exposes both HTML and JSON routes. PDFs incontext/are served via/pdf/<filename>so the UI and API responses can link to the exact report page. - Frontend: The
app/templates/index.htmltemplate renders filters for county, municipality, year, and accreditation status. It calls/api/reportsto show matching entries and links to municipality detail pages (/municipality/<slug>) and PDF anchors (#page=<n>).
Key routes:
/– search dashboard UI./municipality/<slug>– all records for a municipality./api/meta– metadata for populating filters (counties, years, municipalities)./api/reports– filtered report data with links to PDFs and profiles./api/municipalities/<slug>– records for a specific municipality./pdf/<filename>– serves source PDFs stored incontext/.
- Create a virtual environment and install dependencies (Python 3.10+ recommended):
python -m venv .venv source .venv/bin/activate pip install -r requirements.txt - Verify data and PDFs: Ensure
data/reports.jsonexists and that the referenced PDFs live incontext/. If you add new PDFs or want to refresh the dataset, run:python scripts/extract_reports.py
- Run the development server:
The site will be available at http://127.0.0.1:5000/.
flask --app app:build_app --debug run
- Production server: Point a WSGI server like gunicorn at the factory
app:build_app, e.g.:Serve thegunicorn --bind 0.0.0.0:8000 'app:build_app()'context/directory so/pdf/<filename>can return the source PDFs. - Static hosting setup: Behind a reverse proxy (nginx/Apache), route application traffic to the
WSGI server and allow direct access to
context/for PDF downloads. Ensure the proxy forwardsX-Forwarded-Protoheaders if you terminate TLS upstream. - Refreshing data: Place new yearly accreditation PDFs in
context/, rerunpython scripts/extract_reports.py, and redeploy or reload the WSGI process to pick up the updatedreports.json.
app/__init__.py– Flask application factory, routes, and filtering logic.app/templates/– HTML templates for the search page and municipality details.app/static/– Shared styling for the UI.data/reports.json– Parsed accreditation metadata.context/– Source accreditation report PDFs and related context files.scripts/extract_reports.py– PDF parser that regeneratesdata/reports.json.
Query the JSON API directly, for example:
curl 'http://127.0.0.1:5000/api/reports?county=Monmouth&accredited=true'Each record includes pdf_url (link to the PDF page) and municipality_url (link to the municipality
summary page) to make integrating the data into other tools straightforward.