{"id":1019,"library":"python-gitlab","title":"python-gitlab","description":"python-gitlab is a Python package that provides a comprehensive wrapper for the GitLab REST and GraphQL APIs. It allows developers to interact with GitLab resources in a Pythonic way, offering both synchronous and asynchronous clients, along with a CLI tool. The library maintains a regular release cadence, typically releasing new versions monthly, ensuring up-to-date support for GitLab API features.","status":"active","version":"8.2.0","language":"python","source_language":"en","source_url":"https://github.com/python-gitlab/python-gitlab","tags":["gitlab","api","wrapper","devops","automation","ci-cd"],"install":[{"cmd":"pip install python-gitlab","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Requires Python 3.10 or higher.","package":"python","optional":false}],"imports":[{"note":"Importing the top-level 'gitlab' module is the standard and recommended practice for accessing the Gitlab class and other functionalities.","wrong":"from gitlab import Gitlab # While technically possible, the standard and often safer practice is to import the top-level 'gitlab' module, especially to avoid conflicts or when using other submodules.","symbol":"Gitlab","correct":"import gitlab\ngl = gitlab.Gitlab(...)"}],"quickstart":{"code":"import os\nimport gitlab\n\n# Configure GitLab connection using environment variables\nGITLAB_URL = os.environ.get('GITLAB_URL', 'https://gitlab.com')\nGITLAB_PRIVATE_TOKEN = os.environ.get('GITLAB_PRIVATE_TOKEN', 'your_private_token_here')\n\n# Initialize the Gitlab API client\n# Ensure you use 'https://' if your GitLab instance redirects from http\ntry:\n    gl = gitlab.Gitlab(\n        url=GITLAB_URL,\n        private_token=GITLAB_PRIVATE_TOKEN,\n        api_version='4' # Explicitly set API version, often '4'\n    )\n    \n    # Optional: Validate the token by getting the current authenticated user\n    gl.auth() \n    user = gl.user.get()\n    print(f\"Connected to GitLab as: {user.username}\")\n\n    # List current user's projects\n    print(\"\\nListing your projects:\")\n    projects = gl.projects.list(owned=True, all=True)\n    if projects:\n        for project in projects:\n            print(f\"  - {project.name} (ID: {project.id})\")\n    else:\n        print(\"  No projects found.\")\n\nexcept gitlab.exceptions.GitlabError as e:\n    print(f\"GitLab API error: {e}\")\nexcept Exception as e:\n    print(f\"An unexpected error occurred: {e}\")","lang":"python","description":"This quickstart demonstrates how to connect to a GitLab instance using a personal access token and then fetch a list of projects owned by the authenticated user. It highlights setting the GitLab URL and private token via environment variables for security and explicitly uses API v4."},"warnings":[{"fix":"Upgrade your Python environment to 3.10 or newer. Ensure your `pyproject.toml` or `requirements.txt` specifies `python_requires='>=3.10'` for compatibility.","message":"python-gitlab v7.0.0 and later require Python 3.10 or higher. Python 3.9 and older are no longer supported.","severity":"breaking","affected_versions":">=7.0.0"},{"fix":"Review the GraphQL client usage and adapt to the updated `GraphQL.execute()` signature, likely by passing the query string directly or using `gql` package objects.","message":"In python-gitlab v8.0.0, the GraphQL API client's `GraphQL.execute()` method no longer accepts `graphql.Source` objects directly.","severity":"breaking","affected_versions":">=8.0.0"},{"fix":"Switch to Personal Access Tokens, Project Access Tokens, or OAuth tokens for authentication. Avoid using direct username/password pairs.","message":"Password-based authentication (username/password) is deprecated and largely removed from GitLab API v10.2 onwards. It is highly recommended to use Personal Access Tokens or OAuth tokens.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always use the canonical (final) URL of your GitLab instance, typically starting with `https://`, when initializing the `Gitlab` object.","message":"If your GitLab instance redirects HTTP requests to HTTPS (e.g., `http://gitlab.example.com` to `https://gitlab.example.com`), you must specify the final HTTPS URL in the `Gitlab` object constructor to avoid `RedirectionError` or malformed requests.","severity":"gotcha","affected_versions":"All versions"},{"fix":"To customize rate limiting behavior (e.g., disable waiting), use `obey_rate_limit=False` or `max_retries`. To enable automatic retries for transient errors, set `retry_transient_errors=True` during `Gitlab` object initialization or on individual API calls.","message":"By default, python-gitlab handles rate limiting by sleeping and retrying based on `Retry-After` headers or exponential backoff. It also does *not* retry transient HTTP errors (5xx codes) by default.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-05-12T22:40:40.591Z","next_check":"2026-06-27T00:00:00.000Z","problems":[{"fix":"pip install python-gitlab","cause":"The `python-gitlab` library is not installed in the Python environment being used.","error":"ModuleNotFoundError: No module named 'gitlab'"},{"fix":"Verify your GitLab URL and private token, ensuring it has the necessary scopes (e.g., `api`) and is still active.","cause":"This error indicates that the provided personal access token is invalid, expired, or lacks the necessary scope to perform the requested action.","error":"gitlab.exceptions.GitlabError: 401 Unauthorized"},{"fix":"Double-check the ID or name of the resource you are trying to access and ensure your token has the correct permissions for visibility.","cause":"This error occurs when the requested GitLab resource (e.g., project, user, group) does not exist or the authenticated user does not have permission to access it.","error":"gitlab.exceptions.GitlabError: 404 Not Found"},{"fix":"Review the GitLab API documentation for the specific endpoint (e.g., `projects.create()`) to ensure all required parameters are provided and correctly formatted.","cause":"This error typically indicates that an API request was malformed, missing required parameters, or contained invalid data according to the GitLab API specification for that endpoint.","error":"gitlab.exceptions.GitlabError: 400 Bad Request"},{"fix":"Access the data directly as a Python list or dictionary, or iterate through its elements, as `python-gitlab` handles decoding automatically.","cause":"This error occurs when attempting to call the `decode()` method on a `GitlabList` or `GitlabDict` object, which are Python objects representing API responses, not raw byte strings.","error":"AttributeError: 'GitlabList' object has no attribute 'decode'"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":null,"quickstart_tag":null,"pypi_latest":"8.3.0","cli_name":"gitlab","install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","installed_version":"6.5.0","pypi_latest":"8.3.0","is_stale":true,"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"python-gitlab","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.63,"mem_mb":11.4,"disk_size":"23.2M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"python-gitlab","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.67,"mem_mb":11.3,"disk_size":"23.1M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"python-gitlab","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.3,"import_time_s":0.48,"mem_mb":11.4,"disk_size":"24M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"python-gitlab","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.47,"mem_mb":11.3,"disk_size":"24M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"python-gitlab","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.81,"mem_mb":12.8,"disk_size":"25.5M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"python-gitlab","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.93,"mem_mb":12.7,"disk_size":"25.4M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"python-gitlab","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.3,"import_time_s":0.74,"mem_mb":12.8,"disk_size":"26M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"python-gitlab","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.7,"mem_mb":12.7,"disk_size":"26M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"python-gitlab","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.74,"mem_mb":12.6,"disk_size":"17.2M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"python-gitlab","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.8,"mem_mb":12.5,"disk_size":"17.1M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"python-gitlab","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.1,"import_time_s":0.73,"mem_mb":12.6,"disk_size":"18M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"python-gitlab","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.78,"mem_mb":12.5,"disk_size":"18M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"python-gitlab","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.73,"mem_mb":13.1,"disk_size":"16.9M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"python-gitlab","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.74,"mem_mb":13,"disk_size":"16.7M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"python-gitlab","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.1,"import_time_s":0.69,"mem_mb":13.1,"disk_size":"17M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"python-gitlab","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.74,"mem_mb":13,"disk_size":"17M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"python-gitlab","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.57,"mem_mb":10.9,"disk_size":"22.4M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"python-gitlab","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.63,"mem_mb":10.9,"disk_size":"22.4M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"python-gitlab","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.7,"import_time_s":0.55,"mem_mb":10.9,"disk_size":"23M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"python-gitlab","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.55,"mem_mb":10.9,"disk_size":"23M"}]},"quickstart_checks":{"last_tested":"2026-04-24","tag":null,"tag_description":null,"results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}