Commit da78fce7 authored by Roman Lacko's avatar Roman Lacko
Browse files

moved POD to wiki

parent 8dddf469
`GitLab::API::Iterator` - iterator for paginated responses
use GitLab::API;
use GitLab::Users;
my $gitlab = GitLab::API->new(...);
my $users = $gitlab->users(-iterator => 1);
while (my $user = $users->next) {
# ...
print "Total users: ", $users->count, "\n";
# ...
while (my $user = $users->next()) {
# ...
The iterator provides methods `next` and `rewind`.
It also remembers pages that have already been downloaded.
When the iterator reaches the end of data, it tries to download the next page.
Note that all entities are memoized, so rewinding the iterator will **not** cause it to request pages again.
Use **reset** for this kind of behaviour.
- `new()`
$iterator = GitLab::API::Iterator->new($api, $url, %extra)
Not intended to be called directly, [`exec_request` in GitLab::API]( constructs the instance itself.
- `$api`
The [`GitLab::API`]( instance that will be used to issue calls.
- `$url`
[URI]( instance for the call.
- `%extra`
Extra arguments.
Currently only `per_page` is used, which controls how many entities in a page can the iterator request.
- `next()`
Returns the next element or `undef` if there are no elements left.
Automatically downloads next page from API if required.
- `reset()`
Resets the iterator to the original state that can be reused.
Clears all data and error flags, so that the requests can be issued again.
- `rewind()`
Resets the iterator to the position before the first element, so that the call to `next` will return the first element.
Note that this will **not** cause the iterator to re-download all pages.
Use `reset` for this purpose.
- `all()`
my @items = @{ $iterator->all };
Downloads all pages and returns an arrayref of all elements.
## Internal methods
- `next_block()`
Tries to download the next page from the GitLab API.
Returns false if no page left or an error occured.
Roman Lacko <[``](>
- [`GitLab::API`](
Lightweight GitLab API client.
- [`GitLab`](
Wrapper around [`GitLab::API`]( and other modules.
`GitLab::API` - lightweight GitLab API client.
Also implements **Session** API to obtain authentication token if needed.
Other modules are needed for additional methods.
See [GitLab API]( for details.
use GitLab::API;
use GitLab::Users;
use GitLab::Groups;
use GitLab::Projects;
my $gitlab = GitLab::API->new(AuthToken => $token);
# simple result
my $groups = $gitlab->groups(search => "awesome-group");
die("Failed to get groups") unless defined $groups;
# result with response
my ($users, $response) = $gitlab->users(-response => 1);
die("Request failed: " . $response->message) unless $response->is_success;
# iterator for paginated responses
my $projects = $gitlab->projects(-iterator => 1);
while (my $project = $projects->next) {
# ...
- `new()`
$gitlab = GitLab::API->new(arg => value, ...);
Creates a new instance of `GitLab::API`. Takes a hash of arguments:
| argument | description |
| ------------- | --------------------------------------------------------- |
| Login | user login |
| Email | user e-mail, required only if Login is not provided, |
| Password | user password |
| AuthToken | authentication token |
| URL | url to connect to, usually `https://gitlab.domain/api/v3` |
| DieOnError | see `die_on_error()` method |
`URL` is always required.
The method also requires __either__ `AuthToken` __or__ ((`Login` or `Email`) and `Password`).
That is, the only meaningful combinations are
GitLab::API->new(URL => $URL, AuthToken => $TOKEN);
GitLab::API->new(URL => $URL, Login => $LOGIN, Password => $PASSWD);
GitLab::API->new(URL => $URL, Email => $EMAIL, Password => $PASSWD);
- `sudo()`
Similar to [sudo(8)](, changes identity to the user with the `$username`.
If the `$username` argument is not defined, changes the identity back to the original user.
__This feature is available only to the admins.__
You can test for that with the [`whoami`](#whoami) method this way:
if ($gitlab->whoami()->{is_admin}) {
# Booyah!
- `whoami()`
Returns the user whose authentication key is used for the request (or impersonated user if [`sudo`](#sudo) is in effect).
See [REQUEST METHODS](#request-methods) below.
- `is_admin()`
Returns `true` if the logged in user has administrator permissions.
The result is not affected by [`sudo()`](#sudo).
- `die_on_error()`
my $value = $gitlab->die_on_error();
When called without an argument, returns the current value of the settings.
Otherwise sets the first argument as the value.
If enabled, any call that returns an unsuccessful (!= 2\*\*) HTTP code will call `Carp::croak` with the status code.
If disabled, unsuccessful calls will simply return `undef`.
The setting can be 'overriden' temporarily with the `-immortal => 1` option passed to the method.
See [`exec_request`](#exec_request) below.
## Internal Methods
The following methods are intended to be called from additional methods implemented by `GitLab::*` modules.
**It is not recommended to use these methods directly.**
- `http()`
Returns the HTTP User Agent.
- `json()`
Returns the JSON decoder.
- `response()`
Returns the HTTP response of the last method.
- `login()`
$gitlab->login(arg => value, ...);
With provided login information (`Email`, `Login`, `Password`), this method attempts to obtain user's private token.
Under the hood it simply calls the [session]( API method.
- `create_uri()`
$uri = $gitlab->create_uri($template, $arguments);
Constructs an [URI]( instance for the template using given arguments.
- `decode_data()`
$data = $gitlab->decode_data($response);
Decodes the JSON content from the `$response` and converts it to Perl data.
- `exec_request()`
$data = $gitlab->exec_request($template, $arguments);
# if arguments contain {-response => 1}
($data, $response) = $gitlab->exec_request($template, $arguments);
Sends a request constructed from the given `$template` and `$arguments` hashref.
Arguments that start with `-` (minus) are reserved to modify the client's behaviour and are **never** forwarded to GitLab.
Returns data received from GitLab API, either as hashref or arrayref (this depends on the request) or `undef` if the request failed (and `die_on_error` is disabled).
Additionally it saves the last [HTTP::Response]( object as the `response` attribute of `$self`.
The following arguments can be used to modify [`exec_request`](#exec_request)'s behaviour:
- `-response => [0|1]`
Return both data and the [HTTP::Response]( object as a list of two elements if set to true value.
my ($data, $response) = $gitlab->$method(..., -response => 1);
- `-immortal => [0|1]`
When enabled, calls will not not carp on error even when `die_on_error` is enabled.
Recommended with `-response` option so that the status code can be inspected directly.
my ($data, $response) = $gitlab->$method(..., -response => 1, -immortal => 1);
if (!$response->is_success) {
# handle the error
- `-page => N`
When used with paginated requests, returns only entries from the given page.
The number of entities in each page is by default _50_ except (of course) the last one.
It is possible to change the default page size with the `-per_page` option.
The API returns an empty response for invalid page numbers.
The method _croaks_ if used with a template without `$tmpl->{paginated}` attribute or if combined with `-iterator`.
- `-per_page => N`
Change the page size for `-page` or `-iterator` options.
The maximum allowed value by GitLab is currently `100`.
- `-iterator`
When non-zero, return an instance of [`GitLab::API::Iterator`]( that will sequentially request pages when needed.
# Package methods
- `methods()`
$methods = GitLab::API::methods();
Returns an arrayref of method names registered with the API.
This method __cannot__ be exported, use
to obtain the result.
Request methods are methods that create requests and call GitLab API.
This package provides an easy data-driven way to create such methods with
request templates (see ["REQUEST TEMPLATES"](#request-templates) section and [`register`](#register)
method below).
Unless specified otherwise, these methods take a hash of options, e.g.
$gitlab->$method(key => value, ...);
Generally, keys starting with the `-` (minus) characters are intended to modify the underlying `exec_request`'s behaviour and are not forwarded to GitLab.
This module contains only the [`whoami`](#whoami) API method, other methods are provided
by additional `GitLab::*` modules.
This section contains instruction on how to implement API request methods.
See [`GitLab::Users`]( and [`GitLab::Groups`]( for examples.
The requests are made by calling the [`exec_request`](#exec_request) method with the following parameters:
| parameter | description |
| ---------- | ------------------------------------- |
| `$tmpl` | request template |
| `$args` | hashref of request arguments |
The _request template_ is a hashref with the following keys:
| key | description |
| ----------- | -------------------------------------------------------------------------------|
| `method` | **[required]** `GET`, `POST`, `PUT` or `DELETE` |
| `path` | **[required]** URL relative to the URL parameter given to constructor |
| `paginated` | if set to `true`, the request will be repeated and results concatented until all items are obtained` |
| `query` | arrayref of paramters that should be passed as query string in the URL |
| `required` | arrayref of required arguments |
| `optional` | optional arguments |
| `ret` | hashref of HTTP codes whose values will be used as status messages |
| `encode` | arrayref of path components that should be URI-encoded |
The `path` value can contain placeholders in the format `<name>`, e.g. `/groups/<gid>/projects/<projid>` is a path that contains placeholders `gid` and `projid`.
When processing the template, these placeholders will automatically become __required arguments__.
Arguments specified in the `query` are _not_ required by default, hence, if missing, they will not be included in the final URL.
Additional arguments (those not mentioned in `query`) will be passed as the request content, that is, `arg=value&arg=value...`, since the request's `Content-Type` is `application/x-www-form-urlencoded` by default.
Optional arguments can be specified by the `optional` key.
The value of this key is an arrayref with strings.
As the name suggests, _required arguments_ must be provided, otherwise the [`exec_request`](#exec_request) will croak.
All values for `path` placeholders are encoded before replacement.
However, if the value can contain reserved URI characters (e.g. `'/'`), the encoding must be forced.
This can be done by specifying this placeholder in the `encode` arrayref.
## Examples
### Simple
Consider the following template hashref:
my $user_by_id = {
name => "user_by_id",
method => "GET",
path => "/users/<uid>",
ret => { 404 => "User not found" },
Called as `$gitlab->exec_request($user_by_id, { uid => 10 })`, the method will replace `<uid>` placeholder with `10` and then it will call
GET .../api/v3/users/10
with empty content.
The `uid` argument is required; the method will croak if it is not present.
If the given user is not found, the method will return status `404` with reason `User not found`.
For other status codes it will return the reason provided either by GitLab or underlying HTTP client.
### Required arguments
my $user_add_ssh_key = {
name => "user_add_ssh_key",
method => "POST",
path => "/users/<uid>/keys",
required => [ qw!title key! ],
This request requires arguments `title`, `key` and `uid` (since it appears in the `path`).
The latter argument will be substituted in the path, the former two will be passed in the body of the request.
### Encoding
my $project_by_id = {
method => "GET",
path => "/projects/<id>",
encode => [ qw(id) ],
From API documentation, this operation returns a project with the given `id`, which can be a numerical value or a string `"NAMESPACE/PROJECT_NAME"`.
Without the `encode` parameter in the template, the following request
would result in the path `gitlab_url/projects/user/project` which is invalid.
The slash, as a reserved character, needs to be encoded using `encode_required` parameter for [`URI::Encode`](
This option is enabled by specifying `id` in the `encode` parameter in the template.
Final URL in this case would be `gitlab_url/projects/user%2Fproject`.
### Pagination and optional arguments
my $groups = {
name => "groups",
method => "GET",
path => "/groups",
query => [ qw!search! ],
paginated => 1,
When called, the request will be repeated with increasing `page` query value until all pages are returned.
These responses will be concatenated to a single one.
The method will croak if any of the returned pages is not an array.
In addition, the request __can__ have (but does not require) an argument `search` that will be passed in the query string (`...?search=$search`).
In order to make this argument required, the template would have to contain the following key:
# ...
required => [ qw!search! ],
as well.
## Registering methods
- `register()`
GitLab::API->register($template, ...);
Instead of modifying `GitLab::API` source to add a new method, or writing wrapper subs like this:
sub my_method {
my ($api, $args) = @_;
return $api->exec_request($my_method_template, $args);
for each request, the `register` method creates a convenience wrapper method in this package.
The above example can be written as the following:
# ...
The method name is the same as `$my_method_template->{name}` attribute.
The call will fail if a template does not containt the `name` attribute or a method with the same name already exists.
Roman Lacko <[``](>
- [GitLab::API::v3](
Complete GitLab API v3 implementation with CLI support.
- [GitLab](
Wrapper around `GitLab::API`.
`GitLab::Groups` - implements group API calls
See [GitLab API -- Groups]( for details and
response formats.
Implements API calls for GitLab CE `v8.10.0`.
Checked 2016-09-29 for GitLab CE `v8.12.1`.
## Notation
Please see the documentation for the [`GitLab::Users`]( module.
Note that not all optional arguments are listed.
Please refer to the official documentation for the full list.
## Group CRUD operations
- `groups()`
$groups = $gitlab->groups( [:search] );
Returns a list of groups.
An optional parameter `search` can be used to filter the list by substring match on `name`.
- `group_details()`
$details = $gitlab->group_details( :gid );
Returns details about a group with the given `gid`.
- `group_create()`
$group = $gitlab->group_create( :name, :path, [:description], [:visibility_level] );
Creates a new group. Required arguments are
| argument | description |
| -------- | ----------- |
| `name` | the name of the group |
| `path` | the path for the group (must be unique) |
In addition, the following _optional_ arguments can be specified:
| argument | description |
| -------- | ----------- |
| `description` | group's description |
| `visibility_level` | see [GitLab]( module for possible values |
- `group_update()`
$group = $gitlab->group_update( :gid );
Updates the grup with the given `gid`.
Takes same arguments as `group_create`, except they are all optional.
- `group_delete()`
$gitlab->group_delete( :gid );
Deletes the group with the given `gid`.
## Group members
- `group_members()`
$members = $gitlab->group_members( :gid );
Returns a list of members in the grup with the specified `gid`.
- `group_add_member()`
$gitlab->group_add_member( :gid, :user_id, :access_level );
Adds a user with `user_id` to the group with the given `gid` with the specified `access_level`.
See [GitLab]( module for possible access level values.
- `group_update_member()`
$gitlab->group_update_member( :gid, :user_id, :access_level );
For user with the given `user_id` the function changes his `access_level` in the group with the specified `gid`.
- `group_delete_member()`
$gitlab->group_delete_member( :gid, :user_id );
Removes the user with `user_id` from the group with the specified `gid`.
## Group projects and transfer
- `group_get_projects()`