fluidattacks_gitlab_sdk 8.0.0__tar.gz → 8.1.0__tar.gz
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.
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/PKG-INFO +1 -1
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/flake.lock +12 -12
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/flake.nix +1 -1
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/__init__.py +1 -1
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/milestones/_client.py +1 -2
- fluidattacks_gitlab_sdk-8.1.0/fluidattacks_gitlab_sdk/users/__init__.py +9 -0
- fluidattacks_gitlab_sdk-8.1.0/fluidattacks_gitlab_sdk/users/_client.py +52 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/users/core.py +10 -1
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/pyproject.toml +1 -1
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/arch/arch.py +1 -0
- fluidattacks_gitlab_sdk-8.1.0/tests/users/decoder_test.py +33 -0
- fluidattacks_gitlab_sdk-8.1.0/tests_fx/py.typed +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/uv.lock +8 -7
- fluidattacks_gitlab_sdk-8.0.0/fluidattacks_gitlab_sdk/users/__init__.py +0 -5
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/.envrc +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/build/default.nix +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/build/filter.nix +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/_decoders.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/_gql_client/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/_gql_client/_client.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/_gql_client/_error.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/_gql_client/_handlers.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/_handlers.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/_http_client/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/_http_client/_client_1.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/_http_client/_core.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/_logger.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/ids.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/issues/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/issues/_client/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/issues/_client/_core.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/issues/_client/_decode.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/issues/_client/_get_issue.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/issues/_client/_gql_fields.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/issues/_client/_most_recent.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/issues/core.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/jobs/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/jobs/_client.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/jobs/_decode.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/jobs/core.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/members/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/members/_client.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/members/_decode.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/members/core.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/merge_requests/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/merge_requests/_client.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/merge_requests/_decode.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/merge_requests/core.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/milestones/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/milestones/_decode.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/milestones/core.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/mr_approvals/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/mr_approvals/_client.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/mr_approvals/_decode.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/mr_approvals/core.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/mr_notes/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/mr_notes/_client.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/mr_notes/_core.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/mr_notes/_decode.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/py.typed +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/users/decode.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/mypy.ini +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/ruff.toml +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/arch/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/arch/test_arch.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/issues/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/issues/data.json +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/issues/test_decode.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/issues/test_gql_fields.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/jobs/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/jobs/data.json +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/jobs/test_decode_job.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/members/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/members/data.json +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/members/test_decode_members.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/merge_request/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/merge_request/data.json +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/merge_request/data_mr_updates.json +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/merge_request/test_decode.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/mr_approvals/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/mr_approvals/data.json +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/mr_approvals/decoder_test.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/mr_notes/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/mr_notes/data.json +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/mr_notes/decoder_test.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/py.typed +0 -0
- {fluidattacks_gitlab_sdk-8.0.0/tests_fx → fluidattacks_gitlab_sdk-8.1.0/tests/users}/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0/tests_fx/issues → fluidattacks_gitlab_sdk-8.1.0/tests_fx}/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests_fx/_utils.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0/tests_fx/jobs → fluidattacks_gitlab_sdk-8.1.0/tests_fx/issues}/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests_fx/issues/test_issue_client.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0/tests_fx/members → fluidattacks_gitlab_sdk-8.1.0/tests_fx/jobs}/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests_fx/jobs/client_test.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0/tests_fx/milestones → fluidattacks_gitlab_sdk-8.1.0/tests_fx/members}/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests_fx/members/test_client_members.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0/tests_fx/mr_approvals → fluidattacks_gitlab_sdk-8.1.0/tests_fx/milestones}/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests_fx/milestones/client_test.py +0 -0
- /fluidattacks_gitlab_sdk-8.0.0/tests_fx/py.typed → /fluidattacks_gitlab_sdk-8.1.0/tests_fx/mr_approvals/__init__.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests_fx/mr_approvals/client_test.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests_fx/test_gql_client.py +0 -0
- {fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests_fx/test_mr.py +0 -0
|
@@ -206,18 +206,18 @@
|
|
|
206
206
|
"uv2nix": "uv2nix_2"
|
|
207
207
|
},
|
|
208
208
|
"locked": {
|
|
209
|
-
"dir": "
|
|
210
|
-
"lastModified":
|
|
211
|
-
"narHash": "sha256-
|
|
209
|
+
"dir": "develops/utils/python-builder",
|
|
210
|
+
"lastModified": 1793317305,
|
|
211
|
+
"narHash": "sha256-Fib0dOCrgVRbg8rweiOayunztGkQeShPJIaDiJjxyNw=",
|
|
212
212
|
"ref": "refs/heads/trunk",
|
|
213
|
-
"rev": "
|
|
213
|
+
"rev": "c08ac98b3d84d5858fe1d64c837df02c9db1ae04",
|
|
214
214
|
"shallow": true,
|
|
215
215
|
"type": "git",
|
|
216
216
|
"url": "ssh://git@gitlab.com/fluidattacks/universe"
|
|
217
217
|
},
|
|
218
218
|
"original": {
|
|
219
|
-
"dir": "
|
|
220
|
-
"rev": "
|
|
219
|
+
"dir": "develops/utils/python-builder",
|
|
220
|
+
"rev": "c08ac98b3d84d5858fe1d64c837df02c9db1ae04",
|
|
221
221
|
"shallow": true,
|
|
222
222
|
"type": "git",
|
|
223
223
|
"url": "ssh://git@gitlab.com/fluidattacks/universe"
|
|
@@ -238,18 +238,18 @@
|
|
|
238
238
|
]
|
|
239
239
|
},
|
|
240
240
|
"locked": {
|
|
241
|
-
"dir": "
|
|
242
|
-
"lastModified":
|
|
243
|
-
"narHash": "sha256-
|
|
241
|
+
"dir": "develops/utils/shell-helpers",
|
|
242
|
+
"lastModified": 1793311103,
|
|
243
|
+
"narHash": "sha256-kt32aGdMaZGxD0MS9Giqst8leP83IgYUppCNZQy+vo8=",
|
|
244
244
|
"ref": "refs/heads/trunk",
|
|
245
|
-
"rev": "
|
|
245
|
+
"rev": "3747456d06ecbfe0523e68f4841a536e7a4b3c88",
|
|
246
246
|
"shallow": true,
|
|
247
247
|
"type": "git",
|
|
248
248
|
"url": "ssh://git@gitlab.com/fluidattacks/universe"
|
|
249
249
|
},
|
|
250
250
|
"original": {
|
|
251
|
-
"dir": "
|
|
252
|
-
"rev": "
|
|
251
|
+
"dir": "develops/utils/shell-helpers",
|
|
252
|
+
"rev": "3747456d06ecbfe0523e68f4841a536e7a4b3c88",
|
|
253
253
|
"shallow": true,
|
|
254
254
|
"type": "git",
|
|
255
255
|
"url": "ssh://git@gitlab.com/fluidattacks/universe"
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
inputs = {
|
|
5
5
|
nixpkgs.url = "github:nixos/nixpkgs/2f5a153c270b70cb0f8c11f46d96d6d3bc39f4e3";
|
|
6
6
|
python_builder = {
|
|
7
|
-
url = "git+ssh://git@gitlab.com/fluidattacks/universe?shallow=1&rev=
|
|
7
|
+
url = "git+ssh://git@gitlab.com/fluidattacks/universe?shallow=1&rev=c08ac98b3d84d5858fe1d64c837df02c9db1ae04&dir=develops/utils/python-builder";
|
|
8
8
|
inputs.nixpkgs_flake.follows = "nixpkgs";
|
|
9
9
|
};
|
|
10
10
|
};
|
|
@@ -113,8 +113,7 @@ def most_recent_milestone(
|
|
|
113
113
|
"milestones",
|
|
114
114
|
)
|
|
115
115
|
params: dict[str, Primitive] = {
|
|
116
|
-
"
|
|
117
|
-
"sort": "desc",
|
|
116
|
+
"sort": "created_desc",
|
|
118
117
|
"per_page": 1,
|
|
119
118
|
}
|
|
120
119
|
empty: Maybe[tuple[MilestoneFullId, Milestone]] = Maybe[
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
from fa_purity import Cmd, FrozenTools, ResultE, cast_exception
|
|
6
|
+
from fa_purity.json import JsonObj, JsonUnfolder, Unfolder
|
|
7
|
+
from fluidattacks_etl_utils.decode import DecodeUtils
|
|
8
|
+
|
|
9
|
+
from fluidattacks_gitlab_sdk._gql_client import GraphQlGitlabClient
|
|
10
|
+
from fluidattacks_gitlab_sdk._http_client import Credentials
|
|
11
|
+
|
|
12
|
+
from .core import User, UsersClient
|
|
13
|
+
|
|
14
|
+
_IS_BOT = """
|
|
15
|
+
query isBot($username: String!) {
|
|
16
|
+
user(username: $username) {
|
|
17
|
+
bot
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def decode_is_bot(raw: JsonObj) -> ResultE[bool]:
|
|
24
|
+
# An unknown account is a deleted one, and those were people.
|
|
25
|
+
return JsonUnfolder.require(
|
|
26
|
+
raw,
|
|
27
|
+
"user",
|
|
28
|
+
lambda v: DecodeUtils.to_maybe(
|
|
29
|
+
v,
|
|
30
|
+
lambda v: Unfolder.to_json(v).bind(
|
|
31
|
+
lambda user: JsonUnfolder.require(user, "bot", DecodeUtils.to_bool),
|
|
32
|
+
),
|
|
33
|
+
),
|
|
34
|
+
).map(lambda found: found.value_or(False))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def is_bot(client: GraphQlGitlabClient, user: User) -> Cmd[ResultE[bool]]:
|
|
38
|
+
values: dict[str, str] = {"username": user.value}
|
|
39
|
+
return client.get(_IS_BOT, FrozenTools.freeze(values)).map(
|
|
40
|
+
lambda r: r.alt(cast_exception).bind(decode_is_bot),
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _from_client(new_gql_client: Cmd[GraphQlGitlabClient]) -> UsersClient:
|
|
45
|
+
return UsersClient(lambda user: new_gql_client.bind(lambda c: is_bot(c, user)))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass(frozen=True)
|
|
49
|
+
class UsersClientFactory:
|
|
50
|
+
@staticmethod
|
|
51
|
+
def new(creds: Credentials) -> UsersClient:
|
|
52
|
+
return _from_client(GraphQlGitlabClient.new(creds.api_key))
|
|
@@ -6,7 +6,9 @@ from typing import TYPE_CHECKING
|
|
|
6
6
|
from fluidattacks_gitlab_sdk.ids import UserId
|
|
7
7
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
|
-
from
|
|
9
|
+
from collections.abc import Callable
|
|
10
|
+
|
|
11
|
+
from fa_purity import Cmd, Maybe, ResultE
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
@dataclass(frozen=True)
|
|
@@ -29,3 +31,10 @@ class UserObj:
|
|
|
29
31
|
user: User
|
|
30
32
|
name: UserName
|
|
31
33
|
public_email: Maybe[str]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass(frozen=True)
|
|
37
|
+
class UsersClient:
|
|
38
|
+
# Whether gitlab calls the account a bot. REST user objects do not carry
|
|
39
|
+
# the flag, and a service account is named like a person's account.
|
|
40
|
+
is_bot: Callable[[User], Cmd[ResultE[bool]]]
|
|
@@ -35,7 +35,7 @@ dev = [
|
|
|
35
35
|
|
|
36
36
|
[tool.uv]
|
|
37
37
|
exclude-newer = "7 days"
|
|
38
|
-
exclude-newer-package = { fluidattacks-core = "2099-01-02T00:00:00Z", fluid-blends = "2099-01-02T00:00:00Z" , fluidattacks-utils-logger = "2099-01-02T00:00:00Z" }
|
|
38
|
+
exclude-newer-package = { fluidattacks-core = "2099-01-02T00:00:00Z", fluid-blends = "2099-01-02T00:00:00Z" , fluidattacks-utils-logger = "2099-01-02T00:00:00Z", certifi = "2026-10-21T00:00:00Z" }
|
|
39
39
|
override-dependencies = [
|
|
40
40
|
"cryptography==50.0.0"
|
|
41
41
|
]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from fa_purity import Unsafe
|
|
2
|
+
from fa_purity.json import JsonValueFactory, Unfolder
|
|
3
|
+
|
|
4
|
+
from fluidattacks_gitlab_sdk.users._client import decode_is_bot
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def _decode(raw: dict[str, object]) -> bool:
|
|
8
|
+
return (
|
|
9
|
+
JsonValueFactory.from_any(raw)
|
|
10
|
+
.bind(Unfolder.to_json)
|
|
11
|
+
.bind(decode_is_bot)
|
|
12
|
+
.alt(Unsafe.raise_exception)
|
|
13
|
+
.to_union()
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_decode_bot() -> None:
|
|
18
|
+
assert _decode({"user": {"bot": True}})
|
|
19
|
+
assert not _decode({"user": {"bot": False}})
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_decode_unknown_user_is_a_person() -> None:
|
|
23
|
+
assert not _decode({"user": None})
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_decode_without_flag_fails() -> None:
|
|
27
|
+
outcome = (
|
|
28
|
+
JsonValueFactory.from_any({"user": dict[str, bool]()})
|
|
29
|
+
.bind(Unfolder.to_json)
|
|
30
|
+
.bind(decode_is_bot)
|
|
31
|
+
.to_union()
|
|
32
|
+
)
|
|
33
|
+
assert isinstance(outcome, Exception)
|
|
File without changes
|
|
@@ -7,9 +7,10 @@ exclude-newer = "0001-01-01T00:00:00Z" # This has no effect and is included for
|
|
|
7
7
|
exclude-newer-span = "P7D"
|
|
8
8
|
|
|
9
9
|
[options.exclude-newer-package]
|
|
10
|
-
fluid-blends = "2099-01-02T00:00:00Z"
|
|
11
10
|
fluidattacks-utils-logger = "2099-01-02T00:00:00Z"
|
|
11
|
+
certifi = "2026-10-21T00:00:00Z"
|
|
12
12
|
fluidattacks-core = "2099-01-02T00:00:00Z"
|
|
13
|
+
fluid-blends = "2099-01-02T00:00:00Z"
|
|
13
14
|
|
|
14
15
|
[manifest]
|
|
15
16
|
overrides = [{ name = "cryptography", specifier = "==50.0.0" }]
|
|
@@ -114,11 +115,11 @@ wheels = [
|
|
|
114
115
|
|
|
115
116
|
[[package]]
|
|
116
117
|
name = "certifi"
|
|
117
|
-
version = "2026.
|
|
118
|
+
version = "2026.10.19"
|
|
118
119
|
source = { registry = "https://pypi.org/simple" }
|
|
119
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
120
|
+
sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/1436c50cc46699de0230fbaacc1d1de7bfec413176099949e9d5112e88f2/certifi-2026.10.19.tar.gz", hash = "sha256:035c1e85572b141bf1c3a3eff0e33a8eb74917522f2559075ff8d2fea780a1ae", size = 137598, upload-time = "2026-10-20T02:24:16.604Z" }
|
|
120
121
|
wheels = [
|
|
121
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
122
|
+
{ url = "https://files.pythonhosted.org/packages/c4/51/29046e48f693c54e5b7412216d447a1d8362c9653148d98c02cdf65fa733/certifi-2026.10.19-py3-none-any.whl", hash = "sha256:42d35340cc5b9ba78e818ddbff0c5b1c2b779de448a340fd1b989f5fa8670e1b", size = 136464, upload-time = "2026-10-20T02:24:15.072Z" },
|
|
122
123
|
]
|
|
123
124
|
|
|
124
125
|
[[package]]
|
|
@@ -320,14 +321,14 @@ wheels = [
|
|
|
320
321
|
|
|
321
322
|
[[package]]
|
|
322
323
|
name = "gitpython"
|
|
323
|
-
version = "3.1
|
|
324
|
+
version = "3.2.1"
|
|
324
325
|
source = { registry = "https://pypi.org/simple" }
|
|
325
326
|
dependencies = [
|
|
326
327
|
{ name = "gitdb" },
|
|
327
328
|
]
|
|
328
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
329
|
+
sdist = { url = "https://files.pythonhosted.org/packages/c0/ff/fee293f1ec3e1b64db6eb270e00964f29c086d769201474cedb8d1608930/gitpython-3.2.1.tar.gz", hash = "sha256:0f1229ec5c057bdabdeeda8bda4f17bda679ab33dbccc00f24e6a480553c8613", size = 241688, upload-time = "2026-10-14T12:20:20.589Z" }
|
|
329
330
|
wheels = [
|
|
330
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
331
|
+
{ url = "https://files.pythonhosted.org/packages/6b/50/2a923c4dc02522ff9567f07c67ed1deca6d5fa9474f4708168b8088dfa37/gitpython-3.2.1-py3-none-any.whl", hash = "sha256:d66b0832aa8755c1a84892937282df0befb16c97e5a64aeebd68be9c5e323f53", size = 231548, upload-time = "2026-10-14T12:20:18.844Z" },
|
|
331
332
|
]
|
|
332
333
|
|
|
333
334
|
[[package]]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/_decoders.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/_handlers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/_logger.py
RENAMED
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/ids.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/jobs/core.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/fluidattacks_gitlab_sdk/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/issues/test_gql_fields.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/jobs/test_decode_job.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/members/test_decode_members.py
RENAMED
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/merge_request/__init__.py
RENAMED
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/merge_request/data.json
RENAMED
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/merge_request/test_decode.py
RENAMED
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/mr_approvals/__init__.py
RENAMED
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/mr_approvals/data.json
RENAMED
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/mr_approvals/decoder_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests/mr_notes/decoder_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0/tests_fx → fluidattacks_gitlab_sdk-8.1.0/tests/users}/__init__.py
RENAMED
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0/tests_fx/issues → fluidattacks_gitlab_sdk-8.1.0/tests_fx}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests_fx/issues/test_issue_client.py
RENAMED
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests_fx/jobs/client_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests_fx/milestones/client_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{fluidattacks_gitlab_sdk-8.0.0 → fluidattacks_gitlab_sdk-8.1.0}/tests_fx/mr_approvals/client_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|