Skip to content

Instantly share code, notes, and snippets.

@benwillkommen
Last active June 27, 2022 21:27
Show Gist options
  • Save benwillkommen/b7549414883087923ad574d1e846c5f9 to your computer and use it in GitHub Desktop.
Save benwillkommen/b7549414883087923ad574d1e846c5f9 to your computer and use it in GitHub Desktop.
Unsubscribe from all watched repositories in a particular organization

Remove All Subscriptions from a Specific Github Organization

This script will delete all the subscriptions in your account for the Github Organization passed to it.

This script was created when I took a new job, and my notification settings inadvertantly subscribed me to all 600+ of their repos. I wanted a better signal to noise ratio in my notifications, but I didn't want to click the "Unwatch All" button, which would remove my subscriptions to repos outside my new employer's org.

How To

  1. Create a Personal Access Token with the "repo" scope, and expose it as the GITHUB_PERSONAL_ACCESS_TOKEN environment variable:
$ export GITHUB_PERSONAL_ACCESS_TOKEN=<your-token-here>
  1. Copy both files into a directory and install the requirements:
$ pip install -r requirements.txt
  1. Run the unsubscribe.py script, and pass in the Github Organization that contains the repos you want to unsubscribe from:
$ python unsubscribe.py <whatever-github-org>

You will be prompted for "(y/n)" before any subscriptions are deleted.

Updates

  • 12/3/2020 - Copied and pasted the pagination fix from @Jetersen's comment. Thanks for the fix!
astroid==2.3.1
certifi==2019.9.11
chardet==3.0.4
idna==2.8
isort==4.3.21
lazy-object-proxy==1.4.2
mccabe==0.6.1
pylint==2.4.2
requests==2.22.0
six==1.12.0
typed-ast==1.4.0
urllib3==1.25.6
wrapt==1.11.2
import os
import sys
import requests
def get_subscribed_repos_in_organization(organization, personal_access_token):
url = "https://api.github.com/user/subscriptions?per_page=100&page=1"
organizations = []
while url is not None:
print(f"GET {url}")
response = requests.get(url,
headers={'Authorization': 'token {}'.format(personal_access_token)})
repos = response.json()
[organizations.append(repo['owner']['login']) for repo in repos if repo['owner']['login'] not in organizations]
repos_from_response = [repo['full_name'] for repo in repos if repo['owner']['login'] == organization]
for repo_name in repos_from_response:
yield repo_name
try:
url = response.links['next']['url']
except KeyError:
url = None
print("list of organizations: {}".format(organizations))
def yes_or_no(question):
reply = str(input(question+' (y/n): ')).lower().strip()
if reply[0] == 'y':
return True
if reply[0] == 'n':
return False
else:
return yes_or_no("Please choose")
if __name__ == '__main__':
personal_access_token = os.environ['GITHUB_PERSONAL_ACCESS_TOKEN']
organization = sys.argv[1]
repos_in_organization = [repo for repo in get_subscribed_repos_in_organization(organization, personal_access_token)]
print(repos_in_organization)
if len(repos_in_organization) is not 0:
do_unsubscribe = yes_or_no("\nUnsubscribe from the above {} repositories?".format(len(repos_in_organization)))
if do_unsubscribe:
for repo_full_name in repos_in_organization:
url = "https://api.github.com/repos/{}/subscription".format(repo_full_name)
print("DELETE {}".format(url))
response = requests.delete(url,
# params={'subscribed': False},
headers={'Authorization': 'token {}'.format(personal_access_token)})
print(response.status_code)
@gudrutis
Copy link

gudrutis commented Dec 7, 2020

Great script, worked like a charm, but:

  • didn't catch that credentials were wrong (wrong token)
  • I was hoping it will clean the "Subscription" tab (image bellow), not the "Watching" tab.
    image

@lobo
Copy link

lobo commented Jan 11, 2021

this work really well! Fast and easy

@jacksonrayhamilton
Copy link

Thanks for this! I'd like to mention a few things in case it helps improve the script or its usage:

  • Dependencies seem to require Python 3 (Python 2 is still the system default on macOS)
  • If using Python 3, I found that with the latest version (3.9.5 for me), I needed to update typed-ast==1.4.0 to typed-ast==1.4.3 in order to install it.
  • The personal access token seems to require SSO. (Otherwise, when I run python unsubscribe.py UrbanCompass, none of the Compass repos show up.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment