clear-skies-gitlab 2.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. clear_skies_gitlab-2.0.1.dist-info/METADATA +75 -0
  2. clear_skies_gitlab-2.0.1.dist-info/RECORD +42 -0
  3. clear_skies_gitlab-2.0.1.dist-info/WHEEL +4 -0
  4. clear_skies_gitlab-2.0.1.dist-info/licenses/LICENSE +21 -0
  5. clearskies_gitlab/__init__.py +3 -0
  6. clearskies_gitlab/backends/__init__.py +9 -0
  7. clearskies_gitlab/backends/gitlab_rest_backend.py +150 -0
  8. clearskies_gitlab/defaults/__init__.py +7 -0
  9. clearskies_gitlab/defaults/gitlab_default_auth.py +7 -0
  10. clearskies_gitlab/defaults/gitlab_default_url.py +7 -0
  11. clearskies_gitlab/exceptions/__init__.py +13 -0
  12. clearskies_gitlab/exceptions/gitlab_error.py +50 -0
  13. clearskies_gitlab/models/__init__.py +19 -0
  14. clearskies_gitlab/models/gitlab_cicd_variable.py +23 -0
  15. clearskies_gitlab/models/gitlab_gql_model.py +9 -0
  16. clearskies_gitlab/models/gitlab_group.py +69 -0
  17. clearskies_gitlab/models/gitlab_member.py +24 -0
  18. clearskies_gitlab/models/gitlab_namespace.py +32 -0
  19. clearskies_gitlab/models/gitlab_project.py +110 -0
  20. clearskies_gitlab/models/gitlab_rest_model.py +11 -0
  21. clearskies_gitlab/models/rest/__init__.py +35 -0
  22. clearskies_gitlab/models/rest/gitlab_rest_advanced_search.py +38 -0
  23. clearskies_gitlab/models/rest/gitlab_rest_advanced_search_blob.py +26 -0
  24. clearskies_gitlab/models/rest/gitlab_rest_current_user.py +43 -0
  25. clearskies_gitlab/models/rest/gitlab_rest_group.py +75 -0
  26. clearskies_gitlab/models/rest/gitlab_rest_group_access_token.py +32 -0
  27. clearskies_gitlab/models/rest/gitlab_rest_group_member.py +28 -0
  28. clearskies_gitlab/models/rest/gitlab_rest_group_member_reference.py +6 -0
  29. clearskies_gitlab/models/rest/gitlab_rest_group_project.py +37 -0
  30. clearskies_gitlab/models/rest/gitlab_rest_group_reference.py +6 -0
  31. clearskies_gitlab/models/rest/gitlab_rest_group_search.py +21 -0
  32. clearskies_gitlab/models/rest/gitlab_rest_group_search_blob.py +13 -0
  33. clearskies_gitlab/models/rest/gitlab_rest_group_subgroup.py +65 -0
  34. clearskies_gitlab/models/rest/gitlab_rest_group_subgroup_reference.py +6 -0
  35. clearskies_gitlab/models/rest/gitlab_rest_group_variable.py +22 -0
  36. clearskies_gitlab/models/rest/gitlab_rest_namespace.py +69 -0
  37. clearskies_gitlab/models/rest/gitlab_rest_project.py +81 -0
  38. clearskies_gitlab/models/rest/gitlab_rest_project_reference.py +6 -0
  39. clearskies_gitlab/models/rest/gitlab_rest_project_repository_commit.py +44 -0
  40. clearskies_gitlab/models/rest/gitlab_rest_project_repository_commit_diff.py +34 -0
  41. clearskies_gitlab/models/rest/gitlab_rest_project_variable.py +24 -0
  42. clearskies_gitlab/models/rest/gitlab_rest_project_variable_refence.py +6 -0
@@ -0,0 +1,75 @@
1
+ Metadata-Version: 2.4
2
+ Name: clear-skies-gitlab
3
+ Version: 2.0.1
4
+ Summary: Gitlab module for Clearskies
5
+ Project-URL: Docs, https://https://clearskies.info/modules/clear-skies-gitlab
6
+ Project-URL: Repository, https://github.com/clearskies-py/gitlab
7
+ Project-URL: Issues, https://github.com/clearskies-py/gitlab/issues
8
+ Project-URL: Changelog, https://github.com/clearskies-py/gitlab/blob/main/CHANGELOG.md
9
+ Author-email: Tom Nijboer <tom.nijboer@cimpress.com>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Requires-Python: <4.0,>=3.11
17
+ Requires-Dist: clear-skies>=2.0.0
18
+ Requires-Dist: gql>=4.0.0
19
+ Requires-Dist: requests>=2.32.5
20
+ Provides-Extra: dev
21
+ Requires-Dist: types-requests>=2.32.4; extra == 'dev'
22
+ Description-Content-Type: text/markdown
23
+
24
+
25
+ # gitlab
26
+
27
+
28
+ Gitlab module for Clearskies
29
+
30
+ This template scaffolds a dynamic Clearskies module for any kind of logic, integration, or API. You can use it to build modules for data processing, service integration, automation, or any custom business logic.
31
+
32
+ Your module can implement any logic you need: fetch data, process input, interact with external services, or perform custom actions. The endpoints and payloads are up to you.
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ # Install uv if not already installed
38
+ pip install uv
39
+
40
+ # Create a virtual environment and install dependencies
41
+ uv sync
42
+ ```
43
+
44
+ ## Development
45
+
46
+ To set up your development environment with pre-commit hooks:
47
+
48
+ ```bash
49
+ # Install uv if not already installed
50
+ pip install uv
51
+
52
+ # Create a virtual environment and install all dependencies (including dev)
53
+ uv sync
54
+
55
+ # Install dev dependencies (including ruff, black, mypy) in the project environment
56
+ uv pip install .[dev]
57
+
58
+ # Install pre-commit hooks
59
+ uv run pre-commit install
60
+
61
+ # Optionally, run pre-commit on all files
62
+ uv run pre-commit run --all-files
63
+ ```
64
+
65
+ ## Usage Example
66
+
67
+ ```python
68
+ import clearskies
69
+ import clearskies_gitlab
70
+
71
+ wsgi = clearskies.contexts.WsgiRef(
72
+ clearskies_gitlab.build__module()
73
+ )
74
+ wsgi()
75
+ ```
@@ -0,0 +1,42 @@
1
+ clearskies_gitlab/__init__.py,sha256=ClIA0vw3F7SEkiHWukom62Vc023czAhujTj61w8nZL0,129
2
+ clearskies_gitlab/backends/__init__.py,sha256=edqByrjBImEUO1KvHjBHpA9X15uRXxstCYo9UXpJkPM,254
3
+ clearskies_gitlab/backends/gitlab_rest_backend.py,sha256=v8HiKbQyn5i0OvOr6w8Zag4BQznIrDQNg2FaLgL1Iaw,6543
4
+ clearskies_gitlab/defaults/__init__.py,sha256=GF1ggkRAFoRP7F0mzUj0lfMV1WneKa8z3f5eDWLhCKY,216
5
+ clearskies_gitlab/defaults/gitlab_default_auth.py,sha256=iwlvQrYkODVwoyj4hkRdq-OHaLXX0kxasPvBuyTIHnY,323
6
+ clearskies_gitlab/defaults/gitlab_default_url.py,sha256=lfjr5_rNydY-yGGzKp1D-ANdbc51_yIz2AEUF07tO9U,288
7
+ clearskies_gitlab/exceptions/__init__.py,sha256=QUg8lVn91QMENpN_uZmYdNkhI1EjFAWN9X6cMKgKmtE,301
8
+ clearskies_gitlab/exceptions/gitlab_error.py,sha256=DUplWahAT2hC6GZiuapVZc_PEb-D3068CJmaGFg_yek,2000
9
+ clearskies_gitlab/models/__init__.py,sha256=jJ0Knev4oE8ew_RI01rDD-0G1WOZdF7wfyuaGFb9wUk,645
10
+ clearskies_gitlab/models/gitlab_cicd_variable.py,sha256=Bzk6M6ycIqeUxY6uhT_3zRBxm7pkOqdPjEk4JYO2oxM,506
11
+ clearskies_gitlab/models/gitlab_gql_model.py,sha256=NkmQEqECofkNTDWjSywniUCYDG2inejzVgLxyBfqecg,189
12
+ clearskies_gitlab/models/gitlab_group.py,sha256=mmruk1OLSLb5cwN8xtOY30tCXbgtngz399N4WFzzNa4,2283
13
+ clearskies_gitlab/models/gitlab_member.py,sha256=-x0xU_Kf14Bkc9-h27KYxSbdmS6X2LthLI2Gdch0C80,547
14
+ clearskies_gitlab/models/gitlab_namespace.py,sha256=fW9ADAqXrWPJoVBrQo0JbJvccJZKaGmXtJjShwgXxII,917
15
+ clearskies_gitlab/models/gitlab_project.py,sha256=Fx9xiUrhO4YWdCRSFQLuFphPVZEGNfUoj1Cwo2VdJ-0,4223
16
+ clearskies_gitlab/models/gitlab_rest_model.py,sha256=XnlKBuORJPi4AKPNSuCasx3blmmpWZZv-nJfzYbQ54E,225
17
+ clearskies_gitlab/models/rest/__init__.py,sha256=auEn31pkPk8zcbw6ZamNrMbltydjufUIxh-WhcpWx6w,1854
18
+ clearskies_gitlab/models/rest/gitlab_rest_advanced_search.py,sha256=9ftD-rcMhEejzQdEQBxNpQOxtL0yywB0mg5peSpCyMk,893
19
+ clearskies_gitlab/models/rest/gitlab_rest_advanced_search_blob.py,sha256=ZDko71JUsL1-dIsoWulQVlY30L6GMHS8taFUL_k9fn0,688
20
+ clearskies_gitlab/models/rest/gitlab_rest_current_user.py,sha256=fCyrkk3KO66nTH2I7ioggqdUHRSDOKofZRB9qlD19_4,1107
21
+ clearskies_gitlab/models/rest/gitlab_rest_group.py,sha256=wFXleyn34d1gz9pVBYubuBNLx5B2vkcFv9pEtc83DXM,2102
22
+ clearskies_gitlab/models/rest/gitlab_rest_group_access_token.py,sha256=Wx2NOzsgaRizKZNNk_BqAmUq3wOU8E0YQCdzxE8IzR0,904
23
+ clearskies_gitlab/models/rest/gitlab_rest_group_member.py,sha256=0L03cVruwUvJa-laJVA1bVULJM_gS2DZJGjkgF08Sbc,774
24
+ clearskies_gitlab/models/rest/gitlab_rest_group_member_reference.py,sha256=y1gbRc-XJljMizOOa2diA-cxAllACykN7h08RNzfn6k,200
25
+ clearskies_gitlab/models/rest/gitlab_rest_group_project.py,sha256=bQXIFz1GiLjIB2Pm6W_4JuqEd0sefumpmEFMo8_L0Z8,865
26
+ clearskies_gitlab/models/rest/gitlab_rest_group_reference.py,sha256=mJTBjjiPfjYgngzcotUjcWPPRBA0wdUCcOZKdIrxVcQ,174
27
+ clearskies_gitlab/models/rest/gitlab_rest_group_search.py,sha256=Q_bR6es8l8vZGi5u_31d9V2QY6byzYZAu_ACNEWJx7k,547
28
+ clearskies_gitlab/models/rest/gitlab_rest_group_search_blob.py,sha256=EhCs3KkaZsdmf85Ctt8Wgq681YvmgeYK47VBh1bdRIE,353
29
+ clearskies_gitlab/models/rest/gitlab_rest_group_subgroup.py,sha256=l9bGhkULbL0wtQxp4XfoQS7vwfcJdY96NxsKq4FHvKE,1781
30
+ clearskies_gitlab/models/rest/gitlab_rest_group_subgroup_reference.py,sha256=CXdGQQ4Aswk5e4ixMTn8wWGotI5ETl-xESRPuueJSIA,208
31
+ clearskies_gitlab/models/rest/gitlab_rest_group_variable.py,sha256=s24Q6agioITIfX9G2xnNAzySR0BflGiYnLgrXfCGeFQ,629
32
+ clearskies_gitlab/models/rest/gitlab_rest_namespace.py,sha256=PmY2yHY63G2DJBOo5Xe6BdzfcGumM4cVlX1aONLesEY,1919
33
+ clearskies_gitlab/models/rest/gitlab_rest_project.py,sha256=diO2-8QiN9VvXCNa7egKTnIp6SFl6P2lHrG5wkjaUbk,2492
34
+ clearskies_gitlab/models/rest/gitlab_rest_project_reference.py,sha256=oK42SyFQQTIFeidstoIz-_PFq9qwlzyvhq9cmJcqg2E,182
35
+ clearskies_gitlab/models/rest/gitlab_rest_project_repository_commit.py,sha256=R3Km247_TDyYqtQEGM1w5r1BYpUtA1j0cS2XA06Q9tw,1171
36
+ clearskies_gitlab/models/rest/gitlab_rest_project_repository_commit_diff.py,sha256=EAZd1H6AnuwvzW4ZH5KX4prNn_RoV_0PzBlPOHkXOiQ,892
37
+ clearskies_gitlab/models/rest/gitlab_rest_project_variable.py,sha256=FylNaIBiFx7oVOIz9Nltdp0GT2OsjSghDD4nLQAQ1pA,790
38
+ clearskies_gitlab/models/rest/gitlab_rest_project_variable_refence.py,sha256=jdiE-9v5yovfk5HM7vkmQlkkAthmI6YNh6sDQrrjoSU,216
39
+ clear_skies_gitlab-2.0.1.dist-info/METADATA,sha256=aMsKuagx7ecWaqdlzEeTmFT3z4PRzJ99OONnPPxBUAw,2138
40
+ clear_skies_gitlab-2.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
41
+ clear_skies_gitlab-2.0.1.dist-info/licenses/LICENSE,sha256=MkEX8JF8kZxdyBpTTcB0YTd-xZpWnHvbRlw-pQh8u58,1069
42
+ clear_skies_gitlab-2.0.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025, Tom Nijboer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ from clearskies_gitlab import backends, defaults, exceptions, models
2
+
3
+ __all__ = ["backends", "models", "defaults", "exceptions"]
@@ -0,0 +1,9 @@
1
+ from __future__ import annotations
2
+
3
+ # from clearskies_gitlab.backends.gitlab_gql_backend import GitlabGqlBackend
4
+ from clearskies_gitlab.backends.gitlab_rest_backend import GitlabRestBackend
5
+
6
+ __all__ = [
7
+ "GitlabGqlBackend",
8
+ "GitlabRestBackend",
9
+ ]
@@ -0,0 +1,150 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ import urllib
5
+ from collections.abc import Callable
6
+ from typing import TYPE_CHECKING, Any, cast
7
+
8
+ import requests
9
+ from clearskies import Column, Model, configs
10
+ from clearskies.backends import ApiBackend
11
+ from clearskies.decorators import parameters_to_properties
12
+ from clearskies.di import inject
13
+ from clearskies.functional import string
14
+ from clearskies.query import Query
15
+ from requests.structures import CaseInsensitiveDict
16
+
17
+ from clearskies_gitlab.exceptions import gitlab_error
18
+
19
+ if TYPE_CHECKING:
20
+ from clearskies import model
21
+ from clearskies.authentication import Authentication
22
+ from clearskies.query import Query
23
+
24
+
25
+ class GitlabRestBackend(ApiBackend):
26
+ """Backend for Gitlab.com."""
27
+
28
+ base_url = inject.ByName("gitlab_url", cache=True)
29
+ authentication = inject.ByName("gitlab_auth", cache=False)
30
+ requests = inject.Requests()
31
+ _auth_headers: dict[str, str] = {}
32
+
33
+ api_to_model_map = configs.AnyDict(default={})
34
+ pagination_parameter_name = configs.String(default="page")
35
+
36
+ @parameters_to_properties
37
+ def __init__(
38
+ self,
39
+ base_url: str | None = None,
40
+ authentication: Authentication | None = None,
41
+ model_casing: str = "snake_case",
42
+ api_casing: str = "snake_case",
43
+ api_to_model_map: dict[str, str | list[str]] = {},
44
+ pagination_parameter_name: str = "page",
45
+ pagination_parameter_type: str = "str",
46
+ limit_parameter_name: str = "per_page",
47
+ ):
48
+ self.finalize_and_validate_configuration()
49
+
50
+ def count_method(self, query: Query) -> str:
51
+ """Return the request method to use when making a request for a record count."""
52
+ return "HEAD"
53
+
54
+ def count(self, query: Query) -> int:
55
+ """Return the count of records matching the query."""
56
+ self.check_query(query)
57
+ (url, method, body, headers) = self.build_records_request(query)
58
+ response = self.execute_request(url, self.count_method(query), json=body, headers=headers)
59
+ return self._map_count_response(response.headers)
60
+
61
+ def _map_count_response(self, headers: CaseInsensitiveDict[str]) -> int:
62
+ return int(headers.get("x-total", 0))
63
+
64
+ # def map_records_response(
65
+ # self, response_data: Any, query: Query, query_data: dict[str, Any] | None = None
66
+ # ) -> list[dict[str, Any]]:
67
+ # """Map the response data to model records with support for nested fields."""
68
+ # if query_data is None:
69
+ # query_data = {}
70
+
71
+ # columns = query.model_class.get_columns()
72
+ # result = []
73
+
74
+ # # Handle list response
75
+ # if isinstance(response_data, list):
76
+ # for item in response_data:
77
+ # if not isinstance(item, dict):
78
+ # continue
79
+ # mapped = self.check_dict_and_map_to_model(item, columns, query_data)
80
+ # if mapped:
81
+ # result.append(mapped)
82
+ # # Handle single object response
83
+ # elif isinstance(response_data, dict):
84
+ # mapped = self.check_dict_and_map_to_model(response_data, columns, query_data)
85
+ # if mapped:
86
+ # result.append(mapped)
87
+
88
+ # return result
89
+
90
+ def conditions_to_request_parameters(
91
+ self, query: Query, used_routing_parameters: list[str]
92
+ ) -> tuple[str, dict[str, str], dict[str, Any]]:
93
+ route_id = ""
94
+
95
+ url_parameters = {}
96
+ for condition in query.conditions:
97
+ if condition.column_name in used_routing_parameters:
98
+ continue
99
+ if condition.operator != "=":
100
+ raise ValueError(
101
+ f"I'm not very smart and only know how to search with the equals operator, but I received a condition of {condition.parsed}. If you need to support this, you'll have to extend the ApiBackend and overwrite the build_records_request method."
102
+ )
103
+ if condition.column_name == query.model_class.id_column_name:
104
+ route_id = urllib.parse.quote_plus(condition.values[0]).replace("+", "%20")
105
+ continue
106
+ url_parameters[condition.column_name] = condition.values[0]
107
+
108
+ return (route_id, url_parameters, {})
109
+
110
+ # def set_next_page_data_from_response(
111
+ # self,
112
+ # next_page_data: dict[str, Any],
113
+ # query: Query,
114
+ # response: requests.Response, # type: ignore
115
+ # ) -> None:
116
+ # """
117
+ # Update the next_page_data dictionary with the appropriate data needed to fetch the next page of records.
118
+
119
+ # This method has a very important job, which is to inform clearskies about how to make another API call to fetch the next
120
+ # page of records. The way this happens is by updating the `next_page_data` dictionary in place with whatever pagination
121
+ # information is necessary. Note that this relies on next_page_data being passed by reference, hence the need to update
122
+ # it in place. That means that you can do this:
123
+
124
+ # ```python
125
+ # next_page_data["some_key"] = "some_value"
126
+ # ```
127
+
128
+ # but if you do this:
129
+
130
+ # ```python
131
+ # next_page_data = {"some_key": "some_value"}
132
+ # ```
133
+
134
+ # Then things simply won't work.
135
+ # """
136
+ # # Different APIs generally have completely different ways of communicating pagination data, but one somewhat common
137
+ # # approach is to use a link header, so let's support that in the base class.
138
+ # if "link" not in response.headers:
139
+ # return
140
+ # next_link = [rel for rel in response.headers["link"].split(",") if 'rel="next"' in rel]
141
+ # if not next_link:
142
+ # return
143
+ # parsed_next_link = urllib.parse.urlparse(next_link[0].split(";")[0].strip(" <>"))
144
+ # query_parameters = urllib.parse.parse_qs(parsed_next_link.query)
145
+ # if self.pagination_parameter_name not in query_parameters:
146
+ # raise ValueError(
147
+ # f"Configuration error with {self.__class__.__name__}! I am configured to expect a pagination key of '{self.pagination_parameter_name}. However, when I was parsing the next link from a response to get the next pagination details, I could not find the designated pagination key. This likely means that backend.pagination_parameter_name is set to the wrong value. The link in question was "
148
+ # + parsed_next_link.geturl()
149
+ # )
150
+ # next_page_data[self.pagination_parameter_name] = query_parameters[self.pagination_parameter_name][0]
@@ -0,0 +1,7 @@
1
+ from clearskies_gitlab.defaults.gitlab_default_auth import GitlabDefaultAuth
2
+ from clearskies_gitlab.defaults.gitlab_default_url import GitlabDefaultUrl
3
+
4
+ __all__ = [
5
+ "GitlabDefaultAuth",
6
+ "GitlabDefaultUrl",
7
+ ]
@@ -0,0 +1,7 @@
1
+ import clearskies
2
+
3
+
4
+ class GitlabDefaultAuth(clearskies.di.AdditionalConfigAutoImport):
5
+ def provide_gitlab_auth(self, environment: clearskies.Environment):
6
+ secret_key = environment.get("GITLAB_AUTH_KEY", True)
7
+ return clearskies.authentication.SecretBearer(secret_key=secret_key, header_prefix="Bearer ")
@@ -0,0 +1,7 @@
1
+ import clearskies
2
+
3
+
4
+ class GitlabDefaultUrl(clearskies.di.AdditionalConfigAutoImport):
5
+ def provide_gitlab_url(self, environment: clearskies.Environment):
6
+ gitlab_url = environment.get("GITLAB_URL", True)
7
+ return gitlab_url if gitlab_url else "https://gitlab.com/api/v4/"
@@ -0,0 +1,13 @@
1
+ from clearskies_gitlab.exceptions.gitlab_error import (
2
+ GitlabParamMissingError,
3
+ GitlabResourceError,
4
+ GitlabResponseError,
5
+ MethodNotImplementedError,
6
+ )
7
+
8
+ __all__ = [
9
+ "GitlabParamMissingError",
10
+ "GitlabResourceError",
11
+ "GitlabResponseError",
12
+ "MethodNotImplementedError",
13
+ ]
@@ -0,0 +1,50 @@
1
+ from clearskies.exceptions import ClientError
2
+
3
+
4
+ class CredentialError(ClientError):
5
+ """Throw exception if something goes wrong for fetching the credentials from Akeyless."""
6
+
7
+ def __init__(self, key_name: str) -> None:
8
+ """Create specific message for Credential Issue."""
9
+ super().__init__(f"Could not retrieve {key_name}")
10
+
11
+
12
+ class InvalidCredentialError(ClientError):
13
+ """Throw exception if the token isn't valid anymore."""
14
+
15
+ def __init__(self) -> None:
16
+ """Create specific message for InvalidCredentialError Issue."""
17
+ super().__init__("Gitlab token for was not valid - please contact Cimpress security and privacy")
18
+
19
+
20
+ class MethodNotImplementedError(NotImplementedError):
21
+ """Error if Method is not implemented in the Gitlab api for endpoint."""
22
+
23
+ def __init__(self, method: str, endpoint: str, version: str = "v1") -> None:
24
+ """Create error with method and endpoint on version."""
25
+ super().__init__(f"Method: {method} is not implemented for {endpoint} in {version}.")
26
+
27
+
28
+ class GitlabResourceError(ValueError):
29
+ """Error if resource could be found."""
30
+
31
+ def __init__(self, endpoint: str, resource_name: str) -> None:
32
+ """Create error if resource name is not specified for endpoint."""
33
+ super().__init__(
34
+ f"The Gitlab API for endpoint {endpoint} requires searching by a column named {resource_name}, but it was missing in the query"
35
+ )
36
+
37
+
38
+ class GitlabResponseError(ValueError):
39
+ """Error if response of Gitlab is wrong."""
40
+
41
+ def __init__(self, status_code: int, message: bytes) -> None:
42
+ """Create error with request info."""
43
+ super().__init__(f"Failed request. Status code: {status_code}, message: {message.decode()}")
44
+
45
+
46
+ class GitlabParamMissingError(ValueError):
47
+ """Error if param is missing."""
48
+
49
+ def __init__(self, param_name: str, table_name: str) -> None:
50
+ super().__init__(f"Must provide the {param_name} to add the member to when updating a {table_name}")
@@ -0,0 +1,19 @@
1
+ from __future__ import annotations
2
+
3
+ from clearskies_gitlab.models import rest
4
+ from clearskies_gitlab.models.gitlab_cicd_variable import GitlabCICDVariable
5
+ from clearskies_gitlab.models.gitlab_gql_model import GitlabGqlModel
6
+ from clearskies_gitlab.models.gitlab_group import GitlabGroup
7
+ from clearskies_gitlab.models.gitlab_member import GitlabMember
8
+ from clearskies_gitlab.models.gitlab_project import GitlabProject
9
+ from clearskies_gitlab.models.gitlab_rest_model import GitlabRestModel
10
+
11
+ __all__ = [
12
+ "rest",
13
+ "GitlabGqlModel",
14
+ "GitlabGroup",
15
+ "GitlabMember",
16
+ "GitlabCICDVariable",
17
+ "GitlabProject",
18
+ "GitlabRestModel",
19
+ ]
@@ -0,0 +1,23 @@
1
+ from __future__ import annotations
2
+
3
+ from collections import OrderedDict
4
+ from typing import Any
5
+
6
+ from clearskies import Model
7
+ from clearskies.columns import Boolean, String
8
+
9
+
10
+ class GitlabCICDVariable(Model):
11
+ """Base model for groups ci/cd variables."""
12
+
13
+ id_column_name = "key"
14
+
15
+ key = String()
16
+ value = String()
17
+ description = String()
18
+ environment_scope = String()
19
+ variable_type = String()
20
+ masked = Boolean()
21
+ protected = Boolean()
22
+ hidden = Boolean()
23
+ raw = Boolean()
@@ -0,0 +1,9 @@
1
+ from __future__ import annotations
2
+
3
+ from clearskies import Model
4
+
5
+ # from clearskies_gitlab.backends import GitlabGql
6
+
7
+
8
+ class GitlabGqlModel(Model):
9
+ """Base model for gitlab via GQL."""
@@ -0,0 +1,69 @@
1
+ from __future__ import annotations
2
+
3
+ from collections import OrderedDict
4
+ from typing import Any
5
+
6
+ from clearskies import Model
7
+ from clearskies.columns import Boolean, Datetime, Integer, Json, String
8
+
9
+
10
+ class GitlabGroup(Model):
11
+ """Base model for groups."""
12
+
13
+ id_column_name = "id"
14
+
15
+ id = String()
16
+ web_url = String()
17
+ name = String()
18
+ path = String()
19
+ description = String()
20
+ visibility = String()
21
+ share_with_group_lock = Boolean()
22
+ require_two_factor_authentication = Boolean()
23
+ two_factor_grace_period = Integer()
24
+ project_creation_level = String()
25
+ auto_devops_enabled = Boolean()
26
+ subgroup_creation_level = String()
27
+ emails_disabled = Boolean()
28
+ emails_enabled = Boolean()
29
+ mentions_disabled = String()
30
+ lfs_enabled = String()
31
+ math_rendering_limits_enabled = Boolean()
32
+ lock_math_rendering_limits_enabled = Boolean()
33
+ default_branch = String()
34
+ default_branch_protection = String()
35
+ default_branch_protection_defaults = String()
36
+ avatar_url = String()
37
+ request_access_enabled = Boolean()
38
+ full_name = String()
39
+ full_path = String()
40
+ created_at = Datetime()
41
+ parent_id = String()
42
+ organization_id = String()
43
+ shared_runners_setting = String()
44
+ custom_attributes = Json()
45
+ statistics = Json()
46
+ ldap_cn = String()
47
+ ldap_access = String()
48
+ ldap_group_links = Json()
49
+ saml_group_links = Json()
50
+ file_template_project_id = String()
51
+ marked_for_deletion_on = Datetime()
52
+ wiki_access_level = String()
53
+ repository_storage = String()
54
+ duo_features_enabled = Boolean()
55
+ lock_duo_features_enabled = Boolean()
56
+ shared_with_groups = Json()
57
+ runners_token = String()
58
+ enabled_git_access_protocol = String()
59
+ prevent_sharing_groups_outside_hierarchy = Boolean()
60
+ shared_runners_minutes_limit = Integer()
61
+ extra_shared_runners_minutes_limit = Integer()
62
+ prevent_forking_outside_group = Boolean()
63
+ service_access_tokens_expiration_enforced = Boolean()
64
+ membership_lock = Boolean()
65
+ ip_restriction_ranges = Json()
66
+ unique_project_download_limit = String()
67
+ unique_project_download_limit_interval_in_seconds = Integer()
68
+ unique_project_download_limit_alertlist = Json()
69
+ auto_ban_user_on_excessive_projects_download = Boolean()
@@ -0,0 +1,24 @@
1
+ from __future__ import annotations
2
+
3
+ from collections import OrderedDict
4
+ from typing import Any
5
+
6
+ from clearskies import Model
7
+ from clearskies.columns import Datetime, Email, Integer, Json, String
8
+
9
+
10
+ class GitlabMember(Model):
11
+ """Base model for group or project members."""
12
+
13
+ id_column_name = "id"
14
+
15
+ id = Integer()
16
+ username = String()
17
+ name = String()
18
+ state = String()
19
+ avatar_url = String()
20
+ access_level = Integer()
21
+ created_at = Datetime()
22
+ created_by = Json()
23
+ email = Email()
24
+ group_saml_identity = Json()
@@ -0,0 +1,32 @@
1
+ from __future__ import annotations
2
+
3
+ from collections import OrderedDict
4
+ from typing import Any
5
+
6
+ from clearskies import Model
7
+ from clearskies.columns import Boolean, Datetime, Integer, Json, Select, String
8
+
9
+
10
+ class GitlabNamespace(Model):
11
+ """Base model for namespaces."""
12
+
13
+ id_column_name = "id"
14
+
15
+ id = String()
16
+ name = String()
17
+ path = String()
18
+ kind = Select(allowed_values=["group", "user"])
19
+ full_path = String()
20
+ avatar_url = String()
21
+ web_url = String()
22
+ billable_members_count = Integer()
23
+ plan = Select(allowed_values=["free", "premium", "ultimate", "bronze", "silver", "gold"])
24
+ end_date = Datetime()
25
+ trial_ends_on = Datetime()
26
+ trial = Boolean()
27
+ root_repository_size = Integer()
28
+ projects_count = Integer()
29
+ max_seats_used = Integer()
30
+ max_seats_used_changed_at = Datetime()
31
+ seats_in_use = Integer()
32
+ members_counts_with_descendants = Integer()