Tools to search, analyze, and traverse US nonprofit networks using ProPublica Nonprofit Explorer data.
Project description
Nonprofit Networks
This codebase is a collection of tools to analyze and understand nonprofit organizations in the United States.
This codebase is separated into three components:
Nonprofit Search
With huge thanks to ProPublica for their Nonprofit Explorer API, which provides the data for this project.
from nonprofit_networks import ProPublicaClient
client = ProPublicaClient()
org = client.search("donors trust", state="VA", city="Alexandria").organizations[0]]
Nonprofit Filing Details
filing = client.get_full_filing(org.ein, 2024)
for comp in filing.get_compensations():
print(
f"{comp.PersonNm:<30} {comp.TitleTxt:<30} ${comp.ReportableCompFromOrgAmt:>10,.2f} (plus ${comp.OtherCompensationAmt:>10,.2f})"
)
Kimberly O Dennis Chair $ 0.00 (plus $ 0.00)
James Piereson Vice Chair $ 0.00 (plus $ 0.00)
Thomas E Beach Director $ 0.00 (plus $ 0.00)
George GH Coates Jr Director $ 0.00 (plus $ 0.00)
Lawson R Bader President and CEO $393,490.00 (plus $ 72,461.00)
Jeffrey C Zysik CFO, COO and Treasurer $305,587.00 (plus $ 60,430.00)
Peter A Lipsett Vice President / Secretary $227,897.00 (plus $ 54,136.00)
Stephen M Johnson CTO $181,250.00 (plus $ 39,742.00)
Gregory P Conko Vice President of Programs $225,392.00 (plus $ 46,106.00)
Lukas C Dwelly Philanthropic Advisor $179,667.00 (plus $ 40,346.00)
Stephanie L Giovanetti Philanthropic Advisor $156,175.00 (plus $ 23,164.00)
Christopher D Renner Controller $161,704.00 (plus $ 41,228.00)
Elia J Peterson Assistant Controller $115,569.00 (plus $ 25,044.00)
filing.get_net_assets()
$1,289,047,383.00
See also,
| Method | Description |
|---|---|
get_compensations |
Get a list of all reported compensation to staff/board |
get_contractor_compensation |
Get a list of all reported compensation to contractors |
get_grant_recipients |
Get a list of all grant recipients (including EINs) |
get_total_revexp |
Get the total revenue and expenses |
get_net_assets |
Get the net assets |
get_rent_income |
Get a list of rent income |
get_disregarded_entities |
Get a list of disregarded entities |
get_related_tax_exempt_orgs |
Get a list of related tax exempt orgs |
get_transactions_related_orgs |
Get a list of transactions with related orgs |
Network Traversal
Grantmakers
This tool makes it easy to traverse the network of grantmaking organizations:
from nonprofit_networks import ProPublicaClient
from nonprofit_networks.network_builder import GrantmakerNetworkBuilder
client = ProPublicaClient()
org = client.search(...).organizations[0]
grant_net = GrantmakerNetworkBuilder(client)
grant_net.build_network(org.ein, depth=2, year=2023)
These networks have vertices of organizations, and the edges have an amount attribute that represents the amount of the grant.
longest_path = nx.dag_longest_path(grant_net.graph)
print("Longest path:")
for i in range(len(longest_path) - 1):
node = longest_path[i]
next_node = longest_path[i + 1]
amount = grant_net.graph[node][next_node][0]["grant"].CashGrantAmt
print(
# f"{grant_net.graph.nodes[node]['filing'].get_name()} "
f"${amount:,.2f} -> "
f"{grant_net.graph.nodes[next_node]['filing'].get_name()}"
)
Longest Path:
Donor's Trust →
$12,727,215.00 → BRADLEY IMPACT FUND INC
$35,000.00 → STATE POLICY NETWORK
$125,000.00 → Center of the American Experiment
$109,000.00 → JUDICIAL WATCH INC
$5,000.00 → COALITIONS FOR AMERICA
(Note that in this example it is clear that the amount does not all come from the same parent organization or from the same grant, since of course later edges can have larger dollar amounts than earlier edges. While this is useful for "tracing the money", it is not useful for understanding the flow of individual grant allocations.)
You can render these graphs with, for example,
import networkx as nx
import matplotlib.pyplot as plt
sanitized_graph = grant_net.graph.copy()
# Remove anything with net_assets == None, and print them
for node in list(sanitized_graph.nodes):
if sanitized_graph.nodes[node]['filing'].get_net_assets() is None:
print(f"Removing {sanitized_graph.nodes[node]['filing'].get_name()}")
sanitized_graph.remove_node(node)
node_sizes = [(sanitized_graph.nodes[node]['filing'].get_net_assets())/100000 for node in sanitized_graph.nodes]
node_colors = [(sanitized_graph.nodes[node]['filing'].get_total_revexp()[0])/100000 for node in sanitized_graph.nodes]
plt.figure(figsize=(16, 16), dpi=100)
pos = nx.spring_layout(sanitized_graph, weight="amount")
nx.draw_networkx_labels(sanitized_graph, pos, labels={node: sanitized_graph.nodes[node]['filing'].get_name() + "\n\n" for node in sanitized_graph.nodes}, font_size=8)
edges = nx.draw_networkx_edges(sanitized_graph, pos, edge_color='gray', alpha=0.5, node_size=node_sizes, width=[sanitized_graph.edges[edge]['amount']**0.1 for edge in sanitized_graph.edges])
nx.draw_networkx_nodes(sanitized_graph, node_size=node_sizes, node_color=node_colors, cmap='viridis', pos=pos)
plt.show()
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nonprofit_networks-0.1.1.tar.gz.
File metadata
- Download URL: nonprofit_networks-0.1.1.tar.gz
- Upload date:
- Size: 899.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
84c4c6c2360cb47857706e0c26fa126cab31143a6d06bda0dd96cf7e49d3564a
|
|
| MD5 |
399e0047867fa041b8936ea5bf9a3aa0
|
|
| BLAKE2b-256 |
186158db1d0ecdde0bac3c530fc9f736a1d3c588265d6b998214dc4ba1dfe101
|
File details
Details for the file nonprofit_networks-0.1.1-py3-none-any.whl.
File metadata
- Download URL: nonprofit_networks-0.1.1-py3-none-any.whl
- Upload date:
- Size: 24.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
da5f62e63f8e00cb81e5da2de29fa9d4521091bdf327da5d2d3f30bfe0213a96
|
|
| MD5 |
b7bc2dd1e04ae04cc63fd8f9a707bd46
|
|
| BLAKE2b-256 |
8113fe66c55881061eb959e846f7fb978abe46d2c5cdf08dcec4a22430dd7640
|