Bulk Delete Github Repositories

Bulk Delete Github Repositories

Introduction

Deleting repositories hosted in github is not that easy, each time a repository is going to be deleted, github requires ower to type the repository’s name, not to say to delete multiple repositories.

Even if github does not require repository’s ower to type repository’s name to confirm the delete operation, deleting mass repositories is also a big challenge. So is there a convenient way to delete all deprecated repositories?

Github API v3 makes it easy for this task to be accomplished, the central idea is listing repositories and deleting them.

How To

Listing repositories

According to documentation, listing an authenticated user’s repositories, the following API should be used.

1
GET /user/repos

To examin the API and see what does it output, curl can be used, according to documentation, basic authentication is enough, so the command should be like this:

1
curl -u username:password "https://api.github.com/user/repos"

To see what curl really does in the command before just type the following command:

1
curl -v -u username:password "https://api.github.com/user/repos"

Some of the output should be like this:

1
2
3
4
5
GET /user/repos HTTP/1.1
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
User-Agent: curl/7.41.0
Host: api.github.com
Accept: */*

By observing the output, it can be concluded that curl did nothing but built a http request packet in conjunction with user’s name and password by using basic access authentication, sent it to github and printed result back to user.

So it’s might be a little easy to do the same thing in Python code, just build and send a request and wait for result.

1
2
3
4
5
6
7
8
9
10
request = urllib.request.Request('https://api.github.com/user/repos', method='GET')

#Construct authorization field.
auth = base64.encodebytes(str(('%s:%s' % (username, password))).encode('utf-8'))
auth = auth.decode('utf-8').replace('\n', '')
request.add_header('Authorization', 'Basic %s' % auth)
result = urllib.request.urlopen(request).read().decode('utf-8')

#Convert the JSON formatted result to a native Python object
result = json.loads(result)

Deleting a repository

To delete a repository, the following API can be used

1
DELETE /repos/:owner/:repo

Based on the knowledge in last section, the following code just need to be written:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
request = urllib.request.Request('https://api.github.com/repos/' + user + '/' + reponame , method='DELETE')
auth = base64.encodebytes(str(('%s:%s' % (username, password))).encode('utf-8'))
auth = auth.decode('utf-8').replace('\n', '')
request.add_header('Authorization', 'Basic %s' % auth)

try:
response = urllib.request.urlopen(request)

if response.code == 204:
print('repo %s has been successfully deleted' % repo['name'])
else:
return response.code
except HTTPError as error:

if error.code == 403:
print('Repository %s is unavailable due to DMCA takedown.' % repo_name)
skip_count += 1
else:
raise error

Deleting repositories

To bulk delete repositories the only thing need to be done is just mixed previous sections together.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import json
import base64
import urllib.request
from urllib.error import HTTPError


class Github(object):
def __init__(self, user, passwd):
"""
:param user: User name of github
:param passwd: Pass word of github
:return:
"""
self.__user = user
self.__passwd = passwd

# Obtain repositories list
def list_repos(self):
"""
:return: A python object contains all repositories information
"""
request = self.__request('https://api.github.com/user/repos')
result = urllib.request.urlopen(request).read().decode('utf-8')
result = json.loads(result)

return result

def __request(self, url, method=None):

request = urllib.request.Request(url, method=method)
auth = base64.encodebytes(str(('%s:%s' % (self.__user, self.__passwd))).encode('utf-8'))
auth = auth.decode('utf-8').replace('\n', '')
request.add_header('Authorization', 'Basic %s' % auth)

return request

# Delete all github repos
def remove_repos(self):
"""
:return: None
"""
repos = self.list_repos()

#Disabled repositories need to be skipped in order to prevent the loop being interrupted.
skip_count = 0

while len(repos) != skip_count:

for repo in repos:

repo_name = repo['name']
repo_url = 'repos/' + self.__user + '/' + repo_name
request = self.__request('https://api.github.com/' + repo_url, 'DELETE')

try:

response = urllib.request.urlopen(request)

if response.code == 204:
print('repo %s has been successfully deleted' % repo['name'])
else:
return response.code
except HTTPError as error:

if error.code == 403:
print('Repository %s is unavailable due to DMCA takedown.' % repo_name)
skip_count += 1
else:
raise error

repos = self.list_repos()

Conclusion

Manipulating repositories by using Github API v3 is easy, but one of its main drawback is that there is no way to delete repositories that are unavailable due to DMCA Takedown Policy but to contact github manually for help.

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×