1

I need to find all projects and shared projects within a Gitlab group with subgroups. I managed to list the names of all projects like this:

group = gl.groups.get(11111, lazy=True)

# find all projects, also in subgroups
projects=group.projects.list(include_subgroups=True, all=True)
for prj in projects:
    print(prj.attributes['name'])
print("")

What I am missing is to list also the shared projects within the group. Or maybe to put this in other words: find out all projects where my group is a member. Is this possible with the Python API?

3
  • I had much more success just using the HTTP API with the requests library. In my opinion that worked better than using the python library.. Commented Nov 5, 2021 at 8:32
  • Unfortunately, I have zero experience with the HTTP API, it would be way easier for me to stay with python. ;) Commented Nov 5, 2021 at 9:00
  • docs.gitlab.com/ee/api/api_resources.html <- it's not difficult at all :) Commented Nov 5, 2021 at 9:03

4 Answers 4

1

So, inspired by the answer of sytech, I found out that it was not working in the first place, as the shared projects were still hidden in the subgroups. So I came up with the following code that digs through all various levels of subgroups to find all shared projects. I assume this can be written way more elegant, but it works for me:

# group definition
main_group_id = 11111

# create empty list that will contain final result
list_subgroups_id_all = []

# create empty list that act as temporal storage of the results outside the function
list_subgroups_id_stored = []



# function to create a list of subgroups of a group (id)
def find_subgroups(group_id):

    # retrieve group object
    group = gl.groups.get(group_id)

    # create empty lists to store id of subgroups
    list_subgroups_id = []

    #iterate through group to find id of all subgroups
    for sub in group.subgroups.list():
        list_subgroups_id.append(sub.id)

    return(list_subgroups_id)


# function to iterate over the various groups for subgroup detection
def iterate_subgroups(group_id, list_subgroups_id_all):

    # for a given id, find existing subgroups (id) and store them in a list
    list_subgroups_id = find_subgroups(group_id)

    # add the found items to the list storage variable, so that the results are not overwritten
    list_subgroups_id_stored.append(list_subgroups_id)

    # for each found subgroup_id, test if it is already part of the total id list
    # if not, keep store it and test for more subgroups
    for test_id in list_subgroups_id:
        if test_id not in list_subgroups_id_all:

            # add it to total subgroup id list (final results list)
            list_subgroups_id_all.append(test_id)

            # check whether test_id contains more subgroups
            list_subgroups_id_tmp = iterate_subgroups(test_id, list_subgroups_id_all)

            #if so, append to stored subgroup list that is currently checked
            list_subgroups_id_stored.append(list_subgroups_id_tmp)

    return(list_subgroups_id_all)

# find all subgroup and subsubgroups, etc... store ids in list
list_subgroups_id_all = iterate_subgroups(main_group_id , list_subgroups_id_all)

print("***ids of all subgroups***")
print(list_subgroups_id_all)
print("")

print("***names of all subgroups***")
list_names = []
for ids in list_subgroups_id_all:
    group = gl.groups.get(ids)
    group_name = group.attributes['name']
    list_names.append(group_name)
print(list_names)
#print(list_subgroups_name_all)
print("")

# print all directly integrated projects of the main group, also those in subgroups
print("***integrated projects***")
group = gl.groups.get(main_group_id)
projects=group.projects.list(include_subgroups=True, all=True)
for prj in projects:
    print(prj.attributes['name'])
print("")

# print all shared projects
print("***shared projects***")
for sub in list_subgroups_id_all:
    group = gl.groups.get(sub)
    for shared_prj in group.shared_projects:
        print(shared_prj['path_with_namespace'])
print("")

One question that remains - at the very beginning I retrieve the main group by its id (here: 11111), but can I actually also get this id by looking for the name of the group? Something like: group_id = gl.group.get(attribute={'name','foo'}) (not working)?

Sign up to request clarification or add additional context in comments.

Comments

1

This code will query all the projects in each subgroup and handle multiple subgroups inside a subgroup as well. it works perfectly and I hope it helps someone else.

import gitlab
import os

# Set your GitLab API access token
access_token = 'GITLAB_ACCESS_TOKEN'
if not access_token:
    raise ValueError("No GitLab access token found. Please set the GITLAB_ACCESS_TOKEN environment variable.")

# Set the URL of your GitLab instance
gitlab_url = os.getenv('GITLAB_URL', 'https://gitLab.com/')

# Replace this with your target subgroup path
subgroup_path = '2323' #'your/subgroup/path or your subgroup number'

# Initialize the GitLab connection
gl = gitlab.Gitlab(gitlab_url, private_token=access_token)

# Recursively find all projects in the subgroup and its subgroups
def find_projects_in_group(group):
    projects = gl.groups.get(group.id).projects.list(all=True)
    
    subgroups = gl.groups.get(group.id).subgroups.list(all=True)
    
    for subgroup in subgroups:
        projects.extend(find_projects_in_group(subgroup))
    return projects

# Find the target subgroup
try:
    target_group = gl.groups.get(subgroup_path)
except gitlab.exceptions.GitlabGetError:
    raise ValueError("Subgroup not found: " + subgroup_path)

# Get the list of projects
projects = find_projects_in_group(target_group)

# Print the list of projects
for project in projects:
    print("project path:["+project.ssh_url_to_repo+"]" )

Comments

0

You can get the shared projects by the .shared_projects attribute:

group = gl.groups.get(11111)
for proj in group.shared_projects:
    print(proj['path_with_namespace'])

However, you cannot use the lazy=True argument to gl.groups.get.

>>> group = gl.groups.get(11111, lazy=True)
>>> group.shared_projects
AttributeError: shared_projects

1 Comment

Unfortunately, that does not work for me. I only get the same results like before, that means all the projects, but not the shared projects.
0
# This code will list all files with specific extension (*.pdf)



import gitlab
import re

gl = gitlab.Gitlab('<gitlab url>', private_token='<private gitlab token')
f = open('result.txt', 'w')

def processGroup(groupName, parentGroup):
    # print(groupName)

    group = gl.groups.get(groupName)

    # print('***** ' + group.name + ' ******')

    projects = group.projects.list(iterator=True)
    for project in projects:
        print('\n' + parentGroup + '/' + group.name + '/' + project.name + '\n *********************************************')
        f.write('\n' + parentGroup + '/' + group.name + '/' + project.name + '\n *********************************************\n')
    
        prj = gl.projects.get(project.id)
        try:
            for filename in prj.repository_tree(recursive=True, iterator=True):
                # print(filename.get('path'))
                filenamePath = filename.get('path')
                if re.search('[.]pdf$', filenamePath):
                    print(group.name + '/' + project.name + '/' + filenamePath)
                    f.write(group.name + '/' + project.name + '/' + filenamePath + '\n')
        except:
            print('No files in ' + prj.name) 

    parentGroup = parentGroup + '/' if len(parentGroup) else '' + groupName
    for subGroup in group.subgroups.list(iterator=True):
            processGroup(subGroup.id, parentGroup)
    
 

processGroup('<gitlab group>', '')
f.close()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.