fluidattacks_gitlab_sdk 7.0.0__tar.gz → 8.0.1__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.
Files changed (98) hide show
  1. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/PKG-INFO +1 -1
  2. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/__init__.py +1 -1
  3. fluidattacks_gitlab_sdk-8.0.1/fluidattacks_gitlab_sdk/issues/_client/_core.py +17 -0
  4. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/issues/_client/_decode.py +12 -11
  5. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/issues/_client/_get_issue.py +7 -8
  6. fluidattacks_gitlab_sdk-7.0.0/fluidattacks_gitlab_sdk/issues/_client/_updated_by.py → fluidattacks_gitlab_sdk-8.0.1/fluidattacks_gitlab_sdk/issues/_client/_gql_fields.py +35 -10
  7. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/issues/_client/_most_recent.py +9 -9
  8. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/issues/core.py +1 -0
  9. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/milestones/_client.py +1 -2
  10. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/pyproject.toml +1 -1
  11. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/arch/arch.py +3 -1
  12. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/issues/test_decode.py +12 -2
  13. fluidattacks_gitlab_sdk-8.0.1/tests/issues/test_gql_fields.py +70 -0
  14. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/uv.lock +39 -51
  15. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/.envrc +0 -0
  16. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/build/default.nix +0 -0
  17. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/build/filter.nix +0 -0
  18. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/flake.lock +0 -0
  19. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/flake.nix +0 -0
  20. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/_decoders.py +0 -0
  21. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/_gql_client/__init__.py +0 -0
  22. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/_gql_client/_client.py +0 -0
  23. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/_gql_client/_error.py +0 -0
  24. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/_gql_client/_handlers.py +0 -0
  25. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/_handlers.py +0 -0
  26. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/_http_client/__init__.py +0 -0
  27. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/_http_client/_client_1.py +0 -0
  28. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/_http_client/_core.py +0 -0
  29. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/_logger.py +0 -0
  30. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/ids.py +0 -0
  31. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/issues/__init__.py +0 -0
  32. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/issues/_client/__init__.py +0 -0
  33. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/jobs/__init__.py +0 -0
  34. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/jobs/_client.py +0 -0
  35. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/jobs/_decode.py +0 -0
  36. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/jobs/core.py +0 -0
  37. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/members/__init__.py +0 -0
  38. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/members/_client.py +0 -0
  39. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/members/_decode.py +0 -0
  40. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/members/core.py +0 -0
  41. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/merge_requests/__init__.py +0 -0
  42. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/merge_requests/_client.py +0 -0
  43. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/merge_requests/_decode.py +0 -0
  44. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/merge_requests/core.py +0 -0
  45. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/milestones/__init__.py +0 -0
  46. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/milestones/_decode.py +0 -0
  47. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/milestones/core.py +0 -0
  48. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/mr_approvals/__init__.py +0 -0
  49. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/mr_approvals/_client.py +0 -0
  50. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/mr_approvals/_decode.py +0 -0
  51. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/mr_approvals/core.py +0 -0
  52. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/mr_notes/__init__.py +0 -0
  53. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/mr_notes/_client.py +0 -0
  54. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/mr_notes/_core.py +0 -0
  55. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/mr_notes/_decode.py +0 -0
  56. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/py.typed +0 -0
  57. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/users/__init__.py +0 -0
  58. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/users/core.py +0 -0
  59. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/fluidattacks_gitlab_sdk/users/decode.py +0 -0
  60. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/mypy.ini +0 -0
  61. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/ruff.toml +0 -0
  62. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/__init__.py +0 -0
  63. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/arch/__init__.py +0 -0
  64. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/arch/test_arch.py +0 -0
  65. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/issues/__init__.py +0 -0
  66. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/issues/data.json +0 -0
  67. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/jobs/__init__.py +0 -0
  68. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/jobs/data.json +0 -0
  69. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/jobs/test_decode_job.py +0 -0
  70. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/members/__init__.py +0 -0
  71. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/members/data.json +0 -0
  72. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/members/test_decode_members.py +0 -0
  73. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/merge_request/__init__.py +0 -0
  74. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/merge_request/data.json +0 -0
  75. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/merge_request/data_mr_updates.json +0 -0
  76. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/merge_request/test_decode.py +0 -0
  77. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/mr_approvals/__init__.py +0 -0
  78. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/mr_approvals/data.json +0 -0
  79. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/mr_approvals/decoder_test.py +0 -0
  80. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/mr_notes/__init__.py +0 -0
  81. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/mr_notes/data.json +0 -0
  82. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/mr_notes/decoder_test.py +0 -0
  83. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests/py.typed +0 -0
  84. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests_fx/__init__.py +0 -0
  85. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests_fx/_utils.py +0 -0
  86. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests_fx/issues/__init__.py +0 -0
  87. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests_fx/issues/test_issue_client.py +0 -0
  88. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests_fx/jobs/__init__.py +0 -0
  89. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests_fx/jobs/client_test.py +0 -0
  90. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests_fx/members/__init__.py +0 -0
  91. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests_fx/members/test_client_members.py +0 -0
  92. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests_fx/milestones/__init__.py +0 -0
  93. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests_fx/milestones/client_test.py +0 -0
  94. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests_fx/mr_approvals/__init__.py +0 -0
  95. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests_fx/mr_approvals/client_test.py +0 -0
  96. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests_fx/py.typed +0 -0
  97. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests_fx/test_gql_client.py +0 -0
  98. {fluidattacks_gitlab_sdk-7.0.0 → fluidattacks_gitlab_sdk-8.0.1}/tests_fx/test_mr.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fluidattacks_gitlab_sdk
3
- Version: 7.0.0
3
+ Version: 8.0.1
4
4
  Summary: gitlab SDK
5
5
  Author-email: Product Team <development@fluidattacks.com>
6
6
  Requires-Python: >=3.13.14, <3.14
@@ -11,7 +11,7 @@ from ._logger import (
11
11
  set_logger,
12
12
  )
13
13
 
14
- __version__ = "7.0.0"
14
+ __version__ = "8.0.1"
15
15
 
16
16
  Unsafe.compute(set_logger(__name__, __version__))
17
17
  LOG = logging.getLogger(__name__)
@@ -0,0 +1,17 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import TYPE_CHECKING
5
+
6
+ if TYPE_CHECKING:
7
+ from fa_purity import Maybe
8
+
9
+ from fluidattacks_gitlab_sdk.users.core import UserObj
10
+
11
+
12
+ @dataclass(frozen=True)
13
+ class IssueGqlFields:
14
+ """Issue fields that only the GraphQL API exposes."""
15
+
16
+ updated_by: Maybe[UserObj]
17
+ status: Maybe[str]
@@ -1,6 +1,6 @@
1
1
  import inspect
2
2
 
3
- from fa_purity import Maybe, ResultE
3
+ from fa_purity import ResultE
4
4
  from fa_purity.json import JsonObj, JsonPrimitiveUnfolder, JsonUnfolder, JsonValue, Unfolder
5
5
  from fluidattacks_etl_utils import smash
6
6
  from fluidattacks_etl_utils.bug import Bug
@@ -25,9 +25,10 @@ from fluidattacks_gitlab_sdk.issues.core import (
25
25
  IssueReferences,
26
26
  IssueType,
27
27
  )
28
- from fluidattacks_gitlab_sdk.users.core import UserObj
29
28
  from fluidattacks_gitlab_sdk.users.decode import decode_user_obj
30
29
 
30
+ from ._core import IssueGqlFields
31
+
31
32
 
32
33
  def decode_type(raw: JsonValue) -> ResultE[IssueType]:
33
34
  return Unfolder.to_primitive(raw).bind(
@@ -67,7 +68,7 @@ def _decode_properties(raw: JsonObj) -> ResultE[IssueOtherProperties]:
67
68
  ).map(lambda t: IssueOtherProperties(*t))
68
69
 
69
70
 
70
- def _decode_refs(updated_by: Maybe[UserObj], raw: JsonObj) -> ResultE[IssueReferences]:
71
+ def _decode_refs(gql_fields: IssueGqlFields, raw: JsonObj) -> ResultE[IssueReferences]:
71
72
  return smash.smash_result_5(
72
73
  JsonUnfolder.require(raw, "author", lambda v: Unfolder.to_json(v).bind(decode_user_obj)),
73
74
  JsonUnfolder.require(
@@ -96,10 +97,10 @@ def _decode_refs(updated_by: Maybe[UserObj], raw: JsonObj) -> ResultE[IssueRefer
96
97
  "assignees",
97
98
  lambda v: Unfolder.to_list_of(v, lambda v: Unfolder.to_json(v).bind(decode_user_obj)),
98
99
  ),
99
- ).map(lambda t: IssueReferences(*t, updated_by))
100
+ ).map(lambda t: IssueReferences(*t, gql_fields.updated_by))
100
101
 
101
102
 
102
- def _decode_def(raw: JsonObj) -> ResultE[IssueDef]:
103
+ def _decode_def(gql_fields: IssueGqlFields, raw: JsonObj) -> ResultE[IssueDef]:
103
104
  return smash.smash_result_4(
104
105
  JsonUnfolder.require(raw, "title", DecodeUtils.to_str),
105
106
  JsonUnfolder.require(raw, "state", DecodeUtils.to_str),
@@ -109,7 +110,7 @@ def _decode_def(raw: JsonObj) -> ResultE[IssueDef]:
109
110
  "description",
110
111
  lambda v: DecodeUtils.to_maybe(v, DecodeUtils.to_str),
111
112
  ),
112
- ).map(lambda t: IssueDef(*t))
113
+ ).map(lambda t: IssueDef(*t, gql_fields.status))
113
114
 
114
115
 
115
116
  def _decode_dates(raw: JsonObj) -> ResultE[IssueDates]:
@@ -133,11 +134,11 @@ def _decode_dates(raw: JsonObj) -> ResultE[IssueDates]:
133
134
  ).map(lambda t: IssueDates(*t))
134
135
 
135
136
 
136
- def decode_issue(updated_by: Maybe[UserObj], raw: JsonObj) -> ResultE[Issue]:
137
+ def decode_issue(gql_fields: IssueGqlFields, raw: JsonObj) -> ResultE[Issue]:
137
138
  return (
138
139
  smash.smash_result_5(
139
- _decode_def(raw),
140
- _decode_refs(updated_by, raw),
140
+ _decode_def(gql_fields, raw),
141
+ _decode_refs(gql_fields, raw),
141
142
  _decode_properties(raw),
142
143
  _decode_dates(raw),
143
144
  _decode_stats(raw),
@@ -155,11 +156,11 @@ def decode_issue(updated_by: Maybe[UserObj], raw: JsonObj) -> ResultE[Issue]:
155
156
 
156
157
 
157
158
  def decode_issue_and_id(
158
- updated_by: Maybe[UserObj],
159
+ gql_fields: IssueGqlFields,
159
160
  raw: JsonObj,
160
161
  ) -> ResultE[tuple[IssueFullId, Issue]]:
161
162
  _id = decode_issue_full_id(raw)
162
163
  return smash.smash_result_2(
163
164
  _id,
164
- decode_issue(updated_by, raw),
165
+ decode_issue(gql_fields, raw),
165
166
  )
@@ -6,7 +6,6 @@ from fa_purity import (
6
6
  CmdTransform,
7
7
  Coproduct,
8
8
  FrozenDict,
9
- Maybe,
10
9
  Result,
11
10
  cast_exception,
12
11
  )
@@ -19,10 +18,10 @@ from fluidattacks_gitlab_sdk._gql_client import GraphQlGitlabClient
19
18
  from fluidattacks_gitlab_sdk._handlers import NotFound, handle_not_found
20
19
  from fluidattacks_gitlab_sdk._http_client import HttpJsonClient, RelativeEndpoint
21
20
  from fluidattacks_gitlab_sdk.ids import IssueFullId, IssueInternalId, ProjectId
22
- from fluidattacks_gitlab_sdk.issues._client._updated_by import get_updated_by
21
+ from fluidattacks_gitlab_sdk.issues._client._gql_fields import get_gql_fields
23
22
  from fluidattacks_gitlab_sdk.issues.core import Issue, ProjectIdObj
24
- from fluidattacks_gitlab_sdk.users.core import UserObj
25
23
 
24
+ from ._core import IssueGqlFields
26
25
  from ._decode import decode_issue_and_id
27
26
 
28
27
  LOG = logging.getLogger(__name__)
@@ -31,7 +30,7 @@ LOG = logging.getLogger(__name__)
31
30
  def _get_issue(
32
31
  client: HttpJsonClient,
33
32
  project: ProjectId,
34
- updated_by: Maybe[UserObj],
33
+ gql_fields: IssueGqlFields,
35
34
  issue_id: IssueInternalId,
36
35
  ) -> Cmd[Result[tuple[IssueFullId, Issue], Coproduct[NotFound, Exception]]]:
37
36
  endpoint = RelativeEndpoint.new(
@@ -56,7 +55,7 @@ def _get_issue(
56
55
  )
57
56
  .bind(lambda i: assert_single(i).alt(Coproduct[NotFound, Exception].inr))
58
57
  .bind(
59
- lambda i: decode_issue_and_id(updated_by, i).alt(
58
+ lambda i: decode_issue_and_id(gql_fields, i).alt(
60
59
  Coproduct[NotFound, Exception].inr,
61
60
  ),
62
61
  )
@@ -83,8 +82,8 @@ def get_issue(
83
82
  project: ProjectIdObj,
84
83
  issue_id: IssueInternalId,
85
84
  ) -> Cmd[Result[tuple[IssueFullId, Issue], Coproduct[NotFound, Exception]]]:
86
- updated_by = get_updated_by(gql_client, project.project_path, issue_id)
85
+ gql_fields = get_gql_fields(gql_client, project.project_path, issue_id)
87
86
  return CmdTransform.chain_cmd_result(
88
- updated_by,
89
- lambda u: _get_issue(client, project.project_id, u, issue_id),
87
+ gql_fields,
88
+ lambda g: _get_issue(client, project.project_id, g, issue_id),
90
89
  ).map(lambda r: r.alt(merge_coproduct))
@@ -15,13 +15,15 @@ from fa_purity.json import JsonObj, JsonUnfolder, JsonValue, Unfolder
15
15
  from fluidattacks_etl_utils.bug import Bug
16
16
  from fluidattacks_etl_utils.decode import DecodeUtils, int_to_str, str_to_int
17
17
  from fluidattacks_etl_utils.natural import Natural
18
- from fluidattacks_etl_utils.smash import right_map
18
+ from fluidattacks_etl_utils.smash import right_map, smash_result_2
19
19
 
20
20
  from fluidattacks_gitlab_sdk._gql_client import GraphQlGitlabClient
21
21
  from fluidattacks_gitlab_sdk._handlers import NotFound
22
22
  from fluidattacks_gitlab_sdk.ids import IssueInternalId, ProjectPath, UserId
23
23
  from fluidattacks_gitlab_sdk.users.core import User, UserName, UserObj
24
24
 
25
+ from ._core import IssueGqlFields
26
+
25
27
  LOG = logging.getLogger(__name__)
26
28
 
27
29
 
@@ -82,6 +84,26 @@ def decode_updated_by(raw: JsonObj) -> ResultE[Maybe[UserObj]]:
82
84
  )
83
85
 
84
86
 
87
+ def decode_status(raw: JsonObj) -> ResultE[Maybe[str]]:
88
+ return JsonUnfolder.require(
89
+ raw,
90
+ "status",
91
+ lambda v: DecodeUtils.to_maybe(
92
+ v,
93
+ lambda v: Unfolder.to_json(v).bind(
94
+ lambda status: JsonUnfolder.require(status, "name", DecodeUtils.to_str),
95
+ ),
96
+ ),
97
+ )
98
+
99
+
100
+ def _decode_gql_fields(raw: JsonObj) -> ResultE[IssueGqlFields]:
101
+ return smash_result_2(
102
+ decode_updated_by(raw),
103
+ decode_status(raw),
104
+ ).map(lambda t: IssueGqlFields(*t))
105
+
106
+
85
107
  def _set_not_found_if_empty[T](
86
108
  value: JsonValue,
87
109
  transform: Callable[[JsonValue], ResultE[T]],
@@ -100,14 +122,14 @@ def _set_not_found_if_empty[T](
100
122
  )
101
123
 
102
124
 
103
- def _decode(raw: JsonObj) -> Result[Maybe[UserObj], Coproduct[NotFound, Exception]]:
125
+ def decode_gql_response(raw: JsonObj) -> Result[IssueGqlFields, Coproduct[NotFound, Exception]]:
104
126
  return (
105
127
  _nested_key(raw, "project", ("issue",))
106
128
  .alt(Coproduct[NotFound, Exception].inr)
107
129
  .bind(
108
130
  lambda v: _set_not_found_if_empty(
109
131
  v,
110
- lambda v: Unfolder.to_json(v).bind(decode_updated_by),
132
+ lambda v: Unfolder.to_json(v).bind(_decode_gql_fields),
111
133
  ),
112
134
  )
113
135
  .alt(
@@ -115,7 +137,7 @@ def _decode(raw: JsonObj) -> Result[Maybe[UserObj], Coproduct[NotFound, Exceptio
115
137
  Coproduct[NotFound, Exception].inl,
116
138
  lambda e: Coproduct[NotFound, Exception].inr(
117
139
  Bug[Exception].new(
118
- "decode_updated_by",
140
+ "decode_gql_fields",
119
141
  inspect.currentframe(),
120
142
  e,
121
143
  (JsonUnfolder.dumps(raw),),
@@ -126,20 +148,20 @@ def _decode(raw: JsonObj) -> Result[Maybe[UserObj], Coproduct[NotFound, Exceptio
126
148
  )
127
149
 
128
150
 
129
- def get_updated_by(
151
+ def get_gql_fields(
130
152
  client: GraphQlGitlabClient,
131
153
  project: ProjectPath,
132
154
  issue_id: IssueInternalId,
133
- ) -> Cmd[Result[Maybe[UserObj], Coproduct[NotFound, Exception]]]:
155
+ ) -> Cmd[Result[IssueGqlFields, Coproduct[NotFound, Exception]]]:
134
156
  """
135
- Get the updatedBy field of an issue.
157
+ Get the updatedBy and status fields of an issue.
136
158
 
137
159
  To avoid failure ensure:
138
160
  - The issue exist
139
161
  - The credentials are correct
140
162
  """
141
163
  query = """
142
- query getIssueUpdatedBy($project: ID!, $issue_iid: String!){
164
+ query getIssueGqlFields($project: ID!, $issue_iid: String!){
143
165
  project(fullPath: $project) {
144
166
  issue(iid: $issue_iid) {
145
167
  updatedBy {
@@ -148,6 +170,9 @@ def get_updated_by(
148
170
  username
149
171
  publicEmail
150
172
  }
173
+ status {
174
+ name
175
+ }
151
176
  }
152
177
  }
153
178
  }
@@ -159,12 +184,12 @@ def get_updated_by(
159
184
  return client.get(query, FrozenTools.freeze(values)).map(
160
185
  lambda r: (
161
186
  r.alt(Coproduct[NotFound, Exception].inr)
162
- .bind(_decode)
187
+ .bind(decode_gql_response)
163
188
  .alt(
164
189
  lambda c: right_map(
165
190
  c,
166
191
  lambda e: Bug[Exception].new(
167
- "get_updated_by",
192
+ "get_gql_fields",
168
193
  inspect.currentframe(),
169
194
  e,
170
195
  (str(project), str(issue_id)),
@@ -27,10 +27,10 @@ from fluidattacks_gitlab_sdk._http_client import (
27
27
  UnhandledErrors,
28
28
  )
29
29
  from fluidattacks_gitlab_sdk.ids import IssueFullId, ProjectPath
30
- from fluidattacks_gitlab_sdk.issues._client._updated_by import get_updated_by
30
+ from fluidattacks_gitlab_sdk.issues._client._gql_fields import get_gql_fields
31
31
  from fluidattacks_gitlab_sdk.issues.core import Issue, ProjectIdObj
32
- from fluidattacks_gitlab_sdk.users.core import UserObj
33
32
 
33
+ from ._core import IssueGqlFields
34
34
  from ._decode import decode_issue_and_id
35
35
 
36
36
  LOG = logging.getLogger(__name__)
@@ -42,18 +42,18 @@ def _most_recent_issue(
42
42
  project: ProjectPath,
43
43
  ) -> Cmd[ResultE[tuple[IssueFullId, Issue]]]:
44
44
  """
45
- Completes the raw issue obj by getting the updated by field.
45
+ Completes the raw issue obj by getting its GraphQL-only fields.
46
46
 
47
47
  This function should be called always after getting the raw issue.
48
48
  It can fail when:
49
49
  - decode fails
50
50
  - raw issue id not exist and/or is fake
51
51
  """
52
- _updated_by: Cmd[ResultE[Maybe[UserObj]]] = (
52
+ _gql_fields: Cmd[ResultE[IssueGqlFields]] = (
53
53
  decode_issue_internal_id(raw)
54
54
  .to_coproduct()
55
55
  .map(
56
- lambda i: get_updated_by(gql_client, project, i.internal_id).map(
56
+ lambda i: get_gql_fields(gql_client, project, i.internal_id).map(
57
57
  lambda r: r.alt(
58
58
  lambda c: c.map(
59
59
  lambda e: Bug[NotFound].new(
@@ -66,14 +66,14 @@ def _most_recent_issue(
66
66
  ),
67
67
  ),
68
68
  ),
69
- lambda e: Cmd[ResultE[Maybe[UserObj]]].wrap_value(
70
- ResultE[Maybe[UserObj]].failure(e),
69
+ lambda e: Cmd[ResultE[IssueGqlFields]].wrap_value(
70
+ ResultE[IssueGqlFields].failure(e),
71
71
  ),
72
72
  )
73
73
  )
74
- return _updated_by.map(
74
+ return _gql_fields.map(
75
75
  lambda r: r.bind(
76
- lambda u: decode_issue_and_id(u, raw),
76
+ lambda g: decode_issue_and_id(g, raw),
77
77
  ),
78
78
  )
79
79
 
@@ -73,6 +73,7 @@ class IssueDef:
73
73
  state: str
74
74
  issue_type: IssueType
75
75
  description: Maybe[str]
76
+ status: Maybe[str]
76
77
 
77
78
 
78
79
  @dataclass(frozen=True)
@@ -113,8 +113,7 @@ def most_recent_milestone(
113
113
  "milestones",
114
114
  )
115
115
  params: dict[str, Primitive] = {
116
- "order_by": "created_at",
117
- "sort": "desc",
116
+ "sort": "created_desc",
118
117
  "per_page": 1,
119
118
  }
120
119
  empty: Maybe[tuple[MilestoneFullId, Milestone]] = Maybe[
@@ -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
  ]
@@ -50,8 +50,10 @@ _dag: dict[str, tuple[tuple[str, ...] | str, ...]] = {
50
50
  "core",
51
51
  ),
52
52
  "fluidattacks_gitlab_sdk.issues._client": (
53
- ("_get_issue", "_most_recent", "_updated_by"),
53
+ ("_get_issue", "_most_recent"),
54
+ "_gql_fields",
54
55
  "_decode",
56
+ "_core",
55
57
  ),
56
58
  "fluidattacks_gitlab_sdk.members": (
57
59
  "_client",
@@ -20,6 +20,7 @@ from fluidattacks_gitlab_sdk.ids import (
20
20
  ProjectId,
21
21
  UserId,
22
22
  )
23
+ from fluidattacks_gitlab_sdk.issues._client._core import IssueGqlFields
23
24
  from fluidattacks_gitlab_sdk.issues._client._decode import decode_issue_and_id
24
25
  from fluidattacks_gitlab_sdk.issues.core import (
25
26
  Issue,
@@ -47,7 +48,13 @@ def test_decode() -> None:
47
48
  Maybe[str].some(""),
48
49
  )
49
50
  closed_by = assignee
50
- issue_def = IssueDef("The title", "closed", IssueType.ISSUE, Maybe[str].some(""))
51
+ issue_def = IssueDef(
52
+ "The title",
53
+ "closed",
54
+ IssueType.ISSUE,
55
+ Maybe[str].some(""),
56
+ Maybe[str].some("Won't do"),
57
+ )
51
58
  milestone_id = MilestoneFullId(
52
59
  MilestoneGlobalId(NaturalOperations.absolute(5)),
53
60
  MilestoneFullInternalId(
@@ -108,7 +115,10 @@ def test_decode() -> None:
108
115
  .to_union()
109
116
  )
110
117
  decoded_issue_obj = (
111
- decode_issue_and_id(Maybe[UserObj].some(author), raw_data)
118
+ decode_issue_and_id(
119
+ IssueGqlFields(Maybe[UserObj].some(author), Maybe[str].some("Won't do")),
120
+ raw_data,
121
+ )
112
122
  .alt(Unsafe.raise_exception)
113
123
  .to_union()
114
124
  )
@@ -0,0 +1,70 @@
1
+ from fa_purity import Maybe, ResultE, Unsafe, cast_exception
2
+ from fa_purity.json import JsonObj, UnfoldedFactory
3
+ from fluidattacks_etl_utils.natural import NaturalOperations
4
+
5
+ from fluidattacks_gitlab_sdk.ids import UserId
6
+ from fluidattacks_gitlab_sdk.issues._client._core import IssueGqlFields
7
+ from fluidattacks_gitlab_sdk.issues._client._gql_fields import (
8
+ decode_gql_response,
9
+ decode_status,
10
+ )
11
+ from fluidattacks_gitlab_sdk.users.core import User, UserName, UserObj
12
+
13
+
14
+ def _json(raw: str) -> JsonObj:
15
+ return UnfoldedFactory.loads(raw).alt(Unsafe.raise_exception).to_union()
16
+
17
+
18
+ def _is_failure[T](result: ResultE[T]) -> bool:
19
+ return result.map(lambda _: False).value_or(True)
20
+
21
+
22
+ def test_status_with_name() -> None:
23
+ result = decode_status(_json('{"status": {"name": "Won\'t do"}}'))
24
+ assert result.alt(Unsafe.raise_exception).to_union() == Maybe[str].some("Won't do")
25
+
26
+
27
+ def test_null_status() -> None:
28
+ result = decode_status(_json('{"status": null}'))
29
+ assert result.alt(Unsafe.raise_exception).to_union() == Maybe[str].empty()
30
+
31
+
32
+ def test_missing_status_key_fails() -> None:
33
+ assert _is_failure(decode_status(_json("{}")))
34
+
35
+
36
+ def test_status_without_name_fails() -> None:
37
+ assert _is_failure(decode_status(_json('{"status": {}}')))
38
+
39
+
40
+ def test_non_string_name_fails() -> None:
41
+ assert _is_failure(decode_status(_json('{"status": {"name": 7}}')))
42
+
43
+
44
+ def test_decode_gql_response() -> None:
45
+ raw = _json(
46
+ """
47
+ {
48
+ "project": {
49
+ "issue": {
50
+ "updatedBy": {
51
+ "id": "gid://gitlab/User/1",
52
+ "name": "Ghost User",
53
+ "username": "ghost1",
54
+ "publicEmail": null
55
+ },
56
+ "status": {"name": "Duplicate"}
57
+ }
58
+ }
59
+ }
60
+ """,
61
+ )
62
+ author = UserObj(
63
+ UserId(NaturalOperations.absolute(1)),
64
+ User("ghost1"),
65
+ UserName("Ghost User"),
66
+ Maybe[str].empty(),
67
+ )
68
+ expected = IssueGqlFields(Maybe[UserObj].some(author), Maybe[str].some("Duplicate"))
69
+ result = decode_gql_response(raw).alt(lambda c: c.map(cast_exception, cast_exception))
70
+ assert result.alt(Unsafe.raise_exception).to_union() == expected
@@ -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.6.17"
118
+ version = "2026.10.19"
118
119
  source = { registry = "https://pypi.org/simple" }
119
- sdist = { url = "https://files.pythonhosted.org/packages/c9/c7/424b75da314c1045981bd9777432fad05a9e0c69daa4ed7e308bbaffe405/certifi-2026.6.17.tar.gz", hash = "sha256:024c88eeec92ca068db80f02b8b07c9cef7b9fe261d1d535abfd5abd6f6af432", size = 134594, upload-time = "2026-06-17T10:31:07.894Z" }
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/ef/2f/c5464532e965badff2f4c4c1a3a83f5697f0d7c407ed0cda44aaa99bb451/certifi-2026.6.17-py3-none-any.whl", hash = "sha256:2227dcbaafe0d2f59279d1762ddddc37783ed4354594f194ffc31d20f41fc3db", size = 133289, upload-time = "2026-06-17T10:31:06.348Z" },
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.59"
324
+ version = "3.1.62"
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/ca/dc/126b28e76b24a9268ba931ad3e012f71ebdadf62fd9f17758f7074bb0b20/gitpython-3.1.59.tar.gz", hash = "sha256:0a1475cfdc38a5bfba1a3e9a4a9da52a39749ecec322b772915c019f94e5b7e4", size = 230445, upload-time = "2026-08-10T12:03:20.271Z" }
329
+ sdist = { url = "https://files.pythonhosted.org/packages/e0/db/3ca813cbacb23ab6fe46ff38a9b5ef8e73e970c8051f2ce903aacafe0446/gitpython-3.1.62.tar.gz", hash = "sha256:1791de66309bc0c7cfca40bf8d2e3de7ca091cbf94e6051be1ad0722c61062af", size = 231728, upload-time = "2026-09-07T02:57:21.155Z" }
329
330
  wheels = [
330
- { url = "https://files.pythonhosted.org/packages/ef/ed/ae57eb7d344f43f87b74b3a281ead6ec7d6394eef72a7b1dcb28dd089550/gitpython-3.1.59-py3-none-any.whl", hash = "sha256:67a82f537384578643624c8b2c531938a9b82be431663e575dcf638526631d4c", size = 220996, upload-time = "2026-08-10T12:03:18.804Z" },
331
+ { url = "https://files.pythonhosted.org/packages/d6/0b/29d7965215f8ef830a7ca1f42997fe13e5693d85e9edb18f938d063ef5f2/gitpython-3.1.62-py3-none-any.whl", hash = "sha256:7002251225e10e29d2e1f49e6532613fe5d5d9f0b6f1f02997a52b38fe56899e", size = 222753, upload-time = "2026-09-07T02:57:19.762Z" },
331
332
  ]
332
333
 
333
334
  [[package]]
@@ -426,47 +427,34 @@ wheels = [
426
427
 
427
428
  [[package]]
428
429
  name = "multidict"
429
- version = "6.7.1"
430
- source = { registry = "https://pypi.org/simple" }
431
- sdist = { url = "https://files.pythonhosted.org/packages/1a/c2/c2d94cbe6ac1753f3fc980da97b3d930efe1da3af3c9f5125354436c073d/multidict-6.7.1.tar.gz", hash = "sha256:ec6652a1bee61c53a3e5776b6049172c53b6aaba34f18c9ad04f82712bac623d", size = 102010, upload-time = "2026-01-26T02:46:45.979Z" }
432
- wheels = [
433
- { url = "https://files.pythonhosted.org/packages/f2/22/929c141d6c0dba87d3e1d38fbdf1ba8baba86b7776469f2bc2d3227a1e67/multidict-6.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2b41f5fed0ed563624f1c17630cb9941cf2309d4df00e494b551b5f3e3d67a23", size = 76174, upload-time = "2026-01-26T02:44:18.509Z" },
434
- { url = "https://files.pythonhosted.org/packages/c7/75/bc704ae15fee974f8fccd871305e254754167dce5f9e42d88a2def741a1d/multidict-6.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84e61e3af5463c19b67ced91f6c634effb89ef8bfc5ca0267f954451ed4bb6a2", size = 45116, upload-time = "2026-01-26T02:44:19.745Z" },
435
- { url = "https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:935434b9853c7c112eee7ac891bc4cb86455aa631269ae35442cb316790c1445", size = 43524, upload-time = "2026-01-26T02:44:21.571Z" },
436
- { url = "https://files.pythonhosted.org/packages/e9/3c/414842ef8d5a1628d68edee29ba0e5bcf235dbfb3ccd3ea303a7fe8c72ff/multidict-6.7.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:432feb25a1cb67fe82a9680b4d65fb542e4635cb3166cd9c01560651ad60f177", size = 249368, upload-time = "2026-01-26T02:44:22.803Z" },
437
- { url = "https://files.pythonhosted.org/packages/f6/32/befed7f74c458b4a525e60519fe8d87eef72bb1e99924fa2b0f9d97a221e/multidict-6.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e82d14e3c948952a1a85503817e038cba5905a3352de76b9a465075d072fba23", size = 256952, upload-time = "2026-01-26T02:44:24.306Z" },
438
- { url = "https://files.pythonhosted.org/packages/03/d6/c878a44ba877f366630c860fdf74bfb203c33778f12b6ac274936853c451/multidict-6.7.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4cfb48c6ea66c83bcaaf7e4dfa7ec1b6bbcf751b7db85a328902796dfde4c060", size = 240317, upload-time = "2026-01-26T02:44:25.772Z" },
439
- { url = "https://files.pythonhosted.org/packages/68/49/57421b4d7ad2e9e60e25922b08ceb37e077b90444bde6ead629095327a6f/multidict-6.7.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1d540e51b7e8e170174555edecddbd5538105443754539193e3e1061864d444d", size = 267132, upload-time = "2026-01-26T02:44:27.648Z" },
440
- { url = "https://files.pythonhosted.org/packages/b7/fe/ec0edd52ddbcea2a2e89e174f0206444a61440b40f39704e64dc807a70bd/multidict-6.7.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:273d23f4b40f3dce4d6c8a821c741a86dec62cded82e1175ba3d99be128147ed", size = 268140, upload-time = "2026-01-26T02:44:29.588Z" },
441
- { url = "https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d624335fd4fa1c08a53f8b4be7676ebde19cd092b3895c421045ca87895b429", size = 254277, upload-time = "2026-01-26T02:44:30.902Z" },
442
- { url = "https://files.pythonhosted.org/packages/6a/b2/5fb8c124d7561a4974c342bc8c778b471ebbeb3cc17df696f034a7e9afe7/multidict-6.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:12fad252f8b267cc75b66e8fc51b3079604e8d43a75428ffe193cd9e2195dfd6", size = 252291, upload-time = "2026-01-26T02:44:32.31Z" },
443
- { url = "https://files.pythonhosted.org/packages/5a/96/51d4e4e06bcce92577fcd488e22600bd38e4fd59c20cb49434d054903bd2/multidict-6.7.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:03ede2a6ffbe8ef936b92cb4529f27f42be7f56afcdab5ab739cd5f27fb1cbf9", size = 250156, upload-time = "2026-01-26T02:44:33.734Z" },
444
- { url = "https://files.pythonhosted.org/packages/db/6b/420e173eec5fba721a50e2a9f89eda89d9c98fded1124f8d5c675f7a0c0f/multidict-6.7.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:90efbcf47dbe33dcf643a1e400d67d59abeac5db07dc3f27d6bdeae497a2198c", size = 249742, upload-time = "2026-01-26T02:44:35.222Z" },
445
- { url = "https://files.pythonhosted.org/packages/44/a3/ec5b5bd98f306bc2aa297b8c6f11a46714a56b1e6ef5ebda50a4f5d7c5fb/multidict-6.7.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5c4b9bfc148f5a91be9244d6264c53035c8a0dcd2f51f1c3c6e30e30ebaa1c84", size = 262221, upload-time = "2026-01-26T02:44:36.604Z" },
446
- { url = "https://files.pythonhosted.org/packages/cd/f7/e8c0d0da0cd1e28d10e624604e1a36bcc3353aaebdfdc3a43c72bc683a12/multidict-6.7.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:401c5a650f3add2472d1d288c26deebc540f99e2fb83e9525007a74cd2116f1d", size = 258664, upload-time = "2026-01-26T02:44:38.008Z" },
447
- { url = "https://files.pythonhosted.org/packages/52/da/151a44e8016dd33feed44f730bd856a66257c1ee7aed4f44b649fb7edeb3/multidict-6.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:97891f3b1b3ffbded884e2916cacf3c6fc87b66bb0dde46f7357404750559f33", size = 249490, upload-time = "2026-01-26T02:44:39.386Z" },
448
- { url = "https://files.pythonhosted.org/packages/87/af/a3b86bf9630b732897f6fc3f4c4714b90aa4361983ccbdcd6c0339b21b0c/multidict-6.7.1-cp313-cp313-win32.whl", hash = "sha256:e1c5988359516095535c4301af38d8a8838534158f649c05dd1050222321bcb3", size = 41695, upload-time = "2026-01-26T02:44:41.318Z" },
449
- { url = "https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:960c83bf01a95b12b08fd54324a4eb1d5b52c88932b5cba5d6e712bb3ed12eb5", size = 45884, upload-time = "2026-01-26T02:44:42.488Z" },
450
- { url = "https://files.pythonhosted.org/packages/ca/61/42d3e5dbf661242a69c97ea363f2d7b46c567da8eadef8890022be6e2ab0/multidict-6.7.1-cp313-cp313-win_arm64.whl", hash = "sha256:563fe25c678aaba333d5399408f5ec3c383ca5b663e7f774dd179a520b8144df", size = 43122, upload-time = "2026-01-26T02:44:43.664Z" },
451
- { url = "https://files.pythonhosted.org/packages/6d/b3/e6b21c6c4f314bb956016b0b3ef2162590a529b84cb831c257519e7fde44/multidict-6.7.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:c76c4bec1538375dad9d452d246ca5368ad6e1c9039dadcf007ae59c70619ea1", size = 83175, upload-time = "2026-01-26T02:44:44.894Z" },
452
- { url = "https://files.pythonhosted.org/packages/fb/76/23ecd2abfe0957b234f6c960f4ade497f55f2c16aeb684d4ecdbf1c95791/multidict-6.7.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:57b46b24b5d5ebcc978da4ec23a819a9402b4228b8a90d9c656422b4bdd8a963", size = 48460, upload-time = "2026-01-26T02:44:46.106Z" },
453
- { url = "https://files.pythonhosted.org/packages/c4/57/a0ed92b23f3a042c36bc4227b72b97eca803f5f1801c1ab77c8a212d455e/multidict-6.7.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e954b24433c768ce78ab7929e84ccf3422e46deb45a4dc9f93438f8217fa2d34", size = 46930, upload-time = "2026-01-26T02:44:47.278Z" },
454
- { url = "https://files.pythonhosted.org/packages/b5/66/02ec7ace29162e447f6382c495dc95826bf931d3818799bbef11e8f7df1a/multidict-6.7.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3bd231490fa7217cc832528e1cd8752a96f0125ddd2b5749390f7c3ec8721b65", size = 242582, upload-time = "2026-01-26T02:44:48.604Z" },
455
- { url = "https://files.pythonhosted.org/packages/58/18/64f5a795e7677670e872673aca234162514696274597b3708b2c0d276cce/multidict-6.7.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:253282d70d67885a15c8a7716f3a73edf2d635793ceda8173b9ecc21f2fb8292", size = 250031, upload-time = "2026-01-26T02:44:50.544Z" },
456
- { url = "https://files.pythonhosted.org/packages/c8/ed/e192291dbbe51a8290c5686f482084d31bcd9d09af24f63358c3d42fd284/multidict-6.7.1-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0b4c48648d7649c9335cf1927a8b87fa692de3dcb15faa676c6a6f1f1aabda43", size = 228596, upload-time = "2026-01-26T02:44:51.951Z" },
457
- { url = "https://files.pythonhosted.org/packages/1e/7e/3562a15a60cf747397e7f2180b0a11dc0c38d9175a650e75fa1b4d325e15/multidict-6.7.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:98bc624954ec4d2c7cb074b8eefc2b5d0ce7d482e410df446414355d158fe4ca", size = 257492, upload-time = "2026-01-26T02:44:53.902Z" },
458
- { url = "https://files.pythonhosted.org/packages/24/02/7d0f9eae92b5249bb50ac1595b295f10e263dd0078ebb55115c31e0eaccd/multidict-6.7.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1b99af4d9eec0b49927b4402bcbb58dea89d3e0db8806a4086117019939ad3dd", size = 255899, upload-time = "2026-01-26T02:44:55.316Z" },
459
- { url = "https://files.pythonhosted.org/packages/00/e3/9b60ed9e23e64c73a5cde95269ef1330678e9c6e34dd4eb6b431b85b5a10/multidict-6.7.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6aac4f16b472d5b7dc6f66a0d49dd57b0e0902090be16594dc9ebfd3d17c47e7", size = 247970, upload-time = "2026-01-26T02:44:56.783Z" },
460
- { url = "https://files.pythonhosted.org/packages/3e/06/538e58a63ed5cfb0bd4517e346b91da32fde409d839720f664e9a4ae4f9d/multidict-6.7.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:21f830fe223215dffd51f538e78c172ed7c7f60c9b96a2bf05c4848ad49921c3", size = 245060, upload-time = "2026-01-26T02:44:58.195Z" },
461
- { url = "https://files.pythonhosted.org/packages/b2/2f/d743a3045a97c895d401e9bd29aaa09b94f5cbdf1bd561609e5a6c431c70/multidict-6.7.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f5dd81c45b05518b9aa4da4aa74e1c93d715efa234fd3e8a179df611cc85e5f4", size = 235888, upload-time = "2026-01-26T02:44:59.57Z" },
462
- { url = "https://files.pythonhosted.org/packages/38/83/5a325cac191ab28b63c52f14f1131f3b0a55ba3b9aa65a6d0bf2a9b921a0/multidict-6.7.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:eb304767bca2bb92fb9c5bd33cedc95baee5bb5f6c88e63706533a1c06ad08c8", size = 243554, upload-time = "2026-01-26T02:45:01.054Z" },
463
- { url = "https://files.pythonhosted.org/packages/20/1f/9d2327086bd15da2725ef6aae624208e2ef828ed99892b17f60c344e57ed/multidict-6.7.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:c9035dde0f916702850ef66460bc4239d89d08df4d02023a5926e7446724212c", size = 252341, upload-time = "2026-01-26T02:45:02.484Z" },
464
- { url = "https://files.pythonhosted.org/packages/e8/2c/2a1aa0280cf579d0f6eed8ee5211c4f1730bd7e06c636ba2ee6aafda302e/multidict-6.7.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:af959b9beeb66c822380f222f0e0a1889331597e81f1ded7f374f3ecb0fd6c52", size = 246391, upload-time = "2026-01-26T02:45:03.862Z" },
465
- { url = "https://files.pythonhosted.org/packages/e5/03/7ca022ffc36c5a3f6e03b179a5ceb829be9da5783e6fe395f347c0794680/multidict-6.7.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:41f2952231456154ee479651491e94118229844dd7226541788be783be2b5108", size = 243422, upload-time = "2026-01-26T02:45:05.296Z" },
466
- { url = "https://files.pythonhosted.org/packages/dc/1d/b31650eab6c5778aceed46ba735bd97f7c7d2f54b319fa916c0f96e7805b/multidict-6.7.1-cp313-cp313t-win32.whl", hash = "sha256:df9f19c28adcb40b6aae30bbaa1478c389efd50c28d541d76760199fc1037c32", size = 47770, upload-time = "2026-01-26T02:45:06.754Z" },
467
- { url = "https://files.pythonhosted.org/packages/ac/5b/2d2d1d522e51285bd61b1e20df8f47ae1a9d80839db0b24ea783b3832832/multidict-6.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:d54ecf9f301853f2c5e802da559604b3e95bb7a3b01a9c295c6ee591b9882de8", size = 53109, upload-time = "2026-01-26T02:45:08.044Z" },
468
- { url = "https://files.pythonhosted.org/packages/3d/a3/cc409ba012c83ca024a308516703cf339bdc4b696195644a7215a5164a24/multidict-6.7.1-cp313-cp313t-win_arm64.whl", hash = "sha256:5a37ca18e360377cfda1d62f5f382ff41f2b8c4ccb329ed974cc2e1643440118", size = 45573, upload-time = "2026-01-26T02:45:09.349Z" },
469
- { url = "https://files.pythonhosted.org/packages/81/08/7036c080d7117f28a4af526d794aab6a84463126db031b007717c1a6676e/multidict-6.7.1-py3-none-any.whl", hash = "sha256:55d97cc6dae627efa6a6e548885712d4864b81110ac76fa4e534c03819fa4a56", size = 12319, upload-time = "2026-01-26T02:46:44.004Z" },
430
+ version = "7.0.0"
431
+ source = { registry = "https://pypi.org/simple" }
432
+ sdist = { url = "https://files.pythonhosted.org/packages/c4/64/642465a4827331a98ba4ae29f97658be25d1bdcb868872a2f78f7482b507/multidict-7.0.0.tar.gz", hash = "sha256:a7fcd089a0af2e0ef053c0d39c22c9ebf2434dddcb91034fd2f59ec99623788e", size = 280561, upload-time = "2026-09-26T19:36:12.283Z" }
433
+ wheels = [
434
+ { url = "https://files.pythonhosted.org/packages/5c/6e/c388fccb88dd6cb41ce2454e420c869fb0629ce10bfe12e4cad578ba940d/multidict-7.0.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:15d9ad70615ce1b37c124445145f071ba4eaa88cb21b49a6b81727cc85aefc37", size = 92310, upload-time = "2026-09-26T19:32:24.366Z" },
435
+ { url = "https://files.pythonhosted.org/packages/58/2f/33505a5c498613d53ab1d87b3c9425f6757afc7e48c2409f7aa001d0cdc1/multidict-7.0.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:313e336c75a53447cd943d93235c4702428b9740cb681e7174e398ba1f3f2918", size = 85114, upload-time = "2026-09-26T19:32:25.975Z" },
436
+ { url = "https://files.pythonhosted.org/packages/76/f5/27b19597821cb80d082b649e5e6e01033aed5e0eebdbbc6a644eb49515a7/multidict-7.0.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a4838959217e2652ef7dce1d01bb370aed3e5b694eb7a8258fa1cc50beef08ca", size = 86952, upload-time = "2026-09-26T19:32:27.429Z" },
437
+ { url = "https://files.pythonhosted.org/packages/f7/58/a5e44d5453c8bb295979d242cfd3beee06f6ab9f6c1c06a13c2191b792b1/multidict-7.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bd6520538e19fe104c3b74cc64767d6f8959dd2c9b8d59da62d83641ea646deb", size = 147356, upload-time = "2026-09-26T19:32:28.816Z" },
438
+ { url = "https://files.pythonhosted.org/packages/a2/c0/4da412a7267ac85759300a078f3bdad986e18a30c1ead8b74d2e3b335a2b/multidict-7.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3e9bf055becb08ff797d5cf80b760b726b8babb39046564d2b8481bbe6504bce", size = 88022, upload-time = "2026-09-26T19:32:30.44Z" },
439
+ { url = "https://files.pythonhosted.org/packages/b6/46/bebeb7df10298d390942e61bc7fc48472183ee4f5a0b7c285d93369b6874/multidict-7.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8e443cab381f8b6d24950982ae508600d464412cbdcf78e263cf8cd9b8372d68", size = 87046, upload-time = "2026-09-26T19:32:31.881Z" },
440
+ { url = "https://files.pythonhosted.org/packages/ab/d3/38b254c21cb8e9a65f8751ad8ba0a6f9baad75e3b6d3e559d1d05db26482/multidict-7.0.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e45bb7b9c850f216c0081dab8c6862fdec6b8be1c800b2a1aa4d1e56dcfacb54", size = 488729, upload-time = "2026-09-26T19:32:33.338Z" },
441
+ { url = "https://files.pythonhosted.org/packages/2a/28/19d66c476cc44fffdeacd5227a59046f94612075008069286bdbb9d3fa35/multidict-7.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de2f742000b47d806e5798f5ef0cdb2ed43d822fc913331a33ed1a40515495a7", size = 496708, upload-time = "2026-09-26T19:32:35.286Z" },
442
+ { url = "https://files.pythonhosted.org/packages/0d/66/3bb2d2cdf67742b002985906785b0db1584ca2e67ddb3677f6e9614321d6/multidict-7.0.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:70e28954ae5ae3c1806aa6d85bbb26ef7ab73017228eb236a3f245e24720bb34", size = 458261, upload-time = "2026-09-26T19:32:37.027Z" },
443
+ { url = "https://files.pythonhosted.org/packages/af/5c/c8ca15c191f957e8d86ec65148ed1e8ca189f456e66153e23c4ae610649a/multidict-7.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c41ccfa34b152146ccf05e8da753a85f8e67437477f8a00783aa427a132abd31", size = 511932, upload-time = "2026-09-26T19:32:39.025Z" },
444
+ { url = "https://files.pythonhosted.org/packages/14/ff/0665b2c3d5e42165a96fffc4c34c3d5fa66d0819d82b9bc2977b9a6aa1ed/multidict-7.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9a1de5f1da3ae056b45b6599a53dba6c86879bdfa5c3f15d7dde99f6cfbc03c6", size = 529152, upload-time = "2026-09-26T19:32:41.068Z" },
445
+ { url = "https://files.pythonhosted.org/packages/ab/f7/967875e5d1f908613cfcd5d9d078011168acb88a128028b81a0de43e8aa6/multidict-7.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:094852ebc620a10ee0e11f36a68e016d73596c0f5ed8351a9a52fcff7d449ad6", size = 506337, upload-time = "2026-09-26T19:32:42.839Z" },
446
+ { url = "https://files.pythonhosted.org/packages/a8/f9/56f04cf560bf736c23ba9cacc1ae3fcd2bbb591ba4f166c4bc08f5fead61/multidict-7.0.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:03cc4027103bb61feac20336a15fced1a6a369fed6a61c516353921207e4578c", size = 448144, upload-time = "2026-09-26T19:32:44.556Z" },
447
+ { url = "https://files.pythonhosted.org/packages/07/ea/ff7978bb38f2e2908cf7fc80061175cbfacdcada248dc48fb79a10c0e92b/multidict-7.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0fef8622896443fd0bdf39586391c2162ac05004ba4c9918827dfd2f79da750c", size = 485535, upload-time = "2026-09-26T19:32:46.439Z" },
448
+ { url = "https://files.pythonhosted.org/packages/ed/6c/1e9a6457587da0a31b3ef31ca0a40624877ca29408c8a7385260a3d45cd9/multidict-7.0.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:1847d33ca198aba3bf5fad036a7e0376cca325e7ec89f26362f9aa48994d8146", size = 471078, upload-time = "2026-09-26T19:32:48.166Z" },
449
+ { url = "https://files.pythonhosted.org/packages/ea/12/ee11505f0ae23a344544010485db982290c0e6105caefd74ce3830c315ca/multidict-7.0.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9b5c93f582f8a973ea803c46097729e34969683bc99f99fc00321b1f76317e81", size = 490764, upload-time = "2026-09-26T19:32:49.861Z" },
450
+ { url = "https://files.pythonhosted.org/packages/b9/8d/1e954f7cbb1f2080c2712b6a4cb6ce196037c06c686ae030003465b65ad7/multidict-7.0.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7c717376f801dd1ee102b292e0a4ca6037e948a8710316e64e698fe39eeb1307", size = 500752, upload-time = "2026-09-26T19:32:51.756Z" },
451
+ { url = "https://files.pythonhosted.org/packages/da/54/0f3899f51364f502219192b8c03da123c8618e9709499194ecd8e4143cc9/multidict-7.0.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c6d6e73b9f7b70558de5624b036815464a7ead4671fe2c3a4b3ce444c240cba6", size = 444706, upload-time = "2026-09-26T19:32:53.515Z" },
452
+ { url = "https://files.pythonhosted.org/packages/54/03/8edc3cb05a35185a4910582a50aa4dd342cceda3b26b2053dbd004adc9e8/multidict-7.0.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:18f627c69d041ae17d8fb45dbc63e192a2afc3ba062195441b5a50e93c50ae68", size = 511149, upload-time = "2026-09-26T19:32:55.281Z" },
453
+ { url = "https://files.pythonhosted.org/packages/d1/b4/4234b76f97b2966d1de2f3507f5dc9af4072e2ed16cfb476855490e34ae9/multidict-7.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8477e14353097077e1011464794d11e1d7559e821ab7c612cf7c06e7826ee1ba", size = 501451, upload-time = "2026-09-26T19:32:57.073Z" },
454
+ { url = "https://files.pythonhosted.org/packages/d8/a9/fe7965b74cb3cf822d3e88063f13e3eff2600c36022f69c603b5b52f3e21/multidict-7.0.0-cp313-cp313-win32.whl", hash = "sha256:2efca6de4fbefc12f2aaac2d5e1c176a3864d22250246b44fe3823e3634f06f8", size = 76414, upload-time = "2026-09-26T19:32:58.84Z" },
455
+ { url = "https://files.pythonhosted.org/packages/e9/c7/a4960e81ba8a3a9698011d1ac92d4d11ce8c9bb0ed6d235de76c49cae3d1/multidict-7.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:188a7f89a1935a138237088bff22400bacd25d80fb0d3a8a26fab25961df2239", size = 87005, upload-time = "2026-09-26T19:33:00.576Z" },
456
+ { url = "https://files.pythonhosted.org/packages/6c/66/7f6b0898c895f2b39ebaa3fc34d32537d263aa5c74809ee747b5e705da80/multidict-7.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:debb701a0436c96f2717c6156428a2c8bce2559236e120a674d503aeed678aa3", size = 85466, upload-time = "2026-09-26T19:33:02.072Z" },
457
+ { url = "https://files.pythonhosted.org/packages/46/a4/a3e9e72ed0f99587e9e96c3de72b743e1385e5e2b15fb583d8dfc05ffffb/multidict-7.0.0-py3-none-any.whl", hash = "sha256:1ba6a45450243bd8953223adff7183fce5e3f9f3556a03bd17a674caaa046215", size = 26592, upload-time = "2026-09-26T19:36:09.764Z" },
470
458
  ]
471
459
 
472
460
  [[package]]
@@ -905,11 +893,11 @@ wheels = [
905
893
 
906
894
  [[package]]
907
895
  name = "urllib3"
908
- version = "2.7.0"
896
+ version = "2.8.0"
909
897
  source = { registry = "https://pypi.org/simple" }
910
- sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" }
898
+ sdist = { url = "https://files.pythonhosted.org/packages/e3/05/b17359e1cefb4f909b5e40b1b90a496d987258916dbbf88e842c729f510e/urllib3-2.8.0.tar.gz", hash = "sha256:63bf2ead4c879426ebf22ef2a781eeb4aa3b4ae798a0435506f8687fd5bb9b63", size = 458972, upload-time = "2026-09-15T19:29:36.253Z" }
911
899
  wheels = [
912
- { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" },
900
+ { url = "https://files.pythonhosted.org/packages/92/9d/c4e665119135114480843e7ab388fa94d8480650450e6f8e26b70d323a4c/urllib3-2.8.0-py3-none-any.whl", hash = "sha256:0cf3cae568d36aa9576b28dfb35f11328f1cb974ca7647d9475ebb86c75ac6e3", size = 135717, upload-time = "2026-09-15T19:29:34.577Z" },
913
901
  ]
914
902
 
915
903
  [[package]]