naas-abi-core 1.0.6__py3-none-any.whl → 1.0.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- assets/favicon.ico +0 -0
- naas_abi_core/apps/api/api.py +5 -2
- naas_abi_core/cli/__init__.py +4 -3
- naas_abi_core/cli/deploy.py +194 -0
- naas_abi_core/engine/engine_configuration/EngineConfiguration.py +3 -1
- naas_abi_core/engine/engine_configuration/EngineConfiguration_Deploy.py +6 -0
- {naas_abi_core-1.0.6.dist-info → naas_abi_core-1.0.8.dist-info}/METADATA +6 -1
- {naas_abi_core-1.0.6.dist-info → naas_abi_core-1.0.8.dist-info}/RECORD +10 -7
- {naas_abi_core-1.0.6.dist-info → naas_abi_core-1.0.8.dist-info}/WHEEL +0 -0
- {naas_abi_core-1.0.6.dist-info → naas_abi_core-1.0.8.dist-info}/entry_points.txt +0 -0
assets/favicon.ico
ADDED
|
Binary file
|
naas_abi_core/apps/api/api.py
CHANGED
|
@@ -16,6 +16,7 @@ from fastapi.security.oauth2 import OAuth2
|
|
|
16
16
|
from fastapi.security.utils import get_authorization_scheme_param
|
|
17
17
|
from fastapi.staticfiles import StaticFiles
|
|
18
18
|
from naas_abi_core import logger
|
|
19
|
+
from importlib.resources import files
|
|
19
20
|
|
|
20
21
|
# Docs
|
|
21
22
|
from naas_abi_core.apps.api.openapi_doc import API_LANDING_HTML, TAGS_METADATA
|
|
@@ -49,8 +50,10 @@ app.add_middleware(
|
|
|
49
50
|
allow_headers=["*"],
|
|
50
51
|
)
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
|
|
54
|
+
static_dir = os.path.join(os.path.dirname(str(files("naas_abi_core"))), "assets")
|
|
55
|
+
app.mount("/static", StaticFiles(directory=str(static_dir)), name="static")
|
|
56
|
+
|
|
54
57
|
|
|
55
58
|
|
|
56
59
|
# Custom OAuth2 class that accepts query parameter
|
naas_abi_core/cli/__init__.py
CHANGED
|
@@ -7,7 +7,7 @@ from .init import init
|
|
|
7
7
|
from .module import module
|
|
8
8
|
from .new import new
|
|
9
9
|
from .secret import secrets
|
|
10
|
-
|
|
10
|
+
from .deploy import deploy
|
|
11
11
|
# from dotenv import load_dotenv
|
|
12
12
|
|
|
13
13
|
# load_dotenv()
|
|
@@ -48,6 +48,7 @@ main.add_command(agent)
|
|
|
48
48
|
main.add_command(chat)
|
|
49
49
|
main.add_command(new)
|
|
50
50
|
main.add_command(init)
|
|
51
|
+
main.add_command(deploy)
|
|
51
52
|
|
|
52
|
-
if __name__ == "__main__":
|
|
53
|
-
|
|
53
|
+
# if __name__ == "__main__":
|
|
54
|
+
main()
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import subprocess
|
|
3
|
+
from uuid import uuid4
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
import requests
|
|
7
|
+
from pydantic import BaseModel
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
from rich.markdown import Markdown
|
|
10
|
+
|
|
11
|
+
from naas_abi_core import logger
|
|
12
|
+
from naas_abi_core.engine.engine_configuration.EngineConfiguration import (
|
|
13
|
+
EngineConfiguration,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@click.group("deploy")
|
|
18
|
+
def deploy():
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Container(BaseModel):
|
|
23
|
+
name: str
|
|
24
|
+
image: str
|
|
25
|
+
port: int
|
|
26
|
+
cpu: str
|
|
27
|
+
memory: str
|
|
28
|
+
env: dict
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class Space(BaseModel):
|
|
32
|
+
name: str
|
|
33
|
+
containers: list[Container]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class NaasAPIClient:
|
|
37
|
+
naas_api_key: str
|
|
38
|
+
base_url: str
|
|
39
|
+
|
|
40
|
+
def __init__(self, naas_api_key: str):
|
|
41
|
+
self.naas_api_key = naas_api_key
|
|
42
|
+
self.base_url = "https://api.naas.ai"
|
|
43
|
+
|
|
44
|
+
def create_registry(self, name: str):
|
|
45
|
+
response = requests.post(
|
|
46
|
+
f"{self.base_url}/registry/",
|
|
47
|
+
headers={"Authorization": f"Bearer {self.naas_api_key}"},
|
|
48
|
+
json={"name": name},
|
|
49
|
+
)
|
|
50
|
+
if response.status_code == 409:
|
|
51
|
+
return self.get_registry(name)
|
|
52
|
+
response.raise_for_status()
|
|
53
|
+
return response.json()
|
|
54
|
+
|
|
55
|
+
def get_registry(self, name: str):
|
|
56
|
+
response = requests.get(
|
|
57
|
+
f"{self.base_url}/registry/{name}",
|
|
58
|
+
headers={"Authorization": f"Bearer {self.naas_api_key}"},
|
|
59
|
+
)
|
|
60
|
+
response.raise_for_status()
|
|
61
|
+
return response.json()
|
|
62
|
+
|
|
63
|
+
def get_registry_credentials(self, name: str):
|
|
64
|
+
response = requests.get(
|
|
65
|
+
f"{self.base_url}/registry/{name}/credentials",
|
|
66
|
+
headers={"Authorization": f"Bearer {self.naas_api_key}"},
|
|
67
|
+
)
|
|
68
|
+
response.raise_for_status()
|
|
69
|
+
return response.json()
|
|
70
|
+
|
|
71
|
+
def update_space(self, space: Space) -> dict:
|
|
72
|
+
response = requests.put(
|
|
73
|
+
f"{self.base_url}/space/{space.name}",
|
|
74
|
+
headers={"Authorization": f"Bearer {self.naas_api_key}"},
|
|
75
|
+
json=space.model_dump(),
|
|
76
|
+
)
|
|
77
|
+
response.raise_for_status()
|
|
78
|
+
return response.json()
|
|
79
|
+
|
|
80
|
+
def create_space(self, space: Space) -> dict:
|
|
81
|
+
response = requests.post(
|
|
82
|
+
f"{self.base_url}/space/",
|
|
83
|
+
headers={"Authorization": f"Bearer {self.naas_api_key}"},
|
|
84
|
+
json=space.model_dump(),
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
if response.status_code == 409:
|
|
88
|
+
return self.update_space(space)
|
|
89
|
+
|
|
90
|
+
response.raise_for_status()
|
|
91
|
+
return response.json()
|
|
92
|
+
|
|
93
|
+
def get_space(self, name: str) -> dict:
|
|
94
|
+
response = requests.get(
|
|
95
|
+
f"{self.base_url}/space/{name}",
|
|
96
|
+
headers={"Authorization": f"Bearer {self.naas_api_key}"},
|
|
97
|
+
)
|
|
98
|
+
response.raise_for_status()
|
|
99
|
+
return response.json()
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class NaasDeployer:
|
|
103
|
+
image_name: str
|
|
104
|
+
|
|
105
|
+
naas_api_client: NaasAPIClient
|
|
106
|
+
|
|
107
|
+
def __init__(self, configuration: EngineConfiguration):
|
|
108
|
+
self.configuration = configuration
|
|
109
|
+
self.image_name = str(uuid4())
|
|
110
|
+
assert configuration.deploy is not None
|
|
111
|
+
self.naas_api_client = NaasAPIClient(configuration.deploy.naas_api_key)
|
|
112
|
+
|
|
113
|
+
def docker_build(self, image_name: str):
|
|
114
|
+
subprocess.run(
|
|
115
|
+
f"docker build -t {image_name} . --platform linux/amd64", shell=True
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
def deploy(self):
|
|
119
|
+
registry = self.naas_api_client.create_registry(
|
|
120
|
+
self.configuration.deploy.space_name
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
uid = str(uuid4())
|
|
124
|
+
|
|
125
|
+
image_name = f"{registry['registry']['uri']}:{uid}"
|
|
126
|
+
self.docker_build(image_name)
|
|
127
|
+
credentials = self.naas_api_client.get_registry_credentials(
|
|
128
|
+
self.configuration.deploy.space_name
|
|
129
|
+
)
|
|
130
|
+
docker_login_command = f"docker login -u {credentials['credentials']['username']} -p {credentials['credentials']['password']} {registry['registry']['uri']}"
|
|
131
|
+
subprocess.run(docker_login_command, shell=True)
|
|
132
|
+
subprocess.run(f"docker push {image_name}", shell=True)
|
|
133
|
+
|
|
134
|
+
image_sha = (
|
|
135
|
+
subprocess.run(
|
|
136
|
+
"docker inspect --format='{{index .RepoDigests 0}}' "
|
|
137
|
+
+ image_name
|
|
138
|
+
+ " | cut -d'@' -f2",
|
|
139
|
+
shell=True,
|
|
140
|
+
capture_output=True,
|
|
141
|
+
)
|
|
142
|
+
.stdout.strip()
|
|
143
|
+
.decode("utf-8")
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
image_name_with_sha = f"{image_name.replace(':' + uid, '')}@{image_sha}"
|
|
147
|
+
|
|
148
|
+
self.naas_api_client.create_space(
|
|
149
|
+
Space(
|
|
150
|
+
name=self.configuration.deploy.space_name,
|
|
151
|
+
containers=[
|
|
152
|
+
Container(
|
|
153
|
+
name="api",
|
|
154
|
+
image=image_name_with_sha,
|
|
155
|
+
port=9879,
|
|
156
|
+
cpu="1",
|
|
157
|
+
memory="1Gi",
|
|
158
|
+
env={
|
|
159
|
+
"NAAS_API_KEY": self.configuration.deploy.naas_api_key,
|
|
160
|
+
"ENV": "prod",
|
|
161
|
+
},
|
|
162
|
+
)
|
|
163
|
+
],
|
|
164
|
+
)
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
space = self.naas_api_client.get_space(self.configuration.deploy.space_name)
|
|
168
|
+
|
|
169
|
+
Console().print(
|
|
170
|
+
Markdown(f"""
|
|
171
|
+
# Deployment successful
|
|
172
|
+
|
|
173
|
+
- Space: {self.configuration.deploy.space_name}
|
|
174
|
+
- Image: {image_name_with_sha}
|
|
175
|
+
- URL: https://{self.configuration.deploy.space_name}.default.space.naas.ai
|
|
176
|
+
|
|
177
|
+
```json
|
|
178
|
+
{json.dumps(space, indent=4)}
|
|
179
|
+
```
|
|
180
|
+
""")
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
@deploy.command("naas")
|
|
185
|
+
def naas():
|
|
186
|
+
configuration: EngineConfiguration = EngineConfiguration.load_configuration()
|
|
187
|
+
|
|
188
|
+
if configuration.deploy is None:
|
|
189
|
+
logger.error(
|
|
190
|
+
"Deploy configuration not found in the yaml configuration file. Please add a deploy section to the configuration file."
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
deployer = NaasDeployer(configuration)
|
|
194
|
+
deployer.deploy()
|
|
@@ -20,7 +20,7 @@ from naas_abi_core.engine.engine_configuration.EngineConfiguration_VectorStoreSe
|
|
|
20
20
|
from naas_abi_core.services.secret.Secret import Secret
|
|
21
21
|
from pydantic import BaseModel, model_validator
|
|
22
22
|
from typing_extensions import Literal
|
|
23
|
-
|
|
23
|
+
from naas_abi_core.engine.engine_configuration.EngineConfiguration_Deploy import DeployConfiguration
|
|
24
24
|
|
|
25
25
|
class ServicesConfiguration(BaseModel):
|
|
26
26
|
object_storage: ObjectStorageServiceConfiguration
|
|
@@ -80,6 +80,8 @@ class GlobalConfig(BaseModel):
|
|
|
80
80
|
|
|
81
81
|
class EngineConfiguration(BaseModel):
|
|
82
82
|
api: ApiConfiguration
|
|
83
|
+
|
|
84
|
+
deploy: DeployConfiguration | None = None
|
|
83
85
|
|
|
84
86
|
services: ServicesConfiguration
|
|
85
87
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: naas-abi-core
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.8
|
|
4
4
|
Summary: Abi framework allowing you to build your AI system.
|
|
5
5
|
Author-email: Maxime Jublou <maxime@naas.ai>, Florent Ravenel <florent@naas.ai>, Jeremy Ravenel <jeremy@naas.ai>
|
|
6
6
|
Requires-Python: <4,>=3.10
|
|
7
7
|
Requires-Dist: click<8.2,>=8.1.1
|
|
8
|
+
Requires-Dist: docker>=7.1.0
|
|
8
9
|
Requires-Dist: dotenv>=0.9.9
|
|
9
10
|
Requires-Dist: fastapi<0.116,>=0.115.5
|
|
10
11
|
Requires-Dist: fastmcp>=2.13.2
|
|
@@ -14,6 +15,7 @@ Requires-Dist: langgraph>=0.6.6
|
|
|
14
15
|
Requires-Dist: loguru<0.8,>=0.7.2
|
|
15
16
|
Requires-Dist: pandas-stubs>=2.3.2.250926
|
|
16
17
|
Requires-Dist: pandas>=2.3.3
|
|
18
|
+
Requires-Dist: pillow>=12.0.0
|
|
17
19
|
Requires-Dist: pip>=25.1.1
|
|
18
20
|
Requires-Dist: psycopg[binary,pool]>=3.0.0
|
|
19
21
|
Requires-Dist: pydantic>=2.11.5
|
|
@@ -29,11 +31,14 @@ Requires-Dist: starlette>=0.46.2
|
|
|
29
31
|
Requires-Dist: types-tqdm>=4.67.0.20250809
|
|
30
32
|
Provides-Extra: all
|
|
31
33
|
Requires-Dist: boto3<2,>=1.38.19; extra == 'all'
|
|
34
|
+
Requires-Dist: langchain-openai>=0.3.35; extra == 'all'
|
|
32
35
|
Requires-Dist: paramiko<4.0.0,>=3.5.1; extra == 'all'
|
|
33
36
|
Requires-Dist: qdrant-client>=1.14.3; extra == 'all'
|
|
34
37
|
Requires-Dist: sshtunnel>=0.4.0; extra == 'all'
|
|
35
38
|
Provides-Extra: aws
|
|
36
39
|
Requires-Dist: boto3<2,>=1.38.19; extra == 'aws'
|
|
40
|
+
Provides-Extra: openrouter
|
|
41
|
+
Requires-Dist: langchain-openai>=0.3.35; extra == 'openrouter'
|
|
37
42
|
Provides-Extra: qdrant
|
|
38
43
|
Requires-Dist: qdrant-client>=1.14.3; extra == 'qdrant'
|
|
39
44
|
Provides-Extra: ssh
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
naas_abi_core/__init__.py,sha256=kR93ywABUBo8-tAWCHMbRcCDCJZjqq4hWwxMk3Cr9fI,56
|
|
2
|
-
naas_abi_core/apps/api/api.py,sha256=
|
|
2
|
+
naas_abi_core/apps/api/api.py,sha256=C11ItO_Xn0qh7ZubZUnQ4-Mts0Cd-Ui_4KEkU2cshqI,7127
|
|
3
3
|
naas_abi_core/apps/api/api_test.py,sha256=7H_VgnbsGqu6oGY-apAHjJr_yjIcGHY0heaEThWBsUk,10537
|
|
4
4
|
naas_abi_core/apps/api/openapi_doc.py,sha256=JbwzcmSP-Yl1rbN0QvUwOSmOFf-yKXECZ-2ptI7fWoU,11834
|
|
5
5
|
naas_abi_core/apps/mcp/Dockerfile.mcp,sha256=936qaoMFGbMvTARjzkNHMgRfGVWnolpVCrz0fBJYrLA,826
|
|
@@ -7,10 +7,11 @@ naas_abi_core/apps/mcp/mcp_server.py,sha256=U-wDl8rswMk4nefGg2SUByw4x8CM10M59FfL
|
|
|
7
7
|
naas_abi_core/apps/mcp/mcp_server_test.py,sha256=8jixnDyERM_HjjDTRtPDQcJ_rzA0ESAn147sl2Gk8gw,5636
|
|
8
8
|
naas_abi_core/apps/terminal_agent/main.py,sha256=ucrNCGjjixyiO47Eily1yAmrwznS6KOcB1kk02yt_m8,19631
|
|
9
9
|
naas_abi_core/apps/terminal_agent/terminal_style.py,sha256=YOpfvBlKU52wNyGEKbZPiRQVKxug-hI92H8ScV5L8Ew,5254
|
|
10
|
-
naas_abi_core/cli/__init__.py,sha256=
|
|
10
|
+
naas_abi_core/cli/__init__.py,sha256=P89Ihofvv_pQf2wsfYL-PjLJMl6KRj3fNNIZDB77Qy0,1324
|
|
11
11
|
naas_abi_core/cli/agent.py,sha256=fMdbC7HsrOfZSf5zVRHWSmyrejI5mUdRlAT5v5YHXzk,658
|
|
12
12
|
naas_abi_core/cli/chat.py,sha256=3t_TJ7vqCNs0MIIXOtlSke3nzy4rMSEJtB3P6pKItMo,856
|
|
13
13
|
naas_abi_core/cli/config.py,sha256=CcdDX6HKCP32NjRhbVsCOwLUC9LmaqTm2sv8W5rOt00,1484
|
|
14
|
+
naas_abi_core/cli/deploy.py,sha256=sdSRbeg3UPAujHjWLRW7zTpdIZF2GgXtOZ8bYYfe77Q,5701
|
|
14
15
|
naas_abi_core/cli/init.py,sha256=Pcy2-hy-FvpXf3UOKMP6agWyFrCl9z-KP5ktEWltPy0,220
|
|
15
16
|
naas_abi_core/cli/module.py,sha256=TBl-SpeGUcy1Rrp40Irbt34yQS00xJcNje-OijNE4Hk,717
|
|
16
17
|
naas_abi_core/cli/new.py,sha256=aFhKbTHwqYkPdzrd7r8i_h9dfzXNjI03t8qVeqME8w8,262
|
|
@@ -20,7 +21,8 @@ naas_abi_core/engine/EngineProxy.py,sha256=o-D8LlP-PjQ_Yct4JWrDZw7mA7yporxb2XrJF
|
|
|
20
21
|
naas_abi_core/engine/Engine_test.py,sha256=8eLZEnkL0IR4VAr6LF8fJ_fxZzi9s1mXCLgTVOIsR3E,161
|
|
21
22
|
naas_abi_core/engine/IEngine.py,sha256=u-m-Qrvt3SP3gYKWPFPVjV8rs05D6NGnzO3XA0FInnw,2865
|
|
22
23
|
naas_abi_core/engine/conftest.py,sha256=Al-SRVLrEdbTrX8sxQ3bBK4w1bbzE4GoBkzoBK-aXlg,932
|
|
23
|
-
naas_abi_core/engine/engine_configuration/EngineConfiguration.py,sha256=
|
|
24
|
+
naas_abi_core/engine/engine_configuration/EngineConfiguration.py,sha256=12rKgF1LaLC_YMhKEABFSdU_Fb04qGpW4tft3eVCnPI,5529
|
|
25
|
+
naas_abi_core/engine/engine_configuration/EngineConfiguration_Deploy.py,sha256=NbPMxiNt9C4zfNF70fs7a8prELpd3QAHbZlvHfwcbxs,134
|
|
24
26
|
naas_abi_core/engine/engine_configuration/EngineConfiguration_GenericLoader.py,sha256=KK2TQx6cNmoqFcwr9En00NKrX4ckkZl4ecv9QCUwPyc,1995
|
|
25
27
|
naas_abi_core/engine/engine_configuration/EngineConfiguration_ObjectStorageService.py,sha256=cPZBs5-2dqX-piIZ7KTqiOce6O6GbnDDwjPGcfDN_U4,4736
|
|
26
28
|
naas_abi_core/engine/engine_configuration/EngineConfiguration_ObjectStorageService_test.py,sha256=h1PdIbMTJWi_lG83YgpI6zg8gRo0WEWvGSE6R4uKQp4,1063
|
|
@@ -120,7 +122,8 @@ naas_abi_core/utils/onto2py/onto2py.py,sha256=_wn9qrrsWd8gO-BY4_jQJVfY87e9MJ2Er2
|
|
|
120
122
|
naas_abi_core/utils/onto2py/tests/ttl2py_test.py,sha256=5OZqSxPffjJYiX9T4rT1mV0PT1Qhf6goqEYT_mAPnaI,8055
|
|
121
123
|
naas_abi_core/workflow/__init__.py,sha256=hZD58mCB1PApxITqftP_xgjxL7NeLvOfI-rJENg1ENs,250
|
|
122
124
|
naas_abi_core/workflow/workflow.py,sha256=ZufSS073JztVl0OQRTqNyK7FepFvv7gXlc4j5FAEZCI,1216
|
|
123
|
-
|
|
124
|
-
naas_abi_core-1.0.
|
|
125
|
-
naas_abi_core-1.0.
|
|
126
|
-
naas_abi_core-1.0.
|
|
125
|
+
assets/favicon.ico,sha256=nWk8wrHZiJV3DeuWrP2MqilXxCuoNWKGtMZfYmEVQLw,666
|
|
126
|
+
naas_abi_core-1.0.8.dist-info/METADATA,sha256=7Ktah_ysJ6RSGn_ZK765ISBRn961DGiBrPLRoCCQCZw,3897
|
|
127
|
+
naas_abi_core-1.0.8.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
128
|
+
naas_abi_core-1.0.8.dist-info/entry_points.txt,sha256=q68PvlGw_rozZ0nl6mUg6l1l2IhxaTOKlf5K9goRDu0,99
|
|
129
|
+
naas_abi_core-1.0.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|