-
Notifications
You must be signed in to change notification settings - Fork 159
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Apply api handler in vfolder handler
- Loading branch information
1 parent
b1dce6c
commit 1eece08
Showing
11 changed files
with
869 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Add skeleton vFolder handler Interface of manager |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
python_sources(name="src") |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
import uuid | ||
from typing import Any, Mapping, Optional, Self | ||
|
||
from aiohttp import web | ||
from pydantic import AliasChoices, BaseModel, Field | ||
|
||
from ai.backend.common import typed_validators as tv | ||
from ai.backend.common.api_handlers import BaseResponseModel, MiddlewareParam | ||
from ai.backend.common.types import VFolderUsageMode | ||
from ai.backend.manager.api.vfolders.dtos import ( | ||
Keypair, | ||
UserIdentity, | ||
VFolderCreateRequirements, | ||
VFolderList, | ||
VFolderListItem, | ||
VFolderMetadata, | ||
) | ||
from ai.backend.manager.models import ( | ||
VFolderOperationStatus, | ||
VFolderPermission, | ||
) | ||
|
||
|
||
class VFolderCreateRequest(BaseModel): | ||
name: tv.VFolderName = Field( | ||
description="Name of the vfolder", | ||
) | ||
folder_host: Optional[str] = Field( | ||
validation_alias=AliasChoices("host", "folder_host"), | ||
default=None, | ||
) | ||
usage_mode: VFolderUsageMode = Field(default=VFolderUsageMode.GENERAL) | ||
permission: VFolderPermission = Field(default=VFolderPermission.READ_WRITE) | ||
unmanaged_path: Optional[str] = Field( | ||
validation_alias=AliasChoices("unmanaged_path", "unmanagedPath"), | ||
default=None, | ||
) | ||
group_id: Optional[uuid.UUID] = Field( | ||
validation_alias=AliasChoices("group", "groupId", "group_id"), | ||
default=None, | ||
) | ||
cloneable: bool = Field( | ||
default=False, | ||
) | ||
|
||
def to_dto(self) -> VFolderCreateRequirements: | ||
return VFolderCreateRequirements( | ||
name=self.name, | ||
folder_host=self.folder_host, | ||
usage_mode=self.usage_mode, | ||
permission=self.permission, | ||
group_id=self.group_id, | ||
cloneable=self.cloneable, | ||
unmanaged_path=self.unmanaged_path, | ||
) | ||
|
||
|
||
class VFolderListRequest(BaseModel): | ||
group_id: Optional[uuid.UUID] = Field( | ||
default=None, validation_alias=AliasChoices("group_id", "groupId") | ||
) | ||
|
||
|
||
class RenameVFolderId(BaseModel): | ||
vfolder_id: uuid.UUID = Field(validation_alias=AliasChoices("vfolder_id", "vfolderId", "id")) | ||
|
||
|
||
class VFolderNewName(BaseModel): | ||
new_name: tv.VFolderName = Field( | ||
description="Name of the vfolder", | ||
) | ||
|
||
|
||
class VFolderDeleteRequest(BaseModel): | ||
vfolder_id: uuid.UUID = Field( | ||
validation_alias=AliasChoices("vfolder_id", "vfolderId", "id"), | ||
description="Target vfolder id to soft-delete, to go to trash bin", | ||
) | ||
|
||
|
||
class VFolderCreateResponse(BaseResponseModel): | ||
id: str | ||
name: str | ||
quota_scope_id: str | ||
host: str | ||
usage_mode: VFolderUsageMode | ||
permission: str | ||
max_size: int = 0 # migrated to quota scopes, no longer valid | ||
creator: str | ||
ownership_type: str | ||
user: Optional[str] | ||
group: Optional[str] | ||
cloneable: bool | ||
status: VFolderOperationStatus = Field(default=VFolderOperationStatus.READY) | ||
|
||
@classmethod | ||
def from_vfolder_metadata(cls, data: VFolderMetadata): | ||
return cls( | ||
id=data.id, | ||
name=data.name, | ||
quota_scope_id=str(data.quota_scope_id), | ||
host=data.host, | ||
usage_mode=data.usage_mode, | ||
permission=data.permission, | ||
max_size=data.max_size, | ||
creator=data.creator, | ||
ownership_type=data.ownership_type, | ||
user=data.user, | ||
group=data.group, | ||
cloneable=data.cloneable, | ||
status=data.status, | ||
) | ||
|
||
|
||
class VFolderListResponse(BaseResponseModel): | ||
root: list[VFolderListItem] = Field(default_factory=list) | ||
|
||
@classmethod | ||
def from_dataclass(cls, vfolder_list: VFolderList) -> Self: | ||
return cls(root=vfolder_list.entries) | ||
|
||
|
||
class UserIdentityModel(MiddlewareParam): | ||
user_uuid: uuid.UUID | ||
user_role: str | ||
user_email: str | ||
domain_name: str | ||
|
||
@classmethod | ||
def from_request(cls, request: web.Request) -> Self: | ||
return cls( | ||
user_uuid=request["user"]["uuid"], | ||
user_role=request["user"]["role"], | ||
user_email=request["user"]["email"], | ||
domain_name=request["user"]["domain_name"], | ||
) | ||
|
||
def to_dto(self) -> UserIdentity: | ||
return UserIdentity( | ||
user_uuid=self.user_uuid, | ||
user_role=self.user_role, | ||
user_email=self.user_email, | ||
domain_name=self.domain_name, | ||
) | ||
|
||
|
||
class KeypairModel(MiddlewareParam): | ||
access_key: str | ||
resource_policy: Mapping[str, Any] | ||
|
||
@classmethod | ||
def from_request(cls, request: web.Request) -> Self: | ||
return cls( | ||
access_key=request["keypair"]["access_key"], | ||
resource_policy=request["keypair"]["resource_policy"], | ||
) | ||
|
||
def to_dto(self) -> Keypair: | ||
return Keypair(access_key=self.access_key, resource_policy=self.resource_policy) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import uuid | ||
from dataclasses import dataclass | ||
from typing import Any, Mapping, Optional | ||
|
||
from ai.backend.common.types import QuotaScopeID, VFolderUsageMode | ||
from ai.backend.manager.models import ( | ||
ProjectType, | ||
VFolderOperationStatus, | ||
VFolderOwnershipType, | ||
VFolderPermission, | ||
) | ||
|
||
|
||
@dataclass | ||
class UserIdentity: | ||
user_uuid: uuid.UUID | ||
user_role: str | ||
user_email: str | ||
domain_name: str | ||
|
||
|
||
@dataclass | ||
class Keypair: | ||
access_key: str | ||
resource_policy: Mapping[str, Any] | ||
|
||
|
||
@dataclass | ||
class UserScopeInput: | ||
requester_id: uuid.UUID | ||
is_authorized: bool | ||
is_superadmin: bool | ||
delegate_email: Optional[str] = None | ||
|
||
|
||
@dataclass | ||
class VFolderCreateRequirements: | ||
name: str | ||
folder_host: Optional[str] | ||
usage_mode: VFolderUsageMode | ||
permission: VFolderPermission | ||
group_id: Optional[uuid.UUID] | ||
cloneable: bool | ||
unmanaged_path: Optional[str] | ||
|
||
|
||
@dataclass | ||
class VFolderMetadata: | ||
id: str | ||
name: str | ||
quota_scope_id: QuotaScopeID | ||
host: str | ||
usage_mode: VFolderUsageMode | ||
created_at: str | ||
permission: VFolderPermission | ||
max_size: int # migrated to quota scopes, no longer valid | ||
creator: str | ||
ownership_type: VFolderOwnershipType | ||
user: Optional[str] | ||
group: Optional[str] | ||
cloneable: bool | ||
status: VFolderOperationStatus | ||
|
||
|
||
@dataclass | ||
class VFolderListItem: | ||
id: str | ||
name: str | ||
quota_scope_id: str | ||
host: str | ||
usage_mode: VFolderUsageMode | ||
created_at: str | ||
permission: VFolderPermission | ||
max_size: int | ||
creator: str | ||
ownership_type: VFolderOwnershipType | ||
user: Optional[str] | ||
group: Optional[str] | ||
cloneable: bool | ||
status: VFolderOperationStatus | ||
is_owner: bool | ||
user_email: str | ||
group_name: str | ||
type: str # legacy | ||
max_files: int | ||
cur_size: int | ||
|
||
|
||
@dataclass | ||
class VFolderList: | ||
entries: list[VFolderListItem] | ||
|
||
|
||
@dataclass | ||
class VFolderCapabilityInfo: | ||
max_vfolder_count: int | ||
max_quota_scope_size: int | ||
ownership_type: str | ||
quota_scope_id: QuotaScopeID | ||
group_uuid: Optional[uuid.UUID] = None | ||
group_type: Optional[ProjectType] = None |
Oops, something went wrong.