Python wrapper for the GitLab API

Overview
https://readthedocs.org/projects/python-gitlab/badge/?version=latest https://codecov.io/github/python-gitlab/python-gitlab/coverage.svg?branch=master

Python GitLab

python-gitlab is a Python package providing access to the GitLab server API.

It supports the v4 API of GitLab, and provides a CLI tool (gitlab).

Installation

Requirements

python-gitlab depends on:

Install with pip

pip install python-gitlab

Using the python-gitlab docker image

How to build

docker build -t python-gitlab:TAG .

How to use

docker run -it --rm -e GITLAB_PRIVATE_TOKEN=<your token> -v /path/to/python-gitlab.cfg:/python-gitlab.cfg python-gitlab <command> ...

or run it directly from the upstream image:

docker run -it --rm -e GITLAB_PRIVATE_TOKEN=<your token> -v /path/to/python-gitlab.cfg:/python-gitlab.cfg registry.gitlab.com/python-gitlab/python-gitlab:latest <command> ...

To change the GitLab URL, use -e GITLAB_URL=<your url>

Bring your own config file: docker run -it --rm -v /path/to/python-gitlab.cfg:/python-gitlab.cfg -e GITLAB_CFG=/python-gitlab.cfg python-gitlab <command> ...

Bug reports

Please report bugs and feature requests at https://github.com/python-gitlab/python-gitlab/issues.

Documentation

The full documentation for CLI and API is available on readthedocs.

Build the docs

You can build the documentation using sphinx:

pip install sphinx
python setup.py build_sphinx

Contributing

You can contribute to the project in multiple ways:

  • Write documentation
  • Implement features
  • Fix bugs
  • Add unit and functional tests
  • Everything else you can think of

Development workflow

Before contributing, please make sure you have pre-commit installed and configured. This will help automate adhering to code style and commit message guidelines described below:

cd python-gitlab/
pip3 install --user pre-commit
pre-commit install -t pre-commit -t commit-msg --install-hooks

Please provide your patches as GitHub pull requests. Thanks!

Commit message guidelines

We enforce commit messages to be formatted using the conventional-changelog. This leads to more readable messages that are easy to follow when looking through the project history.

Code-Style

We use black as code formatter, so you'll need to format your changes using the black code formatter. Pre-commit hooks will validate/format your code when committing. You can then stage any changes black added if the commit failed.

To format your code according to our guidelines before committing, run:

cd python-gitlab/
pip3 install --user black
black .

Running unit tests

Before submitting a pull request make sure that the tests still succeed with your change. Unit tests and functional tests run using the travis service and passing tests are mandatory to get merge requests accepted.

We're currently in a restructing phase for the unit tests. If you're changing existing tests, feel free to keep the current format. Otherwise please write new tests with pytest and using responses. An example for new tests can be found in tests/objects/test_runner.py

You need to install tox to run unit tests and documentation builds locally:

# run the unit tests for all supported python3 versions, and the pep8 tests:
tox

# run tests in one environment only:
tox -epy38

# build the documentation, the result will be generated in
# build/sphinx/html/
tox -edocs

Running integration tests

Integration tests run against a running gitlab instance, using a docker container. You need to have docker installed on the test machine, and your user must have the correct permissions to talk to the docker daemon.

To run these tests:

# run the CLI tests:
tox -e cli_func_v4

# run the python API tests:
tox -e py_func_v4

By default, the tests run against the latest version of the gitlab/gitlab-ce image. You can override both the image and tag by providing either the GITLAB_IMAGE or GITLAB_TAG environment variables.

This way you can run tests against different versions, such as nightly for features in an upcoming release, or an older release (e.g. 12.8.0-ce.0). The tag must match an exact tag on Docker Hub:

# run tests against `nightly` or specific tag
GITLAB_TAG=nightly tox -e py_func_v4
GITLAB_TAG=12.8.0-ce.0 tox -e py_func_v4

# run tests against the latest gitlab EE image
GITLAB_IMAGE=gitlab/gitlab-ee tox -e py_func_v4

A freshly configured gitlab container will be available at http://localhost:8080 (login root / password 5iveL!fe). A configuration for python-gitlab will be written in /tmp/python-gitlab.cfg.

To cleanup the environment delete the container:

docker rm -f gitlab-test
docker rm -f gitlab-runner-test
Comments
  • api authentication is not working

    api authentication is not working

    api call is not working.

    File "auth.py", line 3, in import gitlab File "D:\DevOps\gitlab\gitlab.py", line 17, in g1() File "D:\DevOps\gitlab\gitlab.py", line 10, in g1 gl = gitlab.Gitlab('http://gitlab.com', oauth_token='rUAuB2dWFxccvbbd') AttributeError: module 'gitlab' has no attribute 'Gitlab'

    In page: api-usage.rst

    opened by jaydip189 28
  • feat: add support for mutually exclusive attributes, consolidate attribute validation, fix boards.py _create_attr

    feat: add support for mutually exclusive attributes, consolidate attribute validation, fix boards.py _create_attr

    feat: add support for mutually exclusive attributes, consolidate attribute validation, fix boards.py _create_attr

    • add exclusive tuple to RequiredOptional data class to add support for mutually exclusive attributes
    • consolidate _check_missing_create_attrs and _check_missing_update_attrs from mixins.py into _validate_attrs in utils.py
    • change _create_attrs in board list manager classes from required=('label_ld',) to exclusive=('label_id','asignee_id','milestone_id')

    closes #1897

    opened by walterrowe 26
  • gl.projects.get() fails when provided

    gl.projects.get() fails when provided "namespace/project_name"

    Description of the problem, including code/CLI snippet

    In project-status.py ...

        for this_project in options.project:
            this_project = my_gitlab.projects.get(this_project)
            print("Adding project:", this_project.path_with_namespace)
            projects = projects + [this_project]
    
    • when this_project provided in "namespace/project_name" format, projects.get() fails with 404 error.
    • when this_project specified in project_id format, projects.get() succeeds.
    • same API access token for both forms of request.
    • access token is a project level token with full rights.

    Expected Behavior

    this_project = my_gitlab.projects.get("namespace/project_name") succeeds

    Actual Behavior

    this_project = my_gitlab.projects.get("namespace/project_name") fails with 404 error

    % ./project-status.py --config ~/.python-gitlab.cfg --section gitlab-https --project https-phase2/ha-proxy-migration
    Traceback (most recent call last):
      File "/usr/local/lib/python3.10/site-packages/gitlab/exceptions.py", line 330, in wrapped_f
        return f(*args, **kwargs)
      File "/usr/local/lib/python3.10/site-packages/gitlab/mixins.py", line 139, in get
        server_data = self.gitlab.http_get(path, **kwargs)
      File "/usr/local/lib/python3.10/site-packages/gitlab/client.py", line 790, in http_get
        result = self.http_request(
      File "/usr/local/lib/python3.10/site-packages/gitlab/client.py", line 756, in http_request
        raise gitlab.exceptions.GitlabHttpError(
    gitlab.exceptions.GitlabHttpError: 404: 404 Not Found
    
    The above exception was the direct cause of the following exception:
    
    Traceback (most recent call last):
      File "/Users/wrowe/git-repos/python-gitlab/./project-status.py", line 139, in <module>
        this_project = my_gitlab.projects.get(this_project)
      File "/usr/local/lib/python3.10/site-packages/gitlab/v4/objects/projects.py", line 775, in get
        return cast(Project, super().get(id=id, lazy=lazy, **kwargs))
      File "/usr/local/lib/python3.10/site-packages/gitlab/exceptions.py", line 332, in wrapped_f
        raise error(e.error_message, e.response_code, e.response_body) from e
    gitlab.exceptions.GitlabGetError: 404: 404 Not Found
    
    % ./project-status.py --config ~/.python-gitlab.cfg --section gitlab-https --project 3894 
    Adding project: https-phase2/ha-proxy-migration
    Scanning issues for ha-proxy-migration ...
    Building report for ha-proxy-migration ...
    Writing report file ...
    

    Specifications

    • python-gitlab version: 3.6.0
    • API version you are using (v3/v4): v4
    • Gitlab server version (or gitlab.com): 14.0.12 Community Edition
    opened by walterrowe 24
  • feat: allow global retry_transient_errors

    feat: allow global retry_transient_errors

    Value set on the Gitlab object will be used as a default in case every subsequent API call does not provide a retry_transient_errors parameter.

    This allows code to be succinct and the retry policy to be set for all calls to the Gitlab instance.

    opened by javatarz 20
  • Support for GitLab API v4

    Support for GitLab API v4

    https://about.gitlab.com/2017/02/22/gitlab-8-17-released/

    This blog post announces the fourth version of the API to be introduced as of March 22nd, GitLab 9.0 and the v3 to be removed with 9.3 (that's about three months).

    enhancement 
    opened by GhostLyrics 20
  • Create a issue board list by milestone_id still depends on label_id

    Create a issue board list by milestone_id still depends on label_id

    Description of the problem, including code/CLI snippet

    I followed the API documentation which says that the usage of label_id, milestone_id and assignee_id is mutually exclusive. So I wanted to create a board which would relate on milestones to have a timeline. The function goes like:

    
    def create_board(repository):
      milestones = repository.milestones.list()
      for milestone in milestones:
        print(f'ID: {milestone.id}')
        timeline_board.lists.create({
          'milestone_id': milestone.id
        })
    

    Expected Behavior

    Normally the board should be created according to the documentation.

    Actual Behavior

    AttributeError: Missing attributes: label_id
    

    Specifications

    • python-gitlab==3.1.1
    • Gitlab server version (or gitlab.com): 14.2.4-ee
    bug good first issue 
    opened by kurisukun 18
  • fix: honor parameter value passed

    fix: honor parameter value passed

    Gitlab allows setting the defaults for MR to delete the source. Also the inline help of the CLI suggest that a boolean is expected, but no matter what value you set, it will always delete.

    To mimic the existing behavior as good as possible, we check for not false instead of true. This way the impact on the cli will be minimal.

    opened by ghost 17
  • Maintainer wanted

    Maintainer wanted

    Hi,

    I'm currently the only maintainer of python-gitlab, and don't have a lot of time to work on this project. I'm looking for co-maintainers for starters, with the goal of retiring entirely from the project at some point.

    Please comment on this bug if you're interested in participating in this project development, or send me a mail if you prefer.

    Thanks!

    opened by gpocentek 17
  • feat: Add play command to project pipeline schedules

    feat: Add play command to project pipeline schedules

    I have added a custom play command to the project pipeline schedules.

    I made a previous pull request #1068 but the commits were incorrect. I also fixed the lint errors.

    Please let me know if I am missing anything else.

    opened by twonds 16
  • `AttributeError` on projects within groups

    `AttributeError` on projects within groups

    I'm testing the creation of files through the API and when the files has a path directory that needs to be created, the API returns an AttributeError.

    Note that using the GitLab POST (https://docs.gitlab.com/ee/api/repository_files.html#create-new-file-in-repository) successfully creates the file and the needed path.

    bug 
    opened by adinriv 16
  • Failed to save issue

    Failed to save issue

    Trying a simple:

    $ python
    Python 3.6.3 (default, Oct 24 2017, 14:48:20)                                                                                                                                             
    [GCC 7.2.0] on linux                                                                                                                                                                      
    Type "help", "copyright", "credits" or "license" for more information.                                                                                                                    
    >>> import gitlab
    >>> gl = gitlab.Gitlab('http://gitlab.com', 'XXXXXXXXXXXXX', api_version=4)
    >>> i = gl.projects.get(XXXXXX).issues.get(XXXX)
    >>> i.save()
    Traceback (most recent call last):
      File "/home/stratos/.virtualenvs/gliss-django/lib/python3.6/site-packages/gitlab/exceptions.py", line 239, in wrapped_f
        return f(*args, **kwargs)
      File "/home/stratos/.virtualenvs/gliss-django/lib/python3.6/site-packages/gitlab/mixins.py", line 222, in update
        return self.gitlab.http_put(path, post_data=data, **kwargs)
      File "/home/stratos/.virtualenvs/gliss-django/lib/python3.6/site-packages/gitlab/__init__.py", line 834, in http_put
        post_data=post_data, **kwargs)
      File "/home/stratos/.virtualenvs/gliss-django/lib/python3.6/site-packages/gitlab/__init__.py", line 713, in http_request
        response_body=result.content)
    gitlab.exceptions.GitlabHttpError: 400: b'{"error":"title, description, assignee_ids, assignee_id, milestone_id, labels, created_at, due_date, confidential, state_event, weight, discussion_locked are missing, at least one parameter must be provided"}'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/stratos/.virtualenvs/gliss-django/lib/python3.6/site-packages/gitlab/mixins.py", line 281, in save
        server_data = self.manager.update(obj_id, updated_data, **kwargs)
      File "/home/stratos/.virtualenvs/gliss-django/lib/python3.6/site-packages/gitlab/exceptions.py", line 241, in wrapped_f
        raise error(e.error_message, e.response_code, e.response_body)
    gitlab.exceptions.GitlabUpdateError: 400: b'{"error":"title, description, assignee_ids, assignee_id, milestone_id, labels, created_at, due_date, confidential, state_event, weight, discussion_locked are missing, at least one parameter must be provided"}'
    >>> i.title
    'Sample issue'
    >>> i.description
    'Sample description'
    

    fails on the current 10.1.3-ee version of gitlab.com.

    docs 
    opened by stratosgear 15
  • feat: PEP 544 – Protocols: Structural subtyping (static duck typing)

    feat: PEP 544 – Protocols: Structural subtyping (static duck typing)

    The purpose of this change is to track api changes. For example: package versioning and breaking change announcement in case of protocol change. This is MVP implementation to be used by #2435 Haven't figured out yet how to implement unit tests for a protocol and its value.

    opened by lmilbaum 1
  • netrc auth overrides OAuth bearer token header

    netrc auth overrides OAuth bearer token header

    Description of the problem, including code/CLI snippet

    When using the OAuth integration while having a .netrc file on the filesystem, the .netrc authentication overrides the OAuth bearer token.

    Use the following code to trigger an error:

    user_token = "long oauth token here"
    client = gitlab.Gitlab(url=settings.GITLAB_BASE_URL, oauth_token=user_token)
    
    # Trigger an HTTP 401 response (GitlabAuthenticationError):
    client.auth()
    

    (Any call using the Client's http_xxx() method should fail; auth() is the easiest to use, though)

    Expected Behavior

    Every request to the GitLab API via the Gitlab object should authenticate using the OAuth token provided by the user when initializing the client. It should use the Authorization header containing the OAuth token as a bearer.

    Actual Behavior

    Instead of using the bearer token from the passed headers kwarg, requests falls back to basic authentication using credentials from the netrc file.

    Troubleshooting

    So far, I've found out the following:

    • The header override occurs in requests.sessions.prepare_request()
    • At line 481, since request.auth is empty, auth is filled using get_netrc_auth()
      • At line 494, the auth containing netrc values is passed to the prepared request
    • At line 490, the python-gitlab authorization header get overridden by requests' basic auth one

    See also this relevant quote from Requests netrc documentation:

    If no authentication method is given with the auth argument, Requests will attempt to get the authentication credentials for the URL’s hostname from the user’s netrc file. The netrc file overrides raw HTTP authentication headers set with headers=.

    If credentials for the hostname are found, the request is sent with HTTP Basic Auth.

    This might be fixed by explicitly passing an auth kwarg when using requests to make requests.

    Specifications

    • python-gitlab version: 3.12.0
    • requests version: 2.28.1
    • API version you are using (v3/v4): v4
    • Gitlab server version (or gitlab.com): 15.6.2-ee
    enhancement docs 
    opened by MHLut 3
  • feat(client): replace basic auth with OAuth ROPC flow

    feat(client): replace basic auth with OAuth ROPC flow

    Small step towards https://github.com/python-gitlab/python-gitlab/issues/1195, and also to get rid of the old username/password auth.

    Also gets rid of the requests-specific HTTPBasicAuth.

    opened by nejch 2
  • Allow update of protected branches

    Allow update of protected branches

    In gitlab 15.6 gitlab finally added api support to update protected branch settings, so ProjectProtectedBranch should be updated accordingly

    https://gitlab.com/gitlab-org/gitlab/-/issues/20229/

    feature EE help wanted 
    opened by hoerup 2
Releases(v3.12.0)
Yes, it's true :two_hearts: This repository has 316 stars.

Yes, it's true! Inspired by a similar repository from @RealPeha, but implemented using a webhook on AWS Lambda and API Gateway, so it's serverless! If

510 Dec 28, 2022
A simple program to display current playing from Spotify app on your desktop

WallSpot A simple program to display current playing from Spotify app on your desktop How to Use: Linux: Currently Supports GNOME and KDE. If you want

Nannan 4 Feb 19, 2022
This is a discord token generator(requests) which works and makes 200 tokens per minute

Discord Email verified token generator Creates email verified discord accounts (unlocked) Report Bug · Discord server Features Profile pictures and na

131 Dec 10, 2022
Python3 script to dump employee information from XING API

XingDumper Python 3 script to dump company employees from XING API. Perfect OSINT tool ;-) The results contain firstname, lastname, position, gender,

LRVT 11 Dec 26, 2022
Torrent-Igruha SDK Python

Простой пример использования библиотеки: Устанавливаем библиотеку python -m

LORD_CODE 2 Jun 25, 2022
Automatically kick deleted accounts

AntiDeletedAccountsBot (ADAB) Automatically kick deleted accounts Based on uniborg, a pluggable asyncio Telegram userbot based on Telethon. Installati

Qwerty-Space 34 Jan 02, 2023
Signs the target email up to over 1000 different mailing lists to get spammed each day.

Email Bomber Say goodbye to that email Features Signs up to over 1k different mailing lists Written in python so the program is lightweight Easy to us

Loxdr 1 Nov 30, 2021
Rio Userbot Adalah Bot Untuk Membantu Mempermudahkan Sesuatu Di Telegram, Last Repository With Pytgcalls v0.8.3

RIO - USERBOT Disclaimer Saya tidak bertanggung jawab atas penyalahgunaan bot ini. Bot ini dimaksudkan untuk bersenang-senang sekaligus membantu Anda

RioProjectX 4 Oct 18, 2022
asyncio client for Deta Cloud

aiodeta Unofficial client for Deta Clound Install pip install aiodeta Supported functionality Deta Base Deta Drive Decorator for cron tasks Examples i

Andrii Leitsius 19 Feb 14, 2022
Ma2tl - macOS forensic timeline generator using the analysis result DBs of mac apt

ma2tl (mac_apt to timeline) This is a DFIR tool for generating a macOS forensic

Minoru Kobayashi 66 Nov 18, 2022
An Telegram Bot By @ZauteKm To Stream Videos In Telegram Voice Chat Of Both Groups & Channels. Supports Live Streams, YouTube Videos & Telegram Media !!

Telegram Video Stream Bot (Py-TgCalls) An Telegram Bot By @ZauteKm To Stream Videos In Telegram Voice Chat Of Both Groups & Channels. Supports Live St

Zaute Km 14 Oct 21, 2022
Herramienta para transferir eventos de Sucuri WAF hacia Azure Data Tables.

Transfiere eventos de Sucuri hacia Azure Data Tables Script para transferir eventos del Sucuri Web Application Firewall (WAF) hacia Azure Data Tables,

CSIRT-RD 1 Dec 22, 2021
✨ A simple project to automate some stuffs in Habbo with G-Earth ✨

⚡️ Habbo G-Earth extensions ⚡️ ✨ A simple project to automate some stuffs in Habbo with G-Earth ✨ About | Getting Started | Authors ➤ Getting Started

Lucca Pessoa 1 Jan 09, 2022
Support for Competitive Coding badges to add in Github readme or portfolio websites.

Support for Competitive Coding badges to add in Github readme or portfolio websites.

Akshat Aggarwal 2 Feb 14, 2022
Google scholar share - Simple python script to pull Google Scholar data from an author's profile

google_scholar_share Simple python script to pull Google Scholar data from an au

Paul Goldsmith-Pinkham 9 Sep 15, 2022
A Terminal User Interface (TUI) for automated trading with Komodo Platform's AtomicDEX-API

PytomicDEX Makerbot A Terminal User Interface (TUI) for automated trading with Komodo Platform's AtomicDEX-API Install sudo apt install wget curl jq g

6 Aug 25, 2022
Python client library for Postmark API

Postmarker Python client library for Postmark API. Gitter: https://gitter.im/Stranger6667/postmarker Installation Postmarker can be obtained with pip:

Dmitry Dygalo 109 Dec 13, 2022
Telegram-Voice Recoginiton Project (Python)

Telegram-Voice Recoginiton Project (Python) It is a telegram bot that analyses voice messages and convert it to text and reply back response on bot's

Krishnadev P Melevila 1 Jan 28, 2022
Simple-nft-tutorial - A simple tutorial on making nft/memecoins on algorand

nft/memecoin Tutorial on Algorand Let's make a simple NFT/memecoin on the Algora

2 Feb 05, 2022
A module to get data about anime characters, news, info, lyrics and more.

Animec A module to get data about anime characters, news, info, lyrics and more. The module scrapes myanimelist to parse requested data. If you wish t

DriftAsimov 31 Aug 31, 2022