-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #41 from jupyter-naas/100-feat-assets-api
100 feat assets api
- Loading branch information
Showing
13 changed files
with
672 additions
and
313 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
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,32 @@ | ||
from .models.Asset import Asset | ||
|
||
from naas_python.domains.asset.AssetSchema import ( | ||
IAssetDomain, | ||
IAssetAdaptor, | ||
Asset, | ||
AssetCreation, | ||
AssetUpdate | ||
) | ||
|
||
class AssetDomain(IAssetDomain): | ||
adaptor: IAssetAdaptor | ||
|
||
def __init__(self, adaptor: IAssetAdaptor): | ||
self.adaptor = adaptor | ||
|
||
def create_asset(self, workspace_id:str, asset_creation:AssetCreation) -> Asset: | ||
asset = self.adaptor.create_asset(workspace_id, asset_creation) | ||
return asset | ||
|
||
def get_asset(self, workspace_id:str, asset_id:str) -> Asset: | ||
asset = self.adaptor.get_asset(workspace_id, asset_id) | ||
return asset | ||
|
||
|
||
def update_asset(self, workspace_id:str, asset_id:str, asset_update: AssetUpdate) -> Asset: | ||
response = self.adaptor.update_asset(workspace_id, asset_id, asset_update) | ||
return response | ||
|
||
def delete_asset(self, workspace_id:str, asset_id:str) -> None: | ||
self.adaptor.delete_asset(workspace_id, asset_id) | ||
return None |
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,54 @@ | ||
from abc import ABCMeta, abstractmethod | ||
|
||
from naas_models.pydantic.asset_p2p import * | ||
from .models.Asset import Asset, AssetCreation, AssetUpdate | ||
|
||
from naas_python.utils.exceptions import NaasException | ||
|
||
# Exception | ||
class AssetNotFound(NaasException): pass | ||
class AssetConflictError(NaasException): pass | ||
class AssetRequestError(NaasException): pass | ||
|
||
# Secondary adaptor | ||
class IAssetAdaptor(metaclass=ABCMeta): | ||
|
||
@abstractmethod | ||
def create_asset(self, workspace_id:str, asset_creation:AssetCreation) -> Asset: | ||
raise NotImplementedError() | ||
|
||
@abstractmethod | ||
def get_asset(self, workspace_id:str, asset_id:str) -> Asset: | ||
raise NotImplementedError() | ||
|
||
@abstractmethod | ||
def update_asset(self, workspace_id:str, asset_id:str, asset_update: AssetUpdate) -> Asset: | ||
raise NotImplementedError() | ||
|
||
@abstractmethod | ||
def delete_asset(self, workspace_id:str, asset_id:str) -> None: | ||
raise NotImplementedError() | ||
|
||
# Domain | ||
class IAssetDomain(metaclass=ABCMeta): | ||
adaptor: IAssetAdaptor | ||
|
||
@abstractmethod | ||
def create_asset(self, workspace_id:str, asset_creation:AssetCreation) -> Asset: | ||
raise NotImplementedError() | ||
|
||
@abstractmethod | ||
def get_asset(self, workspace_id:str, asset_id:str) -> Asset: | ||
raise NotImplementedError() | ||
|
||
@abstractmethod | ||
def update_asset(self, workspace_id:str, asset_id:str, asset_update: AssetUpdate) -> Asset: | ||
raise NotImplementedError() | ||
|
||
@abstractmethod | ||
def delete_asset(self, workspace_id:str, asset_id:str) -> None: | ||
raise NotImplementedError() | ||
|
||
# Primary Adaptor | ||
class IAssetPrimaryAdaptor: | ||
pass |
33 changes: 33 additions & 0 deletions
33
naas_python/domains/asset/adaptors/primary/SDKAssetAdaptor.py
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,33 @@ | ||
|
||
from naas_python.domains.asset.AssetSchema import ( | ||
IAssetDomain, | ||
IAssetPrimaryAdaptor, | ||
Asset, | ||
AssetCreation, | ||
AssetUpdate | ||
) | ||
|
||
class SDKAssetAdaptor(IAssetPrimaryAdaptor): | ||
domain: IAssetDomain | ||
|
||
def __init__(self, domain: IAssetDomain): | ||
self.domain = domain | ||
|
||
def create_asset(self, workspace_id:str, asset_creation: AssetCreation) -> Asset: | ||
"""Create an asset from the given asset_creation object""" | ||
asset = self.domain.create_asset(workspace_id, asset_creation) | ||
return asset | ||
|
||
def get_asset(self, workspace_id:str, asset_id:str) -> Asset: | ||
"""Get an asset from the given workspace_id and asset_id""" | ||
asset = self.domain.get_asset(workspace_id, asset_id) | ||
return asset | ||
|
||
def update_asset(self, workspace_id:str, asset_id:str, asset_update: AssetUpdate) -> Asset: | ||
asset = self.domain.update_asset(workspace_id, asset_id, asset_update) | ||
return asset | ||
|
||
def delete_asset(self, workspace_id:str, asset_id:str) -> dict: | ||
"""Delete an asset from the given asset_id""" | ||
response = self.domain.delete_asset(workspace_id, asset_id) | ||
return response |
130 changes: 130 additions & 0 deletions
130
naas_python/domains/asset/adaptors/primary/TyperAssetAdaptor.py
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,130 @@ | ||
import typer | ||
from typer.core import TyperGroup | ||
from click import Context | ||
from rich.console import Console | ||
from rich import print | ||
from logging import getLogger | ||
|
||
from naas_python.domains.asset.AssetSchema import ( | ||
IAssetDomain, | ||
IAssetPrimaryAdaptor, | ||
# IAssetInvoker, | ||
Asset, | ||
AssetCreation, | ||
AssetUpdate | ||
) | ||
|
||
logger = getLogger(__name__) | ||
|
||
class OrderCommands(TyperGroup): | ||
def list_commands(self, ctx: Context): | ||
"""Return list of commands in the order appear.""" | ||
return list(self.commands) | ||
|
||
class TyperAssetAdaptor(IAssetPrimaryAdaptor): | ||
def __init__(self, domain: IAssetDomain): | ||
super().__init__() | ||
|
||
self.domain = domain | ||
self.console = Console() | ||
|
||
self.app = typer.Typer( | ||
cls=OrderCommands, | ||
help="Naas Asset CLI", | ||
add_completion=False, | ||
no_args_is_help=True, | ||
pretty_exceptions_enable=False, | ||
rich_markup_mode="rich", | ||
context_settings={"help_option_names": ["-h", "--help"]}, | ||
) | ||
|
||
self.app.command("create")(self.create_asset) | ||
self.app.command("delete")(self.delete_asset) | ||
self.app.command("get")(self.get_asset) | ||
self.app.command("update")(self.update_asset) | ||
|
||
def create_asset(self, | ||
workspace_id:str = typer.Option(None, "--workspace-id", "-w", help="ID of the workspace"), | ||
# asset_creation: AssetCreation = typer.Option(..., "--object", "-o", help="Storage object to create an asset from."), | ||
storage: str = typer.Option(None, "--storage", "-s", help="Storage name to create an asset from. ie:\"data1\""), | ||
object: str = typer.Option(None, "--object", "-o", help="Object to create an asset from. ie:\"/dir1/tmp.txt\""), | ||
version: str = typer.Option(None, "--object-version", "-ov", help="Optional version of the storage object"), | ||
visibility: str = typer.Option(None, "--visibility", "-vis", help="Optional visibility of the asset"), | ||
content_disposition: str = typer.Option(None, "--content-disposition", "-cd", help="Optinal content disposition of the asset"), | ||
password: str = typer.Option(None, "--password", "-p", help="Optional password to decrypt the storage object"), | ||
rich_preview: bool = typer.Option( | ||
False, | ||
"--rich-preview", | ||
"-rp", | ||
help="Rich preview of the information as a table", | ||
))-> Asset: | ||
asset_creation_args:dict = {"asset_creation": {}} | ||
if workspace_id is not None: | ||
asset_creation_args["asset_creation"]["workspace_id"] = workspace_id | ||
if storage is not None and object is not None: | ||
asset_creation_args["asset_creation"]["storage_name"] = storage | ||
asset_creation_args["asset_creation"]["object_name"] = object | ||
if version is not None: | ||
asset_creation_args["asset_creation"]["object_version"] = version | ||
if visibility is not None: | ||
asset_creation_args["asset_creation"]["visibility"] = visibility | ||
if content_disposition is not None: | ||
asset_creation_args["asset_creation"]["content_disposition"] = content_disposition | ||
if password is not None: | ||
asset_creation_args["asset_creation"]["password"] = password | ||
|
||
asset_creation : AssetCreation = asset_creation_args | ||
print("creating asset...") | ||
asset = self.domain.create_asset(workspace_id, asset_creation) | ||
|
||
def get_asset(self, | ||
workspace_id:str = typer.Option(None, "--workspace-id", "-w", help="ID of the workspace"), | ||
asset_id: str = typer.Option(None, "--asset-id", "-id", help="ID of the asset to get."), | ||
rich_preview: bool = typer.Option( | ||
False, | ||
"--rich-preview", | ||
"-rp", | ||
help="Rich preview of the information as a table", | ||
))-> Asset: | ||
print("getting asset...") | ||
asset = self.domain.get_asset(workspace_id, asset_id) | ||
print(asset) | ||
|
||
def update_asset(self, | ||
workspace_id:str = typer.Option(None, "--workspace-id", "-w", help="ID of the workspace"), | ||
asset_id: str = typer.Option(None, "--asset-id", "-id", help="ID of the asset to update."), | ||
visibility: str = typer.Option(None, "--visibility", "-vis", help="Optional visibility of the asset"), | ||
content_disposition: str = typer.Option(None, "--content-disposition", "-cd", help="Optinal content disposition of the asset"), | ||
# password: str = typer.Option(None, "--password", "-p", help="Optional password to decrypt the storage object"), | ||
rich_preview: bool = typer.Option( | ||
False, | ||
"--rich-preview", | ||
"-rp", | ||
help="Rich preview of the information as a table", | ||
))-> Asset: | ||
|
||
asset_update_args:dict = {"asset_update": {}} | ||
if visibility is not None: | ||
asset_update_args["asset_update"]["visibility"] = visibility | ||
if content_disposition is not None: | ||
asset_update_args["asset_update"]["content_disposition"] = content_disposition | ||
#TODO feature | ||
# if password is not None: | ||
# asset_update_args["asset_update"]["password"] = password | ||
asset_update : AssetUpdate = asset_update_args | ||
print("updating asset...") | ||
asset = self.domain.update_asset(workspace_id, asset_id, asset_update) | ||
print(asset) | ||
|
||
def delete_asset(self, | ||
workspace_id:str = typer.Option(..., "--workspace-id", "-w", help="ID of the workspace"), | ||
asset_id: str = typer.Option(..., "--asset-id", "-id", help="ID of the asset to delete."), | ||
rich_preview: bool = typer.Option( | ||
False, | ||
"--rich-preview", | ||
"-rp", | ||
help="Rich preview of the information as a table", | ||
))-> None: | ||
print("deleting asset...") | ||
self.domain.delete_asset(workspace_id, asset_id) | ||
print("Done.") |
82 changes: 82 additions & 0 deletions
82
naas_python/domains/asset/adaptors/secondary/NaasAssetAPIAdaptor.py
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,82 @@ | ||
import requests, json | ||
|
||
import pydash as _ | ||
|
||
from naas_python.utils.domains_base.secondary.BaseAPIAdaptor import BaseAPIAdaptor | ||
|
||
from naas_python.domains.asset.AssetSchema import ( | ||
IAssetAdaptor, | ||
AssetConflictError, | ||
AssetNotFound, | ||
AssetRequestError, | ||
Asset, | ||
AssetCreation, | ||
AssetUpdate, | ||
) | ||
|
||
class NaasAssetAPIAdaptor(BaseAPIAdaptor, IAssetAdaptor): | ||
def __init__(self): | ||
super().__init__() | ||
|
||
def _handle_response(self, api_response: requests.Response) -> dict: | ||
if api_response.status_code == 201: | ||
return None | ||
|
||
elif api_response.status_code == 200: | ||
return api_response.json() | ||
|
||
elif api_response.status_code == 409: | ||
raise AssetConflictError(api_response.json()['message']) | ||
|
||
elif api_response.status_code == 404: | ||
raise AssetNotFound(api_response.json()['message']) | ||
|
||
elif api_response.status_code == 400: | ||
raise AssetRequestError(api_response.json()['message']) | ||
|
||
elif api_response.status_code == 500: | ||
if 'code' in api_response.json() and api_response.json()['code'] == AssetError.UNEXPECTED_ERROR: | ||
raise AssetUnexpectedError(api_response.json()['message']) | ||
else: | ||
raise AssetInternalError(api_response.json()['message']) | ||
else: | ||
raise Exception(f"An unknown error occurred: {api_response.json()}") | ||
|
||
@BaseAPIAdaptor.service_status_decorator | ||
def create_asset(self, workspace_id:str, asset_creation:AssetCreation) -> Asset: | ||
_url = f"{self.host}/workspace/{workspace_id}/asset/" | ||
|
||
api_response = self.make_api_request( | ||
requests.post, | ||
_url, | ||
payload=json.dumps(asset_creation) | ||
) | ||
return self._handle_response(api_response) | ||
|
||
@BaseAPIAdaptor.service_status_decorator | ||
def get_asset(self, workspace_id:str, asset_id:str) -> Asset: | ||
_url = f"{self.host}/workspace/{workspace_id}/asset/{asset_id}" | ||
api_response = self.make_api_request( | ||
requests.get, | ||
_url | ||
) | ||
return self._handle_response(api_response) | ||
|
||
@BaseAPIAdaptor.service_status_decorator | ||
def update_asset(self, workspace_id:str, asset_id:str, asset_update: AssetUpdate) -> Asset: | ||
_url = f"{self.host}/workspace/{workspace_id}/asset/{asset_id}" | ||
api_response = self.make_api_request( | ||
requests.put, | ||
_url, | ||
payload=json.dumps(asset_update) | ||
) | ||
return self._handle_response(api_response) | ||
|
||
@BaseAPIAdaptor.service_status_decorator | ||
def delete_asset(self, workspace_id: str, asset_id: str) -> None: | ||
_url = f"{self.host}/workspace/{workspace_id}/asset/{asset_id}" | ||
api_response = self.make_api_request( | ||
requests.delete, | ||
_url | ||
) | ||
return None |
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,12 @@ | ||
|
||
from naas_python.domains.asset.adaptors.secondary.NaasAssetAPIAdaptor import NaasAssetAPIAdaptor | ||
from naas_python.domains.asset.AssetDomain import AssetDomain | ||
from naas_python.domains.asset.adaptors.primary.TyperAssetAdaptor import TyperAssetAdaptor | ||
|
||
import logging | ||
|
||
secondaryAdaptor = NaasAssetAPIAdaptor() | ||
|
||
domain = AssetDomain(secondaryAdaptor) | ||
|
||
primaryAdaptor = TyperAssetAdaptor(domain) |
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,7 @@ | ||
from naas_python.domains.asset.adaptors.secondary.NaasAssetAPIAdaptor import NaasAssetAPIAdaptor | ||
from naas_python.domains.asset.AssetDomain import AssetDomain | ||
from naas_python.domains.asset.adaptors.primary.SDKAssetAdaptor import SDKAssetAdaptor | ||
|
||
secondaryAdaptor = NaasAssetAPIAdaptor() | ||
domain = AssetDomain(secondaryAdaptor) | ||
primaryAdaptor = SDKAssetAdaptor(domain) |
Oops, something went wrong.