Skip to content

Commit 969b873

Browse files
committed
fix(BA-5829): clean BEP refs, drop unused type:ignore, break circular import
Per #11285 review: - Strip the BEP-1052 §X annotations from descriptions, comments, and docstrings — the BEP number doesn't help future readers and clutters the schema. - Move `BulkCreate/UpdateMyAppConfigFragmentsPayloadGQL` from `app_config_fragment/types/bulk_payloads.py` into `app_config/types/bulk_payloads.py`. They referenced `AppConfigGQL` while `AppConfigGQL` already references `AppConfigFragmentGQL`, so splitting them keeps the import direction one-way and resolves the `tests/component/user/test_keypair_ops.py` collection error reported by `test-component`. - Drop unused `# type: ignore[misc]` on `gql_mutation` decorators (the helper preserves the wrapped function's signature, so mypy no longer treats the result as untyped).
1 parent 5b8c2dc commit 969b873

23 files changed

Lines changed: 81 additions & 234 deletions

File tree

src/ai/backend/common/dto/manager/v2/app_config/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
AppConfig (merged view) DTOs v2 for Manager API (BEP-1052 §5).
2+
AppConfig (merged view) DTOs v2 for Manager API.
33
"""
44

55
from .request import (

src/ai/backend/common/dto/manager/v2/app_config/request.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Request DTOs for AppConfig (merged view) DTO v2 (BEP-1052 §5).
2+
Request DTOs for AppConfig (merged view) DTO v2.
33
"""
44

55
from __future__ import annotations
@@ -62,7 +62,7 @@ class SearchMyAppConfigsInput(_AppConfigSearchInputBase):
6262
"""Input for self-service merged-view search (`/v2/app-configs/my/search`).
6363
6464
The adapter pins the caller as the user scope; no `user_id` argument
65-
is accepted here (BEP-1052 §5 — `filter.userId` is ignored).
65+
is accepted here.
6666
"""
6767

6868

src/ai/backend/common/dto/manager/v2/app_config/response.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Response DTOs for AppConfig (merged view) DTO v2 (BEP-1052 §5).
2+
Response DTOs for AppConfig (merged view) DTO v2.
33
"""
44

55
from __future__ import annotations
@@ -25,7 +25,7 @@
2525

2626

2727
class AppConfigNode(BaseResponseModel):
28-
"""Merged per-user AppConfig view (BEP-1052 §5).
28+
"""Merged per-user AppConfig view.
2929
3030
`fragments` are ordered low → high merge priority (matching the
3131
policy's `scope_sources`). `config` is the deep-merged result,
@@ -66,7 +66,7 @@ class BulkCreateMyAppConfigFragmentsPayload(BaseResponseModel):
6666
"""Payload for `bulkCreateMyAppConfigFragments`.
6767
6868
Each successfully created row produces a recomputed merged
69-
`AppConfigNode`; failures are collected per-item (BEP-1052 §3).
69+
`AppConfigNode`; failures are collected per-item.
7070
"""
7171

7272
created: list[AppConfigNode] = Field(

src/ai/backend/common/dto/manager/v2/app_config/types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Common types for AppConfig (merged view) DTO v2 (BEP-1052 §5).
2+
Common types for AppConfig (merged view) DTO v2.
33
"""
44

55
from __future__ import annotations

src/ai/backend/manager/api/adapters/app_config.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,14 +154,14 @@ async def admin_search_app_configs(
154154
# reasons travel back through the per-item `failed` list.
155155

156156
async def my_bulk_create(
157-
self, input: MyBulkCreateAppConfigFragmentsInput
158-
) -> MyBulkCreateAppConfigFragmentsPayload:
157+
self, input: BulkCreateMyAppConfigFragmentsInput
158+
) -> BulkCreateMyAppConfigFragmentsPayload:
159159
items = [
160160
MyAppConfigFragmentBulkItem(name=item.name, config=dict(item.config))
161161
for item in input.items
162162
]
163-
wrapper = await self._processors.app_config_fragment.my_bulk_create.wait_for_complete(
164-
MyBulkCreateAppConfigFragmentsAction(entity_ids=[], items=items)
163+
wrapper = await self._processors.app_config_fragment.bulk_create_my.wait_for_complete(
164+
BulkCreateMyAppConfigFragmentsAction(entity_ids=[], items=items)
165165
)
166166
result = wrapper.result
167167
return MyBulkCreateAppConfigFragmentsPayload(
@@ -170,14 +170,14 @@ async def my_bulk_create(
170170
)
171171

172172
async def my_bulk_update(
173-
self, input: MyBulkUpdateAppConfigFragmentsInput
174-
) -> MyBulkUpdateAppConfigFragmentsPayload:
173+
self, input: BulkUpdateMyAppConfigFragmentsInput
174+
) -> BulkUpdateMyAppConfigFragmentsPayload:
175175
items = [
176176
MyAppConfigFragmentBulkItem(name=item.name, config=dict(item.config))
177177
for item in input.items
178178
]
179-
wrapper = await self._processors.app_config_fragment.my_bulk_update.wait_for_complete(
180-
MyBulkUpdateAppConfigFragmentsAction(entity_ids=[], items=items)
179+
wrapper = await self._processors.app_config_fragment.bulk_update_my.wait_for_complete(
180+
BulkUpdateMyAppConfigFragmentsAction(entity_ids=[], items=items)
181181
)
182182
result = wrapper.result
183183
return MyBulkUpdateAppConfigFragmentsPayload(

src/ai/backend/manager/api/adapters/app_config_fragment.py

Lines changed: 5 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,10 @@
112112
class AppConfigFragmentAdapter(BaseAdapter):
113113
"""Adapter for AppConfigFragment raw-row operations.
114114
115-
Writes are bulk-only (BEP-1052 §3); single-item create / update /
116-
purge entry points are intentionally absent.
115+
Writes are bulk-only; single-item create / update /
116+
purge entry points are intentionally absent. Self-service my_bulk
117+
writes (which return the recomputed merged view) live on
118+
`AppConfigAdapter` alongside the merged-view reads.
117119
"""
118120

119121
async def get(self, key_input: AppConfigFragmentKeyInput) -> GetAppConfigFragmentPayload:
@@ -265,143 +267,7 @@ def _data_to_dto(data: AppConfigFragmentData) -> AppConfigFragmentNode:
265267
updated_at=data.updated_at,
266268
)
267269

268-
# ── Merged-view (AppConfig, BEP-1052 §5) ───────────────────────
269-
270-
async def my_app_config(self, name: str) -> GetUserAppConfigPayload:
271-
"""Read the caller's own merged AppConfig for `name`.
272-
273-
Resolves the current user from the context; there is no way to
274-
target another user through this method.
275-
"""
276-
me = current_user()
277-
if me is None:
278-
raise UnreachableError("User context is not available")
279-
result = await self._processors.app_config_fragment.get_user_app_config.wait_for_complete(
280-
GetUserAppConfigAction(user_id=me.user_id, config_name=name)
281-
)
282-
return GetUserAppConfigPayload(item=self._app_config_data_to_dto(result.app_config))
283-
284-
async def admin_get_user_app_config(
285-
self, input: GetUserAppConfigInput
286-
) -> GetUserAppConfigPayload:
287-
"""Read a specific user's merged AppConfig (admin only)."""
288-
result = await self._processors.app_config_fragment.get_user_app_config.wait_for_complete(
289-
GetUserAppConfigAction(user_id=input.user_id, config_name=input.name)
290-
)
291-
return GetUserAppConfigPayload(item=self._app_config_data_to_dto(result.app_config))
292-
293-
async def my_search_app_configs(
294-
self, input: SearchMyAppConfigsInput
295-
) -> SearchAppConfigsPayload:
296-
"""Paginated merged-view search over the caller's own AppConfigs."""
297-
me = current_user()
298-
if me is None:
299-
raise UnreachableError("User context is not available")
300-
querier = self._build_app_config_querier(input)
301-
result = (
302-
await self._processors.app_config_fragment.search_user_app_configs.wait_for_complete(
303-
SearchUserAppConfigsAction(
304-
scope=UserAppConfigSearchScope(user_id=me.user_id),
305-
querier=querier,
306-
)
307-
)
308-
)
309-
return SearchAppConfigsPayload(
310-
items=[self._app_config_data_to_dto(item) for item in result.items],
311-
total_count=result.total_count,
312-
has_next_page=result.has_next_page,
313-
has_previous_page=result.has_previous_page,
314-
)
315-
316-
async def admin_search_app_configs(
317-
self, input: SearchAppConfigsInput
318-
) -> SearchAppConfigsPayload:
319-
"""Cross-user merged-view search (admin only).
320-
321-
`filter.user_id` pins the query to a single user; otherwise
322-
pagination walks across every user.
323-
"""
324-
querier = self._build_app_config_querier(input)
325-
result = (
326-
await self._processors.app_config_fragment.admin_search_app_configs.wait_for_complete(
327-
AdminSearchAppConfigsAction(querier=querier)
328-
)
329-
)
330-
return SearchAppConfigsPayload(
331-
items=[self._app_config_data_to_dto(item) for item in result.items],
332-
total_count=result.total_count,
333-
has_next_page=result.has_next_page,
334-
has_previous_page=result.has_previous_page,
335-
)
336-
337-
def _build_app_config_querier(
338-
self,
339-
input: SearchMyAppConfigsInput | SearchAppConfigsInput,
340-
) -> BatchQuerier:
341-
"""Querier builder shared by `my_search_app_configs` and
342-
`admin_search_app_configs`.
343-
344-
The merged-view SQL resolves cursor/order internally via the
345-
repository layer; this helper forwards only the filter / order /
346-
pagination fields so cursor tiebreakers stay consistent with
347-
the raw-fragment querier.
348-
"""
349-
conditions = self._convert_app_config_filter(input.filter) if input.filter else []
350-
orders = self._convert_app_config_orders(input.order) if input.order else []
351-
return self._build_querier(
352-
conditions=conditions,
353-
orders=orders,
354-
pagination_spec=self._PAGINATION_SPEC,
355-
first=input.first,
356-
after=input.after,
357-
last=input.last,
358-
before=input.before,
359-
limit=input.limit,
360-
offset=input.offset,
361-
)
362-
363-
def _convert_app_config_filter(self, filter: AppConfigFilter) -> list[QueryCondition]:
364-
conditions: list[QueryCondition] = []
365-
if filter.name is not None:
366-
condition = self.convert_string_filter(
367-
filter.name,
368-
contains_factory=AppConfigFragmentConditions.by_name_contains,
369-
equals_factory=AppConfigFragmentConditions.by_name_equals,
370-
starts_with_factory=AppConfigFragmentConditions.by_name_starts_with,
371-
ends_with_factory=AppConfigFragmentConditions.by_name_ends_with,
372-
in_factory=AppConfigFragmentConditions.by_name_in,
373-
)
374-
if condition is not None:
375-
conditions.append(condition)
376-
# `filter.user_id` handling lives inside the merged-view SQL
377-
# (repository layer) rather than in a BatchQuerier condition —
378-
# see `AppConfigFragmentDBSource.admin_search_app_configs`.
379-
return conditions
380-
381-
@staticmethod
382-
def _convert_app_config_orders(orders: list[AppConfigOrder]) -> list[QueryOrder]:
383-
result: list[QueryOrder] = []
384-
for order in orders:
385-
ascending = order.direction == OrderDirection.ASC
386-
match order.field:
387-
case AppConfigOrderField.NAME:
388-
result.append(AppConfigFragmentOrders.name(ascending))
389-
case AppConfigOrderField.USER_ID:
390-
# USER_ID ordering is applied inside the merged-view SQL
391-
# because the raw `app_config_fragments` row does not
392-
# carry a user_id column directly.
393-
continue
394-
return result
395-
396-
def _app_config_data_to_dto(self, data: AppConfigData) -> AppConfigNode:
397-
return AppConfigNode(
398-
user_id=data.user_id,
399-
name=data.name,
400-
fragments=[self._data_to_dto(fragment) for fragment in data.fragments],
401-
config=dict(data.config) if data.config is not None else None,
402-
)
403-
404-
# ── Bulk mutations (BEP-1052 §3) ───────────────────────────────
270+
# ── Bulk mutations ───────────────────────────────
405271
#
406272
# Each bulk processor returns a `BulkProcessResult[T]` whose
407273
# `.result` field is the underlying `*ActionResult` produced by the

src/ai/backend/manager/api/gql/app_config/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""AppConfig (merged view) GraphQL API package (BEP-1052 §5)."""
1+
"""AppConfig (merged view) GraphQL API package."""
22

33
from .resolver import (
44
admin_app_configs,

src/ai/backend/manager/api/gql/app_config/resolver/query.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""AppConfig (merged view) GQL query resolvers (BEP-1052 §5)."""
1+
"""AppConfig (merged view) GQL query resolvers."""
22

33
from __future__ import annotations
44

@@ -36,7 +36,7 @@
3636
added_version=NEXT_RELEASE_VERSION,
3737
description=(
3838
"Caller's own merged AppConfig list (auth required). Chain per policy "
39-
"(BEP-1052 §5); the adapter pins `(USER, current_user)` internally."
39+
"; the adapter pins `(USER, current_user)` internally."
4040
),
4141
)
4242
) # type: ignore[misc]
@@ -108,7 +108,7 @@ async def admin_app_configs(
108108
added_version=NEXT_RELEASE_VERSION,
109109
description=(
110110
"Public (no-auth) `PUBLIC`-scope app-config fragments — the subset of "
111-
"raw fragments that carry no personally-scoped data (BEP-1052 §3)."
111+
"raw fragments that carry no personally-scoped data."
112112
),
113113
)
114114
) # type: ignore[misc]

src/ai/backend/manager/api/gql/app_config/types/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
from .bulk_payloads import (
2+
BulkCreateMyAppConfigFragmentsPayloadGQL,
3+
BulkUpdateMyAppConfigFragmentsPayloadGQL,
4+
)
15
from .filters import (
26
AppConfigFilterGQL,
37
AppConfigOrderByGQL,
@@ -10,4 +14,6 @@
1014
"AppConfigGQL",
1115
"AppConfigOrderByGQL",
1216
"AppConfigOrderFieldGQL",
17+
"BulkCreateMyAppConfigFragmentsPayloadGQL",
18+
"BulkUpdateMyAppConfigFragmentsPayloadGQL",
1319
]

src/ai/backend/manager/api/gql/app_config/types/bulk_payloads.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
from __future__ import annotations
44

55
from ai.backend.common.dto.manager.v2.app_config.response import (
6-
MyBulkCreateAppConfigFragmentsPayload as MyBulkCreatePayloadDTO,
6+
BulkCreateMyAppConfigFragmentsPayload as BulkCreateMyPayloadDTO,
77
)
88
from ai.backend.common.dto.manager.v2.app_config.response import (
9-
MyBulkUpdateAppConfigFragmentsPayload as MyBulkUpdatePayloadDTO,
9+
BulkUpdateMyAppConfigFragmentsPayload as BulkUpdateMyPayloadDTO,
1010
)
1111
from ai.backend.common.meta.meta import NEXT_RELEASE_VERSION
1212
from ai.backend.manager.api.gql.app_config.types.node import AppConfigGQL
@@ -24,12 +24,12 @@
2424
@gql_pydantic_type(
2525
BackendAIGQLMeta(
2626
added_version=NEXT_RELEASE_VERSION,
27-
description="Payload for `myBulkCreateAppConfigFragments` (recomputed views).",
27+
description="Payload for `bulkCreateMyAppConfigFragments` (recomputed views).",
2828
),
29-
model=MyBulkCreatePayloadDTO,
30-
name="MyBulkCreateAppConfigFragmentsPayload",
29+
model=BulkCreateMyPayloadDTO,
30+
name="BulkCreateMyAppConfigFragmentsPayload",
3131
)
32-
class MyBulkCreateAppConfigFragmentsPayloadGQL(PydanticOutputMixin[MyBulkCreatePayloadDTO]):
32+
class BulkCreateMyAppConfigFragmentsPayloadGQL(PydanticOutputMixin[BulkCreateMyPayloadDTO]):
3333
created: list[AppConfigGQL] = gql_field(
3434
description="Recomputed merged AppConfig views for each created USER fragment.",
3535
)
@@ -41,12 +41,12 @@ class MyBulkCreateAppConfigFragmentsPayloadGQL(PydanticOutputMixin[MyBulkCreateP
4141
@gql_pydantic_type(
4242
BackendAIGQLMeta(
4343
added_version=NEXT_RELEASE_VERSION,
44-
description="Payload for `myBulkUpdateAppConfigFragments` (recomputed views).",
44+
description="Payload for `bulkUpdateMyAppConfigFragments` (recomputed views).",
4545
),
46-
model=MyBulkUpdatePayloadDTO,
47-
name="MyBulkUpdateAppConfigFragmentsPayload",
46+
model=BulkUpdateMyPayloadDTO,
47+
name="BulkUpdateMyAppConfigFragmentsPayload",
4848
)
49-
class MyBulkUpdateAppConfigFragmentsPayloadGQL(PydanticOutputMixin[MyBulkUpdatePayloadDTO]):
49+
class BulkUpdateMyAppConfigFragmentsPayloadGQL(PydanticOutputMixin[BulkUpdateMyPayloadDTO]):
5050
updated: list[AppConfigGQL] = gql_field(
5151
description="Recomputed merged AppConfig views for each updated USER fragment.",
5252
)

0 commit comments

Comments
 (0)