|
2 | 2 |
|
3 | 3 | from __future__ import annotations |
4 | 4 |
|
5 | | -from typing import Any |
| 5 | +from typing import TYPE_CHECKING, Annotated |
6 | 6 | from uuid import UUID |
7 | 7 |
|
| 8 | +import strawberry |
| 9 | +from strawberry.scalars import JSON |
| 10 | + |
8 | 11 | from ai.backend.common.dto.manager.v2.app_config.response import AppConfigNode |
9 | 12 | from ai.backend.common.meta.meta import NEXT_RELEASE_VERSION |
10 | | -from ai.backend.manager.api.gql.app_config_fragment.types.node import AppConfigFragmentGQL |
11 | 13 | from ai.backend.manager.api.gql.decorators import ( |
12 | 14 | BackendAIGQLMeta, |
13 | 15 | gql_field, |
14 | 16 | gql_pydantic_type, |
15 | 17 | ) |
16 | 18 | from ai.backend.manager.api.gql.pydantic_compat import PydanticOutputMixin |
17 | 19 |
|
| 20 | +if TYPE_CHECKING: |
| 21 | + from ai.backend.manager.api.gql.app_config_fragment.types.node import AppConfigFragmentGQL |
| 22 | + |
18 | 23 |
|
19 | 24 | @gql_pydantic_type( |
20 | 25 | BackendAIGQLMeta( |
|
31 | 36 | class AppConfigGQL(PydanticOutputMixin[AppConfigNode]): |
32 | 37 | user_id: UUID = gql_field(description="Target user's UUID.") |
33 | 38 | name: str = gql_field(description="Policy / config name.") |
34 | | - fragments: list[AppConfigFragmentGQL] = gql_field( |
| 39 | + # Use `strawberry.lazy()` to break the import cycle between |
| 40 | + # `app_config.types.node` and `app_config_fragment.types.node`: |
| 41 | + # the fragment package's `__init__.py` eagerly loads its resolver, |
| 42 | + # which imports `MyBulkCreate*` payloads back from `app_config.types`. |
| 43 | + fragments: list[ |
| 44 | + Annotated[ |
| 45 | + AppConfigFragmentGQL, |
| 46 | + strawberry.lazy("ai.backend.manager.api.gql.app_config_fragment.types.node"), |
| 47 | + ] |
| 48 | + ] = gql_field( |
35 | 49 | description="Contributing fragments in merge order (low → high).", |
36 | 50 | ) |
37 | | - config: dict[str, Any] | None = gql_field( |
| 51 | + config: JSON | None = gql_field( |
38 | 52 | description="Deep-merged configuration, or null when every fragment is empty.", |
39 | 53 | ) |
0 commit comments