Skip to content

Instantly share code, notes, and snippets.

@murraco
Last active February 19, 2025 13:54
Show Gist options
  • Save murraco/bd9394fcd1ab48510ce3c80b978388d9 to your computer and use it in GitHub Desktop.
Save murraco/bd9394fcd1ab48510ce3c80b978388d9 to your computer and use it in GitHub Desktop.
GlobalGiving API PoC (https://www.globalgiving.org/api/)
import requests
# Replace with your GlobalGiving API key
API_KEY = "API_KEY"
# Base URL for the GlobalGiving API
BASE_URL = "https://api.globalgiving.org/api/public"
# NOTE:
# - The API only supports searching for projects, not organizations.
# - Projects can be searched using the 'q' parameter in the search_projects function.
# - Organizations can only be retrieved by:
# * Fetching them by ID
# * Listing them
# * Downloading them in bulk
# - Since there are too many organizations, we can filter by active ones.
# * As of February 19, 2025, there are 3,621 active organizations.
# * We could potentially add them all.
# - Pagination is supported for fetching organizations using the 'nextOrgId' query parameter.
# * If we download all at once, pagination won’t be necessary.
# - The data available for each organization can be found here:
# * https://www.globalgiving.org/api/methods/get-organization/
# * See the "Get Organization Response Structure" section.
# - EIN appears to be present only in US organizations, with no other legal ID provided.
# - According to a quick search we already have 973 organizations in our DB.
# WARNING:
# - This script may attempt to fetch a large number of organizations.
# - Comment out any unnecessary parts before running to avoid excessive API calls.
def fetch_active_projects():
"""
Fetches a list of all active projects from the GlobalGiving API.
"""
endpoint = f"{BASE_URL}/projectservice/all/projects/active"
headers = {
"Accept": "application/json",
"Content-Type": "application/json",
}
params = {
"api_key": API_KEY,
}
response = requests.get(endpoint, headers=headers, params=params)
if response.status_code == 200:
return response.json()
else:
print(f"Error fetching active projects: {response.status_code}")
return None
def search_projects(query):
"""
Searches for projects based on a query string.
"""
endpoint = f"{BASE_URL}/services/search/projects/summary"
headers = {
"Accept": "application/json",
"Content-Type": "application/json",
}
params = {
"api_key": API_KEY,
"q": query, # Search query
}
response = requests.get(endpoint, headers=headers, params=params)
if response.status_code == 200:
return response.json()
else:
print(f"Error searching projects: {response.status_code}")
return None
def fetch_active_organizations(next_org_id=None):
"""
Fetches a list of active organizations from the GlobalGiving API with pagination support.
"""
endpoint = f"{BASE_URL}/orgservice/all/organizations/active"
headers = {
"Accept": "application/json",
"Content-Type": "application/json",
}
params = {
"api_key": API_KEY,
}
# Add nextOrgId for pagination
if next_org_id:
params["nextOrgId"] = next_org_id
response = requests.get(endpoint, headers=headers, params=params)
if response.status_code == 200:
return response.json()
else:
print(f"Error fetching organizations: {response.status_code}")
return None
def fetch_all_active_organizations():
"""
Fetches all active organizations using pagination and returns the total count.
"""
all_organizations = []
next_org_id = None
total_count = 0
while True:
response = fetch_active_organizations(next_org_id)
if not response:
break
# Add organizations to the list
if "organizations" in response and "organization" in response["organizations"]:
all_organizations.extend(response["organizations"]["organization"])
total_count += len(response["organizations"]["organization"])
# Check if there are more organizations
if "nextOrgId" in response["organizations"]:
next_org_id = response["organizations"]["nextOrgId"]
else:
break
return {
"organizations": all_organizations,
"total_count": total_count,
}
def display_projects(projects):
"""
Displays project details in a readable format.
"""
if not projects or "projects" not in projects:
print("No projects found.")
return
for project in projects["projects"]["project"]:
print(f"Title: {project['title']}")
print(f"Summary: {project['summary']}")
print(f"Funding: ${project['funding']}")
print(f"Country: {project['country']}")
print(f"URL: {project['projectLink']}")
print("-" * 40)
def display_organizations(organizations):
"""
Displays organization details in a readable format.
"""
if not organizations or not organizations["organizations"]:
print("No organizations found.")
return
for org in organizations["organizations"]:
print(f"Name: {org['name']}")
print(f"Mission: {org['mission']}")
print(f"Country: {org['country']}")
print(f"URL: {org['url']}")
print("-" * 40)
if __name__ == "__main__":
# Fetch and display active projects
print("Fetching active projects...")
active_projects = fetch_active_projects()
if active_projects:
display_projects(active_projects)
# Search for projects
search_query = input("\nEnter a search term (e.g., 'education', 'health'): ")
search_results = search_projects(search_query)
if search_results:
display_projects(search_results)
# Fetch all active organizations with pagination
print("Fetching all active organizations...")
result = fetch_all_active_organizations()
if result:
print(f"Total organizations found: {result['total_count']}")
display_organizations(result)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment