Table of Contents
gitlab
package)gitlab
command)python-gitlab currently only supports v4 of the GitLab REST API.
gitlab.Gitlab
class¶To connect to GitLab.com or another GitLab instance, create agitlab.Gitlab
object:
Hint
You can use different types of tokens for authenticated requests against the GitLab API.You will most likely want to use a resource (project/group) access token or a personalaccess token.
For the full list of available options and how to obtain these tokens, please seehttps://docs.gitlab.com/api/rest/authentication/.
importgitlab# anonymous read-only access for public resources (GitLab.com)gl=gitlab.Gitlab()# anonymous read-only access for public resources (self-hosted GitLab instance)gl=gitlab.Gitlab('https://gitlab.example.com')# private token or personal token authentication (GitLab.com)gl=gitlab.Gitlab(private_token='JVNSESs8EwWRx5yDxM5q')# private token or personal token authentication (self-hosted GitLab instance)gl=gitlab.Gitlab(url='https://gitlab.example.com',private_token='JVNSESs8EwWRx5yDxM5q')# oauth token authenticationgl=gitlab.Gitlab('https://gitlab.example.com',oauth_token='my_long_token_here')# job token authentication (to be used in CI)# bear in mind the limitations of the API endpoints it supports:# https://docs.gitlab.com/ci/jobs/ci_job_tokenimportosgl=gitlab.Gitlab('https://gitlab.example.com',job_token=os.environ['CI_JOB_TOKEN'])# Define your own custom user agent for requestsgl=gitlab.Gitlab('https://gitlab.example.com',user_agent='my-package/1.0.0')# make an API request to create the gl.user object. This is not required but may be useful# to validate your token authentication. Note that this will not work with job tokens.gl.auth()# Enable "debug" mode. This can be useful when trying to determine what# information is being sent back and forth to the GitLab server.# Note: this will cause credentials and other potentially sensitive# information to be printed to the terminal.gl.enable_debug()
You can also use configuration files to creategitlab.Gitlab
objects:
gl=gitlab.Gitlab.from_config('somewhere',['/tmp/gl.cfg'])
See theConfiguration section for more information aboutconfiguration files.
Warning
Note that a url that results in 301/302 redirects will raise an error,so it is highly recommended to use the final destination in theurl
field.For example, if the GitLab server you are using redirects requests from httpto https, make sure to use thehttps://
protocol in the URL definition.
A URL that redirects using 301/302 (rather than 307/308) will most likelycause malformed POST and PUT requests.
python-gitlab will therefore raise aRedirectionError
when it encountersa redirect which it believes will cause such an error, to avoid confusionbetween successful GET and failing POST/PUT requests on the same instance.
GitLab has long removed password-based basic authentication. You can currently still use theresource owner password credentialsflow to obtain an OAuth token.
However, we do not recommend this as it will not work with 2FA enabled, and GitLab is removingROPC-based flows without client IDs in a future release. We recommend you obtain tokens forautomated workflows as linked above or obtain a session cookie from your browser.
For a python example of password authentication using the ROPC-based OAuth2flow, seethis Ansible snippet.
Thegitlab.Gitlab
class provides managers to access the GitLab resources.Each manager provides a set of methods to act on the resources. The availablemethods depend on the resource type.
Examples:
# list all the projectsprojects=gl.projects.list(iterator=True)forprojectinprojects:print(project)# get the group with id == 2group=gl.groups.get(2)forprojectingroup.projects.list(iterator=True):print(project)
Warning
Callinglist()
without any arguments will by default not return the complete listof items. Use either theget_all=True
oriterator=True
parameters to get all theitems when using listing methods. See thePagination section for moreinformation.
# create a new useruser_data={'email':'jen@foo.com','username':'jen','name':'Jen'}user=gl.users.create(user_data)print(user)
Note
python-gitlab attempts to sync the required, optional, and mutually exclusive attributesfor resource creation and update with the upstream API.
You are encouraged to follow upstream API documentation for each resource to find these -each resource documented here links to the corresponding upstream resource documentationat the top of the page.
The attributes of objects are defined upon object creation, and depend on theGitLab API itself. To list the available information associated with an objectuse theattributes
attribute:
project=gl.projects.get(1)print(project.attributes)
Some objects also provide managers to access related GitLab resources:
# list the issues for a projectproject=gl.projects.get(1)issues=project.issues.list(get_all=True)
python-gitlab allows to send any data to the GitLab server when making queries.In case of invalid or missing arguments python-gitlab will raise an exceptionwith the GitLab server error message:
>>>gl.projects.list(get_all=True,sort='invalid value')...GitlabListError: 400: sort does not have a valid value
You can use thequery_parameters
argument to send arguments that wouldconflict with python or python-gitlab when using them as kwargs:
gl.user_activities.list(from='2019-01-01',iterator=True)## invalidgl.user_activities.list(query_parameters={'from':'2019-01-01'},iterator=True)# OK
You can update or delete a remote object when it exists locally:
# update the attributes of a resourceproject=gl.projects.get(1)project.wall_enabled=False# don't forget to apply your changes on the server:project.save()# delete the resourceproject.delete()
Some classes provide additional methods, allowing more actions on the GitLabresources. For example:
# star a git repositoryproject=gl.projects.get(1)project.star()
You can print a Gitlab Object. For example:
project=gl.projects.get(1)print(project)# Or in a prettier format.project.pprint()# Or explicitly via ``pformat()``. This is equivalent to the above.print(project.pformat())
You can also extend the object if the parameter isn’t explicitly listed. For example,if you want to update a field that has been newly introduced to the Gitlab API, settingthe value on the object is accepted:
issues=project.issues.list(get_all=True,state='opened')forissueinissues:issue.my_super_awesome_feature_flag="random_value"issue.save()
You can get a dictionary representation copy of the Gitlab Object. Modifications made tothe dictionary will have no impact on the GitLab Object.
asdict()
method. Returns a dictionary representation of the Gitlab object.
attributes
property. Returns a dictionary representation of the Gitlabobject. Also returns any relevant parent object attributes.
project=gl.projects.get(1)project_dict=project.asdict()# Or a dictionary representation also containing some of the parent attributesissue=project.issues.get(1)attribute_dict=issue.attributes# The following will return the same valuetitle=issue.titletitle=issue.attributes["title"]
Hint
This can be used to access attributes that clash with python-gitlab’s own methods or managers.Note that:
attributes
returns the parent object attributes that are defined inobject._from_parent_attrs
. For example, aProjectIssue
object will have aproject_id
key in the dictionary returned fromattributes
butasdict()
will not.
You can get a JSON string represenation of the Gitlab Object. For example:
project=gl.projects.get(1)print(project.to_json())# Use arguments supported by ``json.dump()``print(project.to_json(sort_keys=True,indent=4))
Thegitlab
package provides some base types.
gitlab.Gitlab
is the primary class, handling the HTTP requests. It holdsthe GitLab URL and authentication information.
gitlab.base.RESTObject
is the base class for all the GitLab v4 objects.These objects provide an abstraction for GitLab resources (projects, groups,and so on).
gitlab.base.RESTManager
is the base class for v4 objects managers,providing the API to manipulate the resources and their attributes.
To avoid useless API calls to the server you can create lazy objects. Theseobjects are created locally using a known ID, and give access to other managersand methods.
The following example will only make one API call to the GitLab server to stara project (the previous example used 2 API calls):
# star a git repositoryproject=gl.projects.get(1,lazy=True)# no API callproject.star()# API call
head()
methods¶All endpoints that supportget()
andlist()
also support ahead()
method.In this case, the server responds only with headers and not the response JSON or body.This allows more efficient API calls, such as checking repository file size withoutfetching its content.
Note
In some cases, GitLab may omit specific headers. See more in thePagination section.
# See total number of personal access tokens for current usergl.personal_access_tokens.head()print(headers["X-Total"])# See returned content-type for project GET endpointheaders=gl.projects.head("gitlab-org/gitlab")print(headers["Content-Type"])
You can use pagination to iterate over long lists. All the Gitlab objectslisting methods support thepage
andper_page
parameters:
ten_first_groups=gl.groups.list(page=1,per_page=10)
Warning
The first page is page 1, not page 0.
By default GitLab does not return the complete list of items. Use theget_all
parameter to get all the items when using listing methods:
all_groups=gl.groups.list(get_all=True)all_owned_projects=gl.projects.list(owned=True,get_all=True)
You can define theper_page
value globally to avoid passing it to everylist()
method call:
gl=gitlab.Gitlab(url,token,per_page=50)
Gitlab allows to also use keyset pagination. You can supply it to your project listing,but you can also do so globally. Be aware that GitLab then also requires you to only use supportedorder options. At the time of writing, onlyorder_by="id"
works.
gl=gitlab.Gitlab(url,token,pagination="keyset",order_by="id",per_page=100)gl.projects.list(get_all=True)
Reference:https://docs.gitlab.com/api/rest/#keyset-based-pagination
list()
methods can also return a generator object, by passing the argumentiterator=True
, which will handle the next calls to the API when required. Thisis the recommended way to iterate through a large number of items:
items=gl.groups.list(iterator=True)foriteminitems:print(item.attributes)
The generator exposes extra listing information as received from the server:
current_page
: current page number (first page is 1)
prev_page
: ifNone
the current page is the first one
next_page
: ifNone
the current page is the last one
per_page
: number of items per page
total_pages
: total number of pages available. This may be aNone
value.
total
: total number of items in the list. This may be aNone
value.
Note
For performance reasons, if a query returns more than 10,000 records, GitLabdoes not return thetotal_pages
ortotal
headers. In this case,total_pages
andtotal
will have a value ofNone
.
For more information see:https://docs.gitlab.com/user/gitlab_com/index#pagination-response-headers
Note
Prior to python-gitlab 3.6.0 the argumentas_list
was used instead ofiterator
.as_list=False
is the equivalent ofiterator=True
.
Note
Ifpage
anditerator=True
are used together, the latter is ignored.
If you have the administrator status, you can usesudo
to act as anotheruser. For example:
p=gl.projects.create({'name':'awesome_project'},sudo='user1')
Warning
When usingsudo
, its usage is not remembered. If you usesudo
toretrieve an object and then later usesave()
to modify the object, itwill not usesudo
. You should usesave(sudo='user1')
if you want toperform subsequent actions as the user.
sudo
¶An example of how toget
an object (usingsudo
), modify the object, andthensave
the object (usingsudo
):
group=gl.groups.get('example-group')notification_setting=group.notificationsettings.get(sudo='user1')notification_setting.level=gitlab.const.NOTIFICATION_LEVEL_GLOBAL# Must use 'sudo' again when doing the save.notification_setting.save(sudo='user1')
To enable debug logging from the underlyingrequests
andhttp.client
calls,you can useenable_debug()
on yourGitlab
instance. For example:
importosimportgitlabgl=gitlab.Gitlab(private_token=os.getenv("GITLAB_TOKEN"))gl.enable_debug()
By default, python-gitlab will mask the token used for authentication in logging output.If you’d like to debug credentials sent to the API, you can disable masking explicitly:
gl.enable_debug(mask_credentials=False)
When methods manipulate an existing object, such as withrefresh()
andsave()
,the object will only have attributes that were returned by the server. In some cases,such as when the initial request fetches attributes that are needed later for additionalprocessing, this may not be desired:
project=gl.projects.get(1,statistics=True)project.statisticsproject.refresh()project.statistics# AttributeError
To avoid this, either copy the object/attributes before callingrefresh()
/save()
or subsequently perform anotherget()
call as needed, to fetch the attributes you want.