-
Notifications
You must be signed in to change notification settings - Fork 159
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
refactor(BA-501): Add draft vFolder handler Interface of manager #3493
base: feat/add-pydantic-handling-decorator-for-req-res
Are you sure you want to change the base?
refactor(BA-501): Add draft vFolder handler Interface of manager #3493
Conversation
src/ai/backend/manager/api/utils.py
Outdated
class BaseResponseModel(BaseModel): | ||
status: Annotated[int, Field(strict=True, exclude=True, ge=100, lt=600)] = 200 |
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.
Why was this changed here?
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.
In the values returned by the VFolder API (ex. VFolder Create), there was an issue where the field called 'status' was duplicated in the returned values, causing conflicts in pants check etc. To prevent this, we changed the part that means status code but is expressed as status
class VFolderCreateResponseModel(BaseResponseModel):
id: str
...
cloneable: bool
status: VFolderOperationStatus = Field(default=VFolderOperationStatus.READY)
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.
If you want to specify the status_code, it might be better to create a wrapper class instead of including it as a field in the Pydantic model.
(However, it must be ensured that the wrapper class is always unwrapped to apply the Pydantic model to the HTTP response, which can be enforced through middleware or similar mechanisms.)
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.
Also, please do not modify the existing model to avoid affecting the current behavior.
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.
We can solve this issue by using new @api_handler
included in #3511
src/ai/backend/manager/api/utils.py
Outdated
class BaseResponseModel(BaseModel): | ||
status: Annotated[int, Field(strict=True, exclude=True, ge=100, lt=600)] = 200 |
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.
If you want to specify the status_code, it might be better to create a wrapper class instead of including it as a field in the Pydantic model.
(However, it must be ensured that the wrapper class is always unwrapped to apply the Pydantic model to the HTTP response, which can be enforced through middleware or similar mechanisms.)
src/ai/backend/manager/api/utils.py
Outdated
class BaseResponseModel(BaseModel): | ||
status: Annotated[int, Field(strict=True, exclude=True, ge=100, lt=600)] = 200 |
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.
Also, please do not modify the existing model to avoid affecting the current behavior.
class VFolderHandlerProtocol(Protocol): | ||
async def create_vfolder( | ||
self, request: web.Request, params: VFolderCreateRequestModel | ||
) -> VFolderCreateResponseModel: ... | ||
|
||
async def list_vfolders( | ||
self, request: web.Request, params: VFolderListRequestModel | ||
) -> VFolderListResponseModel: ... | ||
|
||
async def rename_vfodler( | ||
self, request: web.Request, params: VFolderRenameRequestModel | ||
) -> CreatedResponseModel: ... | ||
|
||
async def delete_vfolder( | ||
self, request: web.Request, params: VFolderDeleteRequestModel | ||
) -> NoContentResponseModel: ... |
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.
It seems that the definition of VFolderHandlerProtocol
is not necessary.
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.
Okay, I will delete it
|
||
|
||
class VFolderListRequestModel(BaseModel): | ||
all: bool = Field(default=False) |
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.
Is all
an existing flag?
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.
all
flag exists, but it seems deprecated option. Can I delete this flag in refactored APIs?
@check_api_params(
t.Dict({
t.Key("all", default=False): t.ToBool,
}),
)
async def list_folders(request: web.Request, params: Any) -> web.Response:
...
if params["all"]:
raise InvalidAPIParameters("Deprecated use of 'all' option")
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: str | None | ||
group: str | None | ||
cloneable: bool | ||
status: VFolderOperationStatus | ||
is_owner: bool | ||
user_email: str | ||
group_name: str | ||
type: str # legacy | ||
max_files: int | ||
cur_size: int |
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.
Is it possible to group the values among the fields?
If it’s difficult right now, we can proceed with it after implementing the service layer
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.
I think we can proceed it when implementing service layer(we could do now, but it will change in high possibility when implementing service layer)
class VFolderListResponseModel(BaseResponseModel): | ||
root: list[VFolderListItem] = Field(default_factory=list) | ||
|
||
@classmethod | ||
def from_dataclass(cls, vfolder_list: VFolderList) -> "VFolderListResponseModel": | ||
return cls(root=vfolder_list.entries) | ||
|
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.
In my opinion, files or packages dealing with request and response should be separated from those dealing with internal models.
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.
I separated api_schemas.py
for req/res and dtos.py
for the dataclasses
b910b73
to
471a16d
Compare
30740cb
to
b000898
Compare
43510a5
to
b1dce6c
Compare
b000898
to
1eece08
Compare
resolves #3433 (BA-501)
This PR adds a skeleton interface for vFolder CRUD operations in manager, laying groundwork for reduced code duplication and improved maintainability in VFolder API handlers.
Codes added under
src/ai/backend/manager/api/vfolders
and test code intests/manager/api/vfolders
Checklist: (if applicable)
ai.backend.test
docs
directory📚 Documentation preview 📚: https://sorna--3493.org.readthedocs.build/en/3493/
📚 Documentation preview 📚: https://sorna-ko--3493.org.readthedocs.build/ko/3493/