{"id":16504970,"url":"https://github.com/sgibson91/github-activity-dashboard","last_synced_at":"2025-10-28T00:32:25.172Z","repository":{"id":37323835,"uuid":"420395088","full_name":"sgibson91/github-activity-dashboard","owner":"sgibson91","description":"A tool to help visualise activity in issues and PRs across many repos and orgs","archived":false,"fork":false,"pushed_at":"2024-10-30T01:14:07.000Z","size":1614,"stargazers_count":6,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-30T03:53:24.390Z","etag":null,"topics":["binder","binder-ready","github","github-activity","jupyter-notebook","python","template","voila","voila-dashboard"],"latest_commit_sha":null,"homepage":"","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sgibson91.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-10-23T11:36:37.000Z","updated_at":"2024-10-30T01:14:10.000Z","dependencies_parsed_at":"2024-01-01T02:25:11.607Z","dependency_job_id":"691ff321-2c0b-4e44-b1c4-66f64a4e69aa","html_url":"https://github.com/sgibson91/github-activity-dashboard","commit_stats":{"total_commits":859,"total_committers":4,"mean_commits":214.75,"dds":0.2630966239813737,"last_synced_commit":"4216caa5b587643c01d104b138804b40dadf633c"},"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgibson91%2Fgithub-activity-dashboard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgibson91%2Fgithub-activity-dashboard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgibson91%2Fgithub-activity-dashboard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sgibson91%2Fgithub-activity-dashboard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sgibson91","download_url":"https://codeload.github.com/sgibson91/github-activity-dashboard/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238578793,"owners_count":19495445,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["binder","binder-ready","github","github-activity","jupyter-notebook","python","template","voila","voila-dashboard"],"created_at":"2024-10-11T15:08:34.793Z","updated_at":"2025-10-28T00:32:19.885Z","avatar_url":"https://github.com/sgibson91.png","language":"Jupyter Notebook","readme":"# My GitHub Activity Dashboard\n\n[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/sgibson91/github-activity-dashboard/main.svg)](https://results.pre-commit.ci/latest/github/sgibson91/github-activity-dashboard/main)\n\nJupyter-based dashboards to help visualise activity in issues and Pull Requests across many repositories and organisations - all in one place!\n\nClick here to view the activity dashboard! :point_right: [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/sgibson91/github-activity-dashboard/notebook-env?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252Fsgibson91%252Fgithub-activity-dashboard%26urlpath%3D%252Fvoila%252Frender%252Fgithub-activity-dashboard%252Factivity-dashboard.ipynb%26branch%3Dmain)\n\nClick here to view the past activity summary! :point_right: [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/sgibson91/github-activity-dashboard/notebook-env?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252Fsgibson91%252Fgithub-activity-dashboard%26urlpath%3D%252Fvoila%252Frender%252Fgithub-activity-dashboard%252Fpast-activity-summary.ipynb%26branch%3Dmain)\n\n---\n\n**Table of Contents:**\n\n- [My GitHub Activity Dashboard](#my-github-activity-dashboard)\n  - [How the dashboards work](#how-the-dashboards-work)\n    - [Python script](#python-script)\n    - [Continuous Delivery of data](#continuous-delivery-of-data)\n    - [Visualising the data](#visualising-the-data)\n    - [Binder and `nbgitpuller`](#binder-and-nbgitpuller)\n  - [Get your own dashboards!](#get-your-own-dashboards)\n  - [Using the tools locally](#using-the-tools-locally)\n    - [Installation requirements](#installation-requirements)\n    - [Getting the data](#getting-the-data)\n    - [Viewing the dashboards](#viewing-the-dashboards)\n\n## How the dashboards work\n\n### Python script\n\n`get-data.py` is a Python script that makes calls to the [GitHub REST API](https://docs.github.com/en/rest) in order to collect information about issues and pull requests.\nIt specifically makes requests to the [search endpoint](https://docs.github.com/en/rest/reference/search#search-issues-and-pull-requests) which allows us search for issues and pull requests as we would expect to do so in GitHub's own search bar.\nFor example, `is:issue is:open assignee:sgibson91` would return all open issues assigned to me.\nThis turned out to be much more efficient than using the ['list issues assigned to the authenticated user' endpoint](https://docs.github.com/en/rest/reference/issues#list-issues-assigned-to-the-authenticated-user) since it made fewer individual requests and, therefore, wouldn't rate-limit the script.\n\nThe script searches for all issues and pull requests that meet the following criteria:\n\n- the user is either assigned to or has created them,\n- they involve the user and were closed in the last month,\n- they involve the user and were closed or updated in the last week;\n- and, any pull requests where the user's review has been requested.\n\nThe results are compiled into a pandas dataframe, along with some metadata, and then written to CSV file called `github-activity.csv`.\n\nYou can provide a `.repoignore` file to prevent results from specific repos turning up the the dataset.\nThis is a plain text file with a repository to be ignored on each new line.\nThe repository to be ignored is represented by the form `ORG_OR_USER/REPO_NAME`.\nYou can also use [regular expressions](https://en.wikipedia.org/wiki/Regular_expression) here as well.\nE.g., if you would like to ignore a whole organisation, this would look like `ORG_NAME/.*`.\n\n### Continuous Delivery of data\n\nThe `get-data.py` script is run in a GitHub Actions workflow on a regular cron trigger.\nThis cron job runs as if running the script locally and commits the updated CSV file to the `main` branch.\n\n### Visualising the data\n\nThe data are visualised using the `activity-dashboard.ipynb` and `past-activity-summary.ipynb` Jupyter Notebooks.\nThey each implement widgets to interact with the data so that users can filter by an individual repository and sort by time created, updated, or closed (past activity summary only).\nThe Notebooks are executed with `voila` in order to give the dashboards a more aesthetically pleasing look.\n\n### Binder and `nbgitpuller`\n\nThe dashboards can be launched in Binder to generate a quick view without needing to use the repository locally.\nBinder usually rebuilds the Docker image of the repository with every new commit it sees on the provided git reference.\nHowever since the CSV file is regularly updated, this meant Binder was rebuilding _a lot_ when it didn't need to since only the data were changing - not the Notebooks or the environment required by the Notebooks.\n\nTo mitigate the number of rebuilds Binder would need to make, the `requirements.txt` file containing _only_ the packages needed to run the Notebooks has been separated out onto the `notebook-env` branch.\nThis is the branch we build with Binder.\nWe then use [`nbgitpuller`](https://jupyterhub.github.io/nbgitpuller/) to dynamically pull in the content from the `main` branch.\nThis results in a Binder environment that is only rebuilt when the Notebooks' requirements are changed, but still operates with the most up-to-date data from the `main` branch.\n\n**Binder needs BOTH the `main` branch and the `notebook-env` branch to operate in this way!**\n**If you are using this project as a template or forking it, DO NOT remove the `notebook-env` branch without ALSO updating the Binder link!**\n\n## Get your own dashboards!\n\n1. [Create your own version of this repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template) by clicking the \"Use this template\" button at the top of this page.\n   :fire: **Make sure to check the \"Include all branches\" box when creating your repo, as you will need the `notebook-env` branch as well for the Binder links to work!** :fire:\n   You can delete any other branches, **except** for `main` and `notebook-env`.\n\n   ![include-all-branches](https://docs.github.com/assets/cb-28415/images/help/repository/include-all-branches.png)\n\n2. Delete the `github-activity.csv` file from your repo.\n   (It will be regenerated when the CI job next runs!)\n3. Delete the `.repoignore` file **or** edit it contain a list of repos you'd like excluded from the dataset, in the form `ORG_OR_USER/REPO_NAME`.\n4. [Create a Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) with `public_repo` scope and [add it as a repository secret](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) called `ACCESS_TOKEN`\n5. Edit the [README](./README.md) and update the Binder badges at the top of the document, replacing all instances of `{{ YOUR_GITHUB_HANDLE_HERE }}` (including `{{}}`!!!) with your GitHub handle in the below snippet:\n\n   ```markdown\n   [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/{{ YOUR_GITHUB_HANDLE_HERE }}/github-activity-dashboard/notebook-env?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252F{{ YOUR_GITHUB_HANDLE_HERE }}%252Fgithub-activity-dashboard%26urlpath%3D%252Fvoila%252Frender%252Fgithub-activity-dashboard%252Factivity-dashboard.ipynb%26branch%3Dmain)\n   [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/{{ YOUR_GITHUB_HANDLE_HERE }}/github-activity-dashboard/notebook-env?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252F{{ YOUR_GITHUB_HANDLE_HERE }}%252Fgithub-activity-dashboard%26urlpath%3D%252Fvoila%252Frender%252Fgithub-activity-dashboard%252Fpast-activity-summary.ipynb%26branch%3Dmain)\n   ```\n\n   :rotating_light: Be careful not to edit anything else in the URL! :rotating_light:\n\nYou can either get started straight away by [manually triggering the 'Update GitHub Activity' workflow](https://docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow#running-a-workflow) or wait for the cron job to run it for you to produce your `github-activity.csv`.\nOnce that has been added to your repo, click your edited Binder badges to see your dashboards!\n\n## Using the tools locally\n\n### Installation requirements\n\nThis project requires a Python installation.\nAny minor patch of Python3 should suffice, but that hasn't been tested so proceed with caution!\n\nThe packages required to run this project are stored in `requirements.txt` and can be installed via `pip`:\n\n```bash\npip install -r requirements.txt\n```\n\n### Getting the data\n\n1. If you have not already done so, [create a Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) with the `public_repo` scope\n2. Add this as a variable called `ACCESS_TOKEN` to your shell environment\n\n   ```bash\n   export ACCESS_TOKEN=\"PASTE YOUR TOKEN HERE\"\n   ```\n\n3. Run the Python script to generate the `github-activity.csv` file\n\n   ```bash\n   python get-data.py\n   ```\n\n:rotating_light: If you see the message \"You are rate limited! :scream:\", you will need to wait ~1hour before trying to run the script again :rotating_light:\n\n### Viewing the dashboards\n\nOnce `github-activity.csv` has been generated, view the dashboards by running:\n\n```bash\nvoila activity-dashboard.ipynb\nvoila past-activity-summary.ipynb\n```\n\nA browser window should be automatically opened.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsgibson91%2Fgithub-activity-dashboard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsgibson91%2Fgithub-activity-dashboard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsgibson91%2Fgithub-activity-dashboard/lists"}