Skip to content

Commit 7fd4435

Browse files
committed
Merge branch 'dev'
2 parents 2cda6ef + 1635545 commit 7fd4435

27 files changed

+1614
-4
lines changed

.github/hooks/pre-commit

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/sh
2+
3+
# Execute the make target
4+
make test
5+
6+
# Capture the exit status of the make command
7+
STATUS=$?
8+
9+
# If the make command fails, exit with the same status
10+
if [ $STATUS -ne 0 ]; then
11+
echo "Pre-commit hook failed: make test failed with status $STATUS"
12+
exit $STATUS
13+
fi
14+
15+
# If the make command succeeds, allow the commit to proceed
16+
exit 0

Makefile

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
install-git-hooks:
2+
cp .github/hooks/pre-commit .git/hooks/pre-commit
3+
chmod +x .git/hooks/pre-commit
4+
5+
.PHONY: install-git-hooks
6+
7+
all: install-git-hooks run
8+
19
openapi-gen:
210
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate \
311
-i /local/openapis/naas-openapi.json \

naas_python/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from .domains.registry.handlers.PythonHandler import primaryAdaptor as registry
22
from .domains.space.handlers.PythonHandler import primaryAdaptor as space
33
from .domains.secret.handlers.PythonHandler import primaryAdaptor as secret
4+
from .domains.asset.handlers.PythonHandler import primaryAdaptor as asset
5+
from .domains.storage.handlers.PythonHandler import primaryAdaptor as storage
46
from .utils.log import initialize_logging
57

68
logger = initialize_logging()

naas_python/cli.py

+13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import typer
2+
import logging
3+
logging.basicConfig(level=logging.ERROR)
24

35
from naas_python.domains.registry.handlers.CLIRegistryHandler import (
46
primaryAdaptor as typerRegistryAdaptor,
@@ -14,6 +16,14 @@
1416
primaryAdaptor as typerSecretAdaptor,
1517
)
1618

19+
from naas_python.domains.asset.handlers.CLIAssetHandler import (
20+
primaryAdaptor as typerAssetAdaptor,
21+
)
22+
23+
from naas_python.domains.storage.handlers.CLIStorageHandler import (
24+
primaryAdaptor as typerStorageAdaptor,
25+
)
26+
1727

1828
def _create_cli_app():
1929
app = typer.Typer(
@@ -27,6 +37,9 @@ def _create_cli_app():
2737
app.add_typer(typerSpaceAdaptor.app, name="space")
2838
app.add_typer(typerRegistryAdaptor.app, name="registry")
2939
app.add_typer(typerSecretAdaptor.app, name="secret")
40+
app.add_typer(typerAssetAdaptor.app, name="asset")
41+
app.add_typer(typerStorageAdaptor.app, name="storage")
42+
3043

3144
return app
3245

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from .models.Asset import Asset
2+
3+
from naas_python.domains.asset.AssetSchema import (
4+
IAssetDomain,
5+
IAssetAdaptor,
6+
Asset,
7+
AssetCreation,
8+
AssetUpdate
9+
)
10+
11+
class AssetDomain(IAssetDomain):
12+
adaptor: IAssetAdaptor
13+
14+
def __init__(self, adaptor: IAssetAdaptor):
15+
self.adaptor = adaptor
16+
17+
def create_asset(self, workspace_id:str, asset_creation:AssetCreation) -> Asset:
18+
asset = self.adaptor.create_asset(workspace_id, asset_creation)
19+
return asset
20+
21+
def get_asset(self, workspace_id:str, asset_id:str) -> Asset:
22+
asset = self.adaptor.get_asset(workspace_id, asset_id)
23+
return asset
24+
25+
26+
def update_asset(self, workspace_id:str, asset_id:str, asset_update: AssetUpdate) -> Asset:
27+
response = self.adaptor.update_asset(workspace_id, asset_id, asset_update)
28+
return response
29+
30+
def delete_asset(self, workspace_id:str, asset_id:str) -> None:
31+
self.adaptor.delete_asset(workspace_id, asset_id)
32+
return None
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from abc import ABCMeta, abstractmethod
2+
3+
from naas_models.pydantic.asset_p2p import *
4+
from .models.Asset import Asset, AssetCreation, AssetUpdate
5+
6+
from naas_python.utils.exceptions import NaasException
7+
8+
# Exception
9+
class AssetNotFound(NaasException): pass
10+
class AssetConflictError(NaasException): pass
11+
class AssetRequestError(NaasException): pass
12+
13+
# Secondary adaptor
14+
class IAssetAdaptor(metaclass=ABCMeta):
15+
16+
@abstractmethod
17+
def create_asset(self, workspace_id:str, asset_creation:AssetCreation) -> Asset:
18+
raise NotImplementedError()
19+
20+
@abstractmethod
21+
def get_asset(self, workspace_id:str, asset_id:str) -> Asset:
22+
raise NotImplementedError()
23+
24+
@abstractmethod
25+
def update_asset(self, workspace_id:str, asset_id:str, asset_update: AssetUpdate) -> Asset:
26+
raise NotImplementedError()
27+
28+
@abstractmethod
29+
def delete_asset(self, workspace_id:str, asset_id:str) -> None:
30+
raise NotImplementedError()
31+
32+
# Domain
33+
class IAssetDomain(metaclass=ABCMeta):
34+
adaptor: IAssetAdaptor
35+
36+
@abstractmethod
37+
def create_asset(self, workspace_id:str, asset_creation:AssetCreation) -> Asset:
38+
raise NotImplementedError()
39+
40+
@abstractmethod
41+
def get_asset(self, workspace_id:str, asset_id:str) -> Asset:
42+
raise NotImplementedError()
43+
44+
@abstractmethod
45+
def update_asset(self, workspace_id:str, asset_id:str, asset_update: AssetUpdate) -> Asset:
46+
raise NotImplementedError()
47+
48+
@abstractmethod
49+
def delete_asset(self, workspace_id:str, asset_id:str) -> None:
50+
raise NotImplementedError()
51+
52+
# Primary Adaptor
53+
class IAssetPrimaryAdaptor:
54+
pass
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
from naas_python.domains.asset.AssetSchema import (
3+
IAssetDomain,
4+
IAssetPrimaryAdaptor,
5+
Asset,
6+
AssetCreation,
7+
AssetUpdate
8+
)
9+
10+
class SDKAssetAdaptor(IAssetPrimaryAdaptor):
11+
domain: IAssetDomain
12+
13+
def __init__(self, domain: IAssetDomain):
14+
self.domain = domain
15+
16+
def create_asset(self, workspace_id:str, asset_creation: AssetCreation) -> Asset:
17+
"""Create an asset from the given asset_creation object"""
18+
asset = self.domain.create_asset(workspace_id, asset_creation)
19+
return asset
20+
21+
def get_asset(self, workspace_id:str, asset_id:str) -> Asset:
22+
"""Get an asset from the given workspace_id and asset_id"""
23+
asset = self.domain.get_asset(workspace_id, asset_id)
24+
return asset
25+
26+
def update_asset(self, workspace_id:str, asset_id:str, asset_update: AssetUpdate) -> Asset:
27+
asset = self.domain.update_asset(workspace_id, asset_id, asset_update)
28+
return asset
29+
30+
def delete_asset(self, workspace_id:str, asset_id:str) -> dict:
31+
"""Delete an asset from the given asset_id"""
32+
response = self.domain.delete_asset(workspace_id, asset_id)
33+
return response
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import typer
2+
from typer.core import TyperGroup
3+
from click import Context
4+
from rich.console import Console
5+
from rich import print
6+
from logging import getLogger
7+
8+
from naas_python.domains.asset.AssetSchema import (
9+
IAssetDomain,
10+
IAssetPrimaryAdaptor,
11+
# IAssetInvoker,
12+
Asset,
13+
AssetCreation,
14+
AssetUpdate
15+
)
16+
17+
logger = getLogger(__name__)
18+
19+
class OrderCommands(TyperGroup):
20+
def list_commands(self, ctx: Context):
21+
"""Return list of commands in the order appear."""
22+
return list(self.commands)
23+
24+
class TyperAssetAdaptor(IAssetPrimaryAdaptor):
25+
def __init__(self, domain: IAssetDomain):
26+
super().__init__()
27+
28+
self.domain = domain
29+
self.console = Console()
30+
31+
self.app = typer.Typer(
32+
cls=OrderCommands,
33+
help="Naas Asset CLI",
34+
add_completion=False,
35+
no_args_is_help=True,
36+
pretty_exceptions_enable=False,
37+
rich_markup_mode="rich",
38+
context_settings={"help_option_names": ["-h", "--help"]},
39+
)
40+
41+
self.app.command("create")(self.create_asset)
42+
self.app.command("delete")(self.delete_asset)
43+
self.app.command("get")(self.get_asset)
44+
self.app.command("update")(self.update_asset)
45+
46+
def create_asset(self,
47+
workspace_id:str = typer.Option(None, "--workspace-id", "-w", help="ID of the workspace"),
48+
# asset_creation: AssetCreation = typer.Option(..., "--object", "-o", help="Storage object to create an asset from."),
49+
storage: str = typer.Option(None, "--storage", "-s", help="Storage name to create an asset from. ie:\"data1\""),
50+
object: str = typer.Option(None, "--object", "-o", help="Object to create an asset from. ie:\"/dir1/tmp.txt\""),
51+
version: str = typer.Option(None, "--object-version", "-ov", help="Optional version of the storage object"),
52+
visibility: str = typer.Option(None, "--visibility", "-vis", help="Optional visibility of the asset"),
53+
content_disposition: str = typer.Option(None, "--content-disposition", "-cd", help="Optinal content disposition of the asset"),
54+
password: str = typer.Option(None, "--password", "-p", help="Optional password to decrypt the storage object"),
55+
rich_preview: bool = typer.Option(
56+
False,
57+
"--rich-preview",
58+
"-rp",
59+
help="Rich preview of the information as a table",
60+
))-> Asset:
61+
asset_creation_args:dict = {"asset_creation": {}}
62+
if workspace_id is not None:
63+
asset_creation_args["asset_creation"]["workspace_id"] = workspace_id
64+
if storage is not None and object is not None:
65+
asset_creation_args["asset_creation"]["storage_name"] = storage
66+
asset_creation_args["asset_creation"]["object_name"] = object
67+
if version is not None:
68+
asset_creation_args["asset_creation"]["object_version"] = version
69+
if visibility is not None:
70+
asset_creation_args["asset_creation"]["visibility"] = visibility
71+
if content_disposition is not None:
72+
asset_creation_args["asset_creation"]["content_disposition"] = content_disposition
73+
if password is not None:
74+
asset_creation_args["asset_creation"]["password"] = password
75+
76+
asset_creation : AssetCreation = asset_creation_args
77+
print("creating asset...")
78+
asset = self.domain.create_asset(workspace_id, asset_creation)
79+
80+
def get_asset(self,
81+
workspace_id:str = typer.Option(None, "--workspace-id", "-w", help="ID of the workspace"),
82+
asset_id: str = typer.Option(None, "--asset-id", "-id", help="ID of the asset to get."),
83+
rich_preview: bool = typer.Option(
84+
False,
85+
"--rich-preview",
86+
"-rp",
87+
help="Rich preview of the information as a table",
88+
))-> Asset:
89+
print("getting asset...")
90+
asset = self.domain.get_asset(workspace_id, asset_id)
91+
print(asset)
92+
93+
def update_asset(self,
94+
workspace_id:str = typer.Option(None, "--workspace-id", "-w", help="ID of the workspace"),
95+
asset_id: str = typer.Option(None, "--asset-id", "-id", help="ID of the asset to update."),
96+
visibility: str = typer.Option(None, "--visibility", "-vis", help="Optional visibility of the asset"),
97+
content_disposition: str = typer.Option(None, "--content-disposition", "-cd", help="Optinal content disposition of the asset"),
98+
# password: str = typer.Option(None, "--password", "-p", help="Optional password to decrypt the storage object"),
99+
rich_preview: bool = typer.Option(
100+
False,
101+
"--rich-preview",
102+
"-rp",
103+
help="Rich preview of the information as a table",
104+
))-> Asset:
105+
106+
asset_update_args:dict = {"asset_update": {}}
107+
if visibility is not None:
108+
asset_update_args["asset_update"]["visibility"] = visibility
109+
if content_disposition is not None:
110+
asset_update_args["asset_update"]["content_disposition"] = content_disposition
111+
#TODO feature
112+
# if password is not None:
113+
# asset_update_args["asset_update"]["password"] = password
114+
asset_update : AssetUpdate = asset_update_args
115+
print("updating asset...")
116+
asset = self.domain.update_asset(workspace_id, asset_id, asset_update)
117+
print(asset)
118+
119+
def delete_asset(self,
120+
workspace_id:str = typer.Option(..., "--workspace-id", "-w", help="ID of the workspace"),
121+
asset_id: str = typer.Option(..., "--asset-id", "-id", help="ID of the asset to delete."),
122+
rich_preview: bool = typer.Option(
123+
False,
124+
"--rich-preview",
125+
"-rp",
126+
help="Rich preview of the information as a table",
127+
))-> None:
128+
print("deleting asset...")
129+
self.domain.delete_asset(workspace_id, asset_id)
130+
print("Done.")

0 commit comments

Comments
 (0)