gidgetlab.sansio — sans-I/O support

Webhook events

Webhook events are represented by Event objects. The expectation is that a server will receive an HTTP request from GitLab and then use Event.from_http() to create an Event instance. For example:

import os
import aiohttp.web

SECRET = os.environ["GL_SECRET_TOKEN"]

async def index(request):
    headers = request.headers
    body = await request.read()
    event = gidgetlab.Event.from_http(headers, body,
                                      secret=SECRET)

This is not required, though, as the Event class can be constructed in a more traditional way.

class gidgetlab.sansio.Event(data, *, event, secret=None)

Representation of a GitLab webhook event.

data

The payload of the event

event

The string representation of the triggering event

secret

The secret token of the webhook

property object_attributes: Dict[str, Any] | Any

Property to easily access the object_attributes dict from an event data

property project_id: int | Any

Property to easily access the project_id from an event data

classmethod from_http(headers, body, *, secret=None)

Construct an Event instance from HTTP headers and JSON body data.

The mapping providing the headers is expected to support lowercase keys.

Since this method assumes the body of the HTTP request is JSON, a check is performed for a content-type of “application/json”. If the content-type does not match, BadRequest is raised.

If the appropriate headers are provided for event validation, then it will be performed unconditionally. Any failure in validation (including not providing a secret) will lead to ValidationFailure being raised.

Return type:

Event

Calling the GitLab API

As well as receiving webhook events in response to actions occurring on GitLab, you can use the GitLab API to make calls to REST endpoints. This library provides support to both construct a request to the GitLab API as well as deciphering the response to a request.

Requests

This module provides functions to help in the construction of a URL request by helping to automate the GitLab-specific aspects of a REST call.

import requests

request_headers = create_headers("beenje", access_token=token)
url = "https://gitlab.com/api/v4/groups/gitlab-org/projects"
response = requests.get(url, headers=request_headers)
gidgetlab.sansio.create_headers(requester, *, access_token=None)

Create a dict representing GitLab-specific header fields.

The user agent is set according to who the requester is. GitLab doesn’t require anything specific but setting it to a username or project name is good practice (this is required by GitHub API).

The access_token allows making an authenticated request. Personal/group/project access tokens as well as Oauth 2.0 tokens are supported. Most API requests require authentication, or will only return public data when authentication is not provided.

For consistency, all keys in the returned dict will be lowercased.

Return type:

Dict[str, str]

Responses

Decipher a response from the GitLab API gather together all of the details that are provided to you. Continuing from the example in the Requests section:

# Assuming `response` contains a requests.Response object.
import datetime


status_code = response.status_code
headers = response.headers
body = response.content
data, rate, more = decipher_response(status_code, headers, body)
# Response details are in `data`.
if more:
    if not rate.remaining:
        now = datetime.datetime.now(datetime.tzinfo.utc)
        wait = rate.reset_datetime - now
        time.sleep(wait.total_seconds())
    response_more = requests.get(more, headers=request_headers)
    # Decipher `response_more` ...
gidgetlab.sansio.decipher_response(status_code, headers, body)

Decipher an HTTP response for a GitLab API request.

The mapping providing the headers is expected to support lowercase keys.

The parameters of this function correspond to the three main parts of an HTTP response: the status code, headers, and body. Assuming no errors which lead to an exception being raised, a 3-item tuple is returned. The first item is the decoded body (typically a JSON object, but possibly None or a string depending on the content type of the body). The second item is an instance of RateLimit based on what the response specified.

The last item of the tuple is the URL where to request the next part of results. If there are no more results then None is returned. Do be aware that the URL can be a URI template and so may need to be expanded.

If the status code is anything other than 200, 201, 202, or 204, then an appropriate HTTPException is raised.

Return type:

Tuple[Any, Optional[RateLimit], Optional[str]]

class gidgetlab.sansio.RateLimit(*, limit, remaining, reset_epoch)

The rate limit imposed upon the requester.

The reset_epoch argument is expected to be UTC seconds from the epoch. effectively ‘left’ resets to ‘rate’. The datetime object is timezone-aware and set to UTC.

The boolean value of an instance whether another request can be made. This is determined based on whether there are any remaining requests or if the reset datetime has passed.

classmethod from_http(headers)

Create a RateLimit instance from the HTTP headers of a GitLab API response. Returns None if the ratelimit is not found in the headers.