No project description provided
Project description
pjdev-gitlab
Async GitLab automation SDK. Wraps both the GitLab REST API v4 and GraphQL API directly with httpx.AsyncClient and Pydantic models. Covers issues, workItems (the GraphQL replacement for issues — status, comments, labels), merge requests, repository files, and the generic package registry.
Installation
pip install pjdev-gitlab
Configuration
pjdev-gitlab reads GL_* environment variables (or accepts the same values
via init()):
| variable | required | purpose |
|---|---|---|
GL_TOKEN |
yes | access token (api scope) — a PAT, or an OAuth token with GL_AUTH_SCHEME=bearer |
GL_GITLAB_URL |
yes | base URL, e.g. https://gitlab.com |
GL_AUTH_SCHEME |
no | private-token (default, PAT header) or bearer (OAuth access token) |
GL_DEFAULT_PROJECT_ID |
no | default project for service helpers |
GL_OUTPUT_PATH |
no | directory for downloaded files |
OAuth 2.0 (per-user attribution)
To attribute API writes to a real person instead of a shared bot token, mint a
short-lived OAuth access token with the interactive Authorization Code + PKCE
flow and initialize with auth_scheme="bearer":
from pjdev_gitlab import config_service, oauth_service
# Opens a browser for sign-in/consent on first run; caches + refreshes the token
# per host under ~/.config/pjdev-gitlab/tokens/ (0600) on subsequent runs.
token = oauth_service.get_access_token(
gitlab_url="https://gitlab.example.com",
client_id="<registered PKCE app client id>",
)
config_service.init(
token=token, gitlab_url="https://gitlab.example.com", auth_scheme="bearer"
)
The OAuth application must be registered as a non-confidential (PKCE) app with
scope api and Redirect URI exactly http://localhost:7331/callback
(override the port via get_access_token(redirect_port=...)). A bearer token
is sent as Authorization: Bearer <token>; the default private-token scheme
sends PRIVATE-TOKEN for personal/project/group access tokens.
Recommended: 1Password + op run
On a developer laptop, keep the token in 1Password and inject it into the host
process with op run —
the secret never sits in your shell environment or on disk in plaintext.
-
Install the 1Password CLI (
brew install --cask 1password-cli) and turn on Settings → Developer → Integrate with 1Password CLI in the desktop app. -
Store the token in 1Password (e.g. an API Credential titled
GitLab — purplejaywith acredentialfield). -
Drop a committable
.env.opnext to your project — references only, no real secrets:# .env.op GL_TOKEN="op://Private/GitLab — purplejay/credential" GL_GITLAB_URL="https://gitlab.purplejay.io"
-
Launch your script — or the entire Claude Code session that will use this library — under
op run:op run --env-file=.env.op -- python my_script.py op run --env-file=.env.op -- claude
op run resolves the references, exports them to the subprocess, and tears
them down on exit. Inside Python, just call config_service.init() with no
arguments and the values flow in from the environment.
In CI, skip 1Password and set GL_TOKEN/GL_GITLAB_URL from the job's
existing variables (e.g. CI_JOB_TOKEN for project-scoped operations).
Usage
import asyncio
from pjdev_gitlab import config_service, issues_service
from pjdev_gitlab.models import StateEvent
async def main() -> None:
# Token & URL come from GL_TOKEN / GL_GITLAB_URL (e.g. via `op run`).
config_service.init(default_project_id="my-group/my-project")
issue = await issues_service.create_issue(
project_id="my-group/my-project",
title="Bug: timeout on /widgets",
description="The endpoint times out under load.\n\n/label ~bug ~priority::high",
labels=["bug"],
)
await issues_service.comment_on_issue(
project_id="my-group/my-project",
issue_iid=issue.iid,
body="Investigating now.",
)
await issues_service.set_issue_state(
project_id="my-group/my-project",
issue_iid=issue.iid,
state_event=StateEvent.close,
)
asyncio.run(main())
Run it: op run --env-file=.env.op -- python my_script.py.
WorkItems (GraphQL)
workItem is GitLab's unified replacement for the legacy Issue type — use
work_items_service for status/comments/labels on modern GitLab instances:
import asyncio
from pjdev_gitlab import config_service, work_items_service
from pjdev_gitlab.models import WorkItemState, WorkItemStateEvent
async def main() -> None:
config_service.init()
open_bugs = await work_items_service.search_work_items(
project_path="my-group/my-project",
state=WorkItemState.OPEN,
labels=["bug"],
search="timeout",
)
label = await work_items_service.create_label(
"needs-review", project_path="my-group/my-project", color="#FFAA00"
)
await work_items_service.set_work_item_labels(
open_bugs[0].iid,
[label.id],
mode="add",
project_path="my-group/my-project",
)
await work_items_service.comment_on_work_item(
open_bugs[0].iid,
"Triaged — assigning a reviewer.",
project_path="my-group/my-project",
)
await work_items_service.set_work_item_state(
open_bugs[0].iid, WorkItemStateEvent.CLOSE,
project_path="my-group/my-project",
)
asyncio.run(main())
Bundled agent skills
Skill files for AI agents ship under .agents/skills/ inside the installed package, following the library-skills.io convention. Topics: issues, workItems, merge requests, repository files, generic packages.
License
pjdev-gitlab is distributed under the terms of the MIT license.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pjdev_gitlab-5.1.9.tar.gz.
File metadata
- Download URL: pjdev_gitlab-5.1.9.tar.gz
- Upload date:
- Size: 39.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: Hatch/1.17.0 {"ci":true,"cpu":"aarch64","distro":{"id":"noble","libc":{"lib":"glibc","version":"2.39"},"name":"Ubuntu","version":"24.04"},"implementation":{"name":"CPython","version":"3.12.3"},"installer":{"name":"hatch","version":"1.17.0"},"openssl_version":"OpenSSL 3.0.13 30 Jan 2024","python":"3.12.3","system":{"name":"Linux","release":"6.12.76-linuxkit"}} HTTPX2/2.5.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31cbcb14643037216ca21a81ca14f6515fd3b126d62c8e6af79a33f4770887eb
|
|
| MD5 |
ea9b6e61a29fc64524f6bd515257df8b
|
|
| BLAKE2b-256 |
bb54c4dd199f2e54bcdadd3351874eda5b403a8e8bd8b449b95f8aa242ab3e8e
|
File details
Details for the file pjdev_gitlab-5.1.9-py3-none-any.whl.
File metadata
- Download URL: pjdev_gitlab-5.1.9-py3-none-any.whl
- Upload date:
- Size: 39.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: Hatch/1.17.0 {"ci":true,"cpu":"aarch64","distro":{"id":"noble","libc":{"lib":"glibc","version":"2.39"},"name":"Ubuntu","version":"24.04"},"implementation":{"name":"CPython","version":"3.12.3"},"installer":{"name":"hatch","version":"1.17.0"},"openssl_version":"OpenSSL 3.0.13 30 Jan 2024","python":"3.12.3","system":{"name":"Linux","release":"6.12.76-linuxkit"}} HTTPX2/2.5.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
594f2d082ccc77dbb9f2d59c52ce50abf9dcecb820cfded60072f9deb7920b6e
|
|
| MD5 |
55c5b5adce9772e12602b21338e83df6
|
|
| BLAKE2b-256 |
7ff5beaa04ed96eaad1afdb23a8aa02ce25f2aa1fa8eaca4f669ff4b748ad896
|