Skip to content

Facebook575/python-gitlab

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

""" GitLab API: https://docs.gitlab.com/ee/api/users.html https://docs.gitlab.com/ee/api/projects.html#list-projects-starred-by-a-user """

from __future__ import annotations

from typing import Any, cast, Literal, Optional, overload

import requests

from gitlab import cli from gitlab import exceptions as exc from gitlab import types from gitlab.base import RESTObject, RESTObjectList from gitlab.mixins import (

CreateMixin, CRUDMixin, DeleteMixin, GetWithoutIdMixin, ListMixin, NoUpdateMixin, ObjectDeleteMixin, RetrieveMixin, SaveMixin, UpdateMixin,

) from gitlab.types import ArrayAttribute, RequiredOptional

from .custom_attributes import UserCustomAttributeManager # noqa: F401 from .events import UserEventManager # noqa: F401 from .personal_access_tokens import UserPersonalAccessTokenManager # noqa: F401

__all__ = [
"CurrentUserEmail", "CurrentUserEmailManager", "CurrentUserGPGKey", "CurrentUserGPGKeyManager", "CurrentUserKey", "CurrentUserKeyManager", "CurrentUserRunner", "CurrentUserRunnerManager", "CurrentUserStatus", "CurrentUserStatusManager", "CurrentUser", "CurrentUserManager", "User", "UserManager", "ProjectUser", "ProjectUserManager", "StarredProject", "StarredProjectManager", "UserEmail", "UserEmailManager", "UserActivities", "UserStatus", "UserStatusManager", "UserActivitiesManager", "UserGPGKey", "UserGPGKeyManager", "UserKey", "UserKeyManager", "UserIdentityProviderManager", "UserImpersonationToken", "UserImpersonationTokenManager", "UserMembership", "UserMembershipManager", "UserProject", "UserProjectManager", "UserContributedProject", "UserContributedProjectManager",

]

class CurrentUserEmail(ObjectDeleteMixin, RESTObject):
_repr_attr = "email"
class CurrentUserEmailManager(
RetrieveMixin[CurrentUserEmail], CreateMixin[CurrentUserEmail], DeleteMixin[CurrentUserEmail],
):
_path = "/user/emails" _obj_cls = CurrentUserEmail _create_attrs = RequiredOptional(required=("email",))
class CurrentUserGPGKey(ObjectDeleteMixin, RESTObject):
pass
class CurrentUserGPGKeyManager(
RetrieveMixin[CurrentUserGPGKey], CreateMixin[CurrentUserGPGKey], DeleteMixin[CurrentUserGPGKey],
):
_path = "/user/gpg_keys" _obj_cls = CurrentUserGPGKey _create_attrs = RequiredOptional(required=("key",))
class CurrentUserKey(ObjectDeleteMixin, RESTObject):
_repr_attr = "title"
class CurrentUserKeyManager(
RetrieveMixin[CurrentUserKey], CreateMixin[CurrentUserKey], DeleteMixin[CurrentUserKey],
):
_path = "/user/keys" _obj_cls = CurrentUserKey _create_attrs = RequiredOptional(required=("title", "key"))
class CurrentUserRunner(RESTObject):
pass
class CurrentUserRunnerManager(CreateMixin[CurrentUserRunner]):

_path = "/user/runners" _obj_cls = CurrentUserRunner _types = {"tag_list": types.CommaSeparatedListAttribute} _create_attrs = RequiredOptional(

required=("runner_type",), optional=(

"group_id", "project_id", "description", "paused", "locked", "run_untagged", "tag_list", "access_level", "maximum_timeout", "maintenance_note",

),

)

class CurrentUserStatus(SaveMixin, RESTObject):
_id_attr = None _repr_attr = "message"
class CurrentUserStatusManager(
GetWithoutIdMixin[CurrentUserStatus], UpdateMixin[CurrentUserStatus]
):
_path = "/user/status" _obj_cls = CurrentUserStatus _update_attrs = RequiredOptional(optional=("emoji", "message"))
class CurrentUser(RESTObject):

_id_attr = None _repr_attr = "username"

emails: CurrentUserEmailManager gpgkeys: CurrentUserGPGKeyManager keys: CurrentUserKeyManager runners: CurrentUserRunnerManager status: CurrentUserStatusManager

class CurrentUserManager(GetWithoutIdMixin[CurrentUser]):
_path = "/user" _obj_cls = CurrentUser
class User(SaveMixin, ObjectDeleteMixin, RESTObject):

_repr_attr = "username"

customattributes: UserCustomAttributeManager emails: UserEmailManager events: UserEventManager followers_users: UserFollowersManager following_users: UserFollowingManager gpgkeys: UserGPGKeyManager identityproviders: UserIdentityProviderManager impersonationtokens: UserImpersonationTokenManager keys: UserKeyManager memberships: UserMembershipManager personal_access_tokens: UserPersonalAccessTokenManager projects: UserProjectManager contributed_projects: UserContributedProjectManager starred_projects: StarredProjectManager status: UserStatusManager

@cli.register_custom_action(cls_names="User") @exc.on_http_error(exc.GitlabBlockError) def block(self, **kwargs: Any) -> bool | None:

"""Block the user.

Args:
**kwargs: Extra options to send to the server (e.g. sudo)
Raises:
GitlabAuthenticationError: If authentication is not correct GitlabBlockError: If the user could not be blocked
Returns:
Whether the user status has been changed

""" path = f"/users/{self.encoded_id}/block" # NOTE: Undocumented behavior of the GitLab API is that it returns a # boolean or None server_data = cast(

Optional[bool], self.manager.gitlab.http_post(path, **kwargs)

) if server_data is True:

self._attrs["state"] = "blocked"

return server_data

@cli.register_custom_action(cls_names="User") @exc.on_http_error(exc.GitlabFollowError) def follow(self, **kwargs: Any) -> dict[str, Any] | requests.Response:

"""Follow the user.

Args:
**kwargs: Extra options to send to the server (e.g. sudo)
Raises:
GitlabAuthenticationError: If authentication is not correct GitlabFollowError: If the user could not be followed
Returns:
The new object data (not a RESTObject)

""" path = f"/users/{self.encoded_id}/follow" return self.manager.gitlab.http_post(path, **kwargs)

@cli.register_custom_action(cls_names="User") @exc.on_http_error(exc.GitlabUnfollowError) def unfollow(self, **kwargs: Any) -> dict[str, Any] | requests.Response:

"""Unfollow the user.

Args:
**kwargs: Extra options to send to the server (e.g. sudo)
Raises:
GitlabAuthenticationError: If authentication is not correct GitlabUnfollowError: If the user could not be followed
Returns:
The new object data (not a RESTObject)

""" path = f"/users/{self.encoded_id}/unfollow" return self.manager.gitlab.http_post(path, **kwargs)

@cli.register_custom_action(cls_names="User") @exc.on_http_error(exc.GitlabUnblockError) def unblock(self, **kwargs: Any) -> bool | None:

"""Unblock the user.

Args:
**kwargs: Extra options to send to the server (e.g. sudo)
Raises:
GitlabAuthenticationError: If authentication is not correct GitlabUnblockError: If the user could not be unblocked
Returns:
Whether the user status has been changed

""" path = f"/users/{self.encoded_id}/unblock" # NOTE: Undocumented behavior of the GitLab API is that it returns a # boolean or None server_data = cast(

Optional[bool], self.manager.gitlab.http_post(path, **kwargs)

) if server_data is True:

self._attrs["state"] = "active"

return server_data

@cli.register_custom_action(cls_names="User") @exc.on_http_error(exc.GitlabDeactivateError) def deactivate(self, **kwargs: Any) -> dict[str, Any] | requests.Response:

"""Deactivate the user.

Args:
**kwargs: Extra options to send to the server (e.g. sudo)
Raises:
GitlabAuthenticationError: If authentication is not correct GitlabDeactivateError: If the user could not be deactivated
Returns:
Whether the user status has been changed

""" path = f"/users/{self.encoded_id}/deactivate" server_data = self.manager.gitlab.http_post(path, **kwargs) if server_data:

self._attrs["state"] = "deactivated"

return server_data

@cli.register_custom_action(cls_names="User") @exc.on_http_error(exc.GitlabActivateError) def activate(self, **kwargs: Any) -> dict[str, Any] | requests.Response:

"""Activate the user.

Args:
**kwargs: Extra options to send to the server (e.g. sudo)
Raises:
GitlabAuthenticationError: If authentication is not correct GitlabActivateError: If the user could not be activated
Returns:
Whether the user status has been changed

""" path = f"/users/{self.encoded_id}/activate" server_data = self.manager.gitlab.http_post(path, **kwargs) if server_data:

self._attrs["state"] = "active"

return server_data

@cli.register_custom_action(cls_names="User") @exc.on_http_error(exc.GitlabUserApproveError) def approve(self, **kwargs: Any) -> dict[str, Any] | requests.Response:

"""Approve a user creation request.

Args:
**kwargs: Extra options to send to the server (e.g. sudo)
Raises:
GitlabAuthenticationError: If authentication is not correct GitlabUserApproveError: If the user could not be activated
Returns:
The new object data (not a RESTObject)

""" path = f"/users/{self.encoded_id}/approve" return self.manager.gitlab.http_post(path, **kwargs)

@cli.register_custom_action(cls_names="User") @exc.on_http_error(exc.GitlabUserRejectError) def reject(self, **kwargs: Any) -> dict[str, Any] | requests.Response:

"""Reject a user creation request.

Args:
**kwargs: Extra options to send to the server (e.g. sudo)
Raises:
GitlabAuthenticationError: If authentication is not correct GitlabUserRejectError: If the user could not be rejected
Returns:
The new object data (not a RESTObject)

""" path = f"/users/{self.encoded_id}/reject" return self.manager.gitlab.http_post(path, **kwargs)

@cli.register_custom_action(cls_names="User") @exc.on_http_error(exc.GitlabBanError) def ban(self, **kwargs: Any) -> dict[str, Any] | requests.Response:

"""Ban the user.

Args:
**kwargs: Extra options to send to the server (e.g. sudo)
Raises:
GitlabAuthenticationError: If authentication is not correct GitlabBanError: If the user could not be banned
Returns:
Whether the user has been banned

""" path = f"/users/{self.encoded_id}/ban" server_data = self.manager.gitlab.http_post(path, **kwargs) if server_data:

self._attrs["state"] = "banned"

return server_data

@cli.register_custom_action(cls_names="User") @exc.on_http_error(exc.GitlabUnbanError) def unban(self, **kwargs: Any) -> dict[str, Any] | requests.Response:

"""Unban the user.

Args:
**kwargs: Extra options to send to the server (e.g. sudo)
Raises:
GitlabAuthenticationError: If authentication is not correct GitlabUnbanError: If the user could not be unbanned
Returns:
Whether the user has been unbanned

""" path = f"/users/{self.encoded_id}/unban" server_data = self.manager.gitlab.http_post(path, **kwargs) if server_data:

self._attrs["state"] = "active"

return server_data

class UserManager(CRUDMixin[User]):

_path = "/users" _obj_cls = User

_list_filters = (
"active", "blocked", "username", "extern_uid", "provider", "external", "search", "custom_attributes", "status", "two_factor", "admins",

) _create_attrs = RequiredOptional(

optional=(
"email", "username", "name", "password", "reset_password", "skype", "linkedin", "twitter", "projects_limit", "extern_uid", "provider", "bio", "admin", "can_create_group", "website_url", "skip_confirmation", "external", "organization", "location", "avatar", "public_email", "private_profile", "color_scheme_id", "theme_id",

)

) _update_attrs = RequiredOptional(

required=("email", "username", "name"), optional=(

"password", "skype", "linkedin", "twitter", "projects_limit", "extern_uid", "provider", "bio", "admin", "can_create_group", "website_url", "skip_reconfirmation", "external", "organization", "location", "avatar", "public_email", "private_profile", "color_scheme_id", "theme_id",

),

) _types = {"confirm": types.LowercaseStringAttribute, "avatar": types.ImageAttribute}

class ProjectUser(RESTObject):
pass
class ProjectUserManager(ListMixin[ProjectUser]):
_path = "/projects/{project_id}/users" _obj_cls = ProjectUser _from_parent_attrs = {"project_id": "id"} _list_filters = ("search", "skip_users") _types = {"skip_users": types.ArrayAttribute}
class UserEmail(ObjectDeleteMixin, RESTObject):
_repr_attr = "email"
class UserEmailManager(
RetrieveMixin[UserEmail], CreateMixin[UserEmail], DeleteMixin[UserEmail]
):
_path = "/users/{user_id}/emails" _obj_cls = UserEmail _from_parent_attrs = {"user_id": "id"} _create_attrs = RequiredOptional(required=("email",))
class UserActivities(RESTObject):
_id_attr = "username"
class UserStatus(RESTObject):
_id_attr = None _repr_attr = "message"
class UserStatusManager(GetWithoutIdMixin[UserStatus]):
_path = "/users/{user_id}/status" _obj_cls = UserStatus _from_parent_attrs = {"user_id": "id"}
class UserActivitiesManager(ListMixin[UserActivities]):
_path = "/user/activities" _obj_cls = UserActivities
class UserGPGKey(ObjectDeleteMixin, RESTObject):
pass
class UserGPGKeyManager(
RetrieveMixin[UserGPGKey], CreateMixin[UserGPGKey], DeleteMixin[UserGPGKey]
):
_path = "/users/{user_id}/gpg_keys" _obj_cls = UserGPGKey _from_parent_attrs = {"user_id": "id"} _create_attrs = RequiredOptional(required=("key",))
class UserKey(ObjectDeleteMixin, RESTObject):
pass
class UserKeyManager(
RetrieveMixin[UserKey], CreateMixin[UserKey], DeleteMixin[UserKey]
):
_path = "/users/{user_id}/keys" _obj_cls = UserKey _from_parent_attrs = {"user_id": "id"} _create_attrs = RequiredOptional(required=("title", "key"))
class UserIdentityProviderManager(DeleteMixin[User]):

"""Manager for user identities.

This manager does not actually manage objects but enables functionality for deletion of user identities by provider. """

_path = "/users/{user_id}/identities" _obj_cls = User _from_parent_attrs = {"user_id": "id"}

class UserImpersonationToken(ObjectDeleteMixin, RESTObject):
pass
class UserImpersonationTokenManager(NoUpdateMixin[UserImpersonationToken]):

_path = "/users/{user_id}/impersonation_tokens" _obj_cls = UserImpersonationToken _from_parent_attrs = {"user_id": "id"} _create_attrs = RequiredOptional(

required=("name", "scopes"), optional=("expires_at",)

) _list_filters = ("state",) _types = {"scopes": ArrayAttribute}

class UserMembership(RESTObject):
_id_attr = "source_id"
class UserMembershipManager(RetrieveMixin[UserMembership]):
_path = "/users/{user_id}/memberships" _obj_cls = UserMembership _from_parent_attrs = {"user_id": "id"} _list_filters = ("type",)

# Having this outside projects avoids circular imports due to ProjectUser class UserProject(RESTObject):

pass
class UserProjectManager(ListMixin[UserProject], CreateMixin[UserProject]):

_path = "/projects/user/{user_id}" _obj_cls = UserProject _from_parent_attrs = {"user_id": "id"} _create_attrs = RequiredOptional(

required=("name",), optional=(

"default_branch", "issues_enabled", "wall_enabled", "merge_requests_enabled", "wiki_enabled", "snippets_enabled", "squash_option", "public", "visibility", "description", "builds_enabled", "public_builds", "import_url", "only_allow_merge_if_build_succeeds",

),

) _list_filters = (

"archived", "visibility", "order_by", "sort", "search", "simple", "owned", "membership", "starred", "statistics", "with_issues_enabled", "with_merge_requests_enabled", "with_custom_attributes", "with_programming_language", "wiki_checksum_failed", "repository_checksum_failed", "min_access_level", "id_after", "id_before",

)

@overload def list(

self, *, iterator: Literal[False] = False, **kwargs: Any

) -> list[UserProject]: ...

@overload def list(

self, *, iterator: Literal[True] = True, **kwargs: Any

) -> RESTObjectList[UserProject]: ...

@overload def list(

self, *, iterator: bool = False, **kwargs: Any

) -> RESTObjectList[UserProject] | list[UserProject]: ...

def list(
self, *, iterator: bool = False, **kwargs: Any
) -> RESTObjectList[UserProject] | list[UserProject]:

"""Retrieve a list of objects.

Args:

get_all: If True, return all the items, without pagination per_page: Number of items to retrieve per request page: ID of the page to return (starts with page 1) iterator: If set to True and no pagination option is

defined, return a generator instead of a list

**kwargs: Extra options to send to the server (e.g. sudo)

Returns:
The list of objects, or a generator if iterator is True
Raises:
GitlabAuthenticationError: If authentication is not correct GitlabListError: If the server cannot perform the request

""" if self._parent:

path = f"/users/{self._parent.id}/projects"
else:
path = f"/users/{self._from_parent_attrs['user_id']}/projects"

return super().list(path=path, iterator=iterator, **kwargs)

class UserContributedProject(RESTObject):
_id_attr = "id" _repr_attr = "path_with_namespace"
class UserContributedProjectManager(ListMixin[UserContributedProject]):
_path = "/users/{user_id}/contributed_projects" _obj_cls = UserContributedProject _from_parent_attrs = {"user_id": "id"}
class StarredProject(RESTObject):
pass
class StarredProjectManager(ListMixin[StarredProject]):

_path = "/users/{user_id}/starred_projects" _obj_cls = StarredProject _from_parent_attrs = {"user_id": "id"} _list_filters = (

"archived", "membership", "min_access_level", "order_by", "owned", "search", "simple", "sort", "starred", "statistics", "visibility", "with_custom_attributes", "with_issues_enabled", "with_merge_requests_enabled",

)

class UserFollowersManager(ListMixin[User]):
_path = "/users/{user_id}/followers" _obj_cls = User _from_parent_attrs = {"user_id": "id"}
class UserFollowingManager(ListMixin[User]):
_path = "/users/{user_id}/following" _obj_cls = User _from_parent_attrs = {"user_id": "id"}

About

A python wrapper for the GitLab API.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 99.8%
  • Other 0.2%