Implementation:OpenHands OpenHands GitlabWebhookStore
| Knowledge Sources | |
|---|---|
| Domains | Data_Access, GitLab |
| Last Updated | 2026-02-11 21:00 GMT |
Overview
Data access layer for managing GitLab webhook lifecycle including batch creation, updates, deletion, and secret retrieval via PostgreSQL.
Description
GitlabWebhookStore manages the full lifecycle of GitLab webhook records in the database. It supports both project-level and group-level webhooks using a resource-type classification system. Key features include batch UPSERT via PostgreSQL INSERT ... ON CONFLICT DO NOTHING, row filtering for unprocessed webhooks ordered by last_synced for fair processing, webhook secret storage and retrieval, and admin-initiated reinstallation workflows.
Usage
Use this store when managing GitLab webhook registrations in the OpenHands SaaS platform. It is used by SaaSGitLabService for storing discovered resources and by install_gitlab_webhooks for batch processing.
Code Reference
Source Location
- Repository: OpenHands
- File: enterprise/storage/gitlab_webhook_store.py
- Lines: 1-351
Signature
class GitlabWebhookStore:
@staticmethod
def determine_resource_type(
webhook: GitlabWebhook,
) -> tuple[GitLabResourceType, str]: ...
async def store_webhooks(self, project_details: list[GitlabWebhook]) -> None: ...
async def update_webhook(self, webhook: GitlabWebhook, update_fields: dict) -> None: ...
async def delete_webhook(self, webhook: GitlabWebhook) -> None: ...
async def update_last_synced(self, webhook: GitlabWebhook) -> None: ...
async def filter_rows(self, limit: int = 100) -> list[GitlabWebhook]: ...
async def get_webhooks_by_resources(
self, group_ids: list, project_ids: list
) -> list[GitlabWebhook]: ...
async def get_webhook_secret(
self, webhook_uuid: str, user_id: str
) -> str | None: ...
async def reset_webhook_for_reinstallation_by_resource(
self, group_id=None, project_id=None, new_user_id=None
) -> None: ...
Import
from enterprise.storage.gitlab_webhook_store import GitlabWebhookStore
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| webhook | GitlabWebhook | Yes | Webhook record (group_id OR project_id, mutually exclusive) |
| update_fields | dict | No | Fields to update on existing webhook |
| limit | int | No | Batch size for filtering (default 100) |
| webhook_uuid | str | No | Webhook installation UUID for secret retrieval |
Outputs
| Name | Type | Description |
|---|---|---|
| filter_rows() | list[GitlabWebhook] | Unprocessed webhooks ordered by last_synced |
| get_webhook_secret() | str or None | Webhook secret for signature verification |
| determine_resource_type() | tuple[GitLabResourceType, str] | Resource classification and ID |
Usage Examples
from enterprise.storage.gitlab_webhook_store import GitlabWebhookStore
store = GitlabWebhookStore()
# Batch store discovered webhooks
await store.store_webhooks(project_details=webhook_records)
# Fetch unprocessed webhooks for installation
pending = await store.filter_rows(limit=100)
# Retrieve webhook secret for signature verification
secret = await store.get_webhook_secret(webhook_uuid="abc-123", user_id="user-456")