A python client for the GitHub API
—
Event system module providing GitHub webhook event handling, event parsing, and sample event management for testing and development.
Base functionality for working with GitHub webhook events.
class GhEvent:
"""
Base class for GitHub webhook events.
"""Functions for managing sample events for testing and development.
def load_sample_events():
"""
Load sample GitHub events from storage.
Returns:
Sample event data for testing
"""
def save_sample_events():
"""
Save sample GitHub events to storage.
"""Additional methods added to GhApi for event-related operations.
def list_events(self, per_page=30, page=1, **kwargs):
"""
Fetch public events for repo network, org, user, or all.
Parameters:
- per_page: int, number of events per page
- page: int, page number
- username: str, filter by username
- org: str, filter by organization
- owner: str, repository owner (requires repo)
- repo: str, repository name (requires owner)
Returns:
List of event objects with integer IDs
"""
def list_events_parallel(self, per_page=30, n_pages=8, **kwargs):
"""
Fetch events in parallel for better performance.
Parameters:
- per_page: int, number of events per page
- n_pages: int, number of pages to fetch in parallel
- username: str, filter by username
- org: str, filter by organization
- owner: str, repository owner (requires repo)
- repo: str, repository name (requires owner)
Returns:
List of event objects with integer IDs
"""Specific event classes for different GitHub webhook event types.
class PageBuildEvent(GhEvent):
"""Page build event - triggered when GitHub Pages site is built."""
class ContentReferenceEvent(GhEvent):
"""Content reference event - triggered when content is referenced."""
class RepositoryImportEvent(GhEvent):
"""Repository import event - triggered during repository imports."""
class CreateEvent(GhEvent):
"""Create event - triggered when branch or tag is created."""
class WorkflowRunEvent(GhEvent):
"""Workflow run event - triggered by GitHub Actions workflow runs."""
class DeleteEvent(GhEvent):
"""Delete event - triggered when branch or tag is deleted."""
class OrganizationEvent(GhEvent):
"""Organization event - triggered by organization changes."""
class SponsorshipEvent(GhEvent):
"""Sponsorship event - triggered by GitHub Sponsors activity."""
class ProjectColumnEvent(GhEvent):
"""Project column event - triggered by project column changes."""
class PushEvent(GhEvent):
"""Push event - triggered by git pushes to repository."""
class ContextEvent(GhEvent):
"""Context event - triggered by context changes."""
class MilestoneEvent(GhEvent):
"""Milestone event - triggered by milestone changes."""
class ProjectCardEvent(GhEvent):
"""Project card event - triggered by project card changes."""
class ProjectEvent(GhEvent):
"""Project event - triggered by project changes."""
class PackageEvent(GhEvent):
"""Package event - triggered by GitHub Packages activity."""
class PullRequestEvent(GhEvent):
"""Pull request event - triggered by pull request activity."""
class RepositoryDispatchEvent(GhEvent):
"""Repository dispatch event - triggered by repository dispatch."""
class TeamAddEvent(GhEvent):
"""Team add event - triggered when team is added to repository."""
class WorkflowDispatchEvent(GhEvent):
"""Workflow dispatch event - triggered by manual workflow dispatch."""
class MemberEvent(GhEvent):
"""Member event - triggered by repository collaborator changes."""
class MetaEvent(GhEvent):
"""Meta event - triggered by repository metadata changes."""
class CodeScanningAlertEvent(GhEvent):
"""Code scanning alert event - triggered by code scanning alerts."""
class PublicEvent(GhEvent):
"""Public event - triggered when repository is made public."""
class NeedsEvent(GhEvent):
"""Needs event - triggered by workflow needs changes."""
class CheckRunEvent(GhEvent):
"""Check run event - triggered by check run activity."""
class SecurityAdvisoryEvent(GhEvent):
"""Security advisory event - triggered by security advisories."""
class PullRequestReviewCommentEvent(GhEvent):
"""Pull request review comment event - triggered by PR review comments."""
class OrgBlockEvent(GhEvent):
"""Organization block event - triggered by organization blocks."""
class CommitCommentEvent(GhEvent):
"""Commit comment event - triggered by commit comments."""
class WatchEvent(GhEvent):
"""Watch event - triggered when repository is starred."""
class MarketplacePurchaseEvent(GhEvent):
"""Marketplace purchase event - triggered by GitHub Marketplace purchases."""
class StarEvent(GhEvent):
"""Star event - triggered when repository is starred/unstarred."""
class InstallationRepositoriesEvent(GhEvent):
"""Installation repositories event - triggered by GitHub App installations."""
class CheckSuiteEvent(GhEvent):
"""Check suite event - triggered by check suite activity."""
class GithubAppAuthorizationEvent(GhEvent):
"""GitHub App authorization event - triggered by app authorization."""
class TeamEvent(GhEvent):
"""Team event - triggered by team changes."""
class StatusEvent(GhEvent):
"""Status event - triggered by commit status changes."""
class RepositoryVulnerabilityAlertEvent(GhEvent):
"""Repository vulnerability alert event - triggered by vulnerability alerts."""
class PullRequestReviewEvent(GhEvent):
"""Pull request review event - triggered by PR reviews."""
class LabelEvent(GhEvent):
"""Label event - triggered by label changes."""
class InstallationEvent(GhEvent):
"""Installation event - triggered by GitHub App installations."""
class ReleaseEvent(GhEvent):
"""Release event - triggered by release activity."""
class IssuesEvent(GhEvent):
"""Issues event - triggered by issue activity."""
class RepositoryEvent(GhEvent):
"""Repository event - triggered by repository changes."""
class GollumEvent(GhEvent):
"""Gollum event - triggered by wiki page changes."""
class MembershipEvent(GhEvent):
"""Membership event - triggered by organization membership changes."""
class DeploymentEvent(GhEvent):
"""Deployment event - triggered by deployment activity."""
class DeployKeyEvent(GhEvent):
"""Deploy key event - triggered by deploy key changes."""
class IssueCommentEvent(GhEvent):
"""Issue comment event - triggered by issue comments."""
class PingEvent(GhEvent):
"""Ping event - triggered by webhook ping."""
class DeploymentStatusEvent(GhEvent):
"""Deployment status event - triggered by deployment status changes."""
class ForkEvent(GhEvent):
"""Fork event - triggered when repository is forked."""
class ScheduleEvent(GhEvent):
"""Schedule event - triggered by scheduled workflows."""Utilities for working with GitHub events.
evt_emojis: dict # Emoji mappings for event types
described_evts: dict # Event descriptionsfrom ghapi.all import GhApi
api = GhApi(token='your_token')
# List all public events
events = api.list_events(per_page=50)
for event in events:
print(f"{event.type}: {event.actor.login} on {event.repo.name}")
# List events for specific user
user_events = api.list_events(username='octocat', per_page=25)
for event in user_events:
print(f"{event.created_at}: {event.type}")
# List events for organization
org_events = api.list_events(org='github', per_page=30)
for event in org_events:
print(f"{event.type} in {event.repo.name} by {event.actor.login}")
# List events for repository network
repo_events = api.list_events(owner='octocat', repo='Hello-World')
for event in repo_events:
print(f"{event.type}: {event.created_at}")from ghapi.all import GhApi, Event
api = GhApi(token='your_token')
events = api.list_events(per_page=100)
event_counts = {}
for event in events:
event_type = event.type
event_counts[event_type] = event_counts.get(event_type, 0) + 1
# Handle specific event types
if event_type == 'PushEvent':
print(f"Push to {event.repo.name}: {len(event.payload.commits)} commits")
elif event_type == 'PullRequestEvent':
action = event.payload.action
pr = event.payload.pull_request
print(f"PR {action}: #{pr.number} - {pr.title}")
elif event_type == 'IssuesEvent':
action = event.payload.action
issue = event.payload.issue
print(f"Issue {action}: #{issue.number} - {issue.title}")
elif event_type == 'WatchEvent':
print(f"{event.actor.login} starred {event.repo.name}")
elif event_type == 'ForkEvent':
print(f"{event.actor.login} forked {event.repo.name}")
print("Event type counts:")
for event_type, count in sorted(event_counts.items()):
print(f" {event_type}: {count}")from ghapi.all import GhApi
api = GhApi(token='your_token')
# Get events and examine payloads
events = api.list_events(owner='octocat', repo='Hello-World', per_page=20)
for event in events:
print(f"\\n--- {event.type} Event ---")
print(f"Actor: {event.actor.login}")
print(f"Repository: {event.repo.name}")
print(f"Created: {event.created_at}")
# Examine payload based on event type
payload = event.payload
if event.type == 'PushEvent':
print(f"Ref: {payload.ref}")
print(f"Commits: {len(payload.commits)}")
for commit in payload.commits[:3]: # Show first 3 commits
print(f" - {commit.sha[:8]}: {commit.message.split('\\n')[0]}")
elif event.type == 'PullRequestEvent':
pr = payload.pull_request
print(f"Action: {payload.action}")
print(f"PR #{pr.number}: {pr.title}")
print(f"State: {pr.state}")
print(f"Author: {pr.user.login}")
elif event.type == 'IssuesEvent':
issue = payload.issue
print(f"Action: {payload.action}")
print(f"Issue #{issue.number}: {issue.title}")
print(f"State: {issue.state}")
print(f"Labels: {[label.name for label in issue.labels]}")
elif event.type == 'CreateEvent':
print(f"Ref type: {payload.ref_type}")
print(f"Ref: {payload.ref}")
print(f"Description: {payload.description}")
elif event.type == 'ReleaseEvent':
release = payload.release
print(f"Action: {payload.action}")
print(f"Release: {release.tag_name}")
print(f"Name: {release.name}")
print(f"Draft: {release.draft}")
print(f"Prerelease: {release.prerelease}")from ghapi.all import GhApi
from datetime import datetime, timedelta
from collections import defaultdict
api = GhApi(token='your_token')
# Analyze events for a specific timeframe
events = api.list_events(username='octocat', per_page=100)
# Filter events from last week
week_ago = datetime.now() - timedelta(days=7)
recent_events = []
for event in events:
event_date = datetime.fromisoformat(event.created_at.replace('Z', '+00:00'))
if event_date >= week_ago:
recent_events.append(event)
print(f"Events in last 7 days: {len(recent_events)}")
# Analyze activity patterns
activity_by_repo = defaultdict(int)
activity_by_type = defaultdict(int)
activity_by_day = defaultdict(int)
for event in recent_events:
activity_by_repo[event.repo.name] += 1
activity_by_type[event.type] += 1
event_date = datetime.fromisoformat(event.created_at.replace('Z', '+00:00'))
day_key = event_date.strftime('%Y-%m-%d')
activity_by_day[day_key] += 1
print("\\nMost active repositories:")
for repo, count in sorted(activity_by_repo.items(), key=lambda x: x[1], reverse=True)[:5]:
print(f" {repo}: {count} events")
print("\\nEvent type breakdown:")
for event_type, count in sorted(activity_by_type.items(), key=lambda x: x[1], reverse=True):
print(f" {event_type}: {count}")
print("\\nDaily activity:")
for day, count in sorted(activity_by_day.items()):
print(f" {day}: {count} events")from ghapi.all import load_sample_events, save_sample_events
# Load sample events for testing
sample_events = load_sample_events()
if sample_events:
print(f"Loaded {len(sample_events)} sample events")
# Use sample events for testing webhook handlers
for event in sample_events[:5]:
print(f"Sample {event.get('type', 'unknown')} event")
# Save current events as samples for future testing
from ghapi.all import GhApi
api = GhApi(token='your_token')
current_events = api.list_events(per_page=50)
# Convert to sample format and save
save_sample_events()
print("Saved current events as samples")from ghapi.all import GhApi
def process_repository_events(owner, repo, event_handler):
"""Process events for a repository with custom handler."""
api = GhApi(token='your_token')
events = api.list_events(owner=owner, repo=repo, per_page=50)
for event in events:
try:
event_handler(event)
except Exception as e:
print(f"Error processing {event.type} event: {e}")
def my_event_handler(event):
"""Custom event handler function."""
if event.type == 'PushEvent':
print(f"New push to {event.payload.ref} with {len(event.payload.commits)} commits")
# Check for specific files in commits
for commit in event.payload.commits:
if any('requirements.txt' in file for file in commit.added + commit.modified):
print(f" Dependencies changed in commit {commit.sha[:8]}")
elif event.type == 'PullRequestEvent' and event.payload.action == 'opened':
pr = event.payload.pull_request
print(f"New PR opened: #{pr.number} - {pr.title}")
# Check if PR needs review
if 'WIP' not in pr.title and not pr.draft:
print(f" PR #{pr.number} ready for review")
elif event.type == 'IssuesEvent' and event.payload.action == 'opened':
issue = event.payload.issue
print(f"New issue opened: #{issue.number} - {issue.title}")
# Check for bug reports
if 'bug' in [label.name.lower() for label in issue.labels]:
print(f" Bug report detected: #{issue.number}")
# Process events for a repository
process_repository_events('octocat', 'Hello-World', my_event_handler)Install with Tessl CLI
npx tessl i tessl/pypi-ghapi