The python wrapper for the GitLab REST and GraphQL APIs.
npx @tessl/cli install tessl/pypi-python-gitlab@6.3.0A comprehensive Python wrapper for GitLab's REST and GraphQL APIs, enabling developers to programmatically interact with GitLab repositories, projects, users, issues, merge requests, and other GitLab resources. The library provides both synchronous and asynchronous GraphQL API clients along with a command-line interface.
pip install python-gitlabimport gitlabMain client access:
from gitlab import Gitlab, GitlabListGraphQL clients:
from gitlab import GraphQL, AsyncGraphQLException handling:
from gitlab import GitlabError, GitlabAuthenticationErrorimport gitlab
# Connect to GitLab instance
gl = gitlab.Gitlab("https://gitlab.example.com", private_token="your-token")
# Get current user
user = gl.auth()
print(f"Logged in as: {user.name}")
# List all projects
projects = gl.projects.list(all=True)
# Get a specific project
project = gl.projects.get(123)
print(f"Project: {project.name}")
# Create an issue
issue = project.issues.create({
'title': 'New issue',
'description': 'Issue description'
})
# List merge requests
mrs = project.mergerequests.list(state='opened')
for mr in mrs:
print(f"MR: {mr.title}")Python-GitLab follows a consistent object-manager pattern:
The library uses a lazy loading approach where resource objects and nested managers are created on-demand, providing efficient memory usage and flexible API access patterns.
Core client setup, authentication methods, configuration management, and server connectivity. Supports multiple authentication methods including private tokens, OAuth tokens, and CI job tokens.
class Gitlab:
def __init__(
self,
url: str | None = None,
private_token: str | None = None,
oauth_token: str | None = None,
job_token: str | None = None,
ssl_verify: bool | str = True,
timeout: float | None = None,
**kwargs
) -> None: ...
def auth(self) -> None: ...
def version(self) -> tuple[str, str]: ...Comprehensive project lifecycle management including creation, configuration, access control, and administrative operations. Covers project settings, members, access tokens, and project-level resources.
class Project:
def save(self) -> None: ...
def delete(self) -> None: ...
def transfer_project(self, to_namespace: str) -> dict: ...
def fork(self, namespace: str | None = None) -> dict: ...
class ProjectManager:
def list(self, **kwargs) -> list[Project]: ...
def get(self, id: int, **kwargs) -> Project: ...
def create(self, data: dict, **kwargs) -> Project: ...User account management, group administration, membership control, and access level configuration. Includes user profiles, SSH keys, GPG keys, and group hierarchies.
class User:
def save(self) -> None: ...
def delete(self) -> None: ...
def block(self) -> dict: ...
def unblock(self) -> dict: ...
class Group:
def save(self) -> None: ...
def delete(self) -> None: ...
def transfer(self, to_namespace: str) -> dict: ...Issue tracking, merge request workflows, code review processes, and collaborative development features. Covers issue management, MR approvals, discussions, and state transitions.
class ProjectIssue:
def save(self) -> None: ...
def subscribe(self) -> dict: ...
def unsubscribe(self) -> dict: ...
class ProjectMergeRequest:
def save(self) -> None: ...
def merge(self, **kwargs) -> dict: ...
def approve(self) -> dict: ...
def unapprove(self) -> dict: ...Continuous integration and deployment pipeline control, job management, runner administration, and artifact handling. Includes pipeline triggers, variables, and deployment environments.
class ProjectPipeline:
def cancel(self) -> dict: ...
def retry(self) -> dict: ...
def play(self) -> dict: ...
class ProjectJob:
def cancel(self) -> dict: ...
def retry(self) -> dict: ...
def play(self) -> dict: ...
def erase(self) -> dict: ...Git repository operations, branch management, commit handling, file operations, and version control workflows. Covers repository files, branches, tags, and commit operations.
class ProjectCommit:
def cherry_pick(self, branch: str) -> dict: ...
def revert(self, branch: str) -> dict: ...
class ProjectBranch:
def protect(self, **kwargs) -> dict: ...
def unprotect(self) -> dict: ...
class ProjectFile:
def save(self) -> None: ...
def delete(self) -> None: ...Advanced GraphQL query execution with both synchronous and asynchronous clients. Provides flexible querying capabilities and efficient data fetching for complex GitLab API interactions.
class GraphQL:
def execute(self, query: str, variables: dict | None = None) -> dict: ...
class AsyncGraphQL:
async def execute(self, query: str, variables: dict | None = None) -> dict: ...class GitlabError(Exception):
def __init__(
self,
error_message: str | bytes = "",
response_code: int | None = None,
response_body: bytes | None = None,
) -> None: ...
class GitlabAuthenticationError(GitlabError): ...
class GitlabHttpError(GitlabError): ...
class GitlabOperationError(GitlabError): ...Common exception handling pattern:
try:
project = gl.projects.get(123)
except gitlab.GitlabGetError as e:
print(f"Failed to get project: {e}")
except gitlab.GitlabAuthenticationError:
print("Authentication failed")class GitlabConfigParser:
def __init__(self, gitlab_id: str | None = None, config_files: list[str] | None = None) -> None: ...
def get_gitlab_config(self, gitlab_id: str = "global") -> dict: ...Configuration sources (in order of precedence):
~/.python-gitlab.cfg, /etc/python-gitlab.cfg)GITLAB_URL, GITLAB_PRIVATE_TOKEN, etc.)class AccessLevel(Enum):
NO_ACCESS = 0
MINIMAL_ACCESS = 5
GUEST = 10
PLANNER = 15
REPORTER = 20
DEVELOPER = 30
MAINTAINER = 40
OWNER = 50
ADMIN = 60
class Visibility(Enum):
PRIVATE = "private"
INTERNAL = "internal"
PUBLIC = "public"
# Access level constants
NO_ACCESS: int = 0
MINIMAL_ACCESS: int = 5
GUEST_ACCESS: int = 10
PLANNER_ACCESS: int = 15
REPORTER_ACCESS: int = 20
DEVELOPER_ACCESS: int = 30
MAINTAINER_ACCESS: int = 40
OWNER_ACCESS: int = 50
ADMIN_ACCESS: int = 60
DEFAULT_URL: str = "https://gitlab.com"class GitlabList:
def __iter__(self) -> Iterator: ...
def __len__(self) -> int: ...
@property
def current_page(self) -> int: ...
@property
def next_page(self) -> int | None: ...
@property
def per_page(self) -> int: ...
@property
def total(self) -> int | None: ...
@property
def total_pages(self) -> int | None: ...Usage with automatic pagination:
# Get all projects (automatically handles pagination)
projects = gl.projects.list(all=True)
# Manual pagination control
projects = gl.projects.list(page=1, per_page=20)
for project in projects:
print(project.name)
# Check pagination info
print(f"Page {projects.current_page} of {projects.total_pages}")