Home  >  Article  >  Backend Development  >  What is the use of the gitlab library in python?

What is the use of the gitlab library in python?

PHPz
PHPzforward
2023-05-16 18:01:061402browse

Installation

First you need to install python-gitlab Library

pip installation

sudo pip install --upgrade python-gitlab

Source code installation

git clone https://github.com/python-gitlab/python-gitlab
cd python-gitlab
sudo python setup.py install

Usage

CLI Usage

First you need to configure the environment to use cli. You need to provide a configuration file to indicate the gitlab server information and connection parameters. The configuration file format is INI , the sample is as follows:

[global]
default = somewhere
ssl_verify = true
timeout = 5

[somewhere]
url = https://some.whe.re
private_token = vTbFeqJYCY3sibBP7BZM
api_version = 4

[elsewhere]
url = http://else.whe.re:8080
private_token = CkqsjqcQSFH5FQKDccu4
timeout = 1
  • The global part must be provided, mainly the parameters for connecting to gitlab

  • The other parts are optional. When there is no configuration, the default is default

  • . During use, you can specify which section to use through -g, such as gitlab -g somewhere project list

##The configuration file used in this article is as follows:

[global]
ssl_verify = true
timeout = 5

[gitlab]
url = https://gitlab-russellgo.cn
private_token = xxxxxx
api_version = 4
The configuration file can take effect through the following methods:

  • Configure through environment variables

    PYTHON_GITLAB_CFG

  • Place it under the system configuration

    /etc/python-gitlab.cfg

  • Place it in the current user’s home directory

    ~/.python-gitlab.cfg

  • Specify through the command line

    -c or --config-file

The configuration file of this article is placed under home.

When the environment is configured, you can use it happily

  • List all projects (return in pages)

    # 上面定义了一个 gitlab 的组,所以执行时可以通过 -g 指定
    gitlab -g gitlab project list


  • List all projects

    gitlab -g gitlab project list --all


I have a question here, how do I know

gitlab What commands are currently supported?

gitlab -g gitlab 
# 以下是输出
usage: gitlab [-h] [--version] [-v] [-d] [-c CONFIG_FILE] [-g GITLAB]
              [-o {json,legacy,yaml}] [-f FIELDS]
              {application-settings,audit-event,broadcast-message,current-user,current-user-email,current-user-gp-gkey,current-user-key,current-user-status,deploy-key,dockerfile,event,feature,geo-node,gitignore,gitlabciyml,group,group-access-request,group-badge,group-board,group-board-list,group-cluster,group-custom-attribute,group-epic,group-epic-issue,group-epic-resource-label-event,group-issue,group-label,group-member,group-merge-request,group-milestone,group-notification-settings,group-project,group-subgroup,group-variable,hook,issue,l-da-pgroup,license,merge-request,namespace,notification-settings,pages-domain,project,project-access-request,project-additional-statistics,project-approval,project-approval-rule,project-badge,project-board,project-board-list,project-branch,project-cluster,project-commit,project-commit-comment,project-commit-discussion,project-commit-discussion-note,project-commit-status,project-custom-attribute,project-deployment,project-environment,project-event,project-export,project-file,project-fork,project-hook,project-import,project-issue,project-issue-award-emoji,project-issue-discussion,project-issue-discussion-note,project-issue-link,project-issue-note,project-issue-note-award-emoji,project-issue-resource-label-event,project-issues-statistics,project-job,project-key,project-label,project-member,project-merge-request,project-merge-request-approval,project-merge-request-award-emoji,project-merge-request-diff,project-merge-request-discussion,project-merge-request-discussion-note,project-merge-request-note,project-merge-request-note-award-emoji,project-merge-request-resource-label-event,project-milestone,project-note,project-notification-settings,project-pages-domain,project-pipeline,project-pipeline-job,project-pipeline-schedule,project-pipeline-schedule-variable,project-pipeline-variable,project-protected-branch,project-protected-tag,project-push-rules,project-registry-repository,project-registry-tag,project-release,project-runner,project-service,project-snippet,project-snippet-award-emoji,project-snippet-discussion,project-snippet-discussion-note,project-snippet-note,project-snippet-note-award-emoji,project-tag,project-trigger,project-user,project-variable,project-wiki,runner,runner-job,snippet,todo,user,user-activities,user-custom-attribute,user-email,user-event,user-gp-gkey,user-impersonation-token,user-key,user-project,user-status}
This way you can list the resources currently supported by gitlab. Once you know the supported resources, how do you know what operations a certain resource supports? Take project as an example,

gitlab -g gitlab project 
# 以下是输出
usage: gitlab project [-h]
                      {list,get,create,update,delete,repository-blob,repository-contributors,delete-merged-branches,share,archive,repository-compare,create-fork-relation,languages,mirror-pull,unarchive,star,search,artifact,trigger-pipeline,repository-archive,delete-fork-relation,repository-raw-blob,repository-tree,unstar,housekeeping,unshare,upload,snapshot,update-submodule,transfer-project}
                      ...
gitlab project: error: too few arguments
In this way, you can know what operations

gitlab supports on which resources, and then you can know the specific parameters through --help, such as

gitlab -g gitlab project list  --help 
# 以下是输出
usage: gitlab project list [-h] [--sudo SUDO] [--search SEARCH]
                           [--owned OWNED] [--starred STARRED]
                           [--archived ARCHIVED] [--visibility VISIBILITY]
                           [--order-by ORDER_BY] [--sort SORT]
                           [--simple SIMPLE] [--membership MEMBERSHIP]
                           [--statistics STATISTICS]
                           [--with-issues-enabled WITH_ISSUES_ENABLED]
                           [--with-merge-requests-enabled WITH_MERGE_REQUESTS_ENABLED]
                           [--with-custom-attributes WITH_CUSTOM_ATTRIBUTES]
                           [--page PAGE] [--per-page PER_PAGE] [--all]

optional arguments:
  -h, --help            show this help message and exit
  --sudo SUDO
  --search SEARCH
  --owned OWNED
  --starred STARRED
  --archived ARCHIVED
  --visibility VISIBILITY
  --order-by ORDER_BY
  --sort SORT
  --simple SIMPLE
  --membership MEMBERSHIP
  --statistics STATISTICS
  --with-issues-enabled WITH_ISSUES_ENABLED
  --with-merge-requests-enabled WITH_MERGE_REQUESTS_ENABLED
  --with-custom-attributes WITH_CUSTOM_ATTRIBUTES
  --page PAGE
  --per-page PER_PAGE
  --all
This makes it very convenient to operate

gitlab.

Programming Usage

In addition to operating gitlab through the command line, you can also use programming for integration. A common scenario is to download a file from gitlab

Basic usage
#!/usr/bin/env python
# coding=utf-8
from __future__ import print_function

import gitlab

# 实例化一个 gitlab 对象
url = "https://gitlab.russellgao.cn"
private_token = "xxxxxxxx"
gl = gitlab.Gitlab('https://gitlab.russellgao.cn', private_token=private_token)

# 列出所有的项目
projects = gl.projects.list()
for project in projects:
    print(project)

# 获取 group id 是 2 的 list
group = gl.groups.get(2)
for project in group.projects.list():
    print(project)

# 创建一个用户
user_data = {'email': 'jen@foo.com', 'username': 'jen', 'name': 'Jen'}
user = gl.users.create(user_data)
print(user)

# 列出 create 和 update 时需要的参数
# get_create_attrs() 创建时需要的参数
# get_update_attrs() 更新时需要的参数

print(gl.projects.get_create_attrs())
(('name',), ('path', 'namespace_id', ...))

# 返回的是两个元组, 第一个 必选的参数,第二个是可选的参数

# 获取 对象的属性 ,如 project
project = gl.projects.get(1)
print(project.attributes)

# 有些对象提供了 gitlab 相关的资源属性
project = gl.projects.get(1)
issues = project.issues.list()

# python-gitlab 允许向 gitlab 发送任何数据,当发送非法数据或者缺少相关参数时会抛出异常

gl.projects.list(sort='invalid value')
# ...
# GitlabListError: 400: sort does not have a valid value

# 通过 query_parameters 进行传参 当参数和python 关键字冲突时
gl.user_activities.list(from='2019-01-01')  ## invalid
gl.user_activities.list(query_parameters={'from': '2019-01-01'})  # OK
Function encapsulation example
Download files through gitlab raw url

def download_gitlab_file(url, filename, private_token) :
    """
    从 gitlab 上下载文件

    :param url: gitlab raw url
    :param filename: 保存到本地的文件名称
    :param private_token:
    :return:
    """
    import gitlab
    import codecs

    def writeLinesToFile(filename, lines, append=False, encoding=None):
        if (append == True):
            file_mode = "a"
        else:
            file_mode = "w"
        encoding = encoding or 'utf-8'
        with codecs.open(filename, file_mode, encoding=encoding) as fp:
            for line in lines:
                print(unicode(line), file=fp)

    url_patterns = url.split("/")
    if len(url_patterns) < 8 :
        raise ValueError("url: `{}` 参数不合法,以 / 分隔之后长度必须大于8".format(url))
    baseurl = "{}//{}".format(url_patterns[0], url_patterns[2])
    namespace = url_patterns[3]
    project_name = url_patterns[4]
    branch = url_patterns[6]
    url_filename = "/".join(url_patterns[7:])
    if url_patterns[5] == "-" :
        branch = url_patterns[7]
        url_filename = "/".join(url_patterns[8:])

    gl = gitlab.Gitlab(str(baseurl), private_token)
    projects = gl.projects.list(search=project_name)
    projects = filter(lambda x : x.namespace.get("full_path") == namespace, projects )
    if len(projects) == 0 :
        raise ValueError("根据url 没有找到相应的 project ,请检查当前用户是否有权限或者 url 是否正确 ")
    project = projects[0]
    raw_content = project.files.raw(file_path=url_filename, ref=branch)
    writeLinesToFile(filename, [raw_content])
    return raw_content

Source code analysis

Source code address: https://github. com/python-gitlab/python-gitlab/

As can be seen from setup.py#L31:5

from setuptools import setup
from setuptools import find_packages
...
setup(
    name="python-gitlab",
    ...
    entry_points={"console_scripts": ["gitlab = gitlab.cli:main"]},
    ....
)

python-gitlab uses setuptools for packaging, and there are two packages. Function:

  • Use as a python library (default)

  • ##entry_points={"console_scripts": ["gitlab = gitlab. cli:main"]}

    indicates that it can be used as cli. The command is gitlab and the actual call is gitlab.cli:main function

  • Let’s take a look at the entry file
cli.py

. From the entry file, we can see cli.py#L182:14<pre class="brush:php;toolbar:false">def main(): import gitlab.v4.cli ... # 可以跳转到这个函数中查看 parser = _get_base_parser(add_help=False) ... def _get_base_parser(add_help: bool = True) -&gt; argparse.ArgumentParser:     parser = argparse.ArgumentParser(         add_help=add_help, description=&quot;GitLab API Command Line Interface&quot;     )     parser.add_argument(&quot;--version&quot;, help=&quot;Display the version.&quot;, action=&quot;store_true&quot;)     parser.add_argument(         &quot;-v&quot;,         &quot;--verbose&quot;,         &quot;--fancy&quot;,         help=&quot;Verbose mode (legacy format only)&quot;,         action=&quot;store_true&quot;,     ) ...</pre>The cli parsing library can be used here argparse<p> Do the parsing of command line parameters. <code>Through

GitlabCLI

class cli.py#L29:7 we can see that the basic format of <pre class="brush:php;toolbar:false">class GitlabCLI(object):     def __init__(self, gl, what, action, args):         self.cls_name = cli.what_to_cls(what)         self.cls = gitlab.v4.objects.__dict__[self.cls_name]         self.what = what.replace(&quot;-&quot;, &quot;_&quot;)         self.action = action.lower()         self.gl = gl         self.args = args         self.mgr_cls = getattr(gitlab.v4.objects, self.cls.__name__ + &quot;Manager&quot;)         # We could do something smart, like splitting the manager name to find         # parents, build the chain of managers to get to the final object.         # Instead we do something ugly and efficient: interpolate variables in         # the class _path attribute, and replace the value with the result.         self.mgr_cls._path = self.mgr_cls._path % self.args         self.mgr = self.mgr_cls(gl)         if self.mgr_cls._types:             for attr_name, type_cls in self.mgr_cls._types.items():                 if attr_name in self.args.keys():                     obj = type_cls()                     obj.set_from_cli(self.args[attr_name])                     self.args[attr_name] = obj.get()</pre>cli is

gitlab what action args

, which is the above cli mentioned in the chapter What operations are performed on the resources supported by gitlab and the parameters corresponding to this operationBy reading

client.py

client.py#L446 :9 This file can be seen<pre class="brush:php;toolbar:false">def http_request(         self,         verb: str,         path: str,         query_data: Optional[Dict[str, Any]] = None,         post_data: Optional[Dict[str, Any]] = None,         streamed: bool = False,         files: Optional[Dict[str, Any]] = None,         **kwargs: Any,     ) -&gt; requests.Response:         &quot;&quot;&quot;Make an HTTP request to the Gitlab server.         Args:             verb (str): The HTTP method to call ('get', 'post', 'put',                         'delete')             path (str): Path or full URL to query ('/projects' or                         'http://whatever/v4/api/projecs')             query_data (dict): Data to send as query parameters             post_data (dict): Data to send in the body (will be converted to                               json)             streamed (bool): Whether the data should be streamed             files (dict): The files to send to the server             **kwargs: Extra options to send to the server (e.g. sudo)         Returns:             A requests result object.         Raises:             GitlabHttpError: When the return code is not 2xx         &quot;&quot;&quot;         query_data = query_data or {}         url = self._build_url(path)         params: Dict[str, Any] = {}         utils.copy_dict(params, query_data)         # Deal with kwargs: by default a user uses kwargs to send data to the         # gitlab server, but this generates problems (python keyword conflicts         # and python-gitlab/gitlab conflicts).         # So we provide a `query_parameters` key: if it's there we use its dict         # value as arguments for the gitlab server, and ignore the other         # arguments, except pagination ones (per_page and page)         if &quot;query_parameters&quot; in kwargs:             utils.copy_dict(params, kwargs[&quot;query_parameters&quot;])             for arg in (&quot;per_page&quot;, &quot;page&quot;):                 if arg in kwargs:                     params[arg] = kwargs[arg]         else:             utils.copy_dict(params, kwargs)         opts = self._get_session_opts(content_type=&quot;application/json&quot;)         verify = opts.pop(&quot;verify&quot;)         timeout = opts.pop(&quot;timeout&quot;)         # If timeout was passed into kwargs, allow it to override the default         timeout = kwargs.get(&quot;timeout&quot;, timeout)         # We need to deal with json vs. data when uploading files         if files:             json = None             if post_data is None:                 post_data = {}             post_data[&quot;file&quot;] = files.get(&quot;file&quot;)             post_data[&quot;avatar&quot;] = files.get(&quot;avatar&quot;)             data = MultipartEncoder(post_data)             opts[&quot;headers&quot;][&quot;Content-type&quot;] = data.content_type         else:             json = post_data             data = None         # Requests assumes that `.` should not be encoded as %2E and will make         # changes to urls using this encoding. Using a prepped request we can         # get the desired behavior.         # The Requests behavior is right but it seems that web servers don't         # always agree with this decision (this is the case with a default         # gitlab installation)         req = requests.Request(verb, url, json=json, data=data, params=params, **opts)         prepped = self.session.prepare_request(req)         prepped.url = utils.sanitized_url(prepped.url)         settings = self.session.merge_environment_settings(             prepped.url, {}, streamed, verify, None         )         # obey the rate limit by default         obey_rate_limit = kwargs.get(&quot;obey_rate_limit&quot;, True)         # do not retry transient errors by default         retry_transient_errors = kwargs.get(&quot;retry_transient_errors&quot;, False)         # set max_retries to 10 by default, disable by setting it to -1         max_retries = kwargs.get(&quot;max_retries&quot;, 10)         cur_retries = 0 ...</pre>

The above is the detailed content of What is the use of the gitlab library in python?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete