Last active
February 19, 2025 13:54
-
-
Save murraco/bd9394fcd1ab48510ce3c80b978388d9 to your computer and use it in GitHub Desktop.
GlobalGiving API PoC (https://www.globalgiving.org/api/)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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