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)
ToqueIO Nuke tools - A collection of tools designed to assist in enhancing your workflows within nuke

ToqueIO Nuke tools - A collection of tools designed to assist in enhancing your workflows within nuke

4 Feb 19, 2022
PR Changes Matrix Builder

Pr-changes-matrix-builder - A Github Action that will output a variable to be used in a matrix strategy job based on a PR&'s changes

Kyle James Walker (he/him) 21 Oct 04, 2022
Upbit(업비트) Cryptocurrency Exchange OPEN API Client for Python

Base Repository Python Upbit Client Repository Upbit OPEN API Client @Author: uJhin @GitHub: https://github.com/uJhin/upbit-client/ @Officia

Yu Jhin 37 Nov 06, 2022
Unofficial Coinbase Python Library

Unofficial Coinbase Python Library Python Library for the Coinbase API for use with three legged oAuth2 and classic API key usage Version 0.3.0 Requir

George Sibble 104 Dec 01, 2022
An advanced Filter Bot with nearly unlimitted filters!

Unlimited Filter Bot ㅤㅤㅤㅤㅤㅤㅤ ㅤㅤㅤㅤㅤㅤㅤ An advanced Filter Bot with nearly unlimitted filters! Features Nearly unlimited filters Supports all type of fil

TroJanzHEX 445 Jan 03, 2023
Simple integration between FastAPI and cloud authentication services (AWS Cognito, Auth0, Firebase Authentication).

FastAPI Cloud Auth fastapi-cloudauth standardizes and simplifies the integration between FastAPI and cloud authentication services (AWS Cognito, Auth0

tokusumi 255 Jan 07, 2023
Netflix Movies and TV Series Downloader Tool including CDM L1 which you guys can Donwload 4K Movies

NFRipper2.0 I could not shared all the code here Because its has lots of files inisde it https://new.gdtot.me/file/86651844 - Downoad File From Here.

Kiran 15 May 06, 2022
Covid19 API. (Currently Scrapes: worldometers)

Covid19-API An opensource Covid19 API (currently uses worldometer only) Output Examples Covid19 Every Country Data Request URL your-ip/api/all Resp

Amresh Prasad Sinha 14 Oct 03, 2022
Python wrapper for Coinex APIs

coinexpy - Python wrapper for Coinex APIs Through coinexpy you can simply buy or sell crypto in your Coinex account Features place limit order place m

Iman Mousaei 16 Jan 02, 2023
One version package to rule them all, One version package to find them, One version package to bring them all, and in the darkness bind them.

AwesomeVersion One version package to rule them all, One version package to find them, One version package to bring them all, and in the darkness bind

Joakim Sørensen 39 Dec 31, 2022
Instagram story report with python

instagram-story-report Mass reports a victim stories. Made for fun, but can be used for chaos Single session and multi session support Login, choose a

Joshua Solo 8 May 08, 2022
A small Python app to create Notion pages from Jira issues

Jira to Notion This little program will capture a Jira issue and create a corresponding Notion subpage. Mac users can fetch the current issue from the

Dr. Kerem Koseoglu 12 Oct 27, 2022
An API wrapper for the file.io web service.

🗃️ File.io An API wrapper for the file.io web service. Install $ pip3 install fileio or

nkot56297 1 Dec 18, 2021
A simple Telegram bot that analyses a given word, built with python-telegram-bot

Telegram Word Bot A simple Telegram bot that analyses a given word, built with python-telegram-bot. The bot is fairly useless - unless you often need

Chris N 2 Jul 14, 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
PyHoroscope - Observational Indian lunisolar calendar, horoscope and matching using the Swiss ephemeris

PyHoroscope Observational Indian lunisolar calendar, horoscope and matching usin

4 Jun 05, 2022
A telegram bot that sends a meme a day, from reddit's top meme of the day

MemeBot A telegram bot that sends a meme a day, from reddit's top meme of the day You can use the bot either with an external scheduler (ex: pythonany

Michele Vitulli 1 Dec 13, 2021
Who are we? We are the Hunters of all Torrent in this world.🗡️.Fork from SlamDevs

MIRROR HUNTER This Mirror Bot is a multipurpose Telegram Bot writen in Python for mirroring files on the Internet to our beloved Google Drive. Repo la

Anime Republic 130 May 28, 2022
Wedding website for July 2022.

Capstone Project: a real wedding website! User Stories A user should be able to signup for the website A user should be able to login to the website i

1 Nov 04, 2021
Free & open source API service for obtaining information about +9600 universities worldwide.

Free & open source API service for obtaining information about +9600 universities worldwide.

Yagiz Degirmenci 57 Nov 04, 2022