-
Notifications
You must be signed in to change notification settings - Fork 173
refactor(BA-4011): Remove TODOs in manager/api/resource.py
#8219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Implement all remaining TODOs in the resource handler file in the Manager API. |
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -18,13 +18,11 @@ | |||||||
|
|
||||||||
| import aiohttp_cors | ||||||||
| import trafaret as t | ||||||||
| import yarl | ||||||||
| from aiohttp import web | ||||||||
|
|
||||||||
| from ai.backend.common import validators as tx | ||||||||
| from ai.backend.common.types import LegacyResourceSlotState as ResourceSlotState | ||||||||
| from ai.backend.logging import BraceStyleAdapter | ||||||||
| from ai.backend.manager.errors.api import InvalidAPIParameters | ||||||||
| from ai.backend.manager.services.agent.actions.get_watcher_status import GetWatcherStatusAction | ||||||||
| from ai.backend.manager.services.agent.actions.recalculate_usage import RecalculateUsageAction | ||||||||
| from ai.backend.manager.services.agent.actions.watcher_agent_restart import ( | ||||||||
|
|
@@ -85,22 +83,78 @@ async def list_presets(request: web.Request) -> web.Response: | |||||||
| t.Key("group", default="default"): t.String, | ||||||||
| }) | ||||||||
| ) | ||||||||
| async def check_presets(request: web.Request, params: Any) -> web.Response: | ||||||||
| async def check_presets_legacy(request: web.Request, params: Any) -> web.Response: | ||||||||
| """ | ||||||||
| Returns the list of all resource presets in the current scaling group, | ||||||||
| with additional information including allocatability of each preset, | ||||||||
| amount of total remaining resources, and the current keypair resource limits. | ||||||||
|
|
||||||||
| .. deprecated:: | ||||||||
| Use GET /check-presets instead. This POST endpoint is kept for backward compatibility. | ||||||||
| """ | ||||||||
| root_ctx: RootContext = request.app["_root.context"] | ||||||||
| access_key = request["keypair"]["access_key"] | ||||||||
| resource_policy = request["keypair"]["resource_policy"] | ||||||||
| domain_name = request["user"]["domain_name"] | ||||||||
|
|
||||||||
| log.info( | ||||||||
| "CHECK_PRESETS (ak:{}, g:{}, sg:{})", | ||||||||
| access_key, | ||||||||
| params["group"], | ||||||||
| params["scaling_group"], | ||||||||
| ) | ||||||||
|
|
||||||||
| result = await root_ctx.processors.resource_preset.check_presets.wait_for_complete( | ||||||||
| CheckResourcePresetsAction( | ||||||||
| access_key=access_key, | ||||||||
| resource_policy=resource_policy, | ||||||||
| domain_name=domain_name, | ||||||||
| user_id=request["user"]["uuid"], | ||||||||
| group=params["group"], | ||||||||
| scaling_group=params["scaling_group"], | ||||||||
| ) | ||||||||
| ) | ||||||||
|
|
||||||||
| scaling_groups_json = {} | ||||||||
| for sgname, sg_data in result.scaling_groups.items(): | ||||||||
| scaling_groups_json[sgname] = { | ||||||||
| ResourceSlotState.OCCUPIED: sg_data[ResourceSlotState.OCCUPIED].to_json(), | ||||||||
| ResourceSlotState.AVAILABLE: sg_data[ResourceSlotState.AVAILABLE].to_json(), | ||||||||
| } | ||||||||
|
|
||||||||
| resp = { | ||||||||
| "presets": result.presets, | ||||||||
| "keypair_limits": result.keypair_limits.to_json(), | ||||||||
| "keypair_using": result.keypair_using.to_json(), | ||||||||
| "keypair_remaining": result.keypair_remaining.to_json(), | ||||||||
| "group_limits": result.group_limits.to_json(), | ||||||||
| "group_using": result.group_using.to_json(), | ||||||||
| "group_remaining": result.group_remaining.to_json(), | ||||||||
| "scaling_group_remaining": result.scaling_group_remaining.to_json(), | ||||||||
| "scaling_groups": scaling_groups_json, | ||||||||
| } | ||||||||
|
|
||||||||
| return web.json_response(resp, status=HTTPStatus.OK) | ||||||||
|
|
||||||||
|
|
||||||||
| @server_status_required(READ_ALLOWED) | ||||||||
| @auth_required | ||||||||
| @check_api_params( | ||||||||
| t.Dict({ | ||||||||
| t.Key("scaling_group"): t.String, | ||||||||
|
||||||||
| t.Key("scaling_group"): t.String, | |
| t.Key("scaling_group", default=None): t.Or(t.String, t.Null), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Modifying the existing schema doesn’t look ideal.
Although there’s a desire to enforce stricter value constraints, it’s not something we can change in the current API.
Introducing a new API for this purpose would be a better option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Understood
I will look for better way to handle it, while retainig a exsiting api handlers.
Another small question here:
| cors.add(add_route("POST", "/check-presets", check_presets)) |
is being handled as "POST", although it doesn't effects current state,
best practice i think would be "GET" with parameter querier.
Current plan is adding new handler with "GET" with new function which we can use while transition.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -25,6 +25,7 @@ | |||||
| import attrs | ||||||
| import sqlalchemy as sa | ||||||
| import trafaret as t | ||||||
| import yarl | ||||||
| from aiohttp import web | ||||||
| from pydantic import ( | ||||||
| AliasChoices, | ||||||
|
|
@@ -48,7 +49,6 @@ | |||||
| VFolderUsageMode, | ||||||
| ) | ||||||
| from ai.backend.logging import BraceStyleAdapter | ||||||
| from ai.backend.manager.api.resource import get_watcher_info | ||||||
| from ai.backend.manager.data.agent.types import AgentStatus | ||||||
| from ai.backend.manager.data.kernel.types import KernelStatus | ||||||
| from ai.backend.manager.data.model_serving.types import EndpointLifecycle | ||||||
|
|
@@ -156,6 +156,34 @@ | |||||
| P = ParamSpec("P") | ||||||
|
|
||||||
|
|
||||||
| # NOTE: This function duplicates AgentService._get_watcher_info. | ||||||
| # Both access etcd directly for agent watcher information. | ||||||
| # Consider consolidating into a shared client/repository to eliminate | ||||||
| # this duplication and the direct etcd access pattern. | ||||||
| async def get_watcher_info(request: web.Request, agent_id: str) -> dict: | ||||||
| """ | ||||||
| Get watcher information. | ||||||
|
|
||||||
| :return addr: address of agent watcher (eg: http://127.0.0.1:6009) | ||||||
|
||||||
| :return addr: address of agent watcher (eg: http://127.0.0.1:6009) | |
| :return addr: address of agent watcher (eg: http://127.0.0.1:6099) |
Check warning
Code scanning / devskim
An HTTP-based URL without TLS was detected. Warning
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you check why the open api schema generator changed this?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c229676#diff-51adf4e1db91582bd045aea8a34e9565383e2c437c8cf7aa9eab64aebbdf9b3cR415-R416
I guess that modifcation of OpenAPI would occured from here.
With intention of soft migration I've added Get handler for legacy Post handler which doesn't make sense As it doesn't modify any state of program.
but i still need to investigate why "post" were deleted instead of coexistencing.